在遠端計算機上執行命令
啟用 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
}
如果你需要使用不同的憑據,可以使用 -Credential
引數新增它們:
$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.String Time)
SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)
引數用法
要使用引數作為遠端指令碼塊的引數,可以使用 Invoke-Command
的 ArgumentList
引數,或使用 $Using:
語法。
使用帶有未命名引數的 ArgumentList
(即按照它們傳遞給 scriptblock 的順序):
$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
}