Cross-Platform PowerShell
Prerequisites: Navigating and managing files
PowerShell 7 runs on Windows, Linux, and macOS — but scripts only work everywhere if you write them that way.
Detecting the platform
# illustrative
if ($IsWindows) { 'Windows' }
elseif ($IsLinux) { 'Linux' }
elseif ($IsMacOS) { 'macOS' }
$PSVersionTable.OS
$IsWindows, $IsLinux, and $IsMacOS exist in PowerShell 6+. (In
Windows PowerShell 5.1 they're undefined — treat $null as Windows.)
Paths
$base = Join-Path $PSScriptRoot 'data'
$file = Join-Path 'data' 'reports' 'summary.csv'
[System.IO.Path]::GetFileName($file)
[System.IO.Path]::DirectorySeparatorChar -in '\', '/'
[System.IO.Path]::GetTempPath().Length -gt 0
summary.csv
True
True
- Build paths with
Join-Pathor[IO.Path], never by gluing strings with\. - Use
$HOMEand[IO.Path]::GetTempPath()instead ofC:\Users\...or$env:TEMP, which doesn't exist on Linux. - Linux and macOS file systems are case-sensitive:
Report.csvandreport.csvare different files.
Things that differ
- Aliases — on Linux and macOS,
ls,cp,mv,rm,cat, andsortare not aliases; they run the native commands, which output text instead of objects. Use full cmdlet names. - Windows-only modules —
ActiveDirectory, services (Get-Serviceis limited), the registry, CIM/WMI, and scheduled tasks don't exist elsewhere. - Line endings —
Set-Contentwrites the platform's line ending; Git can convert them. Keep scripts as LF or CRLF consistently. - Native commands — output from
greporsystemctlis text; parse it, or look for a JSON output option (--output json) and pipe it toConvertFrom-Json.
Test cross-platform code in CI on all three systems (see the CI/CD lesson).