Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Perform steps to upgrade all ESXi hosts in a cluster.
- .DESCRIPTION
- Use this script to upgrade all ESXi hosts in a cluster with an offline ZIP file.
- This script assumes availability of the following modules:
- - VMware-PowerCli
- .PARAMETER
- - Cluster: name of the cluster to migrate.
- .EXAMPLE
- .\Upgrade-Cluster.ps1 -Cluster <clustername>
- .NOTES
- Script name: Upgrade-Cluster.ps1
- Author: Jeroen Buren
- DateCreated: 07-03-2020
- #>
- [CmdletBinding(SupportsShouldProcess=$true)]
- Param(
- [parameter(valuefrompipeline = $true, mandatory = $true,
- HelpMessage = "Enter the name of the cluster to upgrade.")]
- [string]$ClusterName
- )
- ####################################################################################
- # #
- # Functions #
- # #
- ####################################################################################
- function Get-ScriptDirectory {
- $Invocation = (Get-Variable MyInvocation -Scope 1).Value
- Split-Path $Invocation.MyCommand.Path
- }
- function Log {
- param(
- [Parameter(Mandatory=$true)][String]$Message,
- [Parameter(Mandatory=$true)][ValidateSet("Info","Debug","Warn","Error")][String]$Type,
- [Parameter(Mandatory=$true)][ValidateSet("Console","LogFile","Both")][String]$OutputMode
- )
- $dateTimeString = Get-Date -Format "yyyy-MM-dd HH:mm:sszz"
- $output = ($dateTimeString + " " + $type.ToUpper() + " " + $message)
- if ($outputMode -eq "Console" -OR $outputMode -eq "Both") {
- Write-Host $output
- }
- if ($outputMode -eq "LogFile" -OR $outputMode -eq "Both") {
- try {
- Add-Content $logFile -Value $output -ErrorAction Stop
- }
- catch {
- Log ("Failed to write to log file: """ + $logFile + """.") -OutputMode Console -Type Error
- Log ("[" + $_.Exception.GetType().FullName + "] " + $_.Exception.Message) -OutputMode Console -Type Error
- }
- }
- }
- ####################################################################################
- # #
- # Variables #
- # #
- ####################################################################################
- # Logfile
- Set-Variable logFile ((Get-ScriptDirectory) + "\Upgrade-Cluster-65.log") -Option Constant -ErrorAction SilentlyContinue
- $vCenter = "vCenter"
- $vib = "cisco-vem-v320-esx"
- $zip = "VMware-VMvisor-Installer-6.5.0.update03-15256549.x86_64-DellEMC_Customized-A05.zip"
- $profile = "DellEMC-ESXi-6.5U3-15256549-A05"
- ####################################################################################
- # #
- # Main Code #
- # #
- ####################################################################################
- Log -Message "Script started" -Type Info -OutputMode LogFile
- # Connect vCenter Server
- Connect-VIserver -Server $vCenter | Out-Null
- Log -Message "Connected to vCenter Server" -Type Info -OutputMode Both
- # Get cluster object
- $cluster = Get-Cluster $clusterName
- # Get two datastores with most free space
- Log -Message "Selecting datastores" -Type Info -OutputMode Both
- $datastore1 = ($cluster | Get-Datastore | Where-Object {$_.Name.Substring(8,3) -eq "DC1"} | Sort-Object FreeSpaceGB -Descending)[0]
- $ds1url = ($datastore1.ExtensionData.Info.Url).Trim("ds:/")
- $datastore2 = ($cluster | Get-Datastore | Where-Object {$_.Name.Substring(8,3) -eq "DC2"} | Sort-Object FreeSpaceGB -Descending)[0]
- $ds2url = ($datastore2.ExtensionData.Info.Url).Trim("ds:/")
- $datastore1 | New-DatastoreDrive -Name DC1
- $datastore2 | New-DatastoreDrive -Name DC2
- # Copy the offline ZIP file to the datastores
- Log -Message "Copying offline ZIP file to $($datastore1.Name)" -Type Info -OutputMode Both
- Copy-DatastoreItem -Item D:\Scripts\VMware\$zip -Destination DC1:\
- Log -Message "Copying offline ZIP file to $($datastore2.Name)" -Type Info -OutputMode Both
- Copy-DatastoreItem -Item D:\Scripts\VMware\$zip -Destination DC2:\
- # Create the depot variables
- $depot1 = "/$ds1url/$zip"
- $depot2 = "/$ds2url/$zip"
- # Disconnect all ISOs that may be attached to VMs and set the CD Drive state to "disconnected"
- Log -Message "Disconnecting CD drives" -Type Info -OutputMode Both
- $cluster | Get-VM | Get-CDDrive | Where-Object {($_.IsoPath -ne $null) -or ($_.ConnectionState.Connected -eq "true")} | Set-CDDrive -NoMedia -Connected:$false -Confirm:$false
- # Upgrade hosts
- Log -Message "Beginning upgrade of cluster" -Type Info -OutputMode Both
- foreach ($h in $cluster | Get-VMHost | Where {$_.Version -ne "6.5.0"} | Sort-Object Name) {
- # Enter maintenance mode
- Log -Message "Host $($h.Name) is entering Maintenance Mode" -Type Info -OutputMode Both
- Set-VMHost -VMHost $h -State Maintenance | Out-Null
- # Wait for the host to enter Maintenance Mode
- do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Maintenance')
- # Start removing the VIB
- Log -Message "Removing VIB from host" -Type Info -OutputMode Both
- $esxcli = Get-EsxCli -VMHost $h -V2
- $param = $esxcli.software.vib.remove.CreateArgs()
- $param.dryrun = $false
- $param.vibname = $vib
- $param.force = $false
- $esxcli.software.vib.remove.Invoke($param) | Out-Null
- # Update the host
- Log -Message "Upgrading host $($h.Name)" -Type Info -OutputMode Both
- $param = $esxcli.software.profile.update.CreateArgs()
- $param.dryrun = $false
- if ($h.Name.Substring(4,1) -eq "0") {$param.depot = $depot1}
- if ($h.Name.Substring(4,1) -eq "1") {$param.depot = $depot2}
- $param.profile = $profile
- $esxcli.software.profile.update.Invoke($param) | Out-Null
- # Reboot host and wait for it to come back
- Log -Message "Host $($h.Name) is rebooting" -Type Info -OutputMode Both
- Restart-VMHost -VMHost $h -Confirm:$false | Out-Null
- # Wait for the host to enter NotConnected state
- do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'NotResponding')
- # Wait for the host to get back
- do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Maintenance')
- # Exit maintenance mode
- Log -Message "Host $($h.Name) is exiting Maintenance Mode" -Type Info -OutputMode Both
- Set-VMHost -VMHost $h -State Connected | Out-Null
- # Wait for the host to leave Maintenance Mode
- do {Start-Sleep -Seconds 5} while ((Get-VMHost -Name $h.Name).ConnectionState -ne 'Connected')
- # Next host...
- }
- # Delete offline ZIP files from datastores
- Log -Message "Removing offline ZIP file from $($datastoreams.Name)" -Type Info -OutputMode Both
- Get-ChildItem -Path "DC1:/$zip" | Remove-Item -Confirm:$false
- Log -Message "Removing offline ZIP file from $($datastorewsn.Name)" -Type Info -OutputMode Both
- Get-ChildItem -Path "DC2:/$zip" | Remove-Item -Confirm:$false
- # Remove PS drives
- Remove-PSDrive -Name DC1 -Confirm:$false
- Remove-PSDrive -Name DC2 -Confirm:$false
- # Disconnect from vCenter Servers
- Disconnect-VIServer -Server $vCenter -Confirm:$false
- Log -Message "Disconnected from vCenter" -Type Info -OutputMode Both
- Log -Message "Script Ended" -Type Info -OutputMode LogFile
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement