PowerShell
Powershell-Remoting
Suche…
Bemerkungen
Aktivieren von PowerShell-Remoting
PowerShell-Remoting muss zuerst auf dem Server aktiviert werden, zu dem Sie eine Remote-Verbindung herstellen möchten.
Enable-PSRemoting -Force
Dieser Befehl führt Folgendes aus:
- Führt das Cmdlet Set-WSManQuickConfig aus, das die folgenden Aufgaben ausführt:
- Startet den WinRM-Dienst.
- Legt den Starttyp für den WinRM-Dienst auf Automatisch fest.
- Erstellt einen Listener, um Anforderungen an eine beliebige IP-Adresse anzunehmen, falls noch keine vorhanden ist.
- Aktiviert eine Firewall-Ausnahme für die WS-Management-Kommunikation.
- Registriert die Microsoft.PowerShell- und Microsoft.PowerShell.Workflow-Sitzungskonfigurationen, sofern diese noch nicht registriert sind.
- Registriert die Microsoft.PowerShell32-Sitzungskonfiguration auf 64-Bit-Computern, sofern diese nicht bereits registriert ist.
- Aktiviert alle Sitzungskonfigurationen.
- Ändert die Sicherheitsbeschreibung aller Sitzungskonfigurationen, um den Fernzugriff zu ermöglichen.
- Startet den WinRM-Dienst neu, damit die vorhergehenden Änderungen wirksam werden.
Nur für Umgebungen außerhalb von Domänen
Bei Servern in einer AD-Domäne erfolgt die PS-Remoting-Authentifizierung über Kerberos ('Default') oder NTLM ('Negotiate'). Wenn Sie Remoting auf einem Nicht-Domänenserver zulassen möchten, haben Sie zwei Möglichkeiten.
Richten Sie entweder die WSMan-Kommunikation über HTTPS ein (dies erfordert die Erzeugung eines Zertifikats) oder aktivieren Sie die Basisauthentifizierung, die Ihre Anmeldeinformationen über die Basis64-Verschlüsselung sendet.
In beiden Fällen müssen Sie die fernen Systeme der Liste der vertrauenswürdigen WSMan-Hosts hinzufügen.
Aktivieren der Standardauthentifizierung
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Dann auf dem Computer , von dem Sie verbinden möchten, müssen Sie es sagen , um den Computer vertrauen Sie eine Verbindung herstellen.
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 *
Wichtig : Sie müssen Ihrem Client mitteilen, dass er dem angesprochenen Computer auf die Art und Weise, wie Sie eine Verbindung herstellen möchten, vertrauen soll (z. B. wenn Sie sich über IP verbinden, muss er der IP und nicht dem Hostnamen vertrauen)
Verbindung zu einem Remote-Server über PowerShell
Verwenden von Anmeldeinformationen von Ihrem lokalen Computer:
Enter-PSSession 192.168.1.1
Aufforderung zur Eingabe von Anmeldeinformationen auf dem Remote-Computer
Enter-PSSession 192.168.1.1 -Credential $(Get-Credential)
Befehle auf einem Remote-Computer ausführen
Sobald Powershell-Remoting aktiviert ist (Enable-PSRemoting), können Sie Befehle auf dem Remote-Computer wie folgt ausführen:
Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Die obige Methode erstellt eine temporäre Sitzung und schließt diese unmittelbar nach Beendigung des Befehls oder Skriptblocks.
Um die Sitzung geöffnet zu lassen und später einen anderen Befehl auszuführen, müssen Sie zuerst eine Remote-Sitzung erstellen:
$Session = New-PSSession -ComputerName "RemoteComputerName"
Sie können diese Sitzung dann jedes Mal verwenden, wenn Sie Befehle auf dem Remote-Computer aufrufen:
Invoke-Command -Session $Session -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Invoke-Command -Session $Session -ScriptBlock {
Get-Date
}
Wenn Sie verschiedene Anmeldeinformationen verwenden müssen, können Sie diese mit dem Parameter -Credential
hinzufügen:
$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}
Serialisierungswarnung für Remoting
Hinweis:
Es ist wichtig zu wissen, dass beim Remoting PowerShell-Objekte auf dem Remote-System serialisiert und am Ende der Remoting-Sitzung deserialisiert werden, dh sie werden während des Transports in XML konvertiert und verlieren alle ihre Methoden.
$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...
Während Sie die Methoden für das reguläre PS-Objekt haben:
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)
Argumentverwendung
Um Argumente als Parameter für den Remote-Skriptblock zu verwenden, kann man entweder den ArgumentList
Parameter von Invoke-Command
oder die $Using:
-Syntax verwenden.
ArgumentList
mit unbenannten Parametern verwenden (dh in der Reihenfolge, in der sie an den Scriptblock übergeben werden):
$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
}
ArgumentList
mit benannten Parametern verwenden:
$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
}
Verwendung von $Using:
Syntax:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
Get-Service $Using:servicesToShow
Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}
Eine bewährte Methode zum automatischen Aufräumen von PSSessions
Wenn eine Remote-Sitzung über das New-PSsession
erstellt wird, bleibt die PSSession bestehen, bis die aktuelle PowerShell-Sitzung endet. Das bedeutet, dass standardmäßig die PSSession
und alle zugeordneten Ressourcen bis zum Ende der aktuellen PowerShell-Sitzung verwendet werden.
Mehrere aktive PSSessions
können Ressourcen PSSessions
, insbesondere für langlaufende oder verknüpfte Skripts, die Hunderte von PSSessions
in einer einzigen PowerShell-Sitzung erstellen.
Es wird PSSession
, jede PSSession
nach der Verwendung explizit zu entfernen. [1]
Die folgende Codevorlage verwendet try-catch-finally
, um die oben genannten PSSessions
zu erreichen. Sie kombiniert die Fehlerbehandlung mit einer sicheren Methode, um sicherzustellen, dass alle erstellten PSSessions
entfernt werden, wenn sie fertig verwendet werden:
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
}
}
Verweise: [1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession