It’s Alastair here with the latest AutoLab automation post, this one is a little about the PowerShell automation that helps bring the pieces together. The first AutoLab automation post is here, the second here and the third here.
One of my favourite automation tools for vSphere is the PowerCLI snapin to Microsoft PowerShell. If you are a Windows guy working in Virtualization then you should get to know PowerCLI. I consider myself a real beginner with PowerCLI, I use it when I have a task to repeat but it’s not where I work all day. There are some awesome scripters who are more comfortable on a command prompt than with a GUI, these are the guys whose scripts I have hacked to make my script and you can start by doing the same. If you are a skilled scripter you may despair at my scripts, feel free to email me to recommend better ways.
The PowerShell scripts in the AutoLab all start in the Automate folder on the build share; from there they are copied to the VM as it’s built. Copying the scripts locally helps avoid PowerShell prompting about running from an untrusted location.
I use a library script to keep a collection of function definitions that I reuse; it’s also a good way to keep your main script clean. Close to the top of most of the AutoLab PowerShell scripts is:
. "C:\PSFunctions.ps1"
A lot of the scripts also need to use the PowerCLI snapin, I choose to explicitly load this in the script as it takes a while and I show messages about the delay before loading
Add-PSSnapin VMware.VimAutomation.Core
The other things is to use a lot of variables rather than typing the same text repeatedly, sometimes even build the variables from other variables in the script
$VMHost = "host"
$VMHost += $i
$VMHost += ".lab.local"
The main script that sets up vCenter is the AddHosts.ps1 script which is run on the vCenter VM. The script is setup specifically for the AutoLab; it hasn’t been written to be re-usable elsewhere but can be the source of inspiration for your scripts. There are a few segments that are conditional; some depend on what version of ESX I find others depend on whether datastores and VMs exist. I’ve left these out of the following sections as they are very AutoLab specific, below are some of the main sections of the AddHosts script
vCenter configuration
Create a Datacenter
New-DataCenter -Location (Get-Folder -NoRecursion) -Name Lab
Create a DRS Cluster inside the Datacenter we just created
New-Cluster Local -DRSEnabled -Location Lab -DRSAutomationLevel PartiallyAutomated
Enable HA, set Admission control and isolation addresses on the cluster
set-cluster -cluster $Cluster -HAEnabled:$True -HAAdmissionControlEnabled:$True -confirm:$False
New-AdvancedSetting -Entity $cluster -Type ClusterHA -Name ‘das.isolationaddress1’ -Value "192.168.199.4" -confirm:$False -force
New-AdvancedSetting -Entity $cluster -Type ClusterHA -Name ‘das.usedefaultisolationaddress’ -Value false -confirm:$False -force
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
$spec.dasConfig.admissionControlPolicy = New-Object VMware.Vim.ClusterFailoverResourcesAdmissionControlPolicy
$spec.dasConfig.admissionControlPolicy.cpuFailoverResourcesPercent = 50
$spec.dasConfig.admissionControlPolicy.memoryFailoverResourcesPercent = 50
$Cluster = Get-View $Cluster
$Cluster.ReconfigureComputeResource_Task($spec, $true)
Create a Guest OS Customization configuration that we can use later
New-OsCustomizationSpec -Name Windows -OSType Windows -FullName Lab -OrgName Lab.local -NamingScheme VM -ProductKey $ProdKey -LicenseMode PerSeat -AdminPass VMware1! -Workgroup Workgroup -ChangeSid -AutoLogonCount 999
ESXi server configuration
These steps are repeated for each ESXi server, this is where having systematic naming and IP addressing is great since we can use a formula to calculate names and IP addresses.
Setup NTP
Add-VmHostNtpServer -NtpServer “192.168.199.4” -VMHost $VMhost
$ntp = Get-VMHostService -VMHost $VMhost | Where {$_.Key -eq ‘ntpd’}
Set-VMHostService $ntp -Policy "On"
Enable local and remote shells
$SSH = Get-VMHostService -VMHost $VMhost | Where {$_.Key -eq ‘TSM-SSH’}
Set-VMHostService $SSH -Policy "On"
$TSM = Get-VMHostService -VMHost $VMhost | Where {$_.Key -eq ‘TSM’}
Set-VMHostService $TSM -Policy "On"
Create a vSwitch and portgroups for VMs
$switch = New-VirtualSwitch -VMhost $vmHost -Nic $pnic.DeviceName -NumPorts 128 -Name vSwitch1
New-VirtualPortGroup -Name Servers -VirtualSwitch $switch
New-VirtualPortGroup -Name Workstations -VirtualSwitch $switch
set-VirtualSwitch $switch -Nic vmnic2,vmnic3 -confirm:$False
Attach NICs to vSwitch0
$switch = Get-VirtualSwitch -vmHost $vmHost
set-VirtualSwitch $switch -Nic vmnic0,vmnic1 -confirm:$False
Create VMkernel ports and set NIC teaming for some of them
$pg = New-VirtualPortGroup -Name vMotion -VirtualSwitch $switch -VLanId 16
New-VMHostNetworkAdapter -VMHost $vmhost -Portgroup $pg -VirtualSwitch $switch -IP $VMotionIP -SubnetMask "255.255.255.0" -vMotionEnabled:$true -managementTrafficEnabled:$True
$pg = New-VirtualPortGroup -Name FT -VirtualSwitch $switch -VLanId 16
New-VMHostNetworkAdapter -VMHost $vmhost -Portgroup $pg -VirtualSwitch $switch -IP $FTIP -SubnetMask "255.255.255.0" -FaultToleranceLoggingEnabled:$true
$pg = New-VirtualPortGroup -Name IPStore1 -VirtualSwitch $switch -VLanId 17
New-VMHostNetworkAdapter -VMHost $vmhost -Portgroup $pg -VirtualSwitch $switch -IP $IPStoreIP1 -SubnetMask "255.255.255.0"
$pg = New-VirtualPortGroup -Name IPStore2 -VirtualSwitch $switch -VLanId 17
New-VMHostNetworkAdapter -VMHost $vmhost -Portgroup $pg -VirtualSwitch $switch -IP $IPStoreIP2 -SubnetMask "255.255.255.0"
Get-VMHostStorage $VMHost | Set-VMHostStorage -SoftwareIScsiEnabled $true
get-virtualportgroup -name vMotion | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicActive vmnic1
get-virtualportgroup -name vMotion | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicStandby vmnic0
Rename the local Datastore, Get-ShareableDatastore is declared in the psfunctions library
$DSName = $VMHost.split(‘.’)[0]
$DSName += "_Local"
$sharableIds = Get-ShareableDatastore | Foreach { $_.ID }
Get-Datastore -vmhost $vmhost | Where { $sharableIds -notcontains $_.ID } | Set-DataStore -Name $DSName
Create NFS datastore
New-Datastore -nfs -VMhost $vmhost -Name Build -NFSHost "172.17.199.7" -Path "/mnt/LABVOL/Build" -readonly
Setup software ISCSI
$MyIQN = "iqn.1998-01.com.vmware:" + $VMHost.split(‘.’)[0]
Get-VMHostHba -VMhost $vmhost -Type iScsi | Set-VMHostHBA -IScsiName $MyIQN
Get-VMHostHba -VMhost $vmhost -Type iScsi | New-IScsiHbaTarget -Address 172.17.199.7 -Type Send
Get-VMHostStorage $VMHost -RescanAllHba
Shared configuration
Create iSCSI datastores
$iSCSILUNs = get-scsilun -vmhost $VMHost -CanonicalName "t10.*"
New-Datastore -VMHost $VMHost -Name iSCSI1 -Path $iSCSILUNs[2].CanonicalName -Vmfs -FileSystemVersion 5
New-Datastore -VMHost $VMHost -Name iSCSI2 -Path $iSCSILUNs[1].CanonicalName -Vmfs -FileSystemVersion 3
New-Datastore -VMHost $VMHost -Name iSCSI3 -Path $iSCSILUNs[0].CanonicalName -Vmfs -FileSystemVersion 3
Create the unattended configuration floppy with a customised winnt.sif containing your windows product key
(Get-Content b:\Automate\VC\Floppy\winnt.sif) | Foreach-Object {$_ -replace "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx", $ProdKey} | Set-Content b:\Automate\VC\Floppy\winnt.sif
b:\automate\vc\bfi.exe -f=b:\WinInstall.flp b:\automate\vc\floppy\ -t=6
Create a new VM and set it up to automaticlly install Windows from the Build share
$VMName="WinTemplate"
$Datastore = Get-Datastore -VMhost $vmHost -name "iSCSI1"
$MyVM = New-VM -Name $VMName -VMhost $vmHost -datastore $Datastore -NumCPU 1 -MemoryMB 384 -DiskMB 3072 -DiskStorageFormat Thin -GuestID winNetEnterpriseGuest
New-CDDrive -VM $MyVM -ISOPath [Build]WinInstall.iso -StartConnected
New-FloppyDrive -VM $MyVM -FloppyImagePath [Build]WinInstall.flp -StartConnected
$intHDiskDeviceKey = ($MyVM.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq "Hard disk 1"}).Key
$oBootableHDisk = New-Object -TypeName VMware.Vim.VirtualMachineBootOptionsBootableDiskDevice -Property @{"DeviceKey" = $intHDiskDeviceKey}
$oBootableCDRom = New-Object -Type VMware.Vim.VirtualMachineBootOptionsBootableCdromDevice
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec -Property @{"BootOptions" = New-Object VMware.Vim.VirtualMachineBootOptions -Property @{BootOrder = $oBootableCDRom, $oBootableHDisk}}
$MyVM.ExtensionData.ReconfigVM_Task($spec)
Start-VM $MyVM
Don’t be afraid of PowerShell, it’s easy to get started with and there are a heap of sample scripts that you can bend to your will.
One thought on “AutoLab automation uncovered, PowerShell”
Comments are closed.