Rather than working in an interactive session, you can use the Invoke-Command cmdlet with the –AsJob parameter to start background jobs and return results to the local computer. When you use the –AsJob parameter, the job object is created on the local computer, even though the job runs on the remote computer. When the job completes, the results are returned to the local computer.
In the following example, we create a noninteractive PowerShell session with three remote computers and then use Invoke-Command to run a background job that gets the events in the System, Application, and Security logs. This is the same job created earlier, only now the job runs on all the computers listed in the –ComputerName parameter. Type the command as a single line:
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 Invoke-command –session $s
-asjob -scriptblock {$share = "\\FileServer85\logs"; $logs = "system","application","security";
foreach ($log in $logs) {
$filename = "$env:computername".ToUpper() + "$log" + "log" + (get-date -format yyyyMMdd) + ".log";
Get-EventLog $log | set-content $share\$filename; } }
receive-job –name Job1 >> c:\logs\mylog.txt receive-job –name Job2 >> c:\logs\mylog.txt receive-job –name Job3 >> c:\logs\mylog.txt
$ms = new-pssession -computername fileserver84
invoke-command -session $ms -scriptblock {get-content c:\logs\mylog.txt}
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 Invoke-command –session $s
-asjob -scriptblock {$share = "\\FileServer85\logs"; $logs = "system","application","security";
foreach ($log in $logs) {
$filename = "$env:computername".ToUpper() + "$log" + "log" + (get-date -format yyyyMMdd) + ".log";
Get-EventLog $log | set-content $share\$filename; } }
Or use the back apostrophe to continue the line as shown here:
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 ` Invoke-command –session $s `
-asjob -scriptblock {$share = "\\FileServer85\logs"; ` $logs = "system","application","security"; `
foreach ($log in $logs) { `
$filename = "$env:computername".ToUpper() + "$log" + "log" + ` (get-date -format yyyyMMdd) + ".log"; `
Get-EventLog $log | set-content $share\$filename; } ` }
Alternatively, you can store the commands as a script on the local computer and then reference the local script using the –FilePath parameter as shown in the examples that follow.
Command line
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 Invoke-command –session $s -asjob -filepath c:\scripts\eventlogs.ps1
Source for Eventlogs.ps1
$share = "\\FileServer85\logs"
$logs = "system","application","security" foreach ($log in $logs) {
$filename = "$env:computername".ToUpper() + "$log" + "log" + ` (get-date -format yyyyMMdd) + ".log"
Get-EventLog $log | set-content $share\$filename }
The script must reside on the local computer or in a directory that the local com- puter can access. As before, when you use FilePath, Windows PowerShell converts the contents of the specifi ed script fi le to a script block and runs the script block as a background job.
Now, you don’t necessarily have to run Invoke-Command via a noninteractive session. However, the advantage of doing so is that you can now work with the job objects running in the session. For example, to get information about the jobs on all three computers, you type the following command:
get-job
To receive job results you type this command:
receive-job -keep
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 ` Invoke-command –session $s `
-asjob -scriptblock {$share = "\\FileServer85\logs"; ` $logs = "system","application","security"; `
foreach ($log in $logs) { `
$filename = "$env:computername".ToUpper() + "$log" + "log" + ` (get-date -format yyyyMMdd) + ".log"; `
Get-EventLog $log | set-content $share\$filename; } ` }
Command line
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 Invoke-command –session $s -asjob -filepath c:\scripts\eventlogs.ps1
Source for Eventlogs.ps1
$share = "\\FileServer85\logs"
$logs = "system","application","security" foreach ($log in $logs) {
$filename = "$env:computername".ToUpper() + "$log" + "log" + ` (get-date -format yyyyMMdd) + ".log"
Get-EventLog $log | set-content $share\$filename }
Or you can type the following if you want to save the results to a file on the local computer:
receive-job > c:\logs\mylog.txt
A variation on this technique is to use the Invoke-Command cmdlet to run the Start-Job cmdlet. This technique allows you to run background jobs on multiple computers and keep the results on the remote computers. Here’s how this works: 1. You use Invoke-Command without the –AsJob parameter to run the Start-
Job cmdlet.
2. A job object is created on each remote computer.
3. Commands in the job are run separately on each remote computer. 4. Job results are maintained separately on each remote computer. 5. You work with the job objects and results on each remote computer
separately.
Here, you use Invoke-Command to start jobs on three computers and store the Job objects in the $j variable:
$s = new-pssession -computername fileserver34, dataserver18, dcserver65 $j = invoke-command –session $s {start-job -filepath c:\scripts\elogs.ps1}
Again, you don’t necessarily have to run Invoke-Command via a noninteractive session. However, the advantage of doing so is that you can now work with the job objects running on all three computers via the session. For example, to get informa- tion about the jobs on all three computers, you type the following command:
invoke-command -session $s -scriptblock {get-job}
Or, because you stored the Job objects in the $j variable, you also could enter:
$j
To receive job results, you type this command:
invoke-command -session $s -scriptblock { param($j) receive-job –job $j -keep} –argumentlist $j
Or you can do the following if you want to save the results to a file on each remote computer:
invoke-command -session $s -command {param($j) receive-job –job $j > c:\ logs\mylog.txt} –argumentlist $j
In both examples, you use Invoke-Command to run a Receive-Job command in each session in $s. Because $j is a local variable, the script block uses the “param” keyword to declare the variable in the command and the ArgumentList parameter to supply the value of $j.