Assistance at your fingertips...

Update PWSH Easily

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

Posted

in

, ,

by