pwsh64.sh - PowerShell amd64/x64 Docker Runner

󰃭 2024-08-07

This post presents a bash script that allows you to run PowerShell commands and scripts in an x64 environment using Docker on Arm based systems. It’s particularly useful for those using Apple Silicon (or other ARM based systems) who need to run x64-only PowerShell tools.

Prerequisites

  • Docker installed and running on your system

Usage

  1. Save the script somewhere on your computer (and optionally add it to your $PATH)

  2. Make the script executable:

chmod +x ./pwsh64.sh
  1. Run PowerShell commands or scripts:
./pwsh64.sh [PowerShell arguments]
  1. Profit?

Examples:

  • Run an interactive PowerShell session:
    ./pwsh64.sh
    
  • Execute a local PowerShell script:
    ./pwsh64.sh -File ./path/to/your/script.ps1
    
  • Run a PowerShell command:
    ./pwsh64.sh  -Command "Write-Host 'Hello from PowerShell!'"
    

How It Works

The script creates a Docker container using the official PowerShell image for Ubuntu 20.04. It mounts the current working directory to the container, allowing access to local files and scripts. Arguments are passed directly the container so the cli is identical to pwsh

#!/usr/bin/env bash

# Using PowerShell 7.2 because 7.3 and 7.4 have an issue that can cause them to hang
# - https://github.com/PowerShell/PowerShell-Docker/issues/799
pwsh_version="7.2-ubuntu-20.04"
pwsh_image="mcr.microsoft.com/powershell:${pwsh_version}"

# Function to display usage
function usage() {
    cat << EOF
Usage: $0 [pwsh arguments]

This script runs PowerShell commands using a x64 Docker container.
It supports running local scripts and interactive sessions.
Note: Access to local files is limited to the current working directory and its subdirectories.

Examples:
  $0 -File ./path/to/local/script.ps1
  $0 -Command "Write-Host 'Hello from PowerShell!'"
  $0
EOF
    exit 0
}

# Function to check if Docker is installed and running
function check_docker() {
    if ! command -v docker &> /dev/null; then
        echo "Error: Docker is not installed. Please install Docker and try again." >&2
        exit 1
    fi

    if ! docker info &> /dev/null; then
        echo "Error: Docker is not running. Please start Docker and try again." >&2
        exit 1
    fi
}

# Function to validate PowerShell version
function validate_pwsh_version() {
    # Check if the image exists locally
    if docker image inspect "$pwsh_image" &> /dev/null; then
        return 0
    fi

    echo "PowerShell $pwsh_version image not found locally. Attempting to pull..."
    if ! docker pull "$pwsh_image" &> /dev/null; then
        echo "Error: PowerShell version ${pwsh_version} is not available. Please check the version and try again." >&2
        exit 1
    fi
    echo "PowerShell $pwsh_version image pulled successfully."
}

# Check for help flags or no arguments
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    usage
fi

# Check if Docker is installed and running
check_docker

# Validate PowerShell version
validate_pwsh_version

# Mount current directory and run the PowerShell Docker container with passed arguments
# Using linux/amd64 platform to ensure consistency across different host architectures
if ! docker run --rm -it --platform linux/amd64 -v "$PWD:/workspace" -w /workspace "$pwsh_image" pwsh "$@"; then
    echo "Error: Failed to run PowerShell in Docker container. Please check your arguments and try again." >&2
    exit 1
fi

Limitations

  • Only files in the current working directory and its subdirectories are accessible to the PowerShell environment in the container.
  • Performance may be somewhat impacted compared to running PowerShell natively on an x64 system.
  • Some system-specific operations might not work as expected due to the containerized environment.

Troubleshooting

  • Ensure Docker is installed and running on your system.
  • Check that you have internet access if the script needs to download the PowerShell Docker image.
  • Verify that your PowerShell scripts and modules are compatible with the PowerShell version used in the container (currently set to 7.2).

License

MIT