Patching VMware ESXi Hosts via PowerCLI!

*** Updated 5/17/2017 – See below ***

This year, I’m trying something new…  Anything that I have to do more than 2-3 times, I’m going to attempt to automate it!

In keeping with this mantra, I recently had a task come across my plate to patch the 20+ ESXi Hosts in one of my production environments.  Along with installing the latest Host Updates, I also wanted to upgrade Dell’s Open Manage Server Administrator to the latest version.

In the past, these updates would have taken me a while as I’d install Host Updates, let the host reboot, come back to it some time later after realizing it was back, install the host extension, then wait for it to come back up, then remove it from Maintenance Mode.  In all, I was doing maybe 2 hosts a day.

In my environment, I have multiple vCenter servers one for QA, one for VDI, one for Production US, one for Production UK, and one for my Lab Environment.  So, at the start of my script, it lists these vCenter servers and I have to choose which one I want to connect to.  Once I choose the number and hit enter, it then connects to that vCenter and lists the hosts that belong to that vCenter.

image

image

image

Once I select the host I want to patch, it initiates a VUM Scan on the host, to make sure it brings the host to the most current level.

image

It then places the host into Maintenance Mode.

image

image

Then, vCenter vMotions the VMs off.  As you are probably aware, this part may take some time depending on how many VMs you have on your host.  A License level to be able to use vMotion is required for the automatic vMotions to occur.  Once in MM, the host patches are installed and the host is rebooted.

image

image

Once back online, the host extension is installed/upgraded and the host is rebooted again.

image

image

Once back online, the host is removed from Maintenance Mode.

image

image

Finally, a popup box is displayed to let me know it’s done.

image

Once I put all those tasks into a single script, I’m able to do both patch baselines (critical & non-critical updates) as well as the host extension (OMSA 8.2) and get the host back online in about 30-45 minutes.  This may change depending on how long it takes your server(s) to POST.  My Dell R920s can take a bit of time to do the memory test as they have 256gb of memory installed.  I’ve been able to get anywhere from 4-6 hosts patched a day using this script!

Enjoy!


########################################
#
# PowerCLI Script to Patch Hosts
# Created by BLiebowitz on 3/4/2016
#
########################################

# Select which vCenter you want to connect to
Write-host "Select which vCenter to connect to:"
Write-Host ""
Write-Host "1. vc01"
Write-Host "2. vc02"
Write-Host "3. vc03"
Write-Host "4. vc04"
Write-Host "5. vc05"

$Ivcenter = read-host “Select a vCenter Server. Enter Number “

if ($Ivcenter –eq 1) {
$vcenter = "vc01"
} elseif ($Ivcenter -eq 2) {
$vcenter = "vc02"
} elseif ($Ivcenter -eq 3) {
$vcenter = "vc03"
} elseif ($Ivcenter -eq 4) {
$vcenter = "vc04"
} else {
$vcenter = "vc05"
}

write-host ""
Write-Host "You Picked: "$vcenter
write-host ""
start-sleep -s 3

# connect to selected vCenter
connect-viserver $vcenter

# List hosts to select
write-host ""
Write-host "Choose which vSphere host to Deploy Patches to:"
write-host "(it may take a few seconds to build the list)"
write-host ""
$IHOST = Get-VMhost | Select Name | Sort-object Name
$i = 1
$IHOST | %{Write-Host $i":" $_.Name; $i++}
$DSHost = Read-host "Enter the number for the host to Patch."
$SHOST = $IHOST[$DSHost -1].Name
write-host "you have selected" $SHOST"."

# Scan selected host
Scan-inventory -entity $SHOST

# Place selected host into Maintenance mode
write-host "Placing host in Maintenance Mode"
Get-VMHost -Name $SHOST | set-vmhost -State Maintenance

# Remediate selected host for Host Patches
write-host "Deploying VMware Host Critical & Non Critical Patches"
get-baseline -name *critical* | remediate-inventory -entity $SHOST -confirm:$false

# Remediate selected host for OMSA 8.2
write-host "Deploying OMSA 8.2"
get-baseline -name "OMSA 8.2" | remediate-inventory -entity $SHOST -confirm:$false

# Remove selected host from Maintenance mode
write-host "Removing host from Maintenance Mode"
Get-VMHost -Name $SHOST | set-vmhost -State Connected

# Display Popup when finished.
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show("The Patching for " + $SHOST + " is now complete..")

Hope you find this useful!

Ben Liebowitz, VCP, vExpert
NJ VMUG Leader

 

*** UPDATE 5/17/2017 ***

With the release of PowerCLI 6.5 comes new VMware Update Manager cmdlets.

Scan-Inventory has been replaced with Test-Compliance. (you can see compliance results using Get-Compliance)
Remediate-Inventory has been replaced with Update-Entity.


########################################
#
# PowerCLI Script to Patch Hosts
# Created by BLiebowitz on 3/4/2016
#
########################################

# Select which vCenter you want to connect to
Write-host "Select which vCenter to connect to:"
Write-Host ""
Write-Host "1. vc01"
Write-Host "2. vc02"
Write-Host "3. vc03"
Write-Host "4. vc04"
Write-Host "5. vc05"

$Ivcenter = read-host “Select a vCenter Server. Enter Number “

if ($Ivcenter –eq 1) {
$vcenter = "vc01"
} elseif ($Ivcenter -eq 2) {
$vcenter = "vc02"
} elseif ($Ivcenter -eq 3) {
$vcenter = "vc03"
} elseif ($Ivcenter -eq 4) {
$vcenter = "vc04"
} else {
$vcenter = "vc05"
}

write-host ""
Write-Host "You Picked: "$vcenter
write-host ""
start-sleep -s 3

# connect to selected vCenter
connect-viserver $vcenter

# List Clusters
write-host ""
Write-host "Choose which Cluster the host you want to patch belongs to:"
write-host "(it may take a few seconds to build the list)"
write-host ""
$ICLUSTER = get-cluster | Select Name | Sort-object Name
$i = 1
$ICLUSTER | %{Write-Host $i":" $_.Name; $i++}
$HCLUSTER = Read-host "Enter the number for the host to Patch."
$SCLUSTER = $ICLUSTER[$HCLUSTER -1].Name
write-host "you have selected" $SCLUSTER"."
start-sleep -s 3

# List hosts to select
write-host ""
Write-host "Choose which vSphere host in $($SCLUSTER) to Deploy Patches to:"
write-host "(it may take a few seconds to build the list)"
write-host ""
$IHOST = Get-Cluster $SCLUSTER | Get-VMhost | Select Name | Sort-object Name
$i = 1
$IHOST | %{Write-Host $i":" $_.Name; $i++}
$DSHost = Read-host "Enter the number for the host to Patch."
$SHOST = $IHOST[$DSHost -1].Name
write-host "you have selected $($SHOST)."

# Scan selected host
test-compliance -entity $SHOST

# Display compliance results and wait 15 seconds
get-compliance -entity $SHOST
start-sleep -s 15

# Place selected host into Maintenance mode
write-host "Placing $($SHOST) in Maintenance Mode"
Get-VMHost -Name $SHOST | set-vmhost -State Maintenance

# Remediate selected host for Host Patches
write-host "Deploying VMware Host Critical & Non Critical Patches"
get-baseline -name *critical* | update-entity -entity $SHOST -confirm:$false

# Remediate selected host for OMSA 8.2
write-host "Deploying OMSA 8.2"
get-baseline -name "OMSA 8.2" | update-entity -entity $SHOST -confirm:$false

# Remove selected host from Maintenance mode
write-host "Removing host from Maintenance Mode"
Get-VMHost -Name $SHOST | set-vmhost -State Connected

# Display Popup when finished.
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show("The Patching for $($SHOST) is now complete..")

Make sure you update your scripts!

– Ben

Share This:

31 thoughts on “Patching VMware ESXi Hosts via PowerCLI!

  1. Wow! that’s awesome! you can always disable the mem check if you wanted to speed up the process even more.

    1. yeah, I know.. pros and cons for doing that, and I’d rather have the memory checked. 🙂

      Thanks for the suggestion though.

  2. Nice work, just wondering why you choose a VC to connect to, is that so you get a smaller list of hosts? You know you can connect to multiple VCs with Connect-VIServer right?

    1. Thanks.

      As for why I didn’t connect to all the vCenters, in my environment, I have over 40 hosts… so listing them all in one shot could get confusing.

      Also, it also narrows down the # of choices, so mistakes aren’t made and a host from the wrong environment doesn’t get taken down, etc. 🙂

  3. Are you relying on DRS for the automatic migrations when placing the host into maintenance mode? Could the script be modified to not rely on DRS using something similar to:

    Get-VM -Location “HostName” | Move-VM -Destination (Get-Vmhost “NewHost”)

    1. Yes, I’m relying on DRS to do the migrations. However, if DRS is not enabled, you could use a command like this before you place the host into maintenance mode:

      Get-vmhost $SHOST | Get-VM | Move-VM -Destination (get-vmhost “NewDestination”)

  4. Nice work

    Couple questions

    1. What if esxi cannot connect to internet? or can I download and cache updates locally to speed things up?
    2. How did you update vcenter? this is more troublesome for us as we have to click through various installs.

    1. 1. The script just runs commands for VMware Update Manager. Only VUM needs to be able to connect to the internet to download patches. The hosts do not.
      You can stage the patches on the hosts using the command below:
      Stage-Patch -Entity $SHOST
      I would place this command after the Scan and before the maintenance mode sections. This will give VUM time to stage the patches before remediation.

      2. I updated vCenter manually. I agree, it’s annoying with the multiple installs… The installs are MSIs, so you COULD script it… That may be an idea for a future blog post. 🙂

  5. Command Scan-inventory -entity $SHOST gives error “Windows Powershell ISE has stopped working”
    VMware vSphere PowerCLi v5.8
    Windows Powershell v3.0

    1. The VUM cmdlets were updated in the last release.

      scan-inventory was deprecated. The new cmdlet is test-compliance. Use get-compliance to see the results of the test.

      Test-Compliance -Entity VMHost-1
      Get-Compliance -Entity VMHost-1 -Baseline $Baseline

      Hope this helps!

      Ben Liebowitz, VCP, vExpert
      NJ VMUG Leader

  6. Hi All

    I have some third party offline bundle in .zip format and i want to import them through powerclii into vcenter,how it can be achieved.
    I got lot of help from your script how to stage , reate base line,but not able to find how to import offline bundle and the proceed with update .

    1. I’ve done this with OMSA on my Dell servers. There are multiple methods depending on if you have the zip file on your PC, in the /tmp folder on the host, or are grabbing it from a URL.

      # LocalPath Method
      # Extract the ZIP file to a folder on your local PC/Server

      Install-VMHostPatch -VMhost VMHOST -LocalPath c:\temp\omsa\metadata.zip

      # HostPath Method
      # Extract the ZIP file and upload the files to the host.

      Install-VMHostPatch -VMhost VMHOST -HostPath /tmp/omsa/metadata.zip

      # WebPath Method
      # to do this you need the direct download path to the zip file.
      Install-VMHostPatch -VMhost VMHOST-webpath http://www.urlofyourpatch.com/bundle.zip

  7. Hey ben
    thanks for the reply ,the above command will directly patch to ESXi host not the update manager.
    what i wan to know is ” how to Import 3rd party host patches into Update Manager” through powercli

  8. Wow this is great stuff! But I have a question, According to VMware’s own documentation “VMware Vsphere updatemanager Powercli installation & Administration guide” page 11 (which I originally misunderstood) you can remediate the cluster! So what does this mean? Can you not just run the following and site back to have the cluster just drain and failback the VMs automatically as it patches hosts one by one? or am I missunderstood again?

    $criticalPatchBaseline = New-PatchBaseline -Dynamic -Name “DynamicBaseline” –TargetType host –SearchPatchVendor *VMware* -SearchPatchSeverity Critical –SearchPatchStartDate
    Attach-Baseline -Baseline $criticalPatchBaseline -Entity
    Test-Compliance -entity
    Get-Cluster –name | Set-Cluster –HAAdmissionControlEnabled:$false –Confirm:$False
    Remediate-Inventory -Entity -Baseline $criticalPatchBaseline -ClusterDisableHighAvailablility -RunAsync -Confirm $false

    ……and then once the whole cluster is patched run the following to re-enable Admission control?
    Get-Cluster –name | Set-Cluster –HAAdmissionControlEnabled:$true –Confirm:$False

    Should the above be good enough to run against one cluster providing it has DRS enabled? or do I have to instruct the script to put into maintenance mode 1 by 1? It does not suggest I need to in the publications?

    1. Hi. First, remediate-inventory is no longer a valid cmdlet since PowerCLI 6.5. The new one is update-entity and it has a lot more switches available.

      Second, yes… You can patch an entire cluster. By default, it should only do 1 host a time, however you can use the -ClusterEnableParallelRemediation switch for update-entity and set it to do more than one at a time. It all depends on how many VMs are in the cluster and how many hosts you want to allow to be down at once.

      Also, the -entity switch is required and requires a string to follow it, be it a hostname, clustername, etc. You’ll want to get-compliance before you do test-compliance too.

      If you use the ClusterDisableHighAvailability switch, it should re-enable the admission control once patching is done, but you’d have to verify to make sure.

      If DRS is set to fully automated, it’ll automatically put the host into maintenance mode and vMotion the VMs off.

  9. Hello Ben,

    greatful Script, thx for your work! I have a small Problem and i don’t know where is the problem (PS-Newbie).
    One Error on this Point in the Script:
    get-baseline -name *critical* | update-entity -entity $SHOST -confirm:$false

    update-entity : 18.08.2017 07:05:14 Update-Entity The operation for the entity “Serverxyz” failed with the following message: “There are errors during the remediation operation. Check the events and log files for details.”
    In F:\Vmware\PowerCLI\ESXi_6.5_Host_Patchen.ps1:77 Zeichen:33
    + … eline -name *critical* | update-entity -entity $SHOST -confirm:$false
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Update-Entity], ExtendedFault
    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VumAutomation.Commands.RemediateInventory

    When i Try the code manual for one server it is OK!?
    Cheers Mike

    1. It sounds like something in the script isn’t working when you choose the host in the list. What point does it get to before it fails? Does it put the host into maintenance mode? What do you see in the events tab or the vmkernel log? Any errors? This is very generic.

      1. Hello Ben,

        i think it is a timeout Problem. I set PowerCLI the WebOperrationTimeoutSeconds
        Get-PowerCLIConfiguration
        Set-PowerCLIConfiguration -WebOperationTimeoutSeconds 600 # Standard 300s /5Min
        Test it for next PtachDay. Thanks a lot!
        Mike

        1. Hello Ben,

          it works! Higher timeout solved the Problem.
          Can you help with another idea, we have no HA or DRS on, before i start the script the machines were manually moved (migrate) from the host. Is ist possible to code a query for checking the Host for Virtual Machines before try to patch the Host? I hope my english is understandable ..
          Greetings Mike

      2. # Display Popup when finished.
        [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
        [System.Windows.Forms.MessageBox]::Show(“The Patching for $($SHOST) is now complete..”)

        Error : C:\AWS_Data\Scripts\Hosts\VUMPatching.ps1:94 char:86
        + … now complete..”)
        + ~~
        The string is missing the terminator: “.

        1. It sounds like you may be missing a terminator somewhere in your code. Without seeing all your code, it’s hard to say what is missing.

          Have you tried putting your code into something like Visual Studio Code or something? Tools like that can help you find missing terminators.

  10. Hi Ben. Could I use this script to patch standalone ESXi hosts? Because it asks me for a cluster before the host. Is there any modification to be done? Regards.

    1. Sure you can. try this, it won’t ask for a list of clusters anymore, it’ll just list ALL hosts.

      ########################################
      #
      # PowerCLI Script to Patch Hosts
      # Created by BLiebowitz on 3/4/2016
      #
      ########################################

      # Select which vCenter you want to connect to
      Write-host “Select which vCenter to connect to:”
      Write-Host “”
      Write-Host “1. vc01”
      Write-Host “2. vc02”
      Write-Host “3. vc03”
      Write-Host “4. vc04”
      Write-Host “5. vc05”

      $Ivcenter = read-host “Select a vCenter Server. Enter Number “

      if ($Ivcenter –eq 1) {
      $vcenter = “vc01”
      } elseif ($Ivcenter -eq 2) {
      $vcenter = “vc02”
      } elseif ($Ivcenter -eq 3) {
      $vcenter = “vc03”
      } elseif ($Ivcenter -eq 4) {
      $vcenter = “vc04”
      } else {
      $vcenter = “vc05”
      }

      write-host “”
      Write-Host “You Picked: “$vcenter
      write-host “”
      start-sleep -s 3

      # connect to selected vCenter
      connect-viserver $vcenter

      # List hosts to select
      write-host “”
      Write-host “Choose which vSphere host in to Deploy Patches to:”
      write-host “(it may take a few seconds to build the list)”
      write-host “”
      $IHOST = Get-VMhost | Select Name | Sort-object Name
      $i = 1
      $IHOST | %{Write-Host $i”:” $_.Name; $i++}
      $DSHost = Read-host “Enter the number for the host to Patch.”
      $SHOST = $IHOST[$DSHost -1].Name
      write-host “you have selected $($SHOST).”

      # Scan selected host
      test-compliance -entity $SHOST

      # Display compliance results and wait 15 seconds
      get-compliance -entity $SHOST
      start-sleep -s 15

      # Place selected host into Maintenance mode
      write-host “Placing $($SHOST) in Maintenance Mode”
      Get-VMHost -Name $SHOST | set-vmhost -State Maintenance

      # Remediate selected host for Host Patches
      write-host “Deploying VMware Host Critical & Non Critical Patches”
      get-baseline -name *critical* | update-entity -entity $SHOST -confirm:$false

      # Remediate selected host for OMSA 8.2
      write-host “Deploying OMSA 8.2”
      get-baseline -name “OMSA 8.2” | update-entity -entity $SHOST -confirm:$false

      # Remove selected host from Maintenance mode
      write-host “Removing host from Maintenance Mode”
      Get-VMHost -Name $SHOST | set-vmhost -State Connected

      # Display Popup when finished.
      [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
      [System.Windows.Forms.MessageBox]::Show(“The Patching for $($SHOST) is now complete..”)

Leave a Reply to andyp Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.