This bypasses the winget manifest update lag
'Update-PWSH.ps1'
<#
.SYNOPSIS
Enterprise-grade PowerShell 7 version validation and controlled update.
.DESCRIPTION
- Retrieves the installed PowerShell 7 version directly from pwsh.exe
(never trusts the calling host — avoids Windows PowerShell version shims).
- Retrieves GitHub stable version via curl.exe (avoids .NET Invoke-RestMethod failures).
- Retrieves winget manifest version and normalizes to 3-part semantic versioning.
- Compares all three sources deterministically.
- Only upgrades when GitHub and winget match (manifest has caught up).
- Prevents premature installs during winget manifest lag.
- Safe for RMM, Intune, Scheduled Tasks, and hybrid environments.
.NOTES
Author: Burwell.Tech LLC
Compliance: SOC-friendly, auditable, deterministic
Warning: Do NOT run this script inside Windows PowerShell 5.1.
This script enforces pwsh.exe detection to avoid version spoofing.
#>
Write-Host "=== Burwell.Tech PowerShell Version Check ===" -ForegroundColor Cyan
# -------------------------------
# Installed Version (always from pwsh.exe)
# -------------------------------
try {
$installed = pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()'
$installed = ($installed -split '\.')[0..2] -join '.'
}
catch {
Write-Warning "pwsh.exe not found. PowerShell 7 is not installed."
$installed = "0.0.0"
}
# -------------------------------
# GitHub Latest Stable (via curl.exe)
# -------------------------------
try {
$github = (
curl.exe -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json |
Select-String '"StableReleaseTag"' |
ForEach-Object { ($_ -split ':')[1].Trim(' ",') }
) -replace '^v',''
$github = ($github -split '\.')[0..2] -join '.'
}
catch {
Write-Warning "Unable to retrieve GitHub metadata."
$github = "0.0.0"
}
# -------------------------------
# Winget Manifest Version
# -------------------------------
try {
$wingetmanifest = (
winget show --id Microsoft.PowerShell --exact |
Select-String '^Version' |
ForEach-Object { ($_ -split '\s+')[1] }
)
$winget = ($wingetmanifest -split '\.')[0..2] -join '.'
}
catch {
Write-Warning "Unable to retrieve winget manifest version."
$winget = "0.0.0"
}
# -------------------------------
# Output Summary
# -------------------------------
Write-Host "Installed Version : $installed"
Write-Host "GitHub Latest : $github"
Write-Host "Winget Latest : $winget"
Write-Host ""
# -------------------------------
# Comparison Logic
# -------------------------------
$vInstalled = [version]$installed
$vGitHub = [version]$github
$vWinget = [version]$winget
# -------------------------------
# Update Logic (Burwell.Tech Standard)
# -------------------------------
if ($vGitHub -gt $vInstalled) {
Write-Host "A newer PowerShell version exists." -ForegroundColor Yellow
if ($vGitHub -eq $vWinget) {
Write-Host "Winget manifest has caught up. Proceeding with upgrade..." -ForegroundColor Green
winget install --id Microsoft.PowerShell --source winget --accept-source-agreements --accept-package-agreements
}
else {
Write-Host "Winget manifest is behind GitHub. Waiting for manifest sync." -ForegroundColor DarkYellow
Write-Host "No upgrade performed." -ForegroundColor DarkYellow
}
}
else {
Write-Host "PowerShell is up to date." -ForegroundColor Green
}
Write-Host "=== Version Check Complete ===" -ForegroundColor Cyan


