Skip to content

Commit 4c361ee

Browse files
Refactor installation logic for PowerShell across platforms to skip installation if the requested version is already installed
1 parent 55afe33 commit 4c361ee

File tree

1 file changed

+30
-215
lines changed

1 file changed

+30
-215
lines changed

action.yml

Lines changed: 30 additions & 215 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
@@ -11,8 +11,7 @@ branding:
1111
inputs:
1212
Version:
1313
description: |
14-
PowerShell version to install (e.g. `7.4.1`).
15-
Defaults to install the latest stable release.
14+
PowerShell version to install (e.g. `7.4.1` or `latest` for newest stable release).
1615
required: false
1716
default: 'latest'
1817

@@ -28,75 +27,17 @@ runs:
2827
GITHUB_TOKEN: ${{ github.token }}
2928
run: |
3029
# Install-PowerShell
31-
set -e
32-
33-
echo "Requested version: [$REQUESTED_VERSION]"
34-
35-
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
36-
case "${REQUESTED_VERSION:-}" in
37-
[Ll][Aa][Tt][Ee][Ss][Tt])
38-
REQUESTED_VERSION=$(
39-
curl -s -f \
40-
-H "Accept: application/vnd.github+json" \
41-
-H "Authorization: Bearer $GITHUB_TOKEN" \
42-
-H "X-GitHub-Api-Version: 2022-11-28" \
43-
https://api.github.com/repos/PowerShell/PowerShell/releases/latest |
44-
jq -r '.tag_name' | sed 's/^v//'
45-
)
46-
echo "Latest stable PowerShell release detected: $REQUESTED_VERSION"
47-
;;
48-
"")
49-
echo "Error: Version input is required (or use 'latest')"
50-
exit 1
51-
;;
52-
esac
53-
54-
DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true)
55-
if [[ -n "$DETECTED_VERSION" ]]; then
56-
echo "Currently installed PowerShell version: $DETECTED_VERSION"
57-
else
58-
echo "PowerShell is not currently installed"
59-
fi
60-
61-
if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then
62-
echo "PowerShell $DETECTED_VERSION already installed. Skipping."
63-
exit 0
64-
fi
65-
66-
# Determine Linux distribution type
67-
ARCH=$(dpkg --print-architecture 2>/dev/null || rpm --eval '%{_arch}' 2>/dev/null || echo "x86_64")
68-
69-
if command -v apt-get >/dev/null || command -v dpkg >/dev/null; then
70-
# Debian/Ubuntu based
71-
echo "Detected Debian/Ubuntu based system..."
72-
DEB_NAME="powershell_${REQUESTED_VERSION}-1.deb_${ARCH}.deb"
73-
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${DEB_NAME}"
74-
echo "Downloading from: $URL"
75-
wget -q "$URL" -O "$DEB_NAME"
76-
echo "Starting installation of PowerShell [$REQUESTED_VERSION)]..."
77-
sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y
78-
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
79-
elif command -v rpm >/dev/null; then
80-
# RHEL/Fedora/CentOS based
81-
echo "Detected RHEL/Fedora/CentOS based system..."
82-
83-
if [[ "$ARCH" == "aarch64" ]]; then
84-
RPM_NAME="powershell-${REQUESTED_VERSION}-1.rh.${ARCH}.rpm"
85-
else
86-
RPM_NAME="powershell-${REQUESTED_VERSION}-1.rh.x86_64.rpm"
30+
# If PowerShell is already installed at the requested version, skip installation
31+
if command -v pwsh &> /dev/null; then
32+
current=$(pwsh -NoProfile -Command '$PSVersionTable.PSVersion.ToString()')
33+
if [ "$REQUESTED_VERSION" != "latest" ] && [ "$current" = "$REQUESTED_VERSION" ]; then
34+
echo "PowerShell $current is already installed. Skipping installation."
35+
exit 0
8736
fi
88-
89-
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${RPM_NAME}"
90-
echo "Downloading from: $URL"
91-
wget -q "$URL" -O "$RPM_NAME"
92-
echo "Starting installation of PowerShell [$REQUESTED_VERSION)]..."
93-
sudo rpm -i "$RPM_NAME" || sudo yum install -y "$RPM_NAME"
94-
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
95-
else
96-
echo "Unsupported Linux distribution. Cannot determine package format."
97-
exit 1
9837
fi
99-
echo "PowerShell [$REQUESTED_VERSION] installed successfully."
38+
# Download and run the official install script for Linux from the PowerShell GitHub repo
39+
echo "Downloading and installing PowerShell $REQUESTED_VERSION on Linux..."
40+
curl -sSL https://aka.ms/install-powershell.sh | sudo bash -s -- "$REQUESTED_VERSION"
10041
10142
- name: Install PowerShell (macOS)
10243
if: runner.os == 'macOS'
@@ -107,60 +48,17 @@ runs:
10748
GITHUB_TOKEN: ${{ github.token }}
10849
run: |
10950
# Install-PowerShell
110-
set -e
111-
112-
echo "Requested version: [$REQUESTED_VERSION]"
113-
114-
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
115-
case "${REQUESTED_VERSION:-}" in
116-
[Ll][Aa][Tt][Ee][Ss][Tt])
117-
REQUESTED_VERSION=$(
118-
curl -s -f \
119-
-H "Accept: application/vnd.github+json" \
120-
-H "Authorization: Bearer $GITHUB_TOKEN" \
121-
-H "X-GitHub-Api-Version: 2022-11-28" \
122-
https://api.github.com/repos/PowerShell/PowerShell/releases/latest |
123-
jq -r '.tag_name' | sed 's/^v//'
124-
)
125-
echo "Latest stable PowerShell release detected: $REQUESTED_VERSION"
126-
;;
127-
"")
128-
echo "Error: Version input is required (or use 'latest')"
129-
exit 1
130-
;;
131-
esac
132-
133-
DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true)
134-
if [[ -n "$DETECTED_VERSION" ]]; then
135-
echo "Currently installed PowerShell version: $DETECTED_VERSION"
136-
else
137-
echo "PowerShell is not currently installed"
138-
fi
139-
140-
if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then
141-
echo "PowerShell $DETECTED_VERSION already installed. Skipping."
142-
exit 0
143-
fi
144-
145-
# Determine architecture and download appropriate package
146-
ARCH=$(uname -m)
147-
case "$ARCH" in
148-
"arm64") PKG_NAME="powershell-${REQUESTED_VERSION}-osx-arm64.pkg" ;;
149-
*) PKG_NAME="powershell-${REQUESTED_VERSION}-osx-x64.pkg" ;;
150-
esac
151-
152-
URL="https://github.com/PowerShell/PowerShell/releases/download/v${REQUESTED_VERSION}/${PKG_NAME}"
153-
echo "Downloading from: $URL"
154-
155-
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
156-
157-
if ! curl -sSL "$URL" -o "$PKG_NAME"; then
158-
echo "Error: Failed to download PowerShell package"
159-
exit 1
51+
# If the requested version of PowerShell is already installed, skip installation
52+
if command -v pwsh &> /dev/null; then
53+
current=$(pwsh -NoProfile -Command '$PSVersionTable.PSVersion.ToString()')
54+
if [ "$REQUESTED_VERSION" != "latest" ] && [ "$current" = "$REQUESTED_VERSION" ]; then
55+
echo "PowerShell $current is already installed. Skipping installation."
56+
exit 0
57+
fi
16058
fi
161-
sudo installer -pkg "$PKG_NAME" -target /
162-
163-
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
59+
echo "Downloading and installing PowerShell $REQUESTED_VERSION on macOS..."
60+
# Run the official install script for macOS (same script handles macOS detection internally)
61+
curl -sSL https://aka.ms/install-powershell.sh | bash -s -- "$REQUESTED_VERSION"
16462
16563
- name: Install PowerShell (Windows)
16664
if: runner.os == 'Windows'
@@ -171,97 +69,14 @@ runs:
17169
GITHUB_TOKEN: ${{ github.token }}
17270
run: |
17371
# Install-PowerShell
174-
Write-Host "Requested version: [$env:REQUESTED_VERSION]"
175-
176-
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
177-
$req = $env:REQUESTED_VERSION
178-
if ($req -and $req.Trim().ToLower() -eq 'latest') {
179-
$latest = (
180-
Invoke-RestMethod -Uri 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest' `
181-
-Headers @{
182-
'Accept' = 'application/vnd.github+json'
183-
'Authorization' = "Bearer $($env:GITHUB_TOKEN)"
184-
'X-GitHub-Api-Version' = '2022-11-28'
185-
}
186-
).tag_name.TrimStart('v')
187-
Write-Host "Latest stable PowerShell release detected: $latest"
188-
$env:REQUESTED_VERSION = $latest
189-
} elseif ([string]::IsNullOrWhiteSpace($req)) {
190-
Write-Host "Error: Version input is required (or use 'latest')"
191-
exit 1
192-
}
193-
194-
try {
195-
$detected = (pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()')
196-
Write-Host "Currently installed PowerShell version: $detected"
197-
} catch {
198-
Write-Host "PowerShell is not currently installed"
199-
$detected = $null
200-
}
201-
202-
if ($detected -eq $env:REQUESTED_VERSION) {
203-
Write-Host "PowerShell $detected already installed. Skipping."
204-
exit 0
205-
}
206-
207-
# Check if we need to handle a downgrade scenario
208-
$isDowngrade = $false
209-
if ($detected -and $detected -ne $env:REQUESTED_VERSION) {
210-
try {
211-
$detectedVersion = [version]$detected
212-
$requestedVersion = [version]$env:REQUESTED_VERSION
213-
if ($detectedVersion -gt $requestedVersion) {
214-
Write-Host "Downgrade detected: $detected → $($env:REQUESTED_VERSION)"
215-
$isDowngrade = $true
216-
} else {
217-
Write-Host "Upgrade detected: $detected → $($env:REQUESTED_VERSION)"
218-
}
219-
} catch {
220-
Write-Host "Warning: Could not compare versions, proceeding with regular installation"
72+
# If the requested version of PowerShell is already installed, skip installation
73+
if (Get-Command pwsh -ErrorAction SilentlyContinue) {
74+
$current = pwsh -NoProfile -Command "$($PSVersionTable.PSVersion)"
75+
if ($env:REQUESTED_VERSION -ne 'latest' -and $current -eq $env:REQUESTED_VERSION) {
76+
Write-Host "PowerShell $current is already installed. Skipping installation."
77+
return
22178
}
22279
}
223-
224-
$msi = "PowerShell-$($env:REQUESTED_VERSION)-win-x64.msi"
225-
$url = "https://github.com/PowerShell/PowerShell/releases/download/v$($env:REQUESTED_VERSION)/$msi"
226-
Write-Host "Downloading from: $url"
227-
228-
if (-not (Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing -PassThru)) {
229-
Write-Host "Error: Failed to download PowerShell package"
230-
exit 1
231-
}
232-
233-
Write-Host "Starting installation of PowerShell [$($env:REQUESTED_VERSION)]..."
234-
235-
if ($isDowngrade) {
236-
# For downgrades, uninstall the existing version first, then install the new one
237-
Write-Host "Downgrade detected - uninstalling existing PowerShell version first..."
238-
239-
# Find PowerShell installation to uninstall
240-
$uninstallString = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue |
241-
Where-Object { $_.DisplayName -like "*PowerShell*" -and $_.Publisher -eq "Microsoft Corporation" } |
242-
Select-Object -First 1 -ExpandProperty UninstallString
243-
244-
if ($uninstallString) {
245-
Write-Host "Found existing PowerShell installation, uninstalling..."
246-
# Extract the product code from the uninstall string
247-
if ($uninstallString -match '{[0-9A-F-]+}') {
248-
$productCode = $matches[0]
249-
Write-Host "Uninstalling PowerShell with product code: $productCode"
250-
Start-Process msiexec.exe -ArgumentList '/x', $productCode, '/quiet', '/norestart' -Wait
251-
Write-Host "Uninstall completed"
252-
} else {
253-
Write-Host "Warning: Could not extract product code from uninstall string: $uninstallString"
254-
}
255-
} else {
256-
Write-Host "Warning: Could not find PowerShell installation to uninstall"
257-
}
258-
259-
# Now install the new version
260-
Write-Host "Installing PowerShell [$($env:REQUESTED_VERSION)]..."
261-
Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait
262-
} else {
263-
# For upgrades or fresh installs, use regular install
264-
Start-Process msiexec.exe -ArgumentList '/i', $msi, '/quiet', '/norestart' -Wait
265-
}
266-
267-
Write-Host "Installation complete. PowerShell [$($env:REQUESTED_VERSION)] is now available."
80+
Write-Host "Downloading and installing PowerShell $env:REQUESTED_VERSION on Windows..."
81+
# Execute the official install script for Windows (downloads and installs the MSI package)
82+
iex "& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -UseMSI -Quiet"

0 commit comments

Comments
 (0)