1

I have a powershell script which takes a number of hostnames as input, then install IE11 and Office 2010 in them. Currently it install these in one host, then continue to the next one etc. This is simply wasting time as the installation in one will not affect the other one. So how can i make it to run in parallel ? TIY Here is my code :

Write-Host "*************************************************"
Write-Host "Welcome to the IE11/Office 2010 Remote Installer"
Write-Host "*************************************************"

$pclist = (Read-Host "Enter the pc names seperated by comma").Split(",")

foreach ($pc in $pclist) {
    Write-Host "-------------------------------------------------------------------------------------------------------"
    Write-Host "Installing IE in $($pc). Please look for the exit code in the end. Exit code 0 means successful"
    psexec -s \\$pc \\myserver\directory\PREREQ.BAT
    psexec -s \\$pc \\myserver\directory\INSTALL.BAT
    Write-Host "-------------------------------------------------------------------------------------------------------"
    Write-Host "Installing office in $($pc). Please look for the exit code in the end. Exit code 0 means successful"
    psexec -s \\$pc \\myserver\directory\INSTALL.BAT
    Write-Host "-------------------------------------------------------------------------------------------------------"
    Write-Host "RESTART THE PC TO APPLY CHANGES"
}

1 Answer 1

1

Have a look at Start-Job, Wait-Job and Receive-Job.
I removed the Write-Host statements to make it simpler to read.

$jobs = $pclist | % {
    Start-Job -ScriptBlock {
        $target = $args[0]
        psexec -s \\$target \\myserver\directory\PREREQ.BAT
        psexec -s \\$target \\myserver\directory\INSTALL.BAT
        psexec -s \\$target \\myserver\directory\INSTALL.BAT
    } -ArgumentList $_
}
$jobs | Wait-Job | Receive-Job

Update for receiving output while jobs are still running via Register-EngineEvent:

$null = Register-EngineEvent -SourceIdentifier PcInstallMsg -Action {
    Write-Host $Event.MessageData
}

$jobs = $pclist | % {
    Start-Job -ScriptBlock {
        $null = Register-EngineEvent -Forward -SourceIdentifier PcInstallMsg

        $target = $args[0]

        $null = New-Event -SourceIdentifier PcInstallMsg -MessageData "Install pre-req stuff to $target"
        Start-Sleep -Seconds 2

        $null = New-Event -SourceIdentifier PcInstallMsg -MessageData "Install main stuff to $target"
        Start-Sleep -Seconds 2

        $null = New-Event -SourceIdentifier PcInstallMsg -MessageData "Do cleanup bc I was messy on $target"
        Start-Sleep -Seconds 2

    } -ArgumentList $_
}
while (-not (Wait-Job $jobs -Timeout 1)) {
}
$jobs | Receive-Job

Unregister-Event -SourceIdentifier PcInstallMsg
Sign up to request clarification or add additional context in comments.

3 Comments

thank you, this works as expected. However is there a way to show comments on the screen on what is happening on the go? Like installing IE on pc1, installing IE on pc2 etc? I put a write-host, but it displays only after the process is completed. [ pardon, this is the first every powershell code that i write]
Well that is unfortunately a bit more complex as jobs are more or less separate PowerShell instances - see my update.
Thanks, but unfortunately, this is not what I am looking for. When the install.bat file is executing, it prints some output at real time on what is happening. I was expecting it to print the same in this case also. Is there any way for that? Currently it prints all at the end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.