Skip to content

Commit 7da1f59

Browse files
authored
🩹 [Patch]: Fix Windows PowerShell downgrade installation (#4)
This pull request refines the PowerShell installation process on Windows based GitHub runners. - Fixes #3 ### Windows-Specific Enhancements: * Added detection for currently installed PowerShell versions and introduced logic to handle downgrades, including uninstalling existing versions if necessary. * Improved uninstall command handling for MSI-based PowerShell installations by ensuring quiet and no-restart flags are added.
1 parent 0605bcb commit 7da1f59

File tree

1 file changed

+84
-18
lines changed

1 file changed

+84
-18
lines changed

action.yml

Lines changed: 84 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Install PowerShell
22
description: |
3-
Install a specific versionor the latest stable version of PowerShell Core
3+
Install a specific version, or the latest stable version, of PowerShell Core
44
on any GitHub runner (Linux, macOS, Windows).
55
Skips the install if the requested version is already present.
66
author: PSModule
@@ -29,7 +29,6 @@ runs:
2929
run: |
3030
# Install-PowerShell
3131
set -e
32-
3332
echo "Requested version: [$REQUESTED_VERSION]"
3433
3534
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
@@ -73,30 +72,26 @@ runs:
7372
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}"
7473
echo "Downloading from: $URL"
7574
wget -q "$URL" -O "$DEB_NAME"
76-
echo "Starting installation of PowerShell [$REQUESTED_VERSION)]..."
75+
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
7776
sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y
78-
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
7977
elif command -v rpm >/dev/null; then
8078
# RHEL/Fedora/CentOS based
8179
echo "Detected RHEL/Fedora/CentOS based system..."
82-
8380
if [[ "$ARCH" == "aarch64" ]]; then
8481
RPM_NAME="powershell-${REQUESTED_VERSION}-1.rh.${ARCH}.rpm"
8582
else
8683
RPM_NAME="powershell-${REQUESTED_VERSION}-1.rh.x86_64.rpm"
8784
fi
88-
8985
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${RPM_NAME}"
9086
echo "Downloading from: $URL"
9187
wget -q "$URL" -O "$RPM_NAME"
92-
echo "Starting installation of PowerShell [$REQUESTED_VERSION)]..."
88+
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
9389
sudo rpm -i "$RPM_NAME" || sudo yum install -y "$RPM_NAME"
94-
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
9590
else
9691
echo "Unsupported Linux distribution. Cannot determine package format."
9792
exit 1
9893
fi
99-
echo "PowerShell [$REQUESTED_VERSION] installed successfully."
94+
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
10095
10196
- name: Install PowerShell (macOS)
10297
if: runner.os == 'macOS'
@@ -108,7 +103,6 @@ runs:
108103
run: |
109104
# Install-PowerShell
110105
set -e
111-
112106
echo "Requested version: [$REQUESTED_VERSION]"
113107
114108
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
@@ -151,15 +145,13 @@ runs:
151145
152146
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}"
153147
echo "Downloading from: $URL"
154-
155148
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
156149
157150
if ! curl -sSL "$URL" -o "$PKG_NAME"; then
158151
echo "Error: Failed to download PowerShell package"
159152
exit 1
160153
fi
161154
sudo installer -pkg "$PKG_NAME" -target /
162-
163155
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
164156
165157
- name: Install PowerShell (Windows)
@@ -173,7 +165,7 @@ runs:
173165
# Install-PowerShell
174166
Write-Host "Requested version: [$env:REQUESTED_VERSION]"
175167
176-
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
168+
# Resolve 'latest' → concrete version
177169
$req = $env:REQUESTED_VERSION
178170
if ($req -and $req.Trim().ToLower() -eq 'latest') {
179171
$latest = (
@@ -191,29 +183,103 @@ runs:
191183
exit 1
192184
}
193185
186+
# Detect currently installed version (if any)
187+
$detected = $null
194188
try {
195189
$detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()')
196190
Write-Host "Currently installed PowerShell version: $detected"
197191
} catch {
198192
Write-Host "PowerShell is not currently installed"
199-
$detected = $null
200193
}
201194
202195
if ($detected -eq $env:REQUESTED_VERSION) {
203196
Write-Host "PowerShell $detected already installed. Skipping."
204197
exit 0
205198
}
206199
200+
# Downgrade detection
201+
$isDowngrade = $false
202+
if ($detected -and $detected -ne $env:REQUESTED_VERSION) {
203+
try {
204+
$detectedVersion = [version]$detected
205+
$requestedVersion = [version]$env:REQUESTED_VERSION
206+
if ($detectedVersion -gt $requestedVersion) {
207+
Write-Host "Downgrade detected: $detected → $($env:REQUESTED_VERSION)"
208+
$isDowngrade = $true
209+
} else {
210+
Write-Host "Upgrade detected: $detected → $($env:REQUESTED_VERSION)"
211+
}
212+
} catch {
213+
Write-Host "Warning: Could not compare versions, proceeding with regular installation"
214+
}
215+
}
216+
217+
# If downgrade → fully uninstall current PowerShell 7
218+
if ($isDowngrade) {
219+
Write-Host "Uninstalling existing PowerShell version before downgrade..."
220+
221+
# Search both 64-bit and 32-bit uninstall hives
222+
$regPaths = @(
223+
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
224+
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
225+
)
226+
227+
$pwshEntries = Get-ItemProperty -Path $regPaths -ErrorAction SilentlyContinue |
228+
Where-Object {
229+
$_.Publisher -eq 'Microsoft Corporation' -and
230+
$_.DisplayName -like 'PowerShell 7*' -and
231+
$_.DisplayName -notlike '*Preview*' -and
232+
$_.DisplayVersion -and
233+
$_.DisplayVersion.StartsWith($detected)
234+
}
235+
236+
$targetEntry = $pwshEntries | Select-Object -First 1
237+
if (-not $targetEntry) {
238+
Write-Host "Warning: Could not find an uninstall entry for PowerShell $detected"
239+
} else {
240+
$uninstallCmd = if ($targetEntry.QuietUninstallString) {
241+
$targetEntry.QuietUninstallString
242+
} else {
243+
$targetEntry.UninstallString
244+
}
245+
246+
# If the uninstall command is MSI-based and lacks /quiet, add it
247+
if ($uninstallCmd -match 'msiexec') {
248+
if ($uninstallCmd -notmatch '/quiet') { $uninstallCmd += ' /quiet' }
249+
if ($uninstallCmd -notmatch '/norestart') { $uninstallCmd += ' /norestart' }
250+
}
251+
252+
Write-Host "Running uninstall command:`n$uninstallCmd"
253+
$proc = Start-Process 'cmd.exe' -ArgumentList '/c', $uninstallCmd -Wait -PassThru
254+
if ($proc.ExitCode -ne 0) {
255+
Write-Host "Error: Uninstall failed (exit code $($proc.ExitCode))."
256+
exit 1
257+
}
258+
259+
# Double-check removal
260+
try {
261+
$after = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()')
262+
if ($after) {
263+
Write-Host "Error: PowerShell is still present ($after) after uninstall. Aborting downgrade."
264+
exit 1
265+
}
266+
} catch { }
267+
}
268+
}
269+
270+
# Download requested MSI
207271
$msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi"
208272
$url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi"
209273
Write-Host "Downloading from: $url"
210274
211-
Write-Host "Starting installation of PowerShell [$($env:REQUESTED_VERSION)]..."
275+
$null = Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing -ErrorAction Stop
212276
213-
if (-not (Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing -PassThru)) {
214-
Write-Host "Error: Failed to download PowerShell package"
277+
# Install requested version
278+
Write-Host "Starting installation of PowerShell [$($env:REQUESTED_VERSION)]..."
279+
$msiProcess = Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait -PassThru
280+
if ($msiProcess.ExitCode -ne 0) {
281+
Write-Host "Error: Installation failed (exit code $($msiProcess.ExitCode))."
215282
exit 1
216283
}
217-
Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait
218284
219285
Write-Host "Installation complete. PowerShell [$($env:REQUESTED_VERSION)] is now available."

0 commit comments

Comments
 (0)