Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Powershell running invoke-command on several servers using -Asjob but log completion log locally

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading