jeroenburen

Upgrade-Hosts-6.5

Apr 3rd, 2020
183
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 with an offline ZIP file.
  6.  
  7.     This script assumes availability of the following modules:
  8.     - VMware-PowerCli
  9. .PARAMETER
  10.     - Cluster: name of the cluster to migrate.
  11. .EXAMPLE
  12.     .\Upgrade-Cluster.ps1 -Cluster <clustername>
  13. .NOTES
  14.     Script name: Upgrade-Cluster.ps1
  15.     Author:      Jeroen Buren
  16.     DateCreated: 07-03-2020
  17. #>
  18.  
  19. [CmdletBinding(SupportsShouldProcess=$true)]
  20. Param(
  21.     [parameter(valuefrompipeline = $true, mandatory = $true,
  22.         HelpMessage = "Enter the name of the cluster to upgrade.")]
  23.         [string]$ClusterName
  24.     )
  25.  
  26.  
  27. ####################################################################################
  28. #                                                                                  #
  29. # Functions                                                                        #
  30. #                                                                                  #
  31. ####################################################################################
  32.  
  33. function Get-ScriptDirectory {
  34.   $Invocation = (Get-Variable MyInvocation -Scope 1).Value
  35.   Split-Path $Invocation.MyCommand.Path
  36. }
  37.  
  38. function Log {
  39.   param(
  40.     [Parameter(Mandatory=$true)][String]$Message,
  41.     [Parameter(Mandatory=$true)][ValidateSet("Info","Debug","Warn","Error")][String]$Type,
  42.     [Parameter(Mandatory=$true)][ValidateSet("Console","LogFile","Both")][String]$OutputMode
  43.   )
  44.  
  45.   $dateTimeString = Get-Date -Format "yyyy-MM-dd HH:mm:sszz"
  46.   $output = ($dateTimeString + " " + $type.ToUpper() + " " + $message)
  47.   if ($outputMode -eq "Console" -OR $outputMode -eq "Both") {
  48.     Write-Host $output
  49.   }
  50.   if ($outputMode -eq "LogFile" -OR $outputMode -eq "Both") {
  51.     try {
  52.       Add-Content $logFile -Value $output -ErrorAction Stop
  53.     }
  54.     catch {
  55.       Log ("Failed to write to log file: """ + $logFile + """.") -OutputMode Console -Type Error
  56.       Log ("[" + $_.Exception.GetType().FullName + "] " + $_.Exception.Message) -OutputMode Console -Type Error
  57.     }
  58.   }
  59. }
  60.  
  61. ####################################################################################
  62. #                                                                                  #
  63. # Variables                                                                        #
  64. #                                                                                  #
  65. ####################################################################################
  66.  
  67. # Logfile
  68. Set-Variable logFile ((Get-ScriptDirectory) + "\Upgrade-Cluster-65.log") -Option Constant -ErrorAction SilentlyContinue
  69. $vCenter = "vCenter"
  70. $vib = "cisco-vem-v320-esx"
  71. $zip = "VMware-VMvisor-Installer-6.5.0.update03-15256549.x86_64-DellEMC_Customized-A05.zip"
  72. $profile = "DellEMC-ESXi-6.5U3-15256549-A05"
  73.  
  74.  
  75. ####################################################################################
  76. #                                                                                  #
  77. # Main Code                                                                        #
  78. #                                                                                  #
  79. ####################################################################################
  80.  
  81. Log -Message "Script started" -Type Info -OutputMode LogFile
  82.  
  83. # Connect vCenter Server
  84. Connect-VIserver -Server $vCenter | Out-Null
  85. Log -Message "Connected to vCenter Server" -Type Info -OutputMode Both
  86.  
  87. # Get cluster object
  88. $cluster = Get-Cluster $clusterName
  89.  
  90. # Get two datastores with most free space
  91. Log -Message "Selecting datastores" -Type Info -OutputMode Both
  92. $datastore1 = ($cluster | Get-Datastore | Where-Object {$_.Name.Substring(8,3) -eq "DC1"} | Sort-Object FreeSpaceGB -Descending)[0]
  93. $ds1url = ($datastore1.ExtensionData.Info.Url).Trim("ds:/")
  94.  
  95. $datastore2 = ($cluster | Get-Datastore | Where-Object {$_.Name.Substring(8,3) -eq "DC2"} | Sort-Object FreeSpaceGB -Descending)[0]
  96. $ds2url = ($datastore2.ExtensionData.Info.Url).Trim("ds:/")
  97.  
  98. $datastore1 | New-DatastoreDrive -Name DC1
  99. $datastore2 | New-DatastoreDrive -Name DC2
  100.  
  101. # Copy the offline ZIP file to the datastores
  102. Log -Message "Copying offline ZIP file to $($datastore1.Name)" -Type Info -OutputMode Both
  103. Copy-DatastoreItem -Item D:\Scripts\VMware\$zip -Destination DC1:\
  104.  
  105. Log -Message "Copying offline ZIP file to $($datastore2.Name)" -Type Info -OutputMode Both
  106. Copy-DatastoreItem -Item D:\Scripts\VMware\$zip -Destination DC2:\
  107.  
  108. # Create the depot variables
  109. $depot1 = "/$ds1url/$zip"
  110. $depot2 = "/$ds2url/$zip"
  111.  
  112. # Disconnect all ISOs that may be attached to VMs and set the CD Drive state to "disconnected"
  113. Log -Message "Disconnecting CD drives" -Type Info -OutputMode Both
  114. $cluster | Get-VM | Get-CDDrive | Where-Object {($_.IsoPath -ne $null) -or ($_.ConnectionState.Connected -eq "true")} | Set-CDDrive -NoMedia -Connected:$false -Confirm:$false
  115.  
  116. # Upgrade hosts
  117. Log -Message "Beginning upgrade of cluster" -Type Info -OutputMode Both
  118.  
  119. foreach ($h in $cluster | Get-VMHost | Where {$_.Version -ne "6.5.0"} | Sort-Object Name) {
  120.   # Enter maintenance mode
  121.   Log -Message "Host $($h.Name) is entering Maintenance Mode" -Type Info -OutputMode Both
  122.   Set-VMHost -VMHost $h -State Maintenance | Out-Null
  123.  
  124.   # Wait for the host to enter Maintenance Mode
  125.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Maintenance')
  126.  
  127.   # Start removing the VIB
  128.   Log -Message "Removing VIB from host" -Type Info -OutputMode Both
  129.   $esxcli = Get-EsxCli -VMHost $h -V2
  130.   $param = $esxcli.software.vib.remove.CreateArgs()
  131.   $param.dryrun = $false
  132.   $param.vibname = $vib
  133.   $param.force = $false
  134.   $esxcli.software.vib.remove.Invoke($param) | Out-Null
  135.  
  136.  
  137.   # Update the host
  138.   Log -Message "Upgrading host $($h.Name)" -Type Info -OutputMode Both
  139.  
  140.   $param = $esxcli.software.profile.update.CreateArgs()
  141.   $param.dryrun = $false
  142.   if ($h.Name.Substring(4,1) -eq "0") {$param.depot = $depot1}
  143.   if ($h.Name.Substring(4,1) -eq "1") {$param.depot = $depot2}
  144.   $param.profile = $profile
  145.  
  146.   $esxcli.software.profile.update.Invoke($param) | Out-Null
  147.  
  148.   # Reboot host and wait for it to come back
  149.   Log -Message "Host $($h.Name) is rebooting" -Type Info -OutputMode Both
  150.   Restart-VMHost -VMHost $h -Confirm:$false | Out-Null
  151.   # Wait for the host to enter NotConnected state
  152.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'NotResponding')
  153.  
  154.   # Wait for the host to get back
  155.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Maintenance')
  156.  
  157.   # Exit maintenance mode
  158.   Log -Message "Host $($h.Name) is exiting Maintenance Mode" -Type Info -OutputMode Both
  159.   Set-VMHost -VMHost $h -State Connected | Out-Null
  160.  
  161.   # Wait for the host to leave Maintenance Mode
  162.   do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Connected')
  163.  
  164.   # Next host...
  165.  
  166. }
  167.  
  168. # Delete offline ZIP files from datastores
  169. Log -Message "Removing offline ZIP file from $($datastoreams.Name)" -Type Info -OutputMode Both
  170. Get-ChildItem -Path "DC1:/$zip" | Remove-Item -Confirm:$false
  171.  
  172. Log -Message "Removing offline ZIP file from $($datastorewsn.Name)" -Type Info -OutputMode Both
  173. Get-ChildItem -Path "DC2:/$zip" | Remove-Item -Confirm:$false
  174.  
  175. # Remove PS drives
  176. Remove-PSDrive -Name DC1 -Confirm:$false
  177. Remove-PSDrive -Name DC2 -Confirm:$false
  178.  
  179. # Disconnect from vCenter Servers
  180. Disconnect-VIServer -Server $vCenter -Confirm:$false
  181. Log -Message "Disconnected from vCenter" -Type Info -OutputMode Both
  182.  
  183. Log -Message "Script Ended" -Type Info -OutputMode LogFile
RAW Paste Data