The PowerShell 7 release in 2020 (rebuilt on .NET Core) changed PowerShell from a Windows shell into a credible general-purpose tool. macOS and Linux engineers can run the same scripts their Windows colleagues do. CI containers ship pwsh alongside Bash and Python. Az and Microsoft Graph modules work natively on all platforms.
This last lesson covers the cross-platform story honestly — what works, what doesn't, and where pwsh sits next to Bash and Python in the modern engineer's toolkit.
What Works Cross-Platform
- Core language — variables, types, control flow, pipelines, classes, modules
- Most utility cmdlets —
Get-Process,Get-ChildItem,Test-Connection,Invoke-WebRequest,Invoke-RestMethod,ConvertFrom-Json,Import-Csv - Az PowerShell — fully cross-platform
- Microsoft Graph PowerShell — fully cross-platform
- PSReadLine — same interactive polish on every platform
- Pester — testing framework, runs anywhere
- Modules from PSGallery — most modern modules target pwsh 7
What Doesn't (or only partially) Work
| Cmdlet / module | Status on Linux/macOS |
|---|---|
CIM / WMI cmdlets (Get-CimInstance) | Windows only — they use the WMI API |
Get-EventLog, Get-WinEvent | Windows only |
Active Directory module (RSAT-AD-PowerShell) | Windows only; use Graph for Entra ID |
| Group Policy management | Windows only |
Get-Service / Start-Service / Stop-Service | Cross-platform for systemd; Linux service control works |
| Out-Printer / printer cmdlets | Windows only |
| Workflow runbooks | Deprecated; do not use |
Rule of thumb: anything that wraps Windows-specific APIs is Windows-only. Everything else, including all the cloud and HTTP work, runs everywhere.
Platform-Aware Scripts
Detect platform at runtime:
if ($IsWindows) { ... }
elseif ($IsLinux) { ... }
elseif ($IsMacOS) { ... }
# Path joins respect platform
$config = Join-Path $HOME ".config" "app.json"
# Environment variables — same on all
$env:HOME # works on Linux/macOS
$env:USERPROFILE # only on Windows; but on Linux it's empty
Use Join-Path, Split-Path, and [System.IO.Path] rather than hardcoded backslashes or slashes.
Running in Containers
Microsoft publishes official PowerShell images:
# Pull and run
docker run -it mcr.microsoft.com/powershell:lts-ubuntu-22.04
# Available tags include
# mcr.microsoft.com/powershell:7.4-ubuntu-22.04
# mcr.microsoft.com/powershell:lts-alpine-3.20
# mcr.microsoft.com/powershell:7.4-mariner-2.0
A minimal Dockerfile for a containerised script:
FROM mcr.microsoft.com/powershell:lts-alpine-3.20
WORKDIR /app
COPY . .
RUN pwsh -NoProfile -Command "Install-Module Az -Force -Scope AllUsers -AcceptLicense"
ENTRYPOINT ["pwsh", "-NoProfile", "-File", "/app/run.ps1"]
Container size: 70-200 MB depending on base. Plenty small for CI / Functions / runbook use.
Mixing with Bash and Python
Three patterns:
Call pwsh from Bash
#!/usr/bin/env bash
set -euo pipefail
result=$(pwsh -NoProfile -Command "
Get-AzVM | Where-Object PowerState -eq 'VM running' | ConvertTo-Json -Depth 5
")
echo "$result" | jq '.[].Name'
Call Bash / external commands from pwsh
# Native executable invocation
$tag = git rev-parse --short HEAD
$image = docker build -t "app:$tag" .
# Multi-line external command
$kubectlOut = kubectl get pods -A -o json | ConvertFrom-Json
$kubectlOut.items | Where-Object { $_.status.phase -ne "Running" }
External commands return text by default. Pipe to ConvertFrom-Json when the tool emits JSON (kubectl, jq output, az CLI with -o json).
Call Python from pwsh
$pyResult = python -c "import json, sys; print(json.dumps({'sum': sum(range(100))}))" | ConvertFrom-Json
$pyResult.sum # 4950
For heavy data work, Python's libraries are richer; for Azure / M365, PowerShell wins. Mix where each is strongest.
Polyglot Project Patterns
A typical platform team's automation repo:
automation/
├── bash/
│ └── ec2-spot-bidding.sh
├── pwsh/
│ ├── audit-azure-tags.ps1
│ ├── tenant-license-report.ps1
│ └── modules/
│ └── PlatformCommon/
├── python/
│ ├── reconcile-finops.py
│ └── chaos-experiment.py
├── .github/
│ └── workflows/
│ ├── weekly-audit.yml # uses pwsh
│ ├── nightly-finops.yml # uses python
│ └── spot-rebid.yml # uses bash
No religious wars. The right language for the job, all running on the same CI runners.
VS Code Integration
The PowerShell extension for VS Code is excellent and cross-platform:
- IntelliSense from PSScriptAnalyzer
- Debug PowerShell scripts with breakpoints, watch, call stack
- Integrated terminal hosts pwsh
- Run selected line / file with F8 / F5
- Pester test discovery and run from the explorer
Pair with PSScriptAnalyzer as a linter in CI — catches naming, performance, and style issues.
Where PowerShell Fits (Honestly)
| Task | Best tool |
|---|---|
| Azure resource automation | PowerShell (Az) or Azure CLI |
| Microsoft 365 / Entra ID admin | PowerShell (Graph) |
| Windows Server admin | PowerShell |
| Intune device management | PowerShell |
| Kubernetes admin | kubectl, Helm (Bash or pwsh) |
| AWS automation | AWS CLI / SDK in Bash or Python (PowerShell AWS module exists; less idiomatic) |
| GCP automation | gcloud + Bash/Python; pwsh works but is less common |
| Linux server admin | Bash (with pwsh for scripts that need objects) |
| Data engineering | Python |
| Web backends / CLIs | Go / Rust / TypeScript |
| Quick text processing | Bash / awk / sed / jq |
PowerShell's home turf is anything Microsoft-flavoured. Outside that, it competes with Python and Bash on merit — sometimes wins, sometimes loses.
Where to Go from Here
- Build something small. A weekly Azure tag-audit runbook. A Microsoft Graph script that reports on inactive users. The shape of the language sticks once you ship.
- Read PSGallery sources. The Azure PowerShell repo and the Microsoft Graph SDK are both open source.
- Cert. AZ-104 (Azure Administrator) tests Az PowerShell knowledge directly. MS-102 covers Graph PowerShell for M365. Both are practical and well-respected.
- Contribute upstream. The PowerShell repo accepts PRs; Microsoft Graph SDK welcomes issues.
Recommended Reading
- PowerShell official documentation
- Learn PowerShell in a Month of Lunches, 4th ed. — Don Jones, James Petty, Travis Plunk
- PowerShell 7 Workshop — Nick Parlow (Packt)
- PSScriptAnalyzer rules — read them, they teach the style guide
- Pair with the CertQnA Azure Cloud Basics and Cloud FinOps courses.
PowerShell is a niche-dominator: in the Microsoft ecosystem it has no rival, and PowerShell 7 made it credible everywhere else. Add it to your toolkit; you will reach for it more often than you expect.