PowerCLI Backup vCenter Guest OS VM Customization Specifications

Recently I migrated from an existing vCenter 6.5 installation to a new vCenter 6.7 installation. I was replacing the existing SSO domains and linking with another vCenter in another site and with the previous vCenters being deployed prior to starting at this job I wanted to start from scratch. As someone who backups up and reports as much of the environment as possible I assumed that just disconnecting ESXi hosts from one vCenter and connecting to the new one would have been good enough. Turns out I was wrong.

After the migration to the new vCenter everything seemed good until someone went to deploy a new VM and saw all the VM customization specs were missing. Having never backed up, exporting, or migrating these guest OS specs before I was afraid I needed to manually re-create each and every one of them. Luckily, VMware thought of this and gives us the ability to just click on a guest OS spec and choose “Export” and then we get an XML file that can be imported into the new vCenter. This got me thinking if there was a way to do this via PowerCLI.

As part of my daily VMware report, I have included the following script to automatically back up these VM customization specifications to a location on my server in XML format. As new specs are created they will be automatically picked up by this script so there is no configuration required. Just run and you get the backup. Now let’s get to the script.

This first line is just to define the output location of these backups. Ensure you include the last backslash as we’ll add the file name to this variable and then we’re going to get a list of all the VM guest OS customization specs and save it to the variable “$specs”:

$location = "C:\Scripts\Specs\"
$specs = Get-View CustomizationSpecManager

Now that we have a list of all the OS specs, we’re going to open a ForEach loop do a backup of each one. Because the list of specs sits in $specs.Info instead of each one being listed in just $specs, we need to add the “.Info” in the loop definition.

ForEach ($spec in $specs.Info) {

Then we grab the name of the spec ($spec.Name) to the variable $specName. We set the file name ($outFile) as the location listed in line 1, add the name of the spec we just captured, then add “.xml” to the end of the file.

$specName = $spec.Name
$outFile = $location + $specName + ".xml"

Now that we have the spec name saved and the output location defined, we can actually get all the details of the OS customization spec and perform the export. $output captures the details of the OS customization spec for the specified spec ($specName). We then convert that spec detail to XML format, then export it to the defined file name and location and close the loop.

$output = $specs.GetCustomizationSpec($specName)
$specs.CustomizationSpecItemToXml($output) | Out-File $outFile }

And with that we’re able to automatically backup these guest OS specs in case of a vCenter loss or someone deleting/changing one accidentally. You could also add the date to the file name in case you’re concerned about versioning. Below is the completed script:

$location = "C:\Scripts\Specs\"
$specs = Get-View CustomizationSpecManager
ForEach ($spec in $specs.Info) {
$specName = $spec.Name
$outFile = $location + $specName + ".xml"
$output = $specs.GetCustomizationSpec($specName)
$specs.CustomizationSpecItemToXml($output) | Out-File $outFile }

Create New NFS Project on Tegile

The basis of a Project on the Tegile array is applying permissions and policies to a single volume or group of volumes. This means that changes made at the Project level can propagate to the volumes that live inside that project. If new IP addresses need to be added for read/write and root access for all the volumes, that can be handled at the Project-level instead of having to modify each export. However, you still have the ability to make changes at the individual volume level if that’s required.

In this setup, I’ll create a new project to host my Windows workloads in VMware. I’ll create a volume for Windows 2012 Operating System files and allow all the host on my NFS network read/write and root access to this volume.

1. Login to the web interface of the Tegile array
2. Click on “Data”
3. Click on the Pool that will host this new project
4. In the “Project” window, click “Add Project”
5. Enter the name of the Project , choose the Purpose, and select “NFS” for access type. Click “Next”
6. Enter the Share Name, enter the number of mount points (more can be added later), and enter any Share limits or reservations. Click “Next”
7. Set “NFS Sharing” to “on”. Set “Access Mode” to “Read-Write”, set “Access Type” to “IP” and enter the individual IP addresses or the subnet that will have access to this share. Check the box for “Root Access” then click “Add”. Repeat for each IP/Subnet then click “Next”
8. Set your snapshot policy (if required). This can be configured at a later time as well. Click “Next”
9. Review your settings and click “Finish”
10. Click on the newly created Project and then you will see the volume share name and the mountpoint

At this point, we just need to mount this new Volume on our ESXi hosts which can be done manually through the vSphere client on each host or we can do it through PowerCLI which will do it a lot faster.

In the example above, the name of our Volume is “2012_OS”, the path is our share mountpoint (/export/PDX_Windows/2012_OS) and the IP of the Tegile is You’ll need to define the hostname as it appears in vCenter. To mount to a single host we can use the following PowerCLI command:

New-Datastore -NFS -VMHost "Hostname" -Name "2012_OS" -Path /export/PDX_Windows/2012_OS -NfsHost

To mount to an entire cluster, we can use this command after defining the name of the cluster as it appears in vCenter:

Get-Cluster "ClusterName" | Get-VMHost | New-Datastore -NFS -Name "2012_OS" -Path /export/PDX_Windows/2012_OS -NfsHost