Example 214 lets you start processes and invoke PowerShell expressions on remote machines. It uses PsExec (from http://www.microsoft.com/technet/sysinternals/utilities/ psexec.mspx) to support the actual remote command execution.
This script offers more power than just remote command execution, however. As Example 213 demonstrates, it leverages PowerShell’s capability to import and export strongly structured data, so you can work with the command output using many of the same techniques you use to work with command output on the local system. Example 213 demonstrates this power by filtering command output on the remote system but sorting it on the local system.
Example 213. Invoking a PowerShell expression on a remote machine
PS >$command = { GetProcess | WhereObject { $_.Handles gt 1000 } } PS >InvokeRemoteExpression \\LEEDESK $command | Sort Handles
Handles NPM(K)
PM(K)
WS(K) VM(M)
CPU(s)
Id ProcessName
1025
8
3780
3772
32
134.42
848 csrss
1306
37
50364
64160
322
409.23
4012 OUTLOOK
1813
39
54764
36360
321
340.45
1452 iTunes
2316
273
29168
41164
218
134.09
1244 svchost
Since this strongly structured data comes from objects on another system, PowerShell does not regenerate the functionality of those objects (except in rare cases).
Example 214. InvokeRemoteExpression.ps1
############################################################################## ## ## InvokeRemoteExpression.ps1 ## ## Invoke a PowerShell expression on a remote machine. Requires PsExec from ## http://www.microsoft.com/technet/sysinternals/utilities/psexec.mspx ## ## ie: ## ## PS >InvokeRemoteExpression \\LEEDESK { GetProcess } ## PS >(InvokeRemoteExpression \\LEEDESK { GetDate }).AddDays(1) ## PS >InvokeRemoteExpression \\LEEDESK { GetProcess } | Sort Handles ## ##############################################################################
param( $computer = "\\$ENV:ComputerName", [ScriptBlock] $expression = $(throw "Please specify an expression to invoke."), [switch] $noProfile )
## Prepare the command line for PsExec. We use the XML output encoding so ## that PowerShell can convert the output back into structured objects. $commandLine = "echo . | powershell Output XML "
if($noProfile) { $commandLine += "NoProfile " }
## Convert the command into an encoded command for PowerShell $commandBytes = [System.Text.Encoding]::Unicode.GetBytes($expression) $encodedCommand = [Convert]::ToBase64String($commandBytes) $commandLine += "EncodedCommand $encodedCommand"
Example 214. InvokeRemoteExpression.ps1 (continued)
## Collect the output and error output $errorOutput = [IO.Path]::GetTempFileName() $output = psexec /acceptEula $computer cmd /c $commandLine 2>$errorOutput
## Check for any errors $errorContent = GetContent $errorOutput RemoveItem $errorOutput if($errorContent match "Access is denied") {
$OFS = "`n" $errorMessage = "Could not execute remote expression. " $errorMessage += "Ensure that your account has administrative " +
"privileges on the target machine.`n" $errorMessage += ($errorContent match "psexec.exe :")
WriteError $errorMessage }
## Return the output to the user $output