PowerShell

Install PowerShell with PowerShell

I’m trying to get better about using the new versions of PowerShell (7.x) instead of Windows PowerShell (5.x), but I find that I forget to install it on some machines. To make that easier, I wrote myself a script (in PowerShell) to install PowerShell. I know – don’t judge me. This is the script.

https://github.com/PowerShell/PowerShell/releases/latest
#region Get the current published releases for PowerShell on GitHub via the API
$GhHeaders = @{ 'Accept' = 'application/vnd.github+json'; 'X-GitHub-Api-Version' = '2026-03-10' }
$Releases = Invoke-RestMethod https://api.github.com/repos/powershell/powershell/releases -Headers $GhHeaders
#endregion Get the current published releases for PowerShell on GitHub via the API

#region Extend the received data for quick filtering
# Add a script property that'll extract out the version type information
$Releases | Add-Member -MemberType ScriptProperty -Name ReleaseType -Value { 
    switch -regex ( $this.tag_name ) {
        '-preview\.' { 'Preview'; break } # Preview build
        '-rc\.'      { 'RC'; break }      # release candicate
        default      { 'GA' }             # generally available
    }
} -Force
# Add a script property that'll extract out the version information (as a [Version] type)
$Releases | Add-Member -MemberType ScriptProperty -Name Version -value { [version]( $this.tag_name -replace '^v', '' -replace '-(?:preview|rc)\.', '.' ) } -Force
#endregion Extend the received data for quick filtering

#region Now we can filter easier and access the asset information, get the URL, and download
# Note: I'm assuming you want the latest regular available and not the RC or preview builds.  If that's different change the below.
$MostRecent = $Releases | Where-Object { $_.ReleaseType -eq 'GA' } | Sort-Object -Property Version -Descending | Select-Object -First 1
# Getting the hashes (for all files) and the MSI for the current architecture download URLs
$DownloadLinkHashes = $MostRecent.assets | Where-Object { $_.name -eq 'hashes.sha256' } | Select-Object -ExpandProperty browser_download_url
$Architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLower()
$DownloadLink = $MostRecent.assets | Where-Object { $_.name -like "PowerShell-*.*.*-win-$( $Architecture ).msi" } | Select-Object -ExpandProperty browser_download_url
if ( $DownloadLink ) { 
    Invoke-WebRequest -Uri $DownloadLink -OutFile ( Join-Path -Path $env:temp -ChildPath ( ( [uri]$DownloadLink ).Segments[-1] ) )
    Invoke-WebRequest -Uri $DownloadLinkHashes -OutFile ( Join-Path -Path $env:temp -ChildPath ( ( [uri]$DownloadLinkHashes ).Segments[-1] ) )
} else {
    Write-Error -Message "No matching download for the architecture or hash file"
    exit
}
#endregion Now we can filter easier and access the asset information, get the URL, and download

#region Check the validity of the MSI and then kick off the installer
# There's a bunch here:
#   - Read in the hashes file
#   - inline replace the '<space>*' string with a comma (so we can treat it as a CSV)
#   - Convert from a CSV
#   - Filter for only the downloaded file name that matches
#   - Grab the hash
#   - store it as its own variable
$Hash = Get-Content -Path ( Join-Path -Path $env:temp -ChildPath ( ( [uri]$DownloadLinkHashes ).Segments[-1] ) ) | ForEach-Object { $_ -replace '\s\*', ',' } | ConvertFrom-Csv -Header @( 'hash', 'file' ) | Where-Object { $_.file -eq ( ( [uri]$DownloadLink ).Segments[-1] ) } | Select-Object -ExpandProperty hash
# compute the file's hash value and store it
$FileHash = Get-FileHash -Path ( Join-Path -Path $env:temp -ChildPath ( ( [uri]$DownloadLink ).Segments[-1] ) ) -Algorithm SHA256 | Select-Object -ExpandProperty Hash
# if they match, then we can Install-Dtc
if ( $FileHash -eq $Hash ) {
	Start-Process -FilePath "C:\WINDOWS\system32\msiexec.exe" -ArgumentList @( "/package", "$( Join-Path -Path $env:temp -ChildPath ( ( [uri]$DownloadLink ).Segments[-1] ) )", "/passive" ) -Wait
} else {
	Write-Error -Message "File doesn't match published hash."
}
#endregion Check the validity of the MSI and then kick off the installer

The script will search on the GitHub releases page for matching (x64) msi files and then download and install the most recent (by version number, not date) one. It’s simple, but effective.

Similar Posts

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.