Skip to content

powershell.exe and pwsh are different languages wearing one syntax

versions · case

bothsilentscriptcithird-partyrepro: verifieddefault-encodingalias-shadowing
Affectspowershell 51, pwsh 7, actions runner, windows, korean codepage
Fails asPARAMETERBINDING, MOJIBAKE
Mechanismdefault encoding, alias shadowing
Safe fixset content utf8nobom

A script works in local testing but breaks in CI (or vice versa): encoding parameters do not exist, aliases behave differently, stderr handling changes, Unicode corrupts. Nothing in the script changed — only which PowerShell ran it.

Terminal window
# pwsh 7: works
Set-Content -Path out.txt -Value "한글" -Encoding utf8NoBOM
# Windows PowerShell 5.1: parameter does not exist
# Set-Content : Cannot bind parameter 'Encoding' ... "utf8NoBOM"

GitHub Actions shell: powershell selects 5.1; shell: pwsh selects 7. The referenced CI fix migrated a Windows workflow from powershell to pwsh and to utf8NoBOM explicitly because Unicode was corrupting in the 5.1 lane.

Windows PowerShell 5.1 (.NET Framework) and PowerShell 7 (.NET) diverge in encodings (default code page + BOM vs UTF-8), aliases (curl/wget), native stderr handling, and available parameters. Scripts that “target PowerShell” without pinning a version target two runtimes at once.

  • Declare the floor: #Requires -Version 5.1 and test both runtimes in CI when you must support both (the cli-jaw installer CI runs 5.1 and 7 lanes).
  • In GitHub Actions, choose shell: pwsh deliberately, not by default.
  • Gate 7-only parameters behind $PSVersionTable.PSVersion.Major checks.