Recently I was looking for a way to consume the Storage Policy Based Management (SPBM) cmdlets in PowerCLI. I wanted to see if I could provision a VM from a Template onto my vSAN datastore with a particular policy rather than simply change it after it was deployed. It wasn’t as easy as I thought, as some of the commands I tried would only change the VM Home Namespace to the new policy, and leave the disks with the default datastore policy. And when I tried to clone a new VM from a template, I couldn’t get the VM to pick up the policy at all. After much trial and error, and some guidance from one of our PowerCLI engineers, Manish Tiwari, we eventually managed to achieve what I set out to so. Here are some examples if you wish to do something like this yourself. Note this is PowerCLI version 10.1.0 build 8346946. The commands are run against a vSphere 6.7 GA deployment.

1. Use New-VM with Set-SpbmEntityConfiguration to set the policy

Result: Works on VM Home Namespace only.

PS C:\Users\chogan>New-VM -Name 30julytest3 -Datastore vsanDatastore \ -ResourcePool CH-Cluster | Set-SpbmEntityConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest3 RAID-5 compliant 7/30/2018 9:38:12 AM PS C:\Users\chogan>Get-VM -Name 30julytest3 | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest3 RAID-5 compliant 7/30/2018 9:38:12 AM PS C:\Users\chogan>Get-VM -Name 30julytest3 | Get-Harddisk | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 vSAN Default Storage Policy compliant 7/30/2018 9:38:07 AM

2. Use New-VM with -AdvancedOption to set the policy

Result: Works for both VM Home Namespace and Hard Disks.

PS C:\Users\chogan>$policy = Get-SpbmStoragePolicy RAID-5 PS C:\Users\chogan>echo $policy Name Description AnyOfRuleSets CommonRule ---- ----------- ------------- ---------- RAID-5 {(VSAN.hostFailuresToTolera... {} PS C:\Users\chogan>New-VM -Name 30julytest1 -Datastore vsanDatastore \ -ResourcePool CH-Cluster -AdvancedOption $policy Name PowerState Num CPUs MemoryGB ---- ---------- -------- -------- 30julytest1 PoweredOff 1 0.250 PS C:\Users\chogan> Get-VM -Name 30julytest1 | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest1 RAID-5 compliant 7/30/2018 8:50:07 AM PS C:\Users\chogan> Get-VM -Name 30julytest1 | Get-Harddisk | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/30/2018 8:50:07 AM

3. Use New-VM (clone from template) with Set-SpbmEntityConfiguration to set the policy

Result: Works on VM Home Namespace only. Same as #1.

4. Use New-VM (clone from template) with -AdvancedOption to set the policy

Result: Doesn’t work at all. Both VM Home Namespace and Hard Disk get default policy, not requested policy.

PS C:\Users\chogan>$policy = Get-SpbmStoragePolicy RAID-5 PS C:\Users\chogan>echo $policy Name Description AnyOfRuleSets CommonRule ---- ----------- ------------- ---------- RAID-5 {(VSAN.hostFailuresToTolera... {} PS C:\Users\chogan> New-VM -Name 30julytest2 -Template win7-desktop-orig \ -Datastore vsanDatastore -ResourcePool CH-Cluster -AdvancedOption $policy Name PowerState Num CPUs MemoryGB ---- ---------- -------- -------- 30julytest2 PoweredOff 1 2.000 PS PS C:\Users\chogan> Get-VM -Name 30julytest2 | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest2 vSAN Default Storage Policy compliant 7/30/2018 9:31:04 AM PS PS C:\Users\chogan> Get-VM -Name 30julytest2 | Get-Harddisk | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 vSAN Default Storage Policy compliant 7/30/2018 9:31:04 AM

5. Multi-command solution using New-VM (clone from template) with Set-SpbmEntityConfiguration to set the policy

Result: It works, but it is not ideal since the VM is first created with one policy and needs to be rebuilt with a new policy, which leads to resync traffic.

PS C:\Users\chogan> New-VM -Name 30julytest -Template win7-desktop-orig \ -Datastore vsanDatastore -ResourcePool CH-Cluster Name PowerState Num CPUs MemoryGB ---- ---------- -------- -------- 30julytest PoweredOff 1 2.000 PS PS C:\Users\chogan> Get-VM -Name 30julytest | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest vSAN Default Storage Policy compliant 7/30/2018 11:54:04 AM PS PS C:\Users\chogan> Get-VM -Name 30julytest | Get-Harddisk | \ Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 vSAN Default Storage Policy compliant 7/30/2018 11:54:12 AM PS C:\Users\chogan> Get-VM -Name 30julytest | Set-SpbmEntityConfiguration \ -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest RAID-5 compliant 7/30/2018 11:54:28 AM PS C:\Users\chogan> Get-VM -Name 30julytest | Get-Harddisk | \ Set-SpbmEntityConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/30/2018 11:55:27 AM PS C:\Users\chogan> Get-VM -Name 30julytest | Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- 30julytest RAID-5 compliant 7/30/2018 11:54:28 AM PS C:\Users\chogan> Get-VM -Name 30julytest | Get-Harddisk | \ Get-SpbmEntityConfiguration Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/30/2018 11:55:27 AM

6. Single command solution using New-VM with Set-SpbmEntityConfiguration to set the policy

Result: Sort of works. The following can be used so long as there is more than one disk attached to the VM. It doesn’t work when there is only a single disk.

PS C:\Users\chogan> New-VM -Name 30julytest6 -Datastore vsanDatastore \ -ResourcePool CH-Cluster -DiskGB 1,2 -AdvancedOption \ (Get-SpbmStoragePolicy RAID-5) | %{((Get-HardDisk -VM $_) + $_)} | \ Set-SpbmEntityConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/30/2018 2:26:54 PM Hard disk 2 RAID-5 compliant 7/30/2018 2:26:59 PM 30julytest6 RAID-5 compliant 7/30/2018 2:27:02 PM

7. Single command solution using New-VM (clone from template) with Set-SpbmEntityConfiguration to set the policy

Result: Same as #6 – sort of works. The following can be used so long as there is more than one disk attached to the VM. It doesn’t work when there is only a single disk.

PS C:\Users\chogan> New-VM -Name 30julytest5 -Template win7-desktop-orig -Datastore \ vsanDatastore -ResourcePool CH-Cluster -OSCustomizationSpec win7 -AdvancedOption \ (Get-SpbmStoragePolicy RAID-5) | %{((Get-HardDisk -VM $_) + $_)} | \ Set-SpbmEnti tyConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/30/2018 2:49:34 PM Hard disk 2 RAID-5 compliant 7/30/2018 2:49:39 PM 30julytest5 RAID-5 compliant 7/30/2018 2:49:44 PM

8. Single command solution using New-VM (clone from template) with Set-SpbmEntityConfiguration to set the policy

Result: This will work when there are one or more disks. But again, the initial VM is deployed with the default datastore policy, and then converted to the desired policy. Not ideal, as it incurs overhead to change the layout of the objects.

PS C:\Users\chogan> New-VM -Name 30julytest6 -Template win7-desktop-orig2 -Datastore \ vsanDatastore -ResourcePool CH-Cluster -OSCustomizationSpec win7 -AdvancedOption \ (Get-SpbmStoragePolicy RAID-5) | %{(@() + (Get-HardDisk -VM $_) + $_)} | \ Set-SpbmEntityConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/31/2018 8:56:31 AM 30julytest6 RAID-5 compliant 7/31/2018 8:56:35 AM PS C:\Users\chogan> New-VM -Name 30julytest5 -Template win7-desktop-orig -Datastore \ vsanDatastore -ResourcePool CH-Cluster -OSCustomizationSpec win7 -AdvancedOption \ (Get-SpbmStoragePolicy RAID-5) | %{(@() + (Get-HardDisk -VM $_) + $_)} | \ Set-SpbmEntityConfiguration -StoragePolicy RAID-5 Entity Storage Policy Status Time Of Check ------ -------------- ------ ------------- Hard disk 1 RAID-5 compliant 7/31/2018 8:31:56 AM Hard disk 2 RAID-5 compliant 7/31/2018 8:32:02 AM 30julytest5 RAID-5 compliant 7/31/2018 8:32:07 AM PS C:\Users\chogan>

Summary

While it is possible to create a single line command to create a VM with a certain storage policy, but if that VM is cloned from a Template, the command is not intuitive. Kudos once again to Manish Tiwari who helped significantly with the more advanced commands. I am going to request that this process for cloning a VM from a Template with a policy gets simplified, and that some simpler PowerCLI commands should be available to simplify the creation of all VM objects with the same policy when it is cloned from a Template.