PowerShell 在远程计算机上运行命令

示例

启用Powershell远程处理(Enable-PSRemoting)之后,您可以在远程计算机上运行以下命令:

Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
    Write host "Remote Computer Name: $ENV:ComputerName"
}

上面的方法创建一个临时会话,并在命令或脚本块结束后立即关闭它。

要使会话保持打开状态并在以后运行其他命令,您需要首先创建一个远程会话:

$Session = New-PSSession -ComputerName "RemoteComputerName"

然后,您可以在每次在远程计算机上调用命令时使用此会话:

Invoke-Command -Session $Session -ScriptBlock {
    Write host "Remote Computer Name: $ENV:ComputerName"
}

Invoke-Command -Session $Session -ScriptBlock {
    Get-Date
}

如果您需要使用其他凭证,则可以使用-CredentialParameter来添加它们:

$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}

远程处理序列化警告

注意:

重要的是要知道,远程处理会序列化远程系统上的PowerShell对象,并在远程处理会话结束时对它们进行反序列化,即,它们在传输期间会转换为XML,并且会丢失所有方法。

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

而您在常规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.StringTime)                                  
SetSecurityDescriptor Method     System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)

参数用法

要将参数用作远程脚本块的ArgumentList参数,可以使用的参数Invoke-Command,也可以使用$Using:语法。

ArgumentList与未命名的参数一起使用(即按将它们传递到脚本块的顺序):

$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与命名参数一起使用:

$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:语法:

$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
    Get-Service $Using:servicesToShow
    Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}