PowerShell
Powershell Remoting
Szukaj…
Uwagi
Włączanie usługi PowerShell Remoting
Przekazywanie programu PowerShell musi być najpierw włączone na serwerze, z którym chcesz się połączyć zdalnie.
Enable-PSRemoting -Force
To polecenie wykonuje następujące czynności:
- Uruchamia polecenie cmdlet Set-WSManQuickConfig, które wykonuje następujące zadania:
- Uruchamia usługę WinRM.
- Ustawia typ uruchamiania w usłudze WinRM na Automatyczny.
- Tworzy detektor do akceptowania żądań na dowolnym adresie IP, jeśli jeszcze nie istnieje.
- Włącza wyjątek zapory dla komunikacji WS-Management.
- Rejestruje konfiguracje sesji Microsoft.PowerShell i Microsoft.PowerShell.Workflow, jeśli nie są one jeszcze zarejestrowane.
- Rejestruje konfigurację sesji Microsoft.PowerShell32 na komputerach 64-bitowych, jeśli nie jest jeszcze zarejestrowana.
- Umożliwia wszystkie konfiguracje sesji.
- Zmienia deskryptor zabezpieczeń wszystkich konfiguracji sesji, aby umożliwić zdalny dostęp.
- Ponownie uruchamia usługę WinRM, aby zastosować powyższe zmiany.
Tylko w środowiskach innych niż domena
W przypadku serwerów w domenie AD uwierzytelnianie zdalne PS odbywa się za pośrednictwem Kerberos („Domyślne”) lub NTLM („Negocjuj”). Jeśli chcesz zezwolić na zdalne przeniesienie na serwer inny niż domena, masz dwie opcje.
Skonfiguruj komunikację WSMan przez HTTPS (która wymaga generowania certyfikatu) lub włącz podstawowe uwierzytelnianie, które wysyła twoje poświadczenia w formie przewodowej w kodowaniu base64 (to w zasadzie to samo co zwykły tekst, więc bądź ostrożny).
W obu przypadkach musisz dodać systemy zdalne do listy zaufanych hostów WSMan.
Włączanie podstawowego uwierzytelniania
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Następnie na komputerze, który chcesz połączyć z, trzeba powiedzieć to zaufanie komputer łączysz się.
Set-Item WSMan:\localhost\Client\TrustedHosts '192.168.1.1,192.168.1.2'
Set-Item WSMan:\localhost\Client\TrustedHosts *.contoso.com
Set-Item WSMan:\localhost\Client\TrustedHosts *
Ważne : musisz powiedzieć klientowi, aby ufał komputerowi adresowanemu w sposób, w jaki chcesz się połączyć (np. Jeśli łączysz się przez IP, musi ufać adresowi IP, a nie nazwie hosta)
Łączenie ze zdalnym serwerem za pomocą programu PowerShell
Korzystanie z poświadczeń z komputera lokalnego:
Enter-PSSession 192.168.1.1
Monitowanie o poświadczenia na komputerze zdalnym
Enter-PSSession 192.168.1.1 -Credential $(Get-Credential)
Uruchom polecenia na komputerze zdalnym
Po włączeniu zdalnego programu PowerShell (Enable-PSRemoting) Możesz uruchamiać polecenia na komputerze zdalnym w następujący sposób:
Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Powyższa metoda tworzy sesję tymczasową i zamyka ją zaraz po zakończeniu polecenia lub skryptu.
Aby pozostawić sesję otwartą i uruchomić w niej inne polecenie, musisz najpierw utworzyć sesję zdalną:
$Session = New-PSSession -ComputerName "RemoteComputerName"
Następnie możesz użyć tej sesji za każdym razem, gdy wywołujesz polecenia na komputerze zdalnym:
Invoke-Command -Session $Session -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Invoke-Command -Session $Session -ScriptBlock {
Get-Date
}
Jeśli chcesz użyć różnych poświadczeń, możesz dodać je za pomocą parametru -Credential
:
$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}
Zdalne ostrzeżenie o serializacji
Uwaga:
Ważne jest, aby wiedzieć, że zdalne serializowanie obiektów PowerShell w zdalnym systemie i deserializowanie ich na końcu sesji zdalnej, tj. Są one konwertowane na XML podczas transportu i tracą wszystkie swoje metody.
$output = Invoke-Command -Session $Session -ScriptBlock {
Get-WmiObject -Class win32_printer
}
$output | Get-Member -MemberType Method
TypeName: Deserialized.System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(string format, System.IFormatProvi...
Podczas gdy masz metody na zwykłym obiekcie PS:
Get-WmiObject -Class win32_printer | Get-Member -MemberType Method
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
CancelAllJobs Method System.Management.ManagementBaseObject CancelAllJobs()
GetSecurityDescriptor Method System.Management.ManagementBaseObject GetSecurityDescriptor()
Pause Method System.Management.ManagementBaseObject Pause()
PrintTestPage Method System.Management.ManagementBaseObject PrintTestPage()
RenamePrinter Method System.Management.ManagementBaseObject RenamePrinter(System.String NewPrinterName)
Reset Method System.Management.ManagementBaseObject Reset()
Resume Method System.Management.ManagementBaseObject Resume()
SetDefaultPrinter Method System.Management.ManagementBaseObject SetDefaultPrinter()
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time)
SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)
Wykorzystanie argumentu
Aby użyć argumentów jako parametrów dla zdalnego bloku skryptowego, można użyć parametru ArgumentList
Invoke-Command
lub użyć składni $Using:
:.
Używanie ArgumentList
z nienazwanymi parametrami (tj. W kolejności, w jakiej są przekazywane do bloku skryptu):
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $args[0]
Remove-Item -Path $args[1] -ErrorAction SilentlyContinue -Force
}
Używanie ArgumentList
z nazwanymi parametrami:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Param($serviceToShowInRemoteSession,$fileToDelete)
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $serviceToShowInRemoteSession
Remove-Item -Path $fileToDelete -ErrorAction SilentlyContinue -Force
}
Using $Using:
składnia:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
Get-Service $Using:servicesToShow
Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}
Najlepsza praktyka do automatycznego usuwania sesji PSS
Gdy sesja zdalna jest tworzona za pomocą New-PSsession
cmdlet New-PSsession
, PSSession trwa do momentu zakończenia bieżącej sesji PowerShell. Oznacza to, że domyślnie PSSession
i wszystkie powiązane zasoby będą używane do momentu zakończenia bieżącej sesji PowerShell.
Wiele aktywnych PSSessions
może stać się obciążeniem dla zasobów, szczególnie dla długo działających lub połączonych skryptów, które tworzą setki PSSessions
w jednej sesji PowerShell.
Najlepszym rozwiązaniem jest jawne usunięcie każdej PSSession
po jej zakończeniu. [1]
Poniższy szablon kodu wykorzystuje try-catch-finally
w celu osiągnięcia powyższego, łącząc obsługę błędów z bezpiecznym sposobem, aby upewnić się, że wszystkie utworzone PSSessions
są usuwane po zakończeniu ich używania:
try
{
$session = New-PSsession -Computername "RemoteMachineName"
Invoke-Command -Session $session -ScriptBlock {write-host "This is running on $ENV:ComputerName"}
}
catch
{
Write-Output "ERROR: $_"
}
finally
{
if ($session)
{
Remove-PSSession $session
}
}
Odniesienia: [1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession