I am trying to run a powershell script that installs some software on a bunch of remote servers. I am using the -Asjob option to run them synchronously. I'm also using for loop to run the remote commands on each server, but i want to write a "Done" log file locally where i am running the script to notify me exactly when each server completes the commands.
This is the sample code i am testing, and the script runs fine, but the "Done" log files gets generated immediately, and not as each server finishes.
$VerbosePreference = 'Continue'
$servers = Get-Content -Path f:\temp\servers.txt
foreach($server in $servers) {
Write-Verbose "Start batch file as a job on $server"
Start-Sleep -Seconds 3
Invoke-Command -ComputerName $server -ScriptBlock {
echo testfile1 > f:\temp\testfile1.txt
Start-Sleep -Seconds 20
echo testfile2 > f:\temp\testfile2.txt
Start-Sleep -Seconds 20
echo testfile3 > f:\temp\testfile3.txt
echo DONE} > f:\temp\$server.done.txt -Asjob
}
thanks
CodePudding user response:
Remove the redirection operator after Invoke-Command { ... }
- otherwise you'll be redirecting the resulting job objects to file, rather than the output from the jobs - instead, collect all the job objects to a variable $jobs
:
$VerbosePreference = 'Continue'
$servers = Get-Content -Path f:\temp\servers.txt
$jobs = foreach($server in $servers) {
Write-Verbose "Start batch file as a job on $server"
Start-Sleep -Seconds 3
Invoke-Command -ComputerName $server -ScriptBlock {
echo testfile1 > f:\temp\testfile1.txt
Start-Sleep -Seconds 20
echo testfile2 > f:\temp\testfile2.txt
Start-Sleep -Seconds 20
echo testfile3 > f:\temp\testfile3.txt
echo DONE} -Asjob
}
Now that we've kicked off all the remoting jobs and collected the pertaining job object, we simply need to wait and then collect the output:
foreach($job in $jobs){
# Wait for jobs to finish, retrieve their output
$jobOutput = $job |Receive-Job -Wait
# Grab the remote server name from the output
$server = $jobOutput |ForEach-Object PSComputerName |Select -First 1
# Write output to file
$jobOutput > f:\temp\$server.done.txt
}