Utilisation des informations d'identification PowerShell sans être invité à entrer un mot de passe

148

Je souhaite 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 Restart-Computerapplet de commande et que je peux transmettre des informations d'identification, mais si mon domaine est par exemple mydomain, mon nom d'utilisateur est myuseret mon mot de passe est mypasswordla bonne syntaxe pour l'utiliser?

J'ai besoin de planifier le redémarrage pour ne pas avoir à taper le mot de passe.

tout regarde sur moi
la source
Vous devriez lire ce lien
jams
Que signifie get-credential domain01 \ admin01? La commande suivante est restart-computer -computername $ s -force -throttlelimit 10 -credential $ c. Cela signifie-t-il que get-credential récupère le mot de passe sans le demander?
all eyez on me

Réponses:

203

Le problème avec Get-Credentialest qu'il demandera toujours un mot de passe. Il existe cependant un moyen de contourner cela, 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:

Utilisation de PSCredentials sans invite

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 c:\mysecurestring.txtsous forme de chaîne cryptée. Vous ne devez le faire qu'une seule fois:

read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring.txt

Partout où vous voyez un -Credentialargument 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 -Authenticationvaleur de commutation différente car je ne connais pas votre environnement.

Kev
la source
24
Vous pouvez également le faire ConvertTo-SecureString "password" -AsPlainText -Force.
x0n
15
Juste pour être clair,$password = ConvertTo-SecureString "password" -AsPlainText -Force
Akira Yamamoto
-Credential [username] était requis dans les paramètres Read-Host pour moi, sinon PowerShell se bloque. Après avoir passé -Credential à read-host, vous serez invité directement dans la console PowerShell et le mot de passe est stocké correctement. Merci!
sephirot
J'essaie de comprendre comment faire fonctionner cela lorsque j'utilise la fonction Send-MailMessage dans PowerShell. Je souhaite stocker les identifiants de mon utilisateur de messagerie et le transmettre afin de ne pas avoir à continuer à les saisir. Une idée de la façon de procéder?
KangarooRIOT
@ user3681591 - Je recommanderais de poser une nouvelle question plutôt que de le faire dans les commentaires. Merci.
Kev
71

Il y a un autre moyen, mais ...

NE FAITES PAS CELA SI VOUS NE VOULEZ PAS VOTRE MOT DE PASSE DANS LE FICHIER SCRIPT (Ce n'est pas une bonne idée de stocker les mots de passe dans des scripts, mais certains d'entre nous aiment simplement 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 à l’utilisation:

$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
Jeroen Landheer
la source
Merci. C'est très utile. Dans mon cas, je créais une cmdlet PowerShell personnalisée qui prend un nom d'utilisateur et un mot de passe (en tant que secureString). En interne, l'applet de commande appelle plusieurs autres applets de commande, certaines n'ont besoin que d'un utilisateur et d'un mot de passe, mais l'une d'elles a besoin d'informations d'identification, je n'ai donc pas besoin de coder en dur le mot de passe dans mon script.
BenR
20
Un peu plus simple: $ password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
Sam
J'essaie de comprendre comment faire fonctionner cela lorsque j'utilise la fonction Send-MailMessage dans PowerShell. Je souhaite stocker les identifiants de mon utilisateur de messagerie et le transmettre afin de ne pas avoir à continuer à les saisir. Une idée de la façon de procéder?
KangarooRIOT
@ user3681591 Ce serait Send-MailMessage -Credential $ cred (avec $ cred créé comme indiqué dans cet article)
Jeroen Landheer
@JeroenLandheer J'ai essayé votre réponse (merci pour votre aide!) Mais cela n'a pas fonctionné. Mon erreur est la suivante: -Credential: Le terme «-Credential» n'est pas reconnu comme le nom d'une applet de commande, d'une fonction, d'un fichier de script ou d'un programme utilisable.
KangarooRIOT
29

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é la première fois, à ce stade, il stockera les informations d'identification dans une chaîne cryptée dans un fichier XML. La deuxième fois que vous exécutez cette ligne, le fichier xml est là et sera ouvert automatiquement.

Winfred
la source
10

Je dois exécuter les fonctions SCOM 2012 à partir d'un serveur distant qui nécessite des informations d'identification différentes. J'évite les mots de passe en texte clair en passant la sortie d'une fonction de décryptage de mot de passe en entrée de ConvertTo-SecureString. Pour plus de clarté, cela 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)
Bruce Gavin
la source
4

Voici deux façons de procéder, si vous planifiez le redémarrage.

Tout d'abord, vous pouvez créer une tâche sur une machine à l'aide des informations d'identification disposant des droits nécessaires pour se connecter et redémarrer une autre machine. Cela rend le planificateur responsable du stockage sécurisé des informations d'identification. La commande de redémarrage (je suis un gars Powershell, mais c'est plus propre.) Est:

SHUTDOWN /r /f /m \\ComputerName

La ligne de commande pour créer une tâche planifiée sur la machine locale, pour en redémarrer une autre à distance, serait:

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 méthode, 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 une machine distante.

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, entrez simplement SYSTEM comme nom d'utilisateur, en laissant les champs de mot de passe vides.

Nathan Hartley
la source
1
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ûr que ...

MockMyBeret
la source
1

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 [pscredential]objet sans problème et masquera les informations d'identification en tant que chaîne sécurisée.

Enfin, utilisez simplement les informations d'identification comme vous le faites normalement.

Restart-Computer -ComputerName ... -Credentail $cred

Remarque sur la sécurité :

Stockez en toute sécurité les informations d'identification sur le disque

Lors de la lecture de la solution, vous pourriez au début hésiter à stocker un mot de passe sur le disque. S'il est naturel (et prudent) de ne pas gâcher votre disque dur d'informations sensibles, l'applet de commande Export-CliXml crypte les objets d'identification à l'aide de l'API de protection des données standard de Windows. Cela garantit que seul votre compte utilisateur peut décrypter correctement son contenu. De même, la cmdlet ConvertFrom-SecureString chiffre également le mot de passe que vous fournissez.

Edit: Relisez simplement la question d'origine. Ce qui précède fonctionnera tant que vous avez initialisé le [pscredential]sur le disque dur. C'est si vous déposez cela dans votre script et exécutez le script une fois qu'il créera ce fichier, puis exécuter le script sans assistance sera simple.

ScriptingDad
la source
1

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 des variables d'environnement secrètes ("cachées des journaux") de votre machine de construction

Résultats des tests par

'# Results'
$credential.GetNetworkCredential().Domain
$credential.GetNetworkCredential().UserName
$credential.GetNetworkCredential().Password

et tu verras

# Results
test-domain
test-login
test-password
it3xl
la source
-3

pourquoi n'essayez-vous pas quelque chose de très simple?

utilisez psexec avec la commande 'shutdown / r / f / t 0' et une liste de PC de CMD.

Boucle racine
la source
C'est un cas particulier. Le point n'est pas de générer une fenêtre de connexion dans un scénario aléatoire.
Overmind