Advertisement
jeroenburen

Upgrade-Hosts

Apr 3rd, 2020
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .SYNOPSIS
  3.     Perform steps to upgrade all ESXi hosts in a cluster.
  4. .DESCRIPTION
  5.     Use this script to upgrade all ESXi hosts in a cluster based on an upgrade baseline.
  6.  
  7.     This script assumes availability of the following modules:
  8.     - VMware-PowerCli
  9. .PARAMETER
  10.     - Cluster: name of the cluster to migrate.
  11.     - Baseline: name of the upgrade baseline.
  12. .EXAMPLE
  13.     .\Upgrade-Cluster.ps1 -Cluster <clustername>
  14. .NOTES
  15.     Script name: Upgrade-Cluster.ps1
  16.     Author:      Jeroen Buren
  17.     DateCreated: 07-03-2020
  18. #>
  19.  
  20. [CmdletBinding(SupportsShouldProcess=$true)]
  21. Param(
  22.     [parameter(valuefrompipeline = $true, mandatory = $true,
  23.         HelpMessage = "Enter the name of the cluster to upgrade.")]
  24.         [PSObject]$ClusterName,
  25.     [parameter(mandatory = $true,
  26.         HelpMessage = "Enter the name of the Host Upgrade Baseline to apply.")]
  27.         [String]$Baseline
  28.     )
  29.  
  30.  
  31. ####################################################################################
  32. #                                                                                  #
  33. # Functions                                                                        #
  34. #                                                                                  #
  35. ####################################################################################
  36.  
  37. function Get-ScriptDirectory {
  38.   $Invocation = (Get-Variable MyInvocation -Scope 1).Value
  39.   Split-Path $Invocation.MyCommand.Path
  40. }
  41.  
  42. function Log {
  43.   param(
  44.     [Parameter(Mandatory=$true)][String]$Message,
  45.     [Parameter(Mandatory=$true)][ValidateSet("Info","Debug","Warn","Error")][String]$Type,
  46.     [Parameter(Mandatory=$true)][ValidateSet("Console","LogFile","Both")][String]$OutputMode
  47.   )
  48.  
  49.   $dateTimeString = Get-Date -Format "yyyy-MM-dd HH:mm:sszz"
  50.   $output = ($dateTimeString + " " + $type.ToUpper() + " " + $message)
  51.   if ($outputMode -eq "Console" -OR $outputMode -eq "Both") {
  52.     Write-Host $output
  53.   }
  54.   if ($outputMode -eq "LogFile" -OR $outputMode -eq "Both") {
  55.     try {
  56.       Add-Content $logFile -Value $output -ErrorAction Stop
  57.     }
  58.     catch {
  59.       Log ("Failed to write to log file: """ + $logFile + """.") -OutputMode Console -Type Error
  60.       Log ("[" + $_.Exception.GetType().FullName + "] " + $_.Exception.Message) -OutputMode Console -Type Error
  61.     }
  62.   }
  63. }
  64.  
  65. ####################################################################################
  66. #                                                                                  #
  67. # Variables                                                                        #
  68. #                                                                                  #
  69. ####################################################################################
  70.  
  71. # Logfile
  72. Set-Variable logFile ((Get-ScriptDirectory) + "\Upgrade-Cluster.log") -Option Constant -ErrorAction SilentlyContinue
  73. $vCenter = "vCenter"
  74. $vib = "cisco-vem-v320-esx"
  75.  
  76. ####################################################################################
  77. #                                                                                  #
  78. # Main Code                                                                        #
  79. #                                                                                  #
  80. ####################################################################################
  81.  
  82. Log -Message "Script started" -Type Info -OutputMode LogFile
  83.  
  84. # Connect vCenter Server
  85. Connect-VIserver -Server $vCenter | Out-Null
  86. Log -Message "Connected to vCenter Server" -Type Info -OutputMode Both
  87.  
  88. # Get cluster object
  89. $cluster = Get-Cluster $clusterName
  90.  
  91. # Disable HA
  92. Set-Cluster -Cluster $cluster -HAEnabled:$false -Confirm:$false | Out-Null
  93.  
  94. # Disconnect all ISOs that may be attached to VMs and set the CD Drive state to "disconnected"
  95. Log -Message "Disconnecting CD drives" -Type Info -OutputMode Both
  96. $cluster | Get-VM | Get-CDDrive | Where-Object {($_.IsoPath -ne $null) -or ($_.ConnectionState.Connected -eq "true")} | Set-CDDrive -NoMedia -Connected:$false -Confirm:$false
  97.  
  98. # Apply baseline to cluster
  99. Add-EntityBaseline -Entity $cluster -Baseline (Get-Baseline -Name $Baseline -BaselineType Upgrade)
  100. Add-EntityBaseline -Entity $cluster -Baseline (Get-PatchBaseline -Name "Critical Host Patches (6.7)")
  101.  
  102. # Test baseline compliance on the cluster
  103. Test-Compliance -Entity $cluster
  104.  
  105. # Check for host compliance to the applied baseline and select all hosts that are not compliant
  106. $hostNotComp = $cluster | Get-VMHost | Get-Compliance | Where-Object {$_.Status -ne "Compliant"}
  107.  
  108. # Upgrade hosts
  109. Log -Message "Beginning baseline installation" -Type Info -OutputMode Both
  110.  
  111. foreach ($h in $hostNotComp) {
  112.   # Enter maintenance mode
  113.   Log -Message "Host $($h.Entity) is entering Maintenance Mode" -Type Info -OutputMode Both
  114.   Set-VMHost -VMHost $h.Entity -State Maintenance | Out-Null
  115.  
  116.   # Wait for the host to enter Maintenance Mode
  117.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Entity).ConnectionState -ne 'Maintenance')
  118.  
  119.   # Start removing the VIB
  120.   Log -Message "Removing VIB from host" -Type Info -OutputMode Both
  121.   $esxcli = Get-EsxCli -VMHost $h.Entity -V2
  122.   $param = $esxcli.software.vib.remove.CreateArgs()
  123.   $param.dryrun = $false
  124.   $param.vibname = $vib
  125.   $param.force = $false
  126.   $esxcli.software.vib.remove.Invoke($param) | Out-Null
  127.  
  128.   # Update the host
  129.   Log -Message "Installing baseline $Baseline on host $($h.Entity)" -Type Info -OutputMode Both
  130.   Update-Entity -Entity $h.Entity -Baseline (Get-Baseline -Name $Baseline -BaselineType Upgrade) -Confirm:$false | Out-Null
  131.  
  132.   # Now check compliancy against patches baseline
  133.   Test-Compliance -Entity $h.Entity -UpdateType HostPatch
  134.  
  135.   # Patch the host
  136.   Log -Message "Installing critical host patches on host $($h.Entity)" -Type Info -OutputMode Both
  137.   Update-Entity -Entity $h.Entity -Baseline (Get-Baseline -BaselineType Patch -Name "Critical Host Patches (6.7)") -Confirm:$false | Out-Null
  138.  
  139.   # Exit maintenance mode
  140.   Log -Message "Host $($h.Entity) is exiting Maintenance Mode" -Type Info -OutputMode Both
  141.   Set-VMHost -VMHost $h.Entity -State Connected | Out-Null
  142.  
  143.   # Wait for the host to leave Maintenance Mode
  144.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Entity).ConnectionState -ne 'Connected')
  145.  
  146.   # Next host...
  147.  
  148. }
  149.  
  150. # Enable HA
  151. Set-Cluster -Cluster $cluster -HAEnabled:$true -Confirm:$false | Out-Null
  152.    
  153. # Disconnect from vCenter Servers
  154. Disconnect-VIServer -Server $vCenter -Confirm:$false
  155.  
  156. Log -Message "Script Ended" -Type Info -OutputMode LogFile
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement