I have been doing a lot of VMware PowerCLI automation this last year and a half. Up Until my recent projects, I have done mostly only HyperV / SCVMM automation (For Virtual Machine Deployments). For OS deployments I mainly used ConfigMgr (SCCM). Today, I would like to go through some powercli oscustomizationspec automation.

I’ll go through in a few posts on some interesting topics on the things I have learned using VMWare and PowerCLI. Things that I either not found in the documentation, or, simply, that I think are worth mentioning because they didn’t seem that obvious to me when I started first with PowerCLI.

The first thing I want to talk about is the the deployment of Virutal Machines using PowerCLI and something called a OSCustomizationSpec. The next step will be how to deploy a VM using a Sysprep file.

How to Deploy a VM using PowerCLI and customized settings using a Powercli CustomizationSpec

As you might know, VMware allows you to create virtual machines based on templates. In order to customize these machines created based on these different templates (or regular Virtual machines), VMWare gives us the specifiy our custom settings using something that is called a CustomizationSpec“. In the end, a CustomizationSpec is nothing more then an object (a big one actually) that contains all the different settings that will make our VMware virtual machine unique from the other ones. It converts all these properties to settings that will be applied during the Sysprep of the machine.

Did you know that behind the covers, the VMtools actually create a sysprep file that is passed as a parameter to the windows setup.exe?

The Customizations are managed using cmdlets having the word OSCustomizationSpec in their name (You guessed it already).

These cmdlets are actually pretty straight forward, and some basic common sense will be sufficent to make you proificent with these 4 cmdlets.

For simple example purposes, here is exactract of how I used powercli oscustomizationspec :

You see, nothing really extragavant. The small thing we could mention here, is the Type” of the powercli OSCustomizationSpec that is set to “NonPersistent“, which as it’s name implies, will create a OSCustomizationSpec that will last only during the powershell session that it runs in. Once the script is over, the customization is automatically deleted.

Also, pay attention to the ChangeSid parameter. If you are thinking, “huh, I don’t need that, I’ll simply won’t use it”. Forget it! Even though, the documentation doesn’t mention it, since Windows Vista, all Windows  Machines must have the ChangeSid option, otherwise you will bump in strange errors.

Since Windows Vista, all versions of Windows, when deployed through a template in combination with an OSCustomizatzionSpec, MUST have their SID changed. That is why, when you use the New-OSCustomizationSpec command, you MUST use the “-ChangeSID parameter, otherwise your deployment will simply fail.

One thing you should be aware of:

If you are like me, and like to go through the different properties of you object either Directly through the powershell console, or perhaps reading through the documentation, you will sooner or later learn about the DeleteAccounts property that is attached to the OSCustomizationSpec object.

Well, I had a use case for that property, and after a few failing attemps and many troubleshooting, I thought I was doing something wrong, and I decided to ask for help on the VMWare forum. Sure enough, the VMware PowerCLI master LucD came to the rescue and answered the questions in minutes! In his answer on the forum, we learn that the property is actually deprecated since version 2.5 of the api. (I didn’t actually know there were several copies of the documentation. I simply google the things, and click the most top result. This seems like not to be the best way of searching for information all the time).

As you can see in the image below, nothing is mentioned in the official documentation from the New-OSCustomizationSpec cmdlet that it has a property that is deprecated.

The thing to take away from my experience here, is that the documentation of VMWare is not up to date (or information to too scattered). So things like deprecated properties are not clearly identifiable in the documentation. It is a shame, since I could have saved my self some investigation time if I had found this out earlier.

–> In the future, do not (!!) use the property DeleteAccountsof the OSCustomization Type since it will not work.

And you? did you had any similar experience with Deprecated Properties? Let us know in the comment to avoid to other people to make the same mistakes!

Creating the network Configuration ( powercli OsCustomizationNicMapping)

Ok, you thought it was all to the powercli OsCustomization right? Well, sometimes life simply wants you to struggle a little bit before achieve something, otherwise, where is the fun, huh? (In a bar with friends maybe?).

Well, if you take a closer look at the $Spec variable (which contains our freshly created powercli OsCustomizationSpec) there is a Property called OsCustomizationNicMapping. If you followed this blog post, it should be empty.

You can actually try to apply your powercli OsCustomizationSpec to your VM now, but that it will not work without a network configuration. So lets do that 🙂

As with any regular IPConfiguration, it is possible to either have an auto generated IP Address via DHCP, or a fixed configuration. In my case, the section above is part of a bigger script, which will dynamically assign the right IPConfiguration according to some internal variables set through different parameters from the script.

Be sure to use the OSCusomizationNicMapping that is already present in the powercli OsCustomizationSpec (The line ‘Get-OSCustomizationNicMapping -OSCustomizationSpec $spec’ ) otherwise you might face the same issues that I did later on, where you end up having only one NIC, but with the wrong Index.

If you create a new one, instead of using the existing one, the nic index will be incremented, and this can complicate your automation. So simply get the existing NicMaping instead of creating a new one 😉


Deploying our VMWare Virtual Machine using New-VM

And now that we have everything set, we can go and create our VM based on our template.

There is actually not much more to say about this. The most ‘confusing’ part, is for sure the OSCustomizationNicMapping. The few things left  to specify are things like the VMfolder (Which you can get using Get-Folder), a Template (Use Get-Template), the VMhost (use Get-Host) where we want to create the VM, the DataStore (Get-DataStore)  where it will be created on, and assign the OSCustomizationSpec we created earlier via the variable $spec


Powercli OscustomizationSpec is not the only way!

That was the easy way of doing things. Where this (the powercli oscustomizationspec) could answer most of the regular VM Vsphere deployment use cases, when you get into more complex scenarios where you need to do more granular OS customizations, the powercli OSCustomizationSpec could end up to be not enough. There exists another way of passing arguments to the new-VM cmdlet using a  Sysprep File. Unfortunatley, this method is really not well documented, but no worries, I got you covered in my next post 😉

I’ll share in another post how to deploy a machine via a template using a Sysprep File instead of a powercli OSCustomizationSpec.

In the mean time, have fun! 🙂