Question

I have a small Powershell script that is used to shut down my virtual machines in event of an extended power outage. It takes a specific VM object and forces a shutdown.

Function DirtyShutdown
{ param([VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl]$VM )
$VM | Stop-VM -Confirm:$false
}

I would like to speed up this process using the start-job command to run all these tasks in parallel. I have tried using several variants including the following which I believe to be correct.

Start-Job -InputObject $VM -ScriptBlock{ $input | Shutdown-VMGuest -Confirm:$false }

Based on the Receive-Job output it appears the problem is the snap in in use (added before the above function is called) is not loaded in the context of Start-Job.

What is the correct syntax to make this happen?

Was it helpful?

Solution

While I appreciate the desire to use PowerShell v2's job subsystem for this task, note that vCenter has a built-in job system which you can take advantage of here. Most PowerCLI cmdlets which perform a change to your environment have a RunAsync parameter. To know which ones, run this piece of PowerShell code:

get-help * -parameter runasync

The RunAsync parameter will take your command(s) and queue them up in vCenter. The cmdlet will return a task object and then immediately return control back to your script.

To turn this into an answer in your case, simply append "-runasync" to the end of your Stop-VM command, like so:

$VM | Stop-VM -Confirm:$false -RunAsync

OTHER TIPS

Each time you start a job, PowerShell creates a new runspace. This means a new environment that you may need to initialize, and that includes loading snap-ins and connecting to your VI Server. Start-Job has a parameter that you can use here called InitializationScript. Try something like this:

Start-Job -InitializationScript { Add-PSSnapin VMware.VimAutomation.Core } {
    Connect-ViServer myserver
    Get-VM foo | Stop-VM
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top