Last active
November 13, 2024 13:07
-
-
Save SMSAgentSoftware/83748e4d3daa61ba5018da052c2f41b4 to your computer and use it in GitHub Desktop.
PowerShell script to extract time statistics from a recently installed feature update (full OS swap)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Get time statistics for a Windows feature update (full OS swap) | |
# Requires that the "Windows.old" folder still exists on the machine | |
#Requires -RunAsAdministrator | |
# Specify the FU version | |
$FUVersion = "24H2" | |
$BuildNumber = "26100" | |
# Check we are on the correct build | |
$CurrentBuildNumber = Get-CimInstance Win32_OperatingSystem | Select -ExpandProperty BuildNumber | |
if ($CurrentBuildNumber -ne $BuildNumber) | |
{ | |
Write-Host "Not on build $BuildNumber. Exiting..." | |
Exit 0 | |
} | |
# Check if Windows.old exists | |
if (-not (Test-Path "C:\Windows.old\Windows\System32\winevt\Logs\System.evtx") ) | |
{ | |
Write-Host "Windows.old does not exist. Exiting..." | |
Exit 0 | |
} | |
# Get the latest restart event before new OS files swap | |
$Params = @{ | |
Path = "C:\Windows.old\Windows\System32\winevt\Logs\System.evtx" | |
Id = 1074 | |
} | |
$PostInstallRebootTime = Get-WinEvent -FilterHashtable $Params -ErrorAction SilentlyContinue | | |
Select -First 1 | | |
Select -ExpandProperty TimeCreated | |
# Get Windows update events prior to reboot | |
$Params = @{ | |
Path = "C:\Windows.old\Windows\System32\winevt\Logs\System.evtx" | |
ProviderName = "Microsoft-Windows-WindowsUpdateClient" | |
} | |
$WUEvents = Get-WinEvent -FilterHashtable $Params -ErrorAction SilentlyContinue | |
# Find upgrade start time | |
$UpgradeStartTime = $WUEvents | | |
Where-Object { $_.Id -eq 43 -and $_.Message -match "11," -and $_.Message -match "$FUVersion" } | | |
Select -First 1 | Select -ExpandProperty TimeCreated | |
# Find download start time | |
$DownloadStartTime = $WUEvents | | |
Where-Object { $_.Id -eq 44 -and [datetime]$_.TimeCreated -lt $UpgradeStartTime } | | |
Select -First 1 | Select -ExpandProperty TimeCreated | |
# Find commit start time | |
$CommitStartTime = $WUEvents | | |
Where-Object { $_.Id -eq 218 -and $_.Message -match "11," -and $_.Message -match "$FUVersion" } | | |
Select -First 1 | Select -ExpandProperty TimeCreated | |
# Find commit finish time | |
$CommitFinishTime = $WUEvents | | |
Where-Object { $_.Id -eq 216 -and $_.Message -match "11," -and $_.Message -match "$FUVersion" } | | |
Select -First 1 | Select -ExpandProperty TimeCreated | |
# Find Upgrade finish time | |
$Params = @{ | |
LogName = "System" | |
ProviderName = "Microsoft-Windows-WindowsUpdateClient" | |
Id = 19 | |
} | |
$UpgradeFinishTime = Get-WinEvent -FilterHashtable $Params -ErrorAction SilentlyContinue | | |
Where-Object { $_.Message -match "11," -and $_.Message -match "$FUVersion" -and $_.Message -notmatch "KB" } | | |
Select -First 1 | Select -ExpandProperty TimeCreated | |
# Calculate durations | |
# Total upgrade duration (ie time between upgrade start, reboot and finish) | |
If ($UpgradeStartTime -and $UpgradeFinishTime) | |
{ | |
$TotalUpgradeDurationMinutes = ($UpgradeFinishTime - $UpgradeStartTime).TotalMinutes | |
} | |
# Install duration - this value is only accurate if the device was rebooted immediately after the upgrade | |
#if ($UpgradeStartTime -and $PostInstallRebootTime) | |
#{ | |
# $InstallDurationMinutes = ($PostInstallRebootTime - $UpgradeStartTime).TotalMinutes | |
#} | |
# Content download duration | |
If ($DownloadStartTime -and $UpgradeStartTime) | |
{ | |
$DownloadDurationMinutes = ($UpgradeStartTime - $DownloadStartTime).TotalMinutes | |
} | |
# Commit duration | |
If ($CommitStartTime -and $CommitFinishTime) | |
{ | |
$CommitDurationMinutes = ($CommitFinishTime - $CommitStartTime).TotalMinutes | |
} | |
# Offline time, ie time between post-install reboot and upgrade finish | |
If ($PostInstallRebootTime -and $UpgradeFinishTime) | |
{ | |
$OfflineTimeMinutes = ($UpgradeFinishTime - $PostInstallRebootTime).TotalMinutes | |
} | |
# Output results | |
[PSCustomObject]@{ | |
DownloadStartTime = $DownloadStartTime | |
UpgradeStartTime = $UpgradeStartTime | |
PostInstallRebootTime = $PostInstallRebootTime | |
CommitStartTime = $CommitStartTime | |
CommitFinishTime = $CommitFinishTime | |
UpgradeFinishTime = $UpgradeFinishTime | |
DownloadDurationMinutes = $DownloadDurationMinutes | |
#InstallDurationMinutes = $InstallDurationMinutes | |
CommitDurationMinutes = $CommitDurationMinutes | |
OfflineTimeMinutes = $OfflineTimeMinutes | |
TotalUpgradeDurationMinutes = $TotalUpgradeDurationMinutes | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment