Customization

Working with Customization Specifications in PowerCLI Part 3

PowerCLI has several cmdlets at your disposal for managing OS Customization Specifications. In our first post we showed you how to create new customization specifications, retrieve and change them, in our second post we covered a common use case, being able to work with network interface card mappings and now in this final post we will show you how to clone a customization specification and give you an end-to-end scenario showing you how to use it in a script.

Cloning customization specifications

PowerCLI also gives you the ability to clone a customization specification (which creates an identical copy). You can clone both persistent and non-persistent specifications. Cloning is useful when you want to duplicate your customization specifications across multiple vCenter Servers. Let’s say you are connected to 2 servers – “vc1” and “vc2” and you want to copy all your customization specifications from “vc1” to “vc2”. Here is how to do that:

Get-OSCustomizationSpec –Type Persistent –Server vc1 | New-OSCustomizationSpec –Server vc2 –Type Persistent

You can also clone a customization specification as a non-persistent one. This is useful when you will be applying this specification to multiple VMs and will need to change the NIC mappings for each VM. Here is how to create a non-persistent clone of a customization specification:

$clone = Get-OSCustomizationSpec –Name BasicWindowsSpec | New-OSCustomizationSpec –Type NonPersistent

Customizing VMs

Now let’s see an end-to-end scenario. You need to deploy 100 new Linux VMs (with a single network adapter) and configure them to use static IPs. You have a list of static IPs in a CSV file.

# We will name the VMs “VM-001”, “VM-002” … “VM-100”

$vmNameTemplate = “VM-{0:D3}”

# The VMs will be created in “MyCluster” and will be based on “Rhel6_VM” template

$cluster = Get-Cluster MyCluster

$template = Get-Template Rhel6_VM

# Create the VMs

$vmList = @()

for ($i = 1; $i –le 100; $i++) {

$vmName = $vmNameTemplate –f $i

$vmList += New-VM –Name $vmName –ResourcePool $cluster –Template $template

}

# The list of static IPs is stored in “StaticIPs.csv” file

$staticIpList = Import-CSV C:\StaticIPs.csv

# Create the customization specification

$linuxSpec = New-OSCustomizationSpec –Name LinuxCustomization –Domain vmware.com –DnsServer “192.168.0.10”, “192.168.0.20” –NamingScheme VM –OSType Linux

# We will be applying this specification to each of our 100 VMs.

# However each time before applying it we need to change the static IP in the NIC mapping.

# Instead of changing the specification that is persisted on the server (and can be reused in the future)

# we will clone it to a non-persistent one and change that instead:

$specClone = New-OSCustomizationSpec –Spec $linuxSpec –Type NonPersistent

# Now apply the customization specification to each VM

for ($i = 0; $i –lt $vmList.Count; $i++) {

# Acquire a new static IP from the list

$ip = $staticIpList[$i].IP

# The specification has a default NIC mapping – retrieve it and update it with the static IP

$nicMapping = Get-OSCustomizationNicMapping –OSCustomizationSpec $specClone

$nicMapping | Set-OSCustomizationNicMapping –IpMode UseStaticIP –IpAddress $ip –SubnetMask “255.255.252.0” –DefaultGateway “192.168.0.1”

# Apply the customization

Set-VM –VM $vmList[$i] –OSCustomizationSpec $specClone –Confirm:$false

}

What if our VMs have more than one network adapter? For simplicity let’s assume that our VMs are already created (and stored in $vmList variable) and each of them has two network adapters – one of them attached to “Public” network and the other to “Private” network. We need to configure the network adapters on the “Public” network with static IPs and the ones on “Private” network to use DHCP.

# The list of static IPs is stored in “StaticIPs.csv” file

$staticIpList = Import-CSV C:\StaticIPs.csv

# Create the customization specification . This time we will directly create a non-persistent specification, so we don’t need to specify a name for it

$linuxSpec = New-OSCustomizationSpec –Domain vmware.com –DnsServer “192.168.0.10”, “192.168.0.20” –NamingScheme VM –OSType Linux –Type NonPersistent

# Now apply the customization specification to each VM

for ($i = 0; $i –lt $vmList.Count; $i++) {

# Acquire a new static IP from the list

$ip = $staticIpList[$i].IP

# Remove any NIC mappings from the specification

$nicMapping = Get-OSCustomizationNicMapping –OSCustomizationSpec $linuxSpec

Remove-OSCustomizationNicMapping –OSCustomizationNicMapping $nicMapping –Confirm:$false

# Retrieve the VM’s network adapter on the “Public” network

$publicNIC = $vmList[$i] | Get-NetworkAdapter | where {$_.NetworkName -eq “Public”}

# Retrieve the VM’s network adapter on the “Private” network

$privateNIC = $vmList[$i] | Get-NetworkAdapter | where {$_.NetworkName -eq “Private”}

# Create a NIC mapping for the “Public” NIC – it will use static IP

$linuxSpec | New-OSCustomizationNicMapping –IpMode UseStaticIP –IpAddress $ip –SubnetMask “255.255.252.0” –DefaultGateway “192.168.0.1” –NetworkAdapterMac $publicNIC.MacAddress

# Create a NIC mapping for the “Private” NIC – it will use DHCP and we will map it by MAC address

$linuxSpec | New-OSCustomizationNicMapping –IpMode UseDhcp –NetworkAdapterMac $privateNIC.MacAddress

# Apply the customization

Set-VM –VM $vmList[$i] –OSCustomizationSpec $linuxSpec –Confirm:$false

}

clip_image002[8]This post was created by Dimitar Barfonchovski.

Dimitar joined VMware and the PowerCLI team in 2007. He is member of the development part of the team and his main responsibilities are the functional design and implementation of features for the vSphere and vCloud PowerCLI components.

As with all members of the team, he is working to deliver a good and valuable product. He is also working to improve all processes and tools involved in the product development and validation.