Cisco UCS and VMware Provisioning

These scripts not only deployed the Cisco UCS blades but also downloaded the latest version of ESXi from the VMware website, used this to PXE boot the UCS blades with VMware Auto Deploy and then finally applied created and utilized a  host configuration using Host Profiles.

There was very minimal pre-work performed for both UCS and VMware in the environment being demoed in the video below.

For UCS, the pre-work that was performed was racking, stacking, and cabling the physical UCS gear and performing an initial configuration of UCS manager.   On the storage side, a 200 GB LUN was created and zoned to a range of 18 WWPN’s as well, of course this could also have been done with PowerShell snapins from some of the storage vendors if needed.

For infrastructure support VMware vCenter and Auto-Deploy software were both installed and configured. DNS, DHCP, and TFTP installed and configured to comply with organizational practices.

From there, PowerShell utilizing the Cisco UCS PowerTool module and VMware PowerCLI snap-ins takes over!!!

Three different scripts were created to perform the following functions:

  1. Initial Configuration – The first scripts configures all of the pools, policies, VLANs, VSANs, Service Profile Templates, etc. needed on the UCS side to create new servers to be used in the cluster to be created in VMware.  On the VMware side, this script will download the latest ESXi hypervisor, as well as create separate AutoDeploy Hypervisor and Cluster rules that define the hypervisor version and destination cluster for net new servers with the Service Profile Template name provided in the OEM strings like  “oemstring=$SPT:CL2021”, where CL2021 is the service profile template name.  The script will create a new service profile from a template, associate it with a server from a pool, monitor the progress of the association and addition of the host into the cluster, perform initial configuration of the new host in the cluster and create a host profile from the configuration, and create a rule for the cluster to use the new host profile.
  2. Addition of New Hypervisors – The second script is run to add new hypervisors to the cluster created in step one.  This script accomplishes that by creating a new service profile from the template created in script one, associating it, and booting it which will cause the server to boot via AutoDeploy based on the AutoDeploy and cluster rules created from script one, which are triggered from the service profile template name.  The script will verify the host is added to the cluster and is fully compliant with the host profile created in step one.
  3. Rolling Hypervisor and Server Firmware Upgrade of a Cluster – The third script will download the newest version of a ESXi hypervisor from VMware, create a new AutoDeploy rule utilizing it for servers that are created from the Service Profile Template created in step one.  Once the rules are updated, the script will loop through each hypervisor one by one in the cluster by first setting the hypervisor in maintenance which will trigger VM evacuation, shutting the hypervisor down, change the host firmware pack on the service profile which upgrades the firmware on the server, powering the server on which will cause the server to boot the updated version of ESXi via AutoDeploy and rejoin the cluster. 

These scripts are provided freely as examples of how you can use both UCS PowerTool and VMware PowerCLI together to achieve end to end automation.  Please feel free to modify and utilize them as examples of how you might automate UCS and VMware in your own datacenter.

Script 1


# Import Modules
if ((Get-Module |where {$_.Name -ilike "CiscoUcsPS"}).Name -ine "CiscoUcsPS")
    {
    Write-Host "Loading Module: Cisco UCS PowerTool Module"
    Import-Module CiscoUcsPs
    }
if ((Get-PSSnapin | where {$_.Name -ilike "Vmware*Core"}).Name -ine "VMware.VimAutomation.Core")
    {
    Write-Host "Loading PS Snap-in: VMware VimAutomation Core"
    Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike " VMware.DeployAutomation"}).Name -ine "VMware.DeployAutomation")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.DeployAutomation"
    Add-PSSnapin VMware.DeployAutomation -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike "VMware.ImageBuilder"}).Name -ine "VMware.ImageBuilder")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.ImageBuilder"
    Add-PSSnapin VMware.ImageBuilder -ErrorAction SilentlyContinue
    }
    
set-ucspowertoolconfiguration -supportmultipledefaultucs $false
# Global Variables
$ucs = "10.3.0.100"
$ucsuser = "admin"
$ucspass = "@_$ecure_P@$$"
$ucsorg = "org-root"
$tenantname = "CL2021"
$macpoolblockfrom = "00:25:B5:ED:01:01"
$macpoolblockto = "00:25:B5:ED:01:09"
$wwpnpoolblockfrom = "20:00:00:25:B5:ED:02:01"
$wwpnpoolblockto = "20:00:00:25:B5:ED:02:12"
$private = "10"
$public = "206"
$vCenter = "10.3.0.80"
$vcuser = "Administrator@vsphere.local"
$vcpass = "@_$ecure_P@$$"
$WarningPreference = "SilentlyContinue"
Try {
    # Login to UCS
    Write-Host "UCS: Logging into UCS Domain: $ucs"
    $ucspasswd = ConvertTo-SecureString $ucspass -AsPlainText -Force
    $ucscreds = New-Object System.Management.Automation.PSCredential ($ucsuser, $ucspasswd)
    $ucslogin = Connect-Ucs -Credential $ucscreds $ucs
    # Create Deploy Rule for Hypervisor to be deploy based on SP name and another rule for cluster name
    Write-Host "vC: Logging into vCenter: $vCenter"
    $vcenterlogin = Connect-VIServer $vCenter -User $vcuser -Password $vcpass | Out-Null
    # Create Mac Pool
    Write-Host "UCS: Creating MAC Pool: $tenantname"
    $startucstransaction = Start-UcsTransaction
    $macpool =  Get-UcsManagedObject -Dn $ucsorg | Add-UcsMacPool -name $tenantname -ModifyPresent
    $macpoolblock = $macpool | Add-UcsMacMemberBlock -From $macpoolblockfrom -To $macpoolblockto -ModifyPresent
    $completeucstransaction = Complete-UcsTransaction
    # Create WWPN Pool
    Write-Host "UCS: Creating WWPN Pool: $tenantname"
    $startucstransaction = Start-UcsTransaction
    $wwpnpool = Get-UcsManagedObject -Dn $ucsorg  | Add-UcsWwnPool -Name $tenantname -Purpose "port-wwn-assignment" -ModifyPresent
    $wwpnpoolblock = $wwpnpool | Add-UcsWwnMemberBlock -From $wwpnpoolblockfrom -To $wwpnpoolblockto -ModifyPresent
    $completeucstransaction = Complete-UcsTransaction
    # Create Server Pool
    Write-Host "UCS: Creating Server Pool: $tenantname"
    $serverpool =  Get-UcsManagedObject -Dn $ucsorg | Add-UcsServerPool -Name $tenantname -ModifyPresent
    # Create Server Qualification Policy
    Write-Host "UCS: Creating Server Qualification Policy: $tenantname"
    $startucstransaction = Start-UcsTransaction
    $serverqualpol = Get-UcsManagedObject -Dn $ucsorg | Add-UcsServerPoolQualification -Name $tenantname -ModifyPresent
    $serveradaptorqual = $serverqualpol | Add-UcsAdaptorQualification -ModifyPresent
    $serveradaptorcapqual = $serveradaptorqual | Add-UcsAdaptorCapQualification -Maximum "unspecified" -Model "N20-AC0002" -Type "virtualized-eth-if" -ModifyPresent
    $servercpuqual = $serverqualpol | Add-UcsCpuQualification -Model "N20-X00002" 
    $completeucstransaction = Complete-UcsTransaction
    # Create Server Pool Policy (for dynamic server pools based on qualification policy)
    Write-Host "UCS: Creating Server Pool Policy: $tenantname"
    $startucstransaction = Start-UcsTransaction
    $serverpoolpol = Get-UcsManagedObject -Dn $ucsorg | Add-UcsServerPoolPolicy -Name $tenantname -PoolDn $serverpool.dn -Qualifier $serverqualpol.Name -ModifyPresent
    $completeucstransaction = Complete-UcsTransaction
    # Create Boot Policy
    Write-Host "UCS: Creating Boot Policy: $tenantname"
    $startucstransaction = Start-UcsTransaction
    $bootpol = Get-UcsManagedObject -Dn $ucsorg | Add-UcsBootPolicy -EnforceVnicName "yes" -Name $tenantname -RebootOnUpdate "no" -ModifyPresent
    $pxe = $bootpol | Add-UcsLsbootLan -ModifyPresent -Order "1" -Prot "pxe"  
    $eth0 = $pxe | Add-UcsLsbootLanImagePath -BootIpPolicyName "" -ISCSIVnicName "" -ImgPolicyName "" -ImgSecPolicyName "" -ProvSrvPolicyName "" -Type "primary" -VnicName "eth0"  -ModifyPresent
    $completeucstransaction = Complete-UcsTransaction
    # Create any needed VLANs
    Write-Host "UCS: Creating VLAN vlan$private"
    $vlanprivate = get-ucslancloud | Add-UcsVlan -Name vlan$private -Id $private -ModifyPresent
    Write-Host "UCS: Creating VLAN vlan$public"
    $vlanpublic = get-ucslancloud | Add-UcsVlan -Name vlan$public -Id $public -ModifyPresent
    # Create any needed VSANs
    Write-Host "UCS: Creating VSAN default"
    $vsan1 = Get-UcsSanCloud | Add-UcsVsan -Name default -Id 1 -ModifyPresent
    # Create Service Profile Template (using MAC, WWPN, Server Pools, VLANs, VSans, Boot Policy, etc. previously created steps) with desired power state to down
    Write-Host "UCS: Creating SP Template: $tenantname in UCS org: $ucsorg"
    $startucstransaction = Start-UcsTransaction
    $sptemplate = Get-UcsManagedObject -Dn $ucsorg |  Add-UcsServiceProfile -BootPolicyName $tenantname -HostFwPolicyName "default" -IdentPoolName "default" -LocalDiskPolicyName "default" -MaintPolicyName "default" -Name $tenantname -PowerPolicyName "default" -StatsPolicyName "default" -Type "initial-template" 
    $sptvnic1 = $sptemplate | Add-UcsVnic -AdaptorProfileName "VMWare" -AdminVcon "any" -IdentPoolName $tenantname -Mtu 1500 -Name "eth0" -Order "1" -StatsPolicyName "default" -SwitchId "A-B"
    $vnic1private = $sptvnic1 | Add-UcsVnicInterface -DefaultNet "yes" -Name $vlanprivate.Name
    $sptvnic2 = $sptemplate | Add-UcsVnic -AdaptorProfileName "VMWare" -AdminVcon "any" -IdentPoolName $tenantname -Mtu 1500 -Name "eth1" -Order "2" -StatsPolicyName "default" -SwitchId "B-A"
    $vnic2public = $sptvnic2 | Add-UcsVnicInterface -DefaultNet "yes" -Name $vlanpublic.Name
    $sptfc0 = $sptemplate | Add-UcsVhba -AdaptorProfileName "VMWare" -AdminVcon "any" -IdentPoolName $tenantname -MaxDataFieldSize 2048 -Name "fc0" -Order "3" -PersBind "disabled" -PersBindClear "no" -StatsPolicyName "default" -SwitchId "A"
    $fc0vsan = $sptfc0 | Add-UcsVhbaInterface -Name $vsan1.Name
    $sptfc1 = $sptemplate | Add-UcsVhba -AdaptorProfileName "VMWare" -AdminVcon "any" -IdentPoolName $tenantname -MaxDataFieldSize 2048 -Name "fc1" -Order "4" -PersBind "disabled" -PersBindClear "no" -StatsPolicyName "default" -SwitchId "B"
    $fc1vsan = $sptfc1 | Add-UcsVhbaInterface -Name $vsan1.Name
    $sptwwnn = $sptemplate | Add-UcsVnicFcNode -IdentPoolName "node-default"
    $sptserverpool = $sptemplate | Add-UcsServerPoolAssignment -Name $tenantname -RestrictMigration "no"
    $sptpowerstate = $sptemplate | Set-UcsServerPower -State "down" -Force
    $completeucstransaction = Complete-UcsTransaction
    # Add ESXi Image Profile from VMware.com
    Write-Host "vC: Adding VMware ESXi Library from online depot"
    $SoftwareDepot = Add-EsxSoftwareDepot "https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml"
    $LatestImageProfile = Get-EsxImageProfile | Where { $_.Name -match "no-tools" } | Sort ModifiedTime -desc | select -first 1
    # Create Auto-deploy rule using the Service Profile Template OEM string from UCS
    $pattern = "oemstring=`$SPT:$($SPTemplate.name)"
    Write-Host "vC: Creating ESXi deploy rule for '$($pattern)'"
    $DeployRule = New-DeployRule -Name "DeployESXiImage" -Item $LatestImageProfile -Pattern $pattern
    $AddRule = $DeployRule | Add-DeployRule
    # Create vCenter Cluster
    Write-Host "vC: Creating vCenter Cluster: $tenantname if it doesnt already exist"
    If (-Not (Get-Cluster $tenantname -ErrorAction SilentlyContinue)) {
        $Cluster = Get-Datacenter | Select -First 1 | New-Cluster $tenantname
    } Else {
        $Cluster = Get-Cluster $tenantname
    }
    Write-Host "vC: Enabling DRS and setting mode to 'FullyAutomated' for Cluster: $($Cluster)"
    $DRSenable = $Cluster | Set-Cluster -DrsEnabled:$true -DrsMode FullyAutomated -drsautomationlevel FullyAutomated -Confirm:$false
    
    Write-Host "vC: Creating vCenter Cluster rule for '$($pattern)'"
    $DeployRule = New-DeployRule -Name "AddHostsTo$($tenantname)Cluster" -Item $Cluster -Pattern $pattern
    $AddRule = $DeployRule | Add-DeployRule
    Write-Host "vC: Repairing active ruleset"
    $RepairRules = Get-VMHost | Test-DeployRuleSetCompliance | Repair-DeployRuleSetCompliance -ErrorAction SilentlyContinue
    # Create Initial ESXi Host from SP Template in UCS
    Write-Host "UCS: Creating new Service Profile from SP Template: $($sptemplate.name)"
    $createnewsp = $sptemplate | Add-UcsServiceProfileFromTemplate -Count 1 -DestinationOrg (Get-UcsManagedObject -Dn $ucsorg) -Prefix "esxi-host"
    $spmacaddr = $createnewsp | Get-UcsVnic -Name eth0
    # Monitor UCS SP Associate for completion
    Write-Host "UCS: Waiting for UCS SP: $($createnewsp.name) to complete SP association process"
        do {
            if ( (Get-UcsManagedObject -Dn $createnewsp.Dn).AssocState -ieq "associated")
            {
                break
            }
            Sleep 40
        } until ((Get-UcsManagedObject -Dn $createnewsp.Dn).AssocState -ieq "associated")
            
    # Set SP Desired Power State to UP in newly created SP
    Write-Host "UCS: Setting Desired Power State to 'up' of Service Profile: $createnewsp"
    $powerspon = $createnewsp | Set-UcsServerPower -State "up" -Force
    # Wait for Hypervisor to boot from network w/ Auto-Deploy and connect to vCenter
    Write "vC: Waiting for Host with MAC address of $($spmacaddr.Addr) to connect to vCenter"
    do {
        Sleep 40
    } until ($VMHost = (get-vmhost -ErrorAction SilentlyContinue | foreach { $_.NetworkInfo.PhysicalNic | where { $_.Mac -ieq $spmacaddr.Addr } } | select -expandproperty vmhost ))
    If ($VMHost.State -ne "Maintenance") {
        $Maint = $VMHost | Set-VMHost -State Maintenance
    }
    # Config changes to host before host profile
    Write "vC: COnfiguring VM Hypervisor Host: $($VMhost.name) before creating a Host Profile"
    Write "vC: Removing defualt VM Network"
    $VMNetwork = Get-VirtualPortGroup -Name "VM Network" -VMHost $VMHost | Remove-VirtualPortGroup -Confirm:$false
    Write "vC: Creating VMotion Network"
    $Vmotion = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup "VMotion" -VirtualSwitch (Get-VirtualSwitch -VMHost $vmhost -Name vSwitch0) -VMotionEnabled:$true
    Write "vC: Creating New Virtual Switch"
    $vSwitch1 = New-VirtualSwitch -VMHost $vmhost -Name "vSwitch1" -Nic (Get-VMHostNetworkAdapter -VMHost $vmhost -Name "vmnic1")
    Write "vC: Creating New VM Network"
    $VMNetwork = $vSwitch1 | New-VirtualPortGroup "VM Network"
    Write "vC: Setting Syslog Server"
    $SyslogServer = Set-VMHostSysLogServer -SysLogServer $vCenter -SysLogServerPort 514 -VMHost $VMhost
    Write-Host "vC: Creating Host Profile: $tenantname from VM Hypervisor Host: $($VMhost.name)"
    If (-Not (Get-VMHostProfile $tenantname -ErrorAction SilentlyContinue) ) {
        $HostProfile = New-VMHostProfile -Name $tenantname -Description "Automatically generated host profile for $tenantname" -ReferenceHost $VMHost
        # Edit the host profile to add the static password entry
        function Copy-Property ($From, $To, $PropertyName ="*")
        {
           foreach ($p in Get-Member -In $From -MemberType Property -Name $propertyName)
           {  trap {
                 Add-Member -In $To -MemberType NoteProperty -Name $p.Name -Value $From.$($p.Name) -Force
                 continue
              }
              $To.$($P.Name) = $From.$($P.Name)
           }
        }
        $hostProfileName = $tenantname
        $newAdminPswd = "VMw@re123"
        $spec = New-Object VMware.Vim.HostProfileCompleteConfigSpec
        Copy-Property -From $HostProfile.ExtensionData.Config -To $spec
        $secpol = New-Object VMware.Vim.ProfilePolicy
        $secpol.Id = "AdminPasswordPolicy"
        $secpol.PolicyOption = New-Object VMware.Vim.PolicyOption
        $secpol.PolicyOption.Id = "FixedAdminPasswordOption"
        $secpol.PolicyOption.Parameter += New-Object VMware.Vim.KeyAnyValue
        $secpol.PolicyOption.Parameter[0].Key = "password"
        $secpol.PolicyOption.Parameter[0].Value = New-Object VMware.Vim.PasswordField
        $secpol.PolicyOption.Parameter[0].Value.Value = $newAdminPswd
        $spec.ApplyProfile.Security.Policy = @($secpol)
        $ChangeHostProfile = $HostProfile.ExtensionData.UpdateHostProfile($spec)
    } else {
        $Hostprofile = Get-VMHostProfile $tenantname
    }

    # Add a new Deployrule to associate the host profile to the Hosts
    Write-Host "vC: Adding rule to use host profile"
    $DeployRule = New-DeployRule -Name "$($tenantname)HostProfile" -Item $HostProfile -Pattern $pattern
    $AddRule = $DeployRule | Add-DeployRule
    Write-Host vC: "Repairing active ruleset"
    $RepairRules = $VMHost | Test-DeployRuleSetCompliance | Repair-DeployRuleSetCompliance -ErrorAction SilentlyContinue
    Write-Host "vC: Assigning HostProfile to new host"
    $Assign = $VMHost | Apply-VMHostProfile -profile $HostProfile -Confirm:$false
    $Test = $VMHost | Test-VMHostProfileCompliance
    Write-Host "vC: VM Hypervisor Host: $($VMHost.Name) Ready to use, removing Maintenance mode"
    $Maint = $VMHost | Set-VMHost -State Connected
    # Logout of UCS
    Write-Host "UCS: Logging out of UCS: $ucs"
    $ucslogout = Disconnect-Ucs 
    # Logout of vCenter
    Write-Host "vC: Logging out of vCenter: $vCenter"
    $vcenterlogout = Disconnect-VIServer $vCenter -Confirm:$false
}
Catch
{
     Write-Host "Error occurred in script:"
     Write-Host ${Error}
     exit
}

Script 2

# Import Modules
if ((Get-Module |where {$_.Name -ilike "CiscoUcsPS"}).Name -ine "CiscoUcsPS")
    {
    Write-Host "Loading Module: Cisco UCS PowerTool Module"
    Import-Module CiscoUcsPs
    }
if ((Get-PSSnapin | where {$_.Name -ilike "Vmware*Core"}).Name -ine "VMware.VimAutomation.Core")
    {
    Write-Host "Loading PS Snap-in: VMware VimAutomation Core"
    Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike " VMware.DeployAutomation"}).Name -ine "VMware.DeployAutomation")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.DeployAutomation"
    Add-PSSnapin VMware.DeployAutomation -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike "VMware.ImageBuilder"}).Name -ine "VMware.ImageBuilder")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.ImageBuilder"
    Add-PSSnapin VMware.ImageBuilder -ErrorAction SilentlyContinue
    }    
    
    
set-ucspowertoolconfiguration -supportmultipledefaultucs 0
# Global Variables
$ucs = "10.3.0.100"
$ucsuser = "admin"
$ucspass = "@_$ecure_P@$$"
$ucsorg = "org-root"
$tenantname = "CL2021"
$vCenter = "10.3.0.80"
$vcuser = "Administrator@vsphere.local"
$vcpass = "@_$ecure_P@$$"
$WarningPreference = "SilentlyContinue"
Try
{
    # Login to UCS
    Write-Host "UCS: Logging into UCS Domain: $ucs"
    $ucspasswd = ConvertTo-SecureString $ucspass -AsPlainText -Force
    $ucscreds = New-Object System.Management.Automation.PSCredential ($ucsuser, $ucspasswd)
    $ucslogin = Connect-Ucs -Credential $ucscreds $ucs
    # Login to vCenter
    Write-Host "vC: Logging into vCenter: $vCenter"
    $vcenterlogin = Connect-VIServer $vCenter -User $vcuser -Password $vcpass | Out-Null
    # Create Initial ESXi Host
    Write-Host "UCS: Creating new Service Profile from SP Template: ${tenantname}"
    $sptemplate = get-ucsmanagedobject -dn $ucsorg | Get-UcsServiceProfile -Type "initial-template" -Name $tenantname
    $createnewsp = $sptemplate | Add-UcsServiceProfileFromTemplate -Count 1 -DestinationOrg (Get-UcsManagedObject -Dn $ucsorg) -Prefix "esxi-host"
    $spmacaddr = $createnewsp | Get-UcsVnic -Name eth0
    # Monitor UCS SP Associate for completion
    Write-Host "UCS: Waiting for UCS SP: $($createnewsp.name) to complete SP association process"
        do {
            if ( (Get-UcsManagedObject -Dn $createnewsp.Dn).AssocState -ieq "associated" )
            {
                break
            }
            Sleep 40
        } until ( (Get-UcsManagedObject -Dn $createnewsp.Dn).AssocState -ieq "associated" )
            
    Write-Host "UCS: Setting Desired Power State to 'up' of Service Profile: $($createnewsp.name)"
    $powerspon = $createnewsp | Set-UcsServerPower -State "up" -Force
    Write "vC: Waiting for VM Hypervisor Host with MAC address of $($spmacaddr.Addr) to connect to vCenter"
    do {
        Sleep 40
    } until ($VMHost = (get-vmhost -ErrorAction SilentlyContinue | foreach { $_.NetworkInfo.PhysicalNic | where { $_.Mac -ieq $spmacaddr.Addr } } | select -expandproperty vmhost ))
    Write "vC: Putting VM Hypervisor Host: $($VMhost.Name) into Maintenance mode"
    If ($VMHost.State -ne "Maintenance") {
        $Maint = $VMHost | Set-VMHost -State Maintenance
    }
    Write-Host "vC: Checking HostProfile Compliance against new VM Hypervisor Host: $($VMhost.Name) "
    $Test = $VMHost | Test-VMHostProfileCompliance
    Write-Host "vC: VM Hypervisor Host: $($VMhost.Name) Ready to use, removing Maintenance mode"
    $Maint = $VMHost | Set-VMHost -State Connected
    #Disconnect from UCS
    Write-Host "UCS: Logging out of UCS Domain: $ucs"
    $ucslogout = Disconnect-Ucs 
    #disconnect from vCenter
    Write-Host "vC: Logging out of vCenter: $vCenter"
    $vcenterlogout = Disconnect-VIServer $vCenter -confirm:$false
}
Catch
{
     Write-Host "Error occurred in script:"
     Write-Host ${Error}
     exit
}

Script 3

# Import Modules
if ((Get-Module |where {$_.Name -ilike "CiscoUcsPS"}).Name -ine "CiscoUcsPS")
    {
    Write-Host "Loading Module: Cisco UCS PowerTool Module"
    Import-Module CiscoUcsPs
    }
if ((Get-PSSnapin | where {$_.Name -ilike "Vmware*Core"}).Name -ine "VMware.VimAutomation.Core")
    {
    Write-Host "Loading PS Snap-in: VMware VimAutomation Core"
    Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike "Vmware*Core"}).Name -ine "VMware.VimAutomation.Core")
    {
    Write-Host "Loading PS Snap-in: VMware VimAutomation Core"
    Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike " VMware.DeployAutomation"}).Name -ine "VMware.DeployAutomation")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.DeployAutomation"
    Add-PSSnapin VMware.DeployAutomation -ErrorAction SilentlyContinue
    }
if ((Get-PSSnapin | where {$_.Name -ilike "VMware.ImageBuilder"}).Name -ine "VMware.ImageBuilder")
    {
    Write-Host "Loading PS Snap-in: VMware VMware.ImageBuilder"
    Add-PSSnapin VMware.ImageBuilder -ErrorAction SilentlyContinue
    }
    
set-ucspowertoolconfiguration -supportmultipledefaultucs 0
# Global Variables
$ucs = "10.3.0.100"
$ucsuser = "admin"
$ucspass = "@_$ecure_P@$$"
$ucsorg = "org-root"
$tenantname = "CL2021"
$vCenter = "10.3.0.80"
$vcuser = "Administrator@vsphere.local"
$vcpass = "@_$ecure_P@$$"
$WarningPreference = "SilentlyContinue"
$NewImageProfile = "C:\VMware\ESX7.1.0.NextImageProfile.zip"
$ucshfpname = "4.1.3c"
$WarningPreference = "SilentlyContinue"
try {
    # Login to UCS
    Write-Host "UCS: Logging into UCS Domain: $ucs"
    $ucspasswd = ConvertTo-SecureString $ucspass -AsPlainText -Force
    $ucscreds = New-Object System.Management.Automation.PSCredential ($ucsuser, $ucspasswd)
    $ucslogin = Connect-Ucs -Credential $ucscreds $ucs
    
    Write-Host "vC: Logging into vCenter: $vCenter"
    $vcenterlogin = Connect-VIServer $vCenter -User $vcuser -Password $vcpass | Out-Null
    Write-Host "vC: Disable the current ESXi Image DeployRule" 
    $RemDepRule = Get-DeployRule -Name "DeployESXiImage" | Remove-DeployRule
    $ESXDepot = Add-EsxSoftwareDepot "https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml"
    #$ESXDeppt = Add-EsxSoftwareDepot $NewImageProfile
    $LatestImageProfile = Get-EsxImageProfile | sort ModifiedTime -Descending | Select -First 1
    $pattern = "oemstring=`$SPT:$($tenantname)"
    Write-Host "vC: Creating ESXi deploy rule for '$($pattern)'"
    $NewRule = New-DeployRule -Name "AddHostsTo$($tenantname)ClusterUpdatedImage" -Item $LatestImageProfile -Pattern $pattern
    $SetActive = $NewRule | Add-DeployRule
    Write-Host "vC: Repairing active ruleset"
    $RepairRules = Get-VMHost | Test-DeployRuleSetCompliance | Repair-DeployRuleSetCompliance -ErrorAction SilentlyContinue
    Foreach ($VMHost in (Get-Cluster $tenantname | Get-VMHost )) {
        Write-Host "vC: Adding VM Hypervisor Host: $($VMHost.Name) into maintenance mode"
        $Maint = $VMHost | Set-VMHost -State Maintenance
        
        Write-Host "vC: Waiting for VM Hypervisor Host: $($VMHost.Name) to enter Maintenance Mode"
        do {
            Sleep 10
        } until ((Get-VMHost $VMHost).State -eq "Maintenance")
        
        Write-Host "vC: VM Hypervisor Host: $($VMHost.Name) now in Maintenance Mode, shutting down Host"
        $Shutdown = $VMHost.ExtensionData.ShutdownHost($true)
        
        Write-Host "UCS: Correlating VM Hypervisor Host: $($VMHost.Name) to running UCS Service Profile (SP)"
        $vmMacAddr = $vmhost.NetworkInfo.PhysicalNic | where { $_.name -ieq "vmnic0" }
        
        $sp2upgrade =  Get-UcsServiceProfile | Get-UcsVnic -Name eth0 |  where { $_.addr -ieq  $vmMacAddr.Mac } | Get-UcsParent 
        
        Write-Host "UCS: VM Hypervisor Host: $($VMhost.Name) is running on UCS SP: $($sp2upgrade.name)"
        Write-Host "UCS: Waiting to for UCS SP: $($sp2upgrade.name) to gracefully power down"
         do {
            if ( (get-ucsmanagedobject -dn $sp2upgrade.PnDn).OperPower -eq "off")
            {
                break
            }
            Sleep 40
        } until ((get-ucsmanagedobject -dn $sp2upgrade.PnDn).OperPower -eq "off" )
        Write-Host "UCS: UCS SP: $($sp2upgrade.name) powered down"
        
        Write-Host "UCS: Setting desired power state for UCS SP: $($sp2upgrade.name) to down"
        $poweron = $sp2upgrade | Set-UcsServerPower -State "down" -Force
        Write-Host "UCS: Changing Host Firmware pack policy for UCS SP: $($sp2upgrade.name) to '$($ucshfpname)'"
        $updatehfp = $sp2upgrade | Set-UcsServiceProfile -HostFwPolicyName (Get-UcsFirmwareComputeHostPack -Name $ucshfpname).Name -Force
        
        Write-Host "UCS: Acknowlodging any User Maintenance Actions for UCS SP: $($sp2upgrade.name)"
        if (($sp2upgrade | Get-UcsLsmaintAck| measure).Count -ge 1)
            {
                $ackuserack = $sp2upgrade | get-ucslsmaintack | Set-UcsLsmaintAck -AdminState "trigger-immediate" -Force
            }
        Write-Host "UCS: Waiting for UCS SP: $($sp2upgrade.name) to complete firmware update process for Host Firmware pack '$($ucshfpname)'"
        do {
            Sleep 40
        } until ((Get-UcsManagedObject -Dn $sp2upgrade.Dn).AssocState -ieq "associated")
        
        Write-Host "UCS: Host Firmware Pack update process comlete.  Setting desired power state for UCS SP: $($sp2upgrade.name) to 'up'"
        $poweron = $sp2upgrade | Set-UcsServerPower -State "up" -Force
        
        Write "vC: Waiting for VM Hypervisor Host: $($VMHost.Name) to connect to vCenter"
        do {
            Sleep 40
        } until (($VMHost = Get-VMHost $VMHost).ConnectionState -eq "Connected" )
    }
    # Logout of UCS
    Write-Host "UCS: Logging out of UCS Domain: $ucs"
    $ucslogout = Disconnect-Ucs 
    # Logout of vCenter
    Write-Host "vC: Logging out of vCenter: $vCenter"
    $vcenterlogout = Disconnect-VIServer $vCenter -Confirm:$false
}
Catch 
{
     Write-Host "Error occurred in script:"
     Write-Host ${Error}
     exit
}