J'aimerais redémarrer un ordinateur distant appartenant à un domaine. J'ai un compte administrateur mais je ne sais pas comment l'utiliser depuis powershell.
Je sais qu'il existe une cmdlet Restart-Computer
et que je peux transmettre les informations d'identification, mais si mon domaine est par exemple mydomain
, mon nom d'utilisateur est myuser
et mon mot de passe est mypassword
. bonne syntaxe pour l'utiliser?
Je dois planifier le redémarrage pour ne pas avoir à saisir le mot de passe.
Le problème avec Get-Credential
est qu'il demandera toujours un mot de passe. Il existe cependant un moyen de contourner ce problème, mais cela implique de stocker le mot de passe sous forme de chaîne sécurisée sur le système de fichiers.
L'article suivant explique comment cela fonctionne:
En résumé, vous créez un fichier pour stocker votre mot de passe (sous forme de chaîne cryptée). La ligne suivante demandera un mot de passe, puis le stockera dans c:\mysecurestring.txt
sous forme de chaîne chiffrée. Vous devez seulement faire ceci une fois:
read-Host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring.txt
Chaque fois que vous voyez un argument -Credential
sur une commande PowerShell, cela signifie que vous pouvez passer un PSCredential
. Donc dans votre cas:
$username = "domain01\admin01"
$password = Get-Content 'C:\mysecurestring.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
$serverNameOrIp = "192.168.1.1"
Restart-Computer -ComputerName $serverNameOrIp `
-Authentication default `
-Credential $cred
<any other parameters relevant to you>
Vous aurez peut-être besoin d'une valeur de commutateur -Authentication
différente, car je ne connais pas votre environnement.
Il y a une autre façon, mais ...
NE LE FAITES PAS SI VOUS NE VOULEZ PAS VOTRE MOT DE PASSE DANS LE FICHIER DU SCRIPT (Ce n'est pas une bonne idée de stocker les mots de passe dans des scripts, mais certains d'entre nous aiment juste savoir comment.)
Ok, c'était l'avertissement, voici le code:
$username = "John Doe"
$password = "ABCDEF"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
$cred
aura les informations d'identification de John Doe avec le mot de passe "ABCDEF".
Autre moyen de préparer le mot de passe:
$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
En ce qui concerne le stockage des informations d'identification, j'utilise deux fonctions (qui sont normalement dans un module chargé à partir de mon profil):
#=====================================================================
# Get-MyCredential
#=====================================================================
function Get-MyCredential
{
param(
$CredPath,
[switch]$Help
)
$HelpText = @"
Get-MyCredential
Usage:
Get-MyCredential -CredPath `$CredPath
If a credential is stored in $CredPath, it will be used.
If no credential is found, Export-Credential will start and offer to
Store a credential at the location specified.
"@
if($Help -or (!($CredPath))){write-Host $Helptext; Break}
if (!(Test-Path -Path $CredPath -PathType Leaf)) {
Export-Credential (Get-Credential) $CredPath
}
$cred = Import-Clixml $CredPath
$cred.Password = $cred.Password | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password)
Return $Credential
}
Et celui-là:
#=====================================================================
# Export-Credential
# Usage: Export-Credential $CredentialObject $FileToSaveTo
#=====================================================================
function Export-Credential($cred, $path) {
$cred = $cred | Select-Object *
$cred.password = $cred.Password | ConvertFrom-SecureString
$cred | Export-Clixml $path
}
Vous l'utilisez comme ceci:
$Credentials = Get-MyCredential (join-path ($PsScriptRoot) Syncred.xml)
Si le fichier d'informations d'identification n'existe pas, vous serez invité pour la première fois. À ce stade, il stockera les informations d'identification dans une chaîne chiffrée à l'intérieur d'un fichier XML. La deuxième fois que vous exécutez cette ligne, le fichier xml est là et sera ouvert automatiquement.
Je dois exécuter les fonctions SCOM 2012 à partir d'un serveur distant nécessitant des informations d'identification différentes. J'évite les mots de passe en clair en transmettant la sortie d'une fonction de déchiffrement de mot de passe à ConvertTo-SecureString. Pour plus de clarté, ceci n'est pas montré ici.
J'aime taper fortement mes déclarations. La déclaration de type pour $ strPass fonctionne correctement.
[object] $objCred = $null
[string] $strUser = 'domain\userID'
[System.Security.SecureString] $strPass = ''
$strPass = ConvertTo-SecureString -String "password" -AsPlainText -Force
$objCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($strUser, $strPass)
Voici deux manières de procéder, si vous planifiez le redémarrage.
Tout d'abord, vous pouvez créer une tâche sur un ordinateur à l'aide des informations d'identification disposant des droits nécessaires pour se connecter et redémarrer un autre ordinateur. Cela rend le planificateur responsable du stockage sécurisé des informations d'identification. La commande de redémarrage (je suis un gars de Powershell, mais c'est plus propre.) Est la suivante:
SHUTDOWN /r /f /m \\ComputerName
La ligne de commande pour créer une tâche planifiée sur la machine locale et en redémarrer une autre à distance serait la suivante:
SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f /m \\ComputerName" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU "domain\username" /RP "password"
Je préfère la deuxième façon, où vous utilisez vos informations d'identification actuelles pour créer une tâche planifiée qui s'exécute avec le compte système sur un ordinateur distant.
SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU SYSTEM /S ComputerName
Cela fonctionne également via l'interface graphique, il suffit d'entrer SYSTEM comme nom d'utilisateur, en laissant les champs de mot de passe vides.
read-Host -assecurestring | convertfrom-securestring | out-file C:\securestring.txt
$pass = cat C:\securestring.txt | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "test",$pass
$mycred.GetNetworkCredential().Password
Soyez très prudent avec le stockage des mots de passe de cette façon ... ce n'est pas aussi sécurisé que ...
J'ai vu un exemple qui utilise Import/Export-CLIXML.
Ce sont mes commandes préférées pour le problème que vous essayez de résoudre. Et le moyen le plus simple de les utiliser est.
$passwordPath = './password.txt'
if (-not (test-path $passwordPath)) {
$cred = Get-Credential -Username domain\username -message 'Please login.'
Export-Cli -InputObject $cred -Path $passwordPath
}
$cred = Import-CliXML -path $passwordPath
Donc, si le fichier n'existe pas localement, il demandera les informations d'identification et les stockera. Cela prendra un objet [pscredential]
sans problème et cachera les informations d'identification en tant que chaîne sécurisée.
Enfin, utilisez les informations d'identification comme vous le faites habituellement.
Restart-Computer -ComputerName ... -Credentail $cred
Note sur la sécurité :
Stocker en toute sécurité les informations d'identification sur le disque
Lors de la lecture de la solution, vous pouvez d’abord vous méfier de l’enregistrement d’un mot de passe sur le disque. Bien qu'il soit naturel (et prudent) de ne pas surcharger le disque dur d'informations sensibles, l'applet de commande Export-CliXml chiffre les objets d'informations d'identification à l'aide de l'API de protection des données standard Windows. Cela garantit que seul votre compte d'utilisateur peut déchiffrer correctement son contenu. De même, la cmdlet ConvertFrom-SecureString chiffre également le mot de passe fourni.
Edit: il suffit de relire la question initiale. Ce qui précède fonctionnera tant que vous aurez initialisé le [pscredential]
sur le disque dur. C’est-à-dire que si vous déposez cela dans votre script et exécutez le script une fois que le fichier sera créé, puis l’exécution du script sans surveillance sera simple.
Solution
$userName = 'test-domain\test-login'
$password = 'test-password'
$pwdSecureString = ConvertTo-SecureString -Force -AsPlainText $password
$credential = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $userName, $pwdSecureString
Pour les machines de construction
Dans le code précédent, remplacez les valeurs de nom d'utilisateur et de mot de passe par les variables d'environnement secrètes ("masquées dans les journaux") de votre build-machine
Résultats du test en ajoutant
'# Results'
$credential.GetNetworkCredential().Domain
$credential.GetNetworkCredential().UserName
$credential.GetNetworkCredential().Password
et vous verrez
# Results
test-domain
test-login
test-password