OK, here you go. I'll start with text notes.
Script to force Microsoft Cluster Aware Updates to pause and wait until StarWind nodes are fully synchronized before applying Windows Updates, in case an update requires a host to be rebooted. This is an enhaced and working solution based on the CAU.ps1 example script that is part of StarWindX-provided Powershell collection. You WILL also need to update the script with hostnames.
1. Put the Runner_CAU.PS1 file in folder shared by both hosts, e.g., C:\ClusterStorage\Volume1\CAU\ where Volume1 is a pointer to the Cluster Shared Volume. I created the CAU folder.
2. Go to Microsoft Failover Cluster Manager -> cluster-name -> Configure -> Cluster-Aware Updating > Configure cluster self-updating options -> Advanced Options -> PreUpdateScript
3. Put in the address of the the Runner-CAU.ps1 file
When you run Cluster Aware Updates, it will run the Runner script, which will run the kmCAU.ps1 script which should be in the same folder.
The kmCAU script can be run interactively to check statuses, in which case it will output updates to the screen. It will also log activity to CAU.LOG.
NOTE: the kmCAU.ps1 must be updated with site-specific details, particularly the node names of the servers being updated.
Runner_CAU.ps1
Code: Select all
powershell.exe -sta -file "C:\ClusterStorage\Volume1\CAU\kmCAU.ps1"
kmCAU.ps1
Code: Select all
Import-Module StarWindX
# Setting IP addresses of the StarWind storage nodes
$ip1 = "kmhv3" # IP address of node 1
$ip2 = "kmhv4" # IP address of node 2
$logfile = "C:\ClusterStorage\Volume1\CAU\CAU_LOG.txt"
# =====================================================================================
# Clear-Content 'C:\ClusterStorage\Volume1\CAU\CAU_LOG.txt'
$time = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R --- Starting StarWind CAU management") -PassThru
# =====================================================================================
$server1 = New-SWServer -host $ip1 -user root -password starwind -port 3261
$server2 = New-SWServer -host $ip2 -user root -password starwind -port 3261
$server1.Connect()
$server2.Connect()
if ($server1.Connected -and $server2.Connected){
# =====================================================================================
$time = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R StarWind servers connected") -PassThru
# =====================================================================================
do {
$result = @()
foreach($device1 in ($server1.Devices | where {$_.deviceType -eq 'HA Image'}))
{
$device1.Refresh()
$syncState1 = $device1.GetPropertyValue("ha_synch_status")
# ==================================================================================
$syncPercent = $device1.GetPropertyValue("ha_synch_percent")
$time1 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R $($device1.TargetName) synch state: $($syncState1) ($($syncPercent)%)") -PassThru
# ==================================================================================
if ($syncState1 -ne "1")
{
# ==================================================================================
# $time1 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R is not synchronized yet. Pausing for 120 seconds") -PassThru
# ==================================================================================
$result += $syncState1
}
}
foreach($device2 in ($server2.Devices | where {$_.deviceType -eq 'HA Image'}))
{
$device2.Refresh()
$syncState2 = $device2.GetPropertyValue("ha_synch_status")
# ==================================================================================
$syncPercent = $device2.GetPropertyValue("ha_synch_percent")
$time2 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R $($device2.TargetName) synch state: $($syncState2) ($($syncPercent)%)") -PassThru
# ==================================================================================
if ($syncState2 -ne "1")
{
# ==================================================================================
# $time2 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R $($device2.TargetName) is not synchronized yet. Pausing for 120 seconds") -PassThru
# ==================================================================================
$result += $syncState2
}
}
# =====================================================================================
#Wait for 120 second and rescan until all synched
$result = $result.length
if ($result -gt "0") {Start-Sleep -s 120}
} while ($result -gt "0")
} else {
# ==================================================================================
$time4 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R StarWind servers not connected. Stopping CAU run. Exiting...") -PassThru
# ==================================================================================
# Cancel CAU Process
Stop-CauRun -Force -Wait
}
$server1.Disconnect()
$server2.Disconnect()
# ==================================================================================
$time5 = (Get-Date -Uformat "%Y/%m/%d %R")
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R Synch OK, StarWind servers disconnected") -PassThru
Add-Content -Path $logfile -Value (Get-Date -Uformat "%Y/%m/%d %R pre-CAU script ended") -PassThru
# ==================================================================================