Korzystanie z poświadczeń programu PowerShell bez pytania o hasło


147

Chciałbym ponownie uruchomić komputer zdalny należący do domeny. Mam konto administratora, ale nie wiem, jak go używać z PowerShell.

Wiem, że istnieje polecenie Restart-Computercmdlet i że mogę przekazać poświadczenia, ale jeśli na przykład moja domena to mydomainmoja nazwa użytkownika, myusera moje hasło jest mypasswordwłaściwą składnią, aby go używać?

Muszę zaplanować ponowne uruchomienie, więc nie muszę wpisywać hasła.


Powinieneś przeczytać ten link
zacina

Co oznacza get-credential domain01 \ admin01? Następne polecenie to restart-computer -computername $ s -force -throttlelimit 10 -credential $ c. Czy to oznacza, że ​​get-credential pobiera hasło bez pytania?
wszyscy patrzą na mnie

Odpowiedzi:


202

Problem Get-Credentialpolega na tym, że zawsze zapyta o hasło. Jest jednak na to sposób, ale wymaga to przechowywania hasła jako bezpiecznego ciągu w systemie plików.

Poniższy artykuł wyjaśnia, jak to działa:

Korzystanie z PSCredentials bez monitu

Podsumowując, tworzysz plik do przechowywania hasła (jako zaszyfrowany ciąg). Następujący wiersz poprosi o hasło, a następnie zapisze je c:\mysecurestring.txtjako zaszyfrowany ciąg. Musisz to zrobić tylko raz:

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

Gdziekolwiek zobaczysz -Credentialargument w poleceniu PowerShell, oznacza to, że możesz przekazać plik PSCredential. Więc w twoim przypadku:

$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>

Możesz potrzebować innej -Authenticationwartości przełącznika, ponieważ nie znam Twojego środowiska.


23
Ty też możesz to zrobić ConvertTo-SecureString "password" -AsPlainText -Force.
x0n

14
Dla jasności,$password = ConvertTo-SecureString "password" -AsPlainText -Force
Akira Yamamoto

-Credential [nazwa użytkownika] było wymagane w parametrach Read-Host dla mnie, w przeciwnym razie PowerShell po prostu się zawiesza. Po przekazaniu -Credential do odczytu-hosta zostaniesz poproszony bezpośrednio w konsoli PowerShell, a hasło zostanie poprawnie zapisane. Dziękuję Ci!
sefira

Próbuję dowiedzieć się, jak to działa, gdy używam funkcji Send-MailMessage w programie PowerShell. Chcę przechowywać dane uwierzytelniające mojego użytkownika poczty e-mail i przejść, aby nie musieć ich wprowadzać. Masz pomysł, jak to zrobić?
KangarooRIOT

@ user3681591 - radziłbym zadać nowe pytanie zamiast robić to w komentarzach. Dzięki.
Kev

71

Jest inny sposób, ale ...

NIE ROBIĆ TEGO, JEŚLI NIE CHCESZ HASŁA W PLIKU SKRYPTU (przechowywanie haseł w skryptach nie jest dobrym pomysłem, ale niektórzy z nas po prostu lubią wiedzieć, jak to zrobić).

Ok, to było ostrzeżenie, oto kod:

$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 będzie mieć poświadczenia od Johna Doe z hasłem „ABCDEF”.

Alternatywne sposoby przygotowania hasła do użycia:

$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force

Dzięki. To jest bardzo pomocne. W moim przypadku tworzyłem niestandardowy cmdlet PowerShell, który przyjmuje nazwę użytkownika i hasło (jako secureString). Wewnętrznie polecenie cmdlet wywołuje kilka innych poleceń cmdlet, niektóre potrzebują tylko użytkownika i hasła, ale jedno z nich wymaga poświadczenia, więc nie muszę w rzeczywistości kodować hasła na stałe w moim skrypcie.
BenR

20
Nieco prostsze: $ password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
Sam

Próbuję dowiedzieć się, jak to działa, gdy używam funkcji Send-MailMessage w programie PowerShell. Chcę przechowywać dane uwierzytelniające mojego użytkownika poczty e-mail i przejść, aby nie musieć ich wprowadzać. Masz pomysł, jak to zrobić?
KangarooRIOT

@ user3681591 To byłoby Send-MailMessage -Credential $ cred (z $ cred utworzonym, jak pokazano w tym poście)
Jeroen Landheer

@JeroenLandheer Wypróbowałem Twoją odpowiedź (dzięki za pomoc!), Ale nie zadziałała. Mój błąd to: -Credential: Termin „-Credential” nie jest rozpoznawany jako nazwa polecenia cmdlet, funkcji, pliku skryptu lub programu operacyjnego.
KangarooRIOT

29

Jeśli chodzi o przechowywanie poświadczeń, używam dwóch funkcji (które zwykle znajdują się w module ładowanym z mojego profilu):

#=====================================================================
# 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
}

I ten:

#=====================================================================
# 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
}

Używasz tego w ten sposób:

$Credentials = Get-MyCredential (join-path ($PsScriptRoot) Syncred.xml)

Jeśli plik poświadczeń nie istnieje, za pierwszym razem zostanie wyświetlony monit, w tym momencie będzie przechowywać poświadczenia w zaszyfrowanym ciągu w pliku XML. Przy drugim uruchomieniu tej linii plik xml jest dostępny i zostanie otwarty automatycznie.


10

Muszę uruchomić funkcje SCOM 2012 ze zdalnego serwera, który wymaga innego poświadczenia. Unikam haseł w postaci zwykłego tekstu, przekazując dane wyjściowe funkcji deszyfrowania hasła jako dane wejściowe do ConvertTo-SecureString. Dla jasności nie pokazano tego tutaj.

Lubię mocno wpisywać swoje deklaracje. Deklaracja typu dla $ strPass działa poprawnie.

[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)

4

Oto dwa sposoby, aby to zrobić, jeśli planujesz ponowne uruchomienie.

Najpierw możesz utworzyć zadanie na jednym komputerze, używając poświadczeń, które mają uprawnienia potrzebne do połączenia i ponownego uruchomienia innego komputera. To powoduje, że planista jest odpowiedzialny za bezpieczne przechowywanie poświadczeń. Polecenie ponownego uruchomienia (jestem facetem z Powershell, ale to jest czystsze) to:

SHUTDOWN /r /f /m \\ComputerName

Wiersz poleceń służący do utworzenia zaplanowanego zadania na komputerze lokalnym, aby zdalnie zrestartować inny, wyglądałby następująco:

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"

Wolę drugi sposób, w którym używasz swoich bieżących poświadczeń do tworzenia zaplanowanego zadania uruchamianego z kontem systemowym na zdalnym komputerze.

SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU SYSTEM /S ComputerName

Działa to również przez GUI, wystarczy wpisać SYSTEM jako nazwę użytkownika, pozostawiając puste pola hasła.


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

Zachowaj ostrożność podczas przechowywania haseł w ten sposób ... nie jest to tak bezpieczne, jak ...


1

Widziałem jeden przykład, który używa Import / Export-CLIXML.

To są moje ulubione polecenia dotyczące problemu, który próbujesz rozwiązać. Najprostszym sposobem ich użycia jest.

$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

Jeśli więc plik nie istnieje lokalnie, zapyta o poświadczenia i zapisze je. To zajmie[pscredential] bezproblemowe obiektu i ukrycie poświadczeń jako bezpieczny ciąg.

Na koniec użyj poświadczeń, tak jak zwykle.

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

Uwaga dotycząca bezpieczeństwa :

Bezpiecznie przechowuj poświadczenia na dysku

Czytając Rozwiązanie, możesz początkowo obawiać się przechowywania hasła na dysku. Chociaż zachowanie ostrożności przed zaśmiecaniem dysku twardego poufnymi informacjami jest naturalne (i rozważne), polecenie cmdlet Export-CliXml szyfruje obiekty poświadczeń przy użyciu standardowego interfejsu API ochrony danych systemu Windows. Dzięki temu tylko Twoje konto użytkownika może poprawnie odszyfrować jego zawartość. Podobnie polecenie cmdlet ConvertFrom-SecureString również szyfruje podane hasło.

Edycja: po prostu ponownie przeczytaj oryginalne pytanie. Powyższe będzie działać tak długo, jak zainicjujesz [pscredential]na dysku twardym. To znaczy, jeśli upuścisz to w swoim skrypcie i uruchomisz go, gdy utworzy on ten plik, a następnie uruchomienie skryptu bez nadzoru będzie proste.


1

Rozwiązanie

$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

Maszyny budujące
W poprzednim kodzie zastąp wartości nazwy użytkownika i hasła tajnymi („ukrytymi w dziennikach”) zmiennymi środowiskowymi maszyny budującej

Wyniki testów wg

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

i zobaczysz

# Results
test-domain
test-login
test-password

-3

dlaczego nie spróbujesz czegoś bardzo prostego?

użyj psexec z poleceniem „shutdown / r / f / t 0” i listą komputerów z CMD.


To szczególny przypadek. Punkt nie tworzy okna logowania w żadnym przypadkowym scenariuszu.
Overmind
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.