about_PowerShell_Editions
Short description
Different editions of PowerShell run on different underlying runtimes.
Long description
From PowerShell 5.1, there are multiple editions of PowerShell that each run on a different .NET runtime. As of PowerShell 6.0 there are two editions of PowerShell:
- Desktop, which runs on .NET Framework. PowerShell 4 and below, as well as PowerShell 5.1 are available for full-featured Windows editions like Windows Desktop, Windows Server, Windows Server Core and most other Windows operating systems. This is the original PowerShell edition and is included in the default installation of the operating system.
- Core, which runs on .NET Core. PowerShell 6.0 and later is installed side-by-side with earlier PowerShell releases on full-featured Windows editions, some reduced-footprint Windows editions such as Windows Nano Server and Windows IoT, or on non-Windows platforms such as Linux and macOS.
Because the edition of PowerShell corresponds to its .NET runtime, it is the primary indicator of .NET API and PowerShell module compatibility; some .NET APIs, types or methods are not available in both .NET runtimes and this affects PowerShell scripts and modules that depend on them.
The $PSEdition
automatic variable
In PowerShell 5.1 and above, you can find out what edition you are running with the $PSEdition
automatic variable:
$PSEdition
Core
In PowerShell 4 and below, this variable does not exist. $PSEdition
being null should be treated
as the same as having the value Desktop
.
Edition in $PSVersionTable
The $PSVersionTable
automatic variable also has PSEdition property in PowerShell 5.1 and above:
$PSVersionTable
Name Value
---- -----
PSVersion 7.2.2
PSEdition Core
GitCommitId 7.2.2
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
The PSEdition field has the same value as the $PSEdition
automatic variable.
The CompatiblePSEditions
module manifest field
PowerShell modules can declare what editions of PowerShell they are compatible with using the
CompatiblePSEditions
field of the module manifest.
For example, a module manifest declaring compatibility with both Desktop
and Core
editions
of PowerShell:
@{
ModuleVersion = '1.0'
FunctionsToExport = @('Test-MyModule')
CompatiblePSEditions = @('Desktop', 'Core')
}
An example of a module manifest with only Desktop
compatibility:
@{
ModuleVersion = '1.0'
FunctionsToExport = @('Test-MyModule')
CompatiblePSEditions = @('Desktop')
}
Omitting the CompatiblePSEditions
field from a module manifest will have the same effect as
setting it to Desktop
, since modules created before this field was introduced were implicitly
written for this edition.
For modules not shipped as part of Windows (i.e. modules you write or install from the gallery),
this field is informational only; PowerShell does not change behavior based on the
CompatiblePSEditions
field, but does expose it on the PSModuleInfo
object (returned by
Get-Module
) for your own logic:
New-ModuleManifest -Path .\TestModuleWithEdition.psd1 -CompatiblePSEditions Desktop,Core -PowerShellVersion '5.1'
$ModuleInfo = Test-ModuleManifest -Path .\TestModuleWithEdition.psd1
$ModuleInfo.CompatiblePSEditions
Desktop
Core
Note
The CompatiblePSEditions
module field is only compatible with PowerShell 5.1 and above.
Including this field will cause a module to be incompatible with PowerShell 4 and below.
Since the field is purely informational, it can be safely omitted in later PowerShell versions.
In PowerShell 6.1, Get-Module -ListAvailable
has had its formatter updated to display the
edition-compatibility of each module:
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...
Edition-compatibility for modules that ship as part of Windows
For modules that come as part of Windows (or are installed as part of a role or feature),
PowerShell 6.1 and above treat the CompatiblePSEditions
field differently. Such modules are found
in the Windows PowerShell system modules directory
(%windir%\System\WindowsPowerShell\v1.0\Modules
).
For modules loaded from or found in this directory, PowerShell 6.1 and above uses the
CompatiblePSEditions
field to determine whether the module will be compatible with the current
session and behaves accordingly.
When Import-Module
is used, a module without Core
in CompatiblePSEditions
will not be imported
and an error will be displayed:
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
When Get-Module -ListAvailable
is used, modules without Core
in CompatiblePSEditions
will not
be displayed:
Get-Module -ListAvailable BitsTransfer
# No output
In both cases, the -SkipEditionCheck
switch parameter can be used to override this behavior:
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,...
Warning
Import-Module -SkipEditionCheck
may appear to succeed for a module, but using that module
runs the risk of encountering an incompatibility later on; while loading the module initially
succeeds, a command may later call an incompatible API and fail spontaneously.
Authoring PowerShell modules for edition cross-compatibility
When writing a PowerShell module to target both Desktop
and Core
editions of PowerShell,
there are things you can do to ensure cross-edition compatibility.
The only true way to confirm and continually validate compatibility however is to write tests for your script or module and run them on all versions and editions of PowerShell you need compatibility with. A recommended testing framework for this is Pester.
PowerShell script
As a language, PowerShell works the same between editions; it is the cmdlets, modules and .NET APIs you use that are affected by edition compatibility.
Generally, scripts that work in PowerShell 6.1 and above will work with Windows PowerShell 5.1, but there are some exceptions.
PSScriptAnalyzer version 1.18+ has rules like PSUseCompatibleCommands and PSUseCompatibleTypes that are able to detect possibly incompatible usage of commands and .NET APIs in PowerShell scripts.
.NET assemblies
If you are writing a binary module or a module that incorporates .NET assemblies (DLLs) generated from source code, you should compile against .NET Standard and PowerShell Standard for compile-time compatibility validation of .NET and PowerShell API compatibility.
Although these libraries are able to check some compatibility at compile time, they won't be able to catch possible behavioral differences between editions. For this you must still write tests.
See also
PowerShell feedback
PowerShell is an open source project. Select a link to provide feedback:
Feedback
Submit and view feedback for