about_PowerShell_Editions
简短说明
不同版本的 PowerShell 在不同的基础运行时上运行。
长说明
在 PowerShell 5.1 中,有多个版本的 PowerShell,每个 版本 在不同的 .NET 运行时上运行。 从 PowerShell 6.2 起,有两个版本的 PowerShell:
- 桌面,在 .NET Framework 上运行。 PowerShell 4 及更低版本以及功能齐全的 Windows 版本(如 Windows 桌面、Windows Server、Windows Server Core 和大多数其他 Windows 操作系统)上的 PowerShell 5.1 都是桌面版。 这是原始 PowerShell 版本。
- Core,在 .NET Core 上运行。 PowerShell 6.0 及更高版本,以及一些占用空间减少的 Windows 版本(例如 Windows Nano Server 和 Windows IoT,其中.NET Framework不可用)上的 PowerShell 5.1。
由于 PowerShell 版本对应于其 .NET 运行时,因此它是 .NET API 和 PowerShell 模块兼容性的主要指标;某些 .NET API、类型或方法在 .NET 运行时中都不可用,这会影响依赖于它们的 PowerShell 脚本和模块。
自动 $PSEdition
变量
在 PowerShell 5.1 及更高版本中,可以使用自动变量查找正在运行 $PSEdition
的版本:
$PSEdition
Core
在 PowerShell 4 及更低版本中,此变量不存在。 $PSEdition
为 null 应被视为与具有值 Desktop
相同。
版本 $PSVersionTable
自动 $PSVersionTable
变量还具有 PowerShell 5.1 及更高版本中的版本信息:
$PSVersionTable
Name Value
---- -----
PSVersion 7.1.6
PSEdition Core
GitCommitId 7.1.6
OS Microsoft Windows 10.0.22000
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PSEdition 字段的值与$PSEdition
自动变量相同。
模块 CompatiblePSEditions
清单字段
PowerShell 模块可以使用模块清单的 字段声明它们与 CompatiblePSEditions
哪些版本的 PowerShell 兼容。
例如,声明与 Desktop
PowerShell 和 Core
版本的兼容性的模块清单:
@{
ModuleVersion = '1.0'
FunctionsToExport = @('Test-MyModule')
CompatiblePSEditions = @('Desktop', 'Core')
}
仅 Desktop
具有兼容性的模块清单示例:
@{
ModuleVersion = '1.0'
FunctionsToExport = @('Test-MyModule')
CompatiblePSEditions = @('Desktop')
}
从模块清单中省略 CompatiblePSEditions
字段的效果与将其设置为 Desktop
相同,因为在引入此字段之前创建的模块是为此版本隐式编写的。
对于未作为 Windows (的一部分随附的模块(即从库) 编写或安装的模块),此字段仅供信息使用;PowerShell 不会基于 CompatiblePSEditions
字段更改行为,但会将其 PSModuleInfo
公开给) 为你自己的逻辑返回 Get-Module
的对象 (:
New-ModuleManifest -Path .\TestModuleWithEdition.psd1 -CompatiblePSEditions Desktop,Core -PowerShellVersion '5.1'
$ModuleInfo = Test-ModuleManifest -Path .\TestModuleWithEdition.psd1
$ModuleInfo.CompatiblePSEditions
Desktop
Core
注意
模块 CompatiblePSEditions
字段仅与 PowerShell 5.1 及更高版本兼容。
包含此字段将导致模块与 PowerShell 4 及更低版本不兼容。
由于 字段纯粹是信息性的,因此在以后的 PowerShell 版本中可以安全地省略它。
在 PowerShell 6.1 中, Get-Module -ListAvailable
已更新其格式化程序以显示每个模块的版本兼容性:
Get-Module -ListAvailable
Directory: C:\Users\me\Documents\PowerShell\Modules
ModuleType Version Name PSEdition ExportedCommands
---------- ------- ---- --------- ----------------
Script 1.4.0 Az Core,Desk
Script 1.3.1 Az.Accounts Core,Desk {Disable-AzDataCollection, Disable-AzContextAutosave, E...
Script 1.0.1 Az.Aks Core,Desk {Get-AzAks, New-AzAks, Remove-AzAks, Import-AzAksCreden...
...
Script 4.4.0 Pester Desk {Describe, Context, It, Should...}
Script 1.18.0 PSScriptAnalyzer Desk {Get-ScriptAnalyzerRule, Invoke-ScriptAnalyzer, Invoke-...
Script 1.0.0 WindowsCompatibility Core {Initialize-WinSession, Add-WinFunction, Invoke-WinComm...
作为 Windows 的一部分随附的模块的版本兼容性
对于作为 Windows (的一部分或作为角色或功能) 的一部分安装的模块,PowerShell 6.1 及更高版本以 CompatiblePSEditions
不同的方式对待 字段。 此类模块位于Windows PowerShell系统模块目录 (%windir%\System\WindowsPowerShell\v1.0\Modules
) 。
对于从此目录加载或在此目录中找到的模块,PowerShell 6.1 及更高版本使用 CompatiblePSEditions
字段来确定该模块是否与当前会话兼容,以及是否具有相应的行为。
使用 时 Import-Module
,不会导入没有 Core
in CompatiblePSEditions
的模块,并显示错误:
Import-Module BitsTransfer
Import-Module : Module 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\BitsTransfer\BitsTransfer.psd1' does not support current PowerShell edition 'Core'. Its supported editions are 'Desktop'. Use 'Import-Module -SkipEditionCheck' to ignore the compatibility of this module.
At line:1 char:1
+ Import-Module BitsTransfer
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (C:\WINDOWS\system32\u2026r\BitsTransfer.psd1:String) [Import-Module], InvalidOperationException
+ FullyQualifiedErrorId : Modules_PSEditionNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand
使用 时 Get-Module -ListAvailable
,不会显示不带 Core
in CompatiblePSEditions
的模块:
Get-Module -ListAvailable BitsTransfer
# No output
在这两种情况下, -SkipEditionCheck
switch 参数都可用于替代此行为:
Get-Module -ListAvailable -SkipEditionCheck BitsTransfer
Directory: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
ModuleType Version Name PSEdition ExportedCommands
---------- ------- ---- --------- ----------------
Manifest 2.0.0.0 BitsTransfer Desk {Add-BitsFile, Complete-BitsTransfer, Get-BitsTransfer,...
警告
Import-Module -SkipEditionCheck
对于某个模块,可能看起来会成功,但使用该模块会面临以后遇到不兼容的风险;虽然最初加载模块成功,但命令稍后可能会调用不兼容的 API 并自发失败。
为版本交叉兼容性创作 PowerShell 模块
编写面向 和 Core
PowerShell 版本的 PowerShell 模块Desktop
时,可以执行一些操作来确保跨版本兼容性。
但是,确认并持续验证兼容性的唯一真正方法是为脚本或模块编写测试,并在需要兼容的所有 PowerShell 版本上运行它们。 为此,建议使用 Pester 测试框架。
PowerShell 脚本
作为一种语言,PowerShell 在各版本之间的工作方式相同;它是你使用的受版本兼容性影响的 cmdlet、模块和 .NET API。
通常,在 PowerShell 6.1 及更高版本中工作的脚本适用于 Windows PowerShell 5.1,但也有一些例外情况。
PSScriptAnalyzer 版本 1.18+ 具有 PSUseCompatibleCommands 和 PSUseCompatibleTypes 等规则,这些规则能够检测 PowerShell 脚本中命令和 .NET API 的可能不兼容使用情况。
.NET 程序集
如果要编写二进制模块或包含 .NET 程序集的模块, (DLL) 从源代码生成,则应针对 .NET Standard 和 PowerShell Standard 进行编译,以便对 .NET 和 PowerShell API 兼容性进行编译时兼容性验证。
尽管这些库能够在编译时检查一些兼容性,但它们无法捕获各版本之间可能存在的行为差异。 为此,仍必须编写测试。