about_PowerShell_Editions

簡短描述

不同版本的 PowerShell 在不同的基礎運行時間上執行。

完整描述

從 PowerShell 5.1 開始,有多個 ,每個版本都在不同的 .NET 執行時執行。 從 PowerShell 6.0 起,PowerShell 有兩個版本:

  • Desktop,該軟體運行於 .NET Framework。 PowerShell 4 及以下版本,以及 PowerShell 5.1 可用於功能完整的 Windows 版本,如 Windows Desktop、Windows Server、Windows Server Core 及大多數其他 Windows 作業系統。 這是原始的PowerShell版本,並包含在作系統的預設安裝中。
  • Core,該系統運行於 .NET 核心。 PowerShell 6.0 及更新版本與早期 PowerShell 版本並列安裝於功能齊全的 Windows 版本、部分較小容量的 Windows 版本(如 Windows Nano Server 和 Windows IoT),或非 Windows 平台如 Linux 和 macOS 上。

由於 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和更新版本中也有 PSEdition 屬性:

$PSVersionTable
Name                           Value
----                           -----
PSVersion                      7.3.9
PSEdition                      Core
GitCommitId                    7.3.9
OS                             Microsoft Windows 10.0.22621
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 版本相容。

例如,模組指令清單會宣告與 PowerShell DesktopCore 版本的相容性:

@{
    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 回傳)中暴露該行為,供你自己的邏輯使用:

$newModuleManifestSplat = @{
    Path = '.\TestModuleWithEdition.psd1'
    CompatiblePSEditions = 'Desktop', 'Core'
    PowerShellVersion = '5.1'
}
New-ModuleManifest @newModuleManifestSplat
$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 中沒有 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 中沒有 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 模組以取得版本交叉相容性

撰寫 PowerShell 模組以 DesktopCore 版 PowerShell 為目標時,您可以執行一些動作來確保跨版本相容性。

不過,確認並持續驗證相容性的唯一方法是撰寫腳本或模組的測試,並在您需要相容性的所有 PowerShell 版本上執行測試。 建議使用此測試架構,Pester

PowerShell 腳本

作為一種語言,PowerShell 在不同版本間運作方式相同;而是你所使用的 cmdlets、模組和 .NET API 會受到版本相容性的影響。

一般來說,能在 PowerShell 6.1 及以上版本運作的腳本也能在 Windows PowerShell 5.1 上運作,但也有一些例外。

PSScriptAnalyzer版本 1.18+ 包含像 PSUseCompatibleCommandsPSUseCompatibleTypes 這些規則,能偵測 PowerShell 腳本中可能不相容的指令與 API .NET API 使用。

.NET 組裝

如果你正在撰寫二進位模組,或包含由原始碼產生的.NET組件(DLL)的模組,應依照 .NET StandardPowerShell Standard編譯,以進行編譯時的相容性驗證,以驗證 .NET 及 PowerShell API 相容性。

雖然這些連結庫能夠在編譯時期檢查某些相容性,但無法攔截版本之間的可能行為差異。 為此,您必須撰寫測試。

另請參閱