Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/powershell/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles
| version | Select or enter a version of PowerShell. | string | latest |
| modules | Optional comma separated list of PowerShell modules to install. If you need to install a specific version of a module, use '==' to specify the version (e.g. 'az.resources==2.5.0') | string | - |
| powershellProfileURL | Optional (publicly accessible) URL to download PowerShell profile. | string | - |
| preserveHistory | Optional Enable to preserve the powershell history across container restart/rebuilds | boolean | true |

## Customizations

Expand Down
17 changes: 16 additions & 1 deletion src/powershell/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "powershell",
"version": "2.0.2",
"version": "2.0.3",
"name": "PowerShell",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/powershell",
"description": "Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
Expand Down Expand Up @@ -28,6 +28,11 @@
"type": "string",
"default": "",
"description": "Optional (publicly accessible) URL to download PowerShell profile."
},
"preserveHistory": {
"type": "boolean",
"default": true,
"description": "Optional Enable to preserve the powershell history across container restart/rebuilds"
}
},
"customizations": {
Expand All @@ -44,6 +49,16 @@
]
}
},
"mounts": [
{
"type": "volume",
"source": "${devcontainerId}-powershell-history",
"target": "/dc/powershell"
}
],
"onCreateCommand": {
"powershell": "/usr/local/share/powershell/scripts/oncreate.sh"
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
Expand Down
29 changes: 28 additions & 1 deletion src/powershell/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@

set -e

# Capture the location of this script once so later directory changes do not affect relative file lookups.
SOURCE_DIR="$(pwd)"

# Clean up
rm -rf /var/lib/apt/lists/*

POWERSHELL_VERSION=${VERSION:-"latest"}
POWERSHELL_MODULES="${MODULES:-""}"
POWERSHELL_PROFILE_URL="${POWERSHELLPROFILEURL}"
PRESERVE_HISTORY="${PRESERVEHISTORY}"

MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
#MICROSOFT_GPG_KEYS_URI=$(curl https://packages.microsoft.com/keys/microsoft.asc -o /usr/share/keyrings/microsoft-archive-keyring.gpg)
Expand Down Expand Up @@ -494,7 +498,30 @@ if [ -n "$POWERSHELL_PROFILE_URL" ]; then
echo "Downloading PowerShell Profile from: $POWERSHELL_PROFILE_URL"
# Get profile path from currently installed pwsh
profilePath=$(pwsh -noni -c '$PROFILE.AllUsersAllHosts')
sudo -E curl -sSL -o "$profilePath" "$POWERSHELL_PROFILE_URL"
# Download to a temp file first so a non-200 response never overwrites the profile
tmpProfile="$(mktemp)"
http_status=$(curl -sSL -w '%{http_code}' -o "$tmpProfile" "$POWERSHELL_PROFILE_URL")
if [ "$http_status" = "200" ]; then
mv "$tmpProfile" "$profilePath"
else
echo "Failed to download PowerShell profile (HTTP ${http_status}). Skipping profile update." >&2
rm -f "$tmpProfile"
fi
fi

# Copy persistent history setup script
ONCREATE_SOURCE="${SOURCE_DIR}/oncreate.sh"
SCRIPTS_DIR="/usr/local/share/powershell/scripts"
mkdir -p "$SCRIPTS_DIR"
echo "Checking oncreate.sh"
if [ ! -f "$ONCREATE_SOURCE" ]; then
echo "oncreate.sh not found at expected path: $ONCREATE_SOURCE" >&2
exit 1
fi
if [ -f "$ONCREATE_SOURCE" ]; then
cp "$ONCREATE_SOURCE" "$SCRIPTS_DIR/oncreate.sh"
sed -i "s|preserveHistoryFromInstallSh|${PRESERVE_HISTORY}|" "$SCRIPTS_DIR/oncreate.sh"
chmod +x "$SCRIPTS_DIR/oncreate.sh"
fi

# Clean up
Expand Down
24 changes: 24 additions & 0 deletions src/powershell/oncreate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -e

PRESERVE_HISTORY="preserveHistoryFromInstallSh"
HISTORY_SAVE_LINE='Set-PSReadLineOption -HistorySavePath /dc/powershell/history.txt'

if [ "${PRESERVE_HISTORY}" = "true" ]; then
if [ "$(stat -c '%u:%g' "/dc/powershell")" = "$(id -u):$(id -g)" ]; then
echo "Already owned by the current user, nothing to do"
elif [ "$(id -u)" -eq 0 ]; then
chown -R "$(id -u):$(id -g)" "/dc/powershell"
elif command -v sudo >/dev/null 2>&1; then
sudo chown -R "$(id -u):$(id -g)" "/dc/powershell"
else
echo "Warning: unable to chown /dc/powershell (current user not root and no sudo available); history may not persist." >&2
fi
profile_path="$(pwsh -NoProfile -Command '$PROFILE')"
mkdir -p "$(dirname "$profile_path")"
touch "$profile_path"

if ! grep -Fxq "$HISTORY_SAVE_LINE" "$profile_path"; then
printf '\n%s\n' "$HISTORY_SAVE_LINE" >> "$profile_path"
fi
fi
Loading