
PowerCLI Cookbook
By :

In this section, you are going to cover all of the cmdlets that have been covered in this chapter by bringing them together into a single script. This script will allow us to take an array of ESXi hosts identified by either their hostname or IP address and to run the full scripted configuration against them.
In many ways, this PowerCLI script will function much like a Host Profile in vSphere. Host Profiles are a configuration definition that can be created from an existing, configured host and applied on hosts to establish a desired configuration state. If hosts deviate from the configuration, the profile might be reapplied to remediate any undesired changes.
Unfortunately, Host Profiles are only available to customers with Enterprise Plus licensing. However, this PowerCLI solution will work for any vSphere customer with Essentials, Essentials Plus, Standard, or Enterprise licensing.
For this last recipe of the chapter, you'll most likely want to open something such as PowerShell ISE. PowerShell ISE provides you with additional tools to edit larger scripts, color code the cmdlets, and ensure that there are no syntax errors. Alternatively, you might want a text editing tool such as NotePad, NoteTab Light, Sublime Text, or NotePad++.
# Script to mass configure ESXi hosts # Step 1 - Store credentials for ESXi hosts # Step 2 – Set a list of target ESXi hosts and IP settings # Step 3 – Write a ForEach loop to iterate through hosts # Step 4 – Connect to ESXi host # Step 5 – Obtain a VMHost object to use for configuration # Step 6 – Join the ESXi system to Active Directory # Step 7 – Enable services on the ESXi host & set firewall # Step 8 – Configure the network settings # Step 9 – Configure NFS & iSCSI settings # Step 10 - Join hosts to vCenter # Step 11 - Rescan for storage changes # Step 12 – Configure persistent syslog storage
connect-viserver
cmdlet.# Step 1 - Store credentials for ESXi hosts $esxiCreds = Get-Credential
When you first covered connecting to ESXi servers from PowerCLI, you experienced the login box for the host. The Get-Credentials
cmdlet causes the same action but returns a credentials object that can be reused. For now, you'll proceed with the stored credentials and you will use them in a later step.
# Step 2 - Set a list of target ESXi hosts and IP settings $esxiTargets = "192.168.0.241","192.168.0.242", "192.168.0.243", "192.168.0.244"
$vMotionNetwork = "192.168.50." $storageNetwork = "192.168.100." $ftlogNetwork = "192.168.200."
ForEach
loop to execute the cmdlets on multiple ESXi hosts:# Step 3 - Write a ForEach loop to iterate through hosts ForEach ($hostname in $esxiTargets) {
ForEach
loop. You will close the loop with a right curly brace later in the script. Inside the loop, you're going to include Steps 4 – 9 from the outline.# Step 4 - Connect to ESXi host $connectedHost = connect-viserver $hostname -Credential $esxiCreds # Step 5 – Obtain a VMHost object to use for configuration $esxihost = Get-VMHost $hostname
# Step 6 – Join the ESXi system to Active Directory $esxihost | Get-VMHostAuthentication | Set-VMHostAuthentication -JoinDomain -Domain domain.local -user username -password ***** -Confirm:$false # Step 7 – Enable services on the ESXi host & set firewall $esxihost | Get-VMHostService | where { $_.key -eq "TSM-SSH" } | Set-VMHostService -Policy "On" -Confirm:$false $esxihost | Get-VMHostService | where { $_.key -eq "TSM-SSH" } | Start-VMHostService -Confirm:$false # Step 8 – Configure the network settings $esxihost | Get-VirtualPortGroup -Name "VM Network" | Remove-VirtualPortGroup –Confirm:$false
$esxihost_ipaddress = $esxihost | Get-VMHostNetworkAdapter -name vmk0
IP
. To split that IP into an array, you will use the Split()
method, which is a built-in PowerShell method that transforms a string into an array by separating characters with the character passed into the method.For instance, you want to separate the string at the periods of the IP address, so you pass "."
into the Split()
method. Since the Split()
method turns it into an array, you can then reference the element you want to return – the fourth element. However, remember arrays begin count at 0, so you will return element 3 using square brackets.
$lastOctet = $esxihost_ipaddress.IP.Split(".")[3]
Because data is stored in objects, objects have both properties and methods. Methods perform operations on the data of the object and properties contain the data of the object. In subsequent recipes throughout this book, you will look at and use other methods to gain more experience using built-in PowerShell functionality to manipulate data stored in objects.
ForEach
loop is to concatenate the final octet with the network strings to build a full IP address:$vmotionIP = $vMotionNetwork + $lastOctet $storageIP = $storageNetwork + $lastOctet $ftlogIP = $ftlogNetwork + $lastOctet
$esxihost | New-VMHostNetworkAdapter -PortGroup "VMotion Network" -VirtualSwitch vSwitch0 -IP $vmotionIP -SubnetMask 255.255.255.0 -VMotionEnabled $true $esxihost | Get-VirtualPortGroup -Name "VMotion Network" | Set-VirtualPortGroup –VlanID 50 # Create new virtual switch for Storage and FT Logging $esxihost | New-VirtualSwitch -Name vSwitch1 -Nic vmnic2,vmnic3 # Create vmkernel ports for Storage and FT Logging $esxihost | New-VMHostNetworkAdapter -PortGroup "Storage Network" -VirtualSwitch vSwitch1 -IP $storageIP -SubnetMask 255.255.255.0 -VsanTrafficEnabled $true $esxihost | Get-VirtualPortGroup -Name "Storage Network" | Set-VirtualPortGroup –VlanID 100 $esxihost | New-VMHostNetworkAdapter -PortGroup "FT Logging Network" -VirtualSwitch vSwitch1 -IP $ftlogIP -SubnetMask 255.255.255.0 -FaultToleranceLoggingEnabled $true $esxihost | Get-VirtualPortGroup -Name "FT Logging Network" | Set-VirtualPortGroup –VlanID 200 # Create new Virtual Switch for Virtual Machines $esxihost | New-VirtualSwitch -Name vSwitch2 -Nic vmnic4,vmnic5 # Create Port Groups for Virtual Machines New-VirtualPortGroup -Name "Infrastructure Network" -VirtualSwitch vSwitch2 -VLanId 1 -Server $connectedhost New-VirtualPortGroup -Name "Application Network" -VirtualSwitch vSwitch2 -VLanId 2 -Server $connectedhost # Step 9 – Configure NFS & iSCSI settings # Connect NFS datastore $esxihost | New-Datastore -Nfs -Name DataStoreName -Path /data1/export -NfsHost nfsserver.domain.local # Configure iSCSI Settings $esxihost | Get-VMHostStorage | Set-VMHostStorage -SoftwareIScsiEnabled $true$iSCSIhba = $esxihost | Get-VMHostHba -Type iScsi New-IScsiHbaTarget -IScsiHba $iSCSIhba -Address $target -ChapType Required -ChapName vSphere -ChapPassword Password1 $esxcli = Get-ESXCLI -VMHost $esxihost $esxcli.iscsi.networkportal.add($iscsihba, $true,"vmk2")
ForEach
loop and then disconnecting from this host so that you can connect to the next host:Disconnect-VIServer -Server $connectedHost -Confirm:$false }
At this point in the initial configuration, you would want to format your datastores on iSCSI or Fibre Channel arrays, but this is not really a repeatable set of steps. I would suggest one of the two things—either configure the datastore manually from PowerCLI or configure it from the GUI and then come back and run the remainder of the script. Since the focus of this example is to make a repeatable configuration script, the datastore formatting doesn't fit since it is a command used just one time .
Add-VMHost
to add them into inventory. While in the same ForEach
loop to accomplish this, you can set central syslog and rescan the hosts for all storage changes:$vcenter = connect-viserver vcentersrv.domain.local $datacenter = Get-Datacenter "Primary"
For the purpose of this script, you are going to assume that vCenter already has a datacenter created and named "Primary." You will use this location to place the ESXi host into vCenter.
ForEach
loop to add the hosts and set their settings in vCenter:ForEach ($hostname in $esxTarget) {
# Step 10 - Join hosts to vCenter Add-VMHost -Server $vcenter -Name $hostname l -Location $datacenter -Credential $esxiCreds
VMHost
object pointing to the host to use with later cmdlets in this loop:$esxihost = Get-VMHost $hostname
# Step 11 - Rescan for storage changes $esxihost | Get-VMHostStorage -RescanAllHBA -RescanVmfs # Step 12 – Configure persistent syslog storage $esxihost | Get-AdvancedSetting | Where {$_.Name -like "Syslog.global.logDirUnique"} | Set-AdvancedSetting -value $true -Confirm:$false $esxhost | Get-AdvancedSetting | Where {$_.Name -like "logDir"} | Set-AdvancedSetting -value "[iSCSIDatastore1] syslog" -Confirm:$false
}
With connect-viserver
, you might have to log in a second time in the script with different credentials to vCenter versus individual hosts. Afterwards, the hosts should be populated into vCenter.
Finally, your settings and desired state should be fully transferred to the ESXi host by the script.
In this example, you wrap up all of the code you have developed throughout the chapter. You bring together the pieces of code that achieve specific tasks into a fully scripted configuration that you can apply toward a number of ESXi hosts. The script gives us repeatability, so when you need to extend the cluster with a new ESXi, or when you rebuild the host because you've replaced or upgraded the hardware, you can run this script against it and be back to the same working condition as before replacement.
The basis of the script is a ForEach
loop. Because you define the ESXi hosts in an array, you can connect to each of them and run all of the commands and then move the next entry in the array. The script also suppresses confirmation dialogs so that it can continue to issue cmdlets against the host. You also stored the login credentials, which means that you only have to log in once and the script will use the same credentials to connect and configure all of the hosts in the defined array.
Change the font size
Change margin width
Change background colour