Add Hard Disks to VMs Asynchronously with PowerCLI

Add Hard Disks to VMs Asynchronously with PowerCLI


At the time of writing the New-HardDisk PowerCLI CmdLet does not yet have a -RunAsync parameter. I found this out when trying to create a new 300 GiB eagerly zeroed disk on multiple VMs in one go. I soon realised that I was going to be sat there for a long time as each new disk was being formatted one at a time. So, I asked around on the PowerCLI Slack channel for any ideas and Steve Kaplan helpfully reminded me that I should be able to work out how to add these disks asynchronously using the Code Capture feature in the HTML5 web client, and he was right! I have put together a script which you can grab from my GitHub to make things easier and I will give some brief examples below.

Using the New-HardDiskAsync.ps1 Script

Once you have a copy of the script downloaded from my GitHub repository, you will first need to connect to a vCenter server using the Connect-VIServer CmdLet.

Connect-VIServer -Server ""

First lets add a single 200 GiB thin provisioned disk to the VM named vm0123.

NOTE - These examples assume that the script is saved in the current working directory.

.\New-HardDiskAsync.ps1 -Name "vm0123" -CapacityGB 200

Now lets create a 500 GiB thick provisioned disk which is eager zeroed.

.\New-HardDiskAsync.ps1 -Name "vm0123" -CapacityGB 500 -StorageFormat "EagerZeroedThick"

We can also use the -Controller parameter to specify a particular SCSI controller if there is more than one assigned to the VM (by default if there is more than one assigned and this parameter is not specified we will pick the first SCSI controller with free capacity).

$ScsiController = Get-ScsiController -VM "vm0123"
.\New-HardDiskAsync.ps1 -Name "vm0123" -CapacityGB 500 -Controller $ScsiController[1]

NOTE - In the example above I am simply specifying which SCSI controller to use based on its index position in the $ScsiController array.

You will notice that a task object is returned by this script. This can be used to check the progress of the asynchronous task which is registered with the vCenter server by the script. In order to do this we will store the output from this script in a variable and then use the Get-Task CmdLet to see the status.

$Task = .\New-HardDiskAsync.ps1 -Name "vm0123" -CapacityGB 200
Get-Task -Id $Task.Id

Name                           State      % Complete Start Time   Finish Time
----                           -----      ---------- ----------   -----------
ReconfigVM_Task                Success           100 03:44:35 PM  03:44:35 PM


Armed with my new script I was able to save a lot of time when adding my 300 GiB thick disks to a couple of hundred VMs. Hopefully this will also help some other people out in the future, at least until VMware add implement a -RunAsync parameter on the New-HardDisk CmdLet!