首页
/ PowerShell 6.0 版本演进全解:从 0.1.0 到 6.0.0 的跨平台化、CoreCLR 化与破坏性变更清单

PowerShell 6.0 版本演进全解:从 0.1.0 到 6.0.0 的跨平台化、CoreCLR 化与破坏性变更清单

2026-09-06 15:37:49作者:董灵辛Dennis

本文基于仓库中的 CHANGELOG/6.0.md(6.0 全生命周期变更日志,覆盖 2016 年 2 月至 2018 年 1 月共 30 余个版本)展开,系统梳理 PowerShell 从 Windows 专属工具演进为跨平台引擎的关键里程碑:.NET Standard 2.0 引入带来的 Windows PowerShell 模块兼容、执行器改名 pwsh、CoreCLR 单轨化等破坏性变更的完整清单,以及管道后台化、字符范围运算符等代表性新特性,并结合当前仓库源码(如 InitialSessionState.csNumericOps.csTelemetry.cs)佐证这些变更的真实落地位置,帮助读者完成版本核对与迁移评估。

文档定位与版本时间线总览

CHANGELOG/6.0.md 按时间倒序记录了 PowerShell 6.0 的完整开发历程,版本编号遵循语义化版本(SemVer)的预发布惯例:

阶段 版本范围 时间 主线工作
0.x 预研 0.1.0 ~ 0.6.0 2016-02 ~ 2016-07 首批跨平台移植(Windows / OS X / Ubuntu),.NET Core 1.0
Alpha 6.0.0-alpha.7 ~ alpha.18 2016-07 ~ 2017-04 命令集补齐、跨平台修复、JEA/遥测基础
Beta 6.0.0-beta.1 ~ beta.9 2017-05 ~ 2017-10 转向 .NET Core 2.0、Windows 模块兼容、改名 pwsh
RC 6.0.0-rc / rc.2 2017-11 ~ 2017-12 收尾修复、合规工作、去除 Pester 捆绑
GA 6.0.0 2018-01-10 正式发布

该文件与 CHANGELOG/README.md 中的版本索引(6.0 ~ 7.7 各版本及 preview 变更日志)共同构成仓库的版本档案体系。需要说明的是:当前仓库源码快照已演进到远晚于 6.0 的版本(global.json 指定 .NET SDK 11.0.100-preview,DotnetRuntimeMetadata.json 指向 .NET 9 运行时),本文在引用源码佐证时会明确区分"6.0 时期的行为"与"当前仓库中的现状"。

演进主线一:运行时底座迁移(.NET Core 1.0 → 1.1 → 2.0)

变更日志显示,6.0 的每一步都伴随运行时底座的升级,这是理解后续所有兼容性变化的前提:

  • 0.6.0(2016-07):目标锁定 .NET Core 1.0 正式版,启用 PowerShellGet,修正 AssemblyLoadContext 依赖拦截与类型目录问题。
  • 0.5.0(2016-06):路径分隔符不再区分 /\;遵循 XDG Base Directory 规范,Linux/OS X 上 profile 固定为 ~/.config/powershell/profile.ps1,历史记录位于 ~/.local/share/powershell/PSReadLine/ConsoleHost_history.txt,用户模块路径为 ~/.local/share/powershell/Modules,并废弃了旧的 ~/.powershell 目录。
  • 6.0.0-alpha.14(2016-12):整体迁移到 .NET Core 1.1。
  • 6.0.0-beta.1(2017-05):迁移到 .NET Core 2.0,即引入 .NET Standard 2.0(PR #3556)。变更日志原文指出其价值:"在 Windows PowerShell(基于完整 .NET Framework)与 PowerShell Core(基于 .NET Core)之间拥有通用的、可移植的模块"——过去无法运行的模块和 cmdlet 在 .NET Core 2.0 上可能直接可用。
  • 6.0.0-beta.6(2017-08):切换到 .NET Core 2.0 final。
  • 6.0.0-rc.2(2017-12):进一步升级到 2.0.4 运行时,并移除所有指向旧可执行文件 powershell/powershell.exe 的引用。

演进主线二:Windows PowerShell 模块向后兼容(beta.1 ~ beta.4 的组合拳)

变更日志中最具实战价值的部分是 6.0.0-beta.4 专门开辟的 "Windows PowerShell backwards compatibility" 小节,它与前两个版本的改动叠加,构成让"存量 Windows PowerShell 模块直接在 PowerShell Core 上工作"的三要素:

  1. .NET Standard 2.0(beta.1 引入):模块程序集可跨运行时共享;
  2. GAC 探测修复(beta.3 引入,PR #3981):允许从 GAC 探测并加载程序集,即可加载依赖 GAC 程序集的 Windows PowerShell 模块。变更日志甚至给出了手动验证方法:
    $env:PSModulePath += ';C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules'
    
  3. 默认合并 PSModulePath(beta.4 引入,PR #4132):在 Windows 上把 Windows PowerShell 的模块目录自动加入默认的 $PSModulePath,使大量现有模块/脚本"开箱即用"(同时修复了 beta.2 中 CDXML 模块回归,PR #4144)。

同期配套的引擎修复还包括:SemanticVersion 与只含 Major/Minor 的 Version 实例之间的比较(修复导入旧 Windows PowerShell 模块的失败场景,PR #3793)、非 Windows 平台 Import-Module 支持 NestedModules/RootModules(PR #4010)等。

破坏性变更完整清单(升级前必读)

6.0 的 Breaking changes 散布在各版本中,按主题归并如下,这也是本文对变更日志最有价值的重组:

执行器与调用方式

  • 可执行文件由 powershell 改名为 pwsh(beta.9,PR #5101):这是 6.0 最著名的重命名,后续大量 CI/文档/安装脚本变更(appimage、macOS launcher、VSCode 配置、man page 等)都是围绕它展开的连锁改动。
  • 位置参数由 -Command 改为 -File(beta.3,PR #4019):修复了非 Windows 平台上脚本 shebang(#!)无法工作的问题,此后 pwsh foo.ps1 无需 -File;但相应地,执行命令必须显式写 -c/-Command
  • 移除 sc 别名(6.0.0 GA,PR #5827):与系统命令 sc.exe 冲突。在当前仓库源码中可以看到这一决策的落地形态:InitialSessionState.cssc 别名的注册被包裹在 #if !CORECLR 预处理块内(与 gwmi/iwmi 等一同),即 CoreCLR 构建(6.0 起的全部构建)都不会注册该别名。
  • -File/-Command 错误信息与退出码对齐 Unix 规范(beta.6,PR #4573)。
  • 移除 powershell.exe-ImportSystemModules-PSConsoleFile 参数,以及凭据 GUI 弹窗代码(beta.9,PR #4995)。

参数与行为

  • $OutputEncoding 默认值由 ASCII 改为 UTF-8(无 BOM)(rc,PR #5369)。
  • Export-Csv/ConvertTo-Csv 默认启用 -NoTypeInformation(beta.9,PR #5164)。
  • Get/Set/Remove-Service 移除 -ComputerName(beta.9,PR #5094);同理 .NET CoreProcess.GetProcesses(computer) 只返回本地进程,-ComputerName 支持被整体移除(PR #4960)。
  • Remove-AllScope 出大多数默认别名(rc,PR #5268),降低新建作用域的开销。
  • -Verbose 不再覆盖 $ErrorActionPreference(rc,PR #5113);Get-Item -LiteralPath a*b 在通配不命中时如实报错(rc,PR #5197)。
  • Web Cmdlets 安全收紧:遗留凭据走非 HTTPS 传输时直接报错(rc,PR #5402);Invoke-RestMethod 单值 JSON null 解析修复(rc,PR #5338)。
  • $PSVersionTable 瘦身(beta.3):移除 BuildVersionClrVersion 两个属性,官方建议改用 GitCommitId 精确定位构建版本。

架构级移除

  • 移除 RunspaceConfiguration 支持(beta.9,PR #4942):这是 5.1 时代遗留的受限会话配置机制,移除后 Register-PSSessionConfiguration 等统一走新模型。
  • CoreCLR 单轨化:变更日志在 beta.5、beta.6 明确声明 "PowerShell 6.0 将完全构建于 CoreCLR 之上",随之大规模删除仅 FullCLR 编译的代码(#if CORECLR 清理专题),并移除 Workflow 代码(beta.7,PR #4777)、未使用的 PSMI 代码(beta.9,PR #5075)等。这也解释了为什么当前仓库中仍存在 #if !CORECLR 历史分支——它们只服务于非 CoreCLR 的构建目标。
  • 模块移除Microsoft.PowerShell.Diagnostics*-Counter 命令(beta.5,PR #4303)与 Microsoft.PowerShell.LocalAccounts(beta.5,PR #4302)因依赖暂不可用的 API 被整体摘除,待更好方案出现后再回归。

代表性新特性与源码佐证

管道末尾 & 后台化为 Job(beta.2,PR #3360)

变更日志给出的语义:流水线末尾加 & 会将其作为 PowerShell Job 运行并返回 Job 对象,此后所有标准 *-Job cmdlet 均可接管;流水线中引用的变量(进程特定变量除外)会自动拷贝进 Job,因此 Copy-Item $foo $bar & 可直接工作,且 Job 运行在当前目录而非用户主目录。这使得 Linux/OS X 用户无需 Start-Job 即可获得类 shell 的后台执行体验。

'a'..'z' 字符范围运算符(rc,PR #5026)

.. 运算符新增 char 重载,'a'..'z' 返回 a 到 z 的字符序列。当前仓库中该能力由 NumericOps.csinternal static object[] Range(char start, char end) 实现,与整型范围共用同一入口。

Web Cmdlets 的能力扩张(贯穿各版本)

变更日志显示 Web Cmdlets 是 6.0 中改动最密集的模块,能力演进脉络清晰:

  • 认证:证书认证(beta.6,PR #4646)→ -Authentication(Basic/OAuth/Bearer)+ -Token + -AllowUnencryptedAuthentication(beta.9,PR #5052);
  • 传输-SslProtocol 指定 SSL 协议(rc,PR #5329)、Multipart 内容(beta.8,PR #4782)、Link header 分页——Invoke-RestMethod 提供 -FollowRelLink 自动跟随 next 链接并配合 -MaximumFollowRelLink 限次(beta.2,PR #3828)、-NoProxy 忽略系统代理(alpha.18,PR #3447);
  • 请求头控制-SkipHeaderValidation(beta.5,PR #4085)、-ResponseHeadersVariable 捕获响应头(beta.8,PR #4888)、UserAgentWindowsPowerShell 统一为 PowerShell(beta.8,PR #4914)。

遥测的引入与退出机制(beta.1,PR #3620)

6.0.0-beta.1 首次在 ConsoleHost 引入极简遥测,仅上报两个值:操作系统平台($PSVersionTable.OSDescription)与精确版本($PSVersionTable.GitCommitId)。退出机制为删除 $PSHome\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY 文件,且在 PowerShell 首次运行前删除同样生效。作为对照,当前仓库的遥测实现 Telemetry.cs 中可见后续演进出的环境变量退出方式 POWERSHELL_TELEMETRY_OPTOUT——读者在较新版本上应优先使用环境变量的退出方式。

文件系统语义向 Unix 靠拢(beta.1 集中修复)

  • 用操作系统调用判断两个路径是否指向同一文件,修复 Unix 大小写敏感路径被当作不敏感的问题(PR #3441);
  • New-Item 支持指向文件/目录乃至不存在目标的符号链接(PR #3509);
  • Remove-Item 作用于符号链接时只删除链接本身(PR #3637);
  • Get-ChildItem 在 Unix 上列出目录链接的内容(PR #3697),后又对齐 ls -R/DIR /S 的递归语义——返回链接本身但不遍历其目标目录(beta.2,PR #3780),并新增按需跟随链接且带环检测的 -FollowSymlink 参数(beta.4,PR #4020);
  • Rename-Item 支持 Unix glob 模式(PR #3661)。

其他值得留意的引擎改进

  • 原生命令通配展开:Unix 上支持 ls *.txt(beta.1,PR #3643);
  • -i 交互开关(beta.1,PR #3558):方便把 PowerShell 设为默认 shell;
  • 长路径支持超过 260 字符(beta.3,PR #3960);
  • Unicode 转义解析,可用 Unicode 字符作参数、字符串甚至变量名(beta.4,PR #3958);
  • GitCommitId 直接显示在启动横幅(beta.3,PR #3916),免去每次都运行 $PSVersionTable
  • $IsOSX 改名 $IsMacOS(beta.7,PR #4757);
  • 执行策略组策略安全检査性能提升(beta.1,PR #2588);
  • 6.0.0 GA 阶段(2018-01-10)还包含:分离组策略设置并启用策略受控日志(PR #5791)、修复 Unix 平台 libpsrpclientDllImport 失败处理(PR #5622)。

测试基础设施演进:从 httpbin.org 到自建 WebListener

6.0 的变更日志有一条贯穿始终的工程线:用自建的 WebListener 测试服务替换对外部站点(httpbin.org、lee.io)的依赖,覆盖 headers、user-agent、redirect、encoding、delay、gzip/deflate、证书认证、HTTPS 等全部 Web Cmdlets 场景(分散在 alpha.18 ~ 6.0.0 GA 的多个 PR 中,如 PR #5035、#4622、#4733、#4738、#5058、#5540、#5665、#5709)。其动机是外部站点不可控导致的 CI 抖动。当前仓库中该模块完整保留在 test/tools/WebListener(含 Program.csControllers 目录及支持 Gzip/Deflate/Brotli 压缩的过滤器),说明这套"本地化测试端点"的思路一直沿用至今。同期还有:Docker 容器验证发布包(PR #5401)、Travis CI 矩阵与 PR 标签([package] tag 触发打包)、Windows 安装程序仅在 Windows 上跑测试(PR #5619)等 CI 改进。

打包、安装与合规

变更日志的 Build and Packaging 小节记录了 6.0 分发形态的定型过程,对运维与 CI 场景有直接参考价值:

  • 跨平台统一安装脚本install-powershell.ps1 由纯 Windows 脚本演进为跨平台脚本(PR #5411),install-powershell.sh 支持 Amazon Linux(PR #5461);当前仓库的 tools/install-powershell.ps1tools/install-powershell.sh 即其延续;
  • ARM 支持:启用 win-arm/win-arm64 构建(PR #5524),新增 linux-arm tarball 包(PR #5652),支持 Raspbian tar.gz 打包(PR #5387)与树莓派 arm32 交叉编译(beta.7,PR #4742);
  • Windows 安装包:MSI 支持升级而非并行安装(beta.5,PR #4259)、x86/x64 包互不覆盖(GA 阶段,PR #5812)、RCEdit 嵌入图标与版本信息(rc,PR #5178)、requestedExecutionLevel 设为 asInvoker 并添加 HighEntropyVA(合规工作,PR #5285、#5455);
  • macOS:包要求 10.12 及以上(PR #5649),提供 launcher(beta.9,PR #5138),使用 Uniform Type Identifier 对齐 Apple 规范(PR #5323);
  • Pester 解耦:6.0.0-rc.2 起 Pester 不再随 PowerShell 包分发,需 Install-Module Pester 自行安装(PR #5623、#5631);
  • 合规(Compliance)工作:变更日志专设小节说明这是微软继续以官方包形式签署发布的必要工作,包括移除未使用的 PerformWSManPluginReportCompletion、以 strnlen 替换 strlen(PR #5510)等。

迁移核对清单:如何用当前仓库验证 6.0 行为

基于上述证据,升级/回滚评估时可按以下要点核对:

  1. 执行器名:所有 powershell/powershell.exe 调用在 6.0 起应为 pwsh;仓库内 assets/manpage/pwsh.1 即新可执行文件的手册页。
  2. 版本指纹:不要再读 $PSVersionTable.BuildVersion/ClrVersion(已移除),改用 GitCommitId;启动横幅已自带该信息。
  3. 脚本位置参数pwsh -File script.ps1 或直接 pwsh script.ps1;执行命令片段需显式 -Command
  4. 模块路径:确认 $PSModulePath 中是否包含 Windows PowerShell 模块目录(Windows 上默认已合并),这是存量模块兼容的关键开关。
  5. CSV 输出与编码:默认不再携带 #TYPE 行(-NoTypeInformation 默认开启);$OutputEncoding 默认为 UTF-8 无 BOM。
  6. 别名清理sc 等与系统二进制冲突的别名不再可用;$IsOSX 应替换为 $IsMacOS
  7. 远程服务操作*-Service 类 cmdlet 不再接受 -ComputerName,跨机操作需改走 PowerShell Remoting。

延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐