Skip to content

Instantly share code, notes, and snippets.

@jakobii
Last active January 7, 2020 20:07
Show Gist options
  • Save jakobii/bc9a19a8f9bdb986c28263867f443a1e to your computer and use it in GitHub Desktop.
Save jakobii/bc9a19a8f9bdb986c28263867f443a1e to your computer and use it in GitHub Desktop.
Remote PSSession Tasks
# This is a scriptblock that will be invoked on the remote computer. This is
# just dummy code that gets the computers hostname from the global built in
# eniorment variable $env.
$RemoteTask = {
param(
[datetime]$Start
)
# pause remote script execition until the specified start time.
# you can use this to loosely sync jobs execution.
$SleepDuration = New-TimeSpan -Start $(get-date) -End $Start
Start-Sleep -Milliseconds $SleepDuration.TotalMilliseconds
# anything in this block will be invoked on the remote computers
Write-Host "Hello from $($env:COMPUTERNAME)!"
}
# An array of all the computer names. Computer names must be valid. ip address
# are also valid
$Computers = @(
'COMPUTER1'
'COMPUTER2'
)
# This script assumses that powershell remoting is enabled on all computers.
$Sessions = New-PSSession -ComputerName $Computers
# A dynamic array to store all the jobs
[system.collections.arraylist]$jobs = @()
# jobs will use this time to sync there execution. this assumes that it will
# take less then 30 second to startup all the jobs.
$JobStartTime = $(get-date).AddSeconds(30)
# Normally the Invoke-Command will wait until the scriptbock finishes before
# moving to the next session in the foreach loop, but the -AsJob parameter
# will convert the command into a powershell job, which will allow the loop
# to continue as soon as the job starts.
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_jobs
foreach($Session in $Sessions){
$jobs += Invoke-Command -Session $Session -ScriptBlock $RemoteTask -ArgumentList $JobStartTime -AsJob
}
# piping jobs to wait-job will cause the script to wait for all remote jobs to finish.
$jobs | Wait-Job | Out-Null
# once all jobs are finished you can receive the output from the jobs.
# in this case it will be the output of Write-Host from the Remote Task.
foreach($job in $jobs){
$RemoteOutput = $job | Receive-Job
Write-Host $RemoteOutput
}
# clean up. just be sure the jobs are finished...
Disconnect-PSSession -Session $Sessions | Out-Null
@jakobii
Copy link
Author

jakobii commented Dec 23, 2019

Alternatively the script could use get-job instead of wait-job to check the status of each job, then use receive-job on jobs that have completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment