Reputation: 16912
I am using multiple versions of PowerShell, but only 2 can find all standard commands (or is it commandlets?).
The original install is Windows PowerShell v5.1, but then I also have PowerShell Core (pwsh.exe
) v6.1.1 installed.
The problem is that I am trying to run some firewall-related stuff in PowerShell Core, but the Get-NetFirewallProfile
command cannot be found.
Get-NetFirewallProfile -Profile Domain, Public, Private | Select-Object Name, Enabled
However, it runs just fine in Windows PowerShell, since the required module NetSecurity
is available there.
How can I make PowerShell Core either find the already existing modules or install them anew?
(Are they even compatible? - If not, how can they be updated?)
In PowerShell Core v6.1 I only have:
$ Get-Module -ListAvailable
Directory: C:\Program Files\PowerShell\Modules
ModuleType Version Name PSEdition ExportedCommands
---------- ------- ---- --------- ----------------
Script 1.8.1 PSVersion Desk {Get-PSVersion, Update-P
Binary 2.1.0.1 PSWindowsUpdate Desk {Add-WUServiceManager, E
Directory: C:\program files\powershell\6\Modules
ModuleType Version Name PSEdition ExportedCommands
---------- ------- ---- --------- ----------------
Manifest 6.1.0.0 CimCmdlets Core {Get-CimAssociatedInstan
Manifest 1.2.2.0 Microsoft.PowerShell.Archive Desk {Compress-Archive, Expan
Manifest 6.1.0.0 Microsoft.PowerShell.Diagnostics Core {Get-WinEvent, New-WinEv
Manifest 6.1.0.0 Microsoft.PowerShell.Host Core {Start-Transcript, Stop-
Manifest 6.1.0.0 Microsoft.PowerShell.Management Core {Add-Content, Clear-Cont
Manifest 6.1.0.0 Microsoft.PowerShell.Security Core {Get-Acl, Set-Acl, Get-P
Manifest 6.1.0.0 Microsoft.PowerShell.Utility Core {Format-List, Format-Cus
Manifest 6.1.0.0 Microsoft.WSMan.Management Core {Disable-WSManCredSSP, E
Script 1.1.7.2 PackageManagement Desk {Find-Package, Get-Packa
Script 1.6.7 PowerShellGet Desk {Find-Command, Find-DSCR
Script 0.0 PSDesiredStateConfiguration Desk {GetSyntax, Write-MetaCo
Script 6.1.0.0 PSDiagnostics Core {Disable-PSTrace, Disabl
Script 2.0.0 PSReadLine Desk {Get-PSReadLineKeyHandle
Binary 1.1.2 ThreadJob Desk Start-ThreadJob
whereas in Windows PowerShell v5.1, I have:
$ Get-Module -ListAvailable *
Directory: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 1.0.0.1 PackageManagement {Find-Package, Get
Script 1.0.0.1 PowerShellGet {Install-Module, F
Script 1.8.1 PSVersion {Get-PSVersion, Up
Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.0.0 AppBackgroundTask {Disable-AppBackgr
Manifest 2.0.0.0 Appx {Add-AppxPackage,
Manifest 1.0.0.0 BitLocker {Unlock-BitLocker,
Manifest 1.0.0.0 BitsTransfer {Add-BitsFile, Com
Manifest 1.0.0.0 CimCmdlets {Get-CimAssociated
Manifest 1.0 Defender {Get-MpPreference,
Manifest 1.0.0.0 DirectAccessClientComponents {Disable-DAManualE
Script 3.0 Dism {Add-AppxProvision
Manifest 1.0.0.0 DnsClient {Resolve-DnsName,
Manifest 2.0.0.0 International {Get-WinDefaultInp
Manifest 1.0.0.0 iSCSI {Get-IscsiTargetPo
Script 1.0.0.0 ISE {New-IseSnippet, I
Manifest 1.0.0.0 Kds {Add-KdsRootKey, G
Manifest 1.0.1.0 Microsoft.PowerShell.Archive {Compress-Archive,
Manifest 3.0.0.0 Microsoft.PowerShell.Diagnostics {Get-WinEvent, Get
Manifest 3.0.0.0 Microsoft.PowerShell.Host {Start-Transcript,
Manifest 1.0.0.0 Microsoft.PowerShell.LocalAccounts {Add-LocalGroupMem
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Content, Clea
Script 1.0 Microsoft.PowerShell.ODataUtils Export-ODataEndpoi
Manifest 3.0.0.0 Microsoft.PowerShell.Security {Get-Acl, Set-Acl,
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Format-List, Form
Manifest 3.0.0.0 Microsoft.WSMan.Management {Disable-WSManCred
Manifest 1.0 MMAgent {Disable-MMAgent,
Manifest 1.0.0.0 MsDtc {New-DtcDiagnostic
Manifest 2.0.0.0 NetAdapter {Disable-NetAdapte
Manifest 1.0.0.0 NetConnection {Get-NetConnection
Manifest 1.0.0.0 NetEventPacketCapture {New-NetEventSessi
Manifest 2.0.0.0 NetLbfo {Add-NetLbfoTeamMe
Manifest 1.0.0.0 NetNat {Get-NetNat, Get-N
Manifest 2.0.0.0 NetQos {Get-NetQosPolicy,
Manifest 2.0.0.0 NetSecurity {Get-DAPolicyChang
Manifest 1.0.0.0 NetSwitchTeam {New-NetSwitchTeam
Manifest 1.0.0.0 NetTCPIP {Get-NetIPAddress,
Manifest 1.0.0.0 NetworkConnectivityStatus {Get-DAConnectionS
Manifest 1.0.0.0 NetworkSwitchManager {Disable-NetworkSw
Manifest 1.0.0.0 NetworkTransition {Add-NetIPHttpsCer
Manifest 1.0.0.0 PcsvDevice {Get-PcsvDevice, S
Manifest 1.0.0.0 PKI {Add-CertificateEn
Manifest 1.1 PrintManagement {Add-Printer, Add-
Manifest 1.1 PSDesiredStateConfiguration {Set-DscLocalConfi
Script 1.0.0.0 PSDiagnostics {Disable-PSTrace,
Binary 1.1.0.0 PSScheduledJob {New-JobTrigger, A
Manifest 1.5.2.6 PSWindowsUpdate {Add-WUOfflineSync
Manifest 2.0.0.0 PSWorkflow {New-PSWorkflowExe
Manifest 1.0.0.0 PSWorkflowUtility Invoke-AsWorkflow
Manifest 1.0.0.0 ScheduledTasks {Get-ScheduledTask
Manifest 2.0.0.0 SecureBoot {Confirm-SecureBoo
Manifest 2.0.0.0 SmbShare {Get-SmbShare, Rem
Manifest 2.0.0.0 SmbWitness {Get-SmbWitnessCli
Manifest 1.0.0.0 StartScreen {Export-StartLayou
Manifest 2.0.0.0 Storage {Add-InitiatorIdTo
Manifest 2.0.0.0 TLS {New-TlsSessionTic
Manifest 1.0.0.0 TroubleshootingPack {Get-Troubleshooti
Manifest 2.0.0.0 TrustedPlatformModule {Get-Tpm, Initiali
Manifest 2.0.0.0 VpnClient {Add-VpnConnection
Manifest 1.0.0.0 Wdac {Get-OdbcDriver, S
Manifest 1.0.0.0 WindowsDeveloperLicense {Get-WindowsDevelo
Script 1.0 WindowsErrorReporting {Enable-WindowsErr
Manifest 1.0.0.0 WindowsSearch {Get-WindowsSearch
And just in case someone wonders, all the available commands in a module can be listed with:
(Get-Module -ListAvailable NetSecurity).ExportedCommands
UPDATE:
I managed to find the correct modules, given a command/comdlet, using this:
(Get-Module -ListAvailable -SkipEditionCheck *).ExportedCommands.Values |select CommandType,Source,Version,Name | sort Name
(Alternatively replace ExportedCommands
with ExportedCmdlets
.)
Upvotes: 4
Views: 15702
Reputation: 437197
ArcSet's helpful answer works in this case, but it's important to note that -SkipEditionCheck
explicitly bypasses a given module's own [lack of] declaration of what PowerShell edition it works with: Desktop
(Windows PowerShell) and/or Core
(PowerShell (Core) 7).
Note that -SkipEditionCheck
is only relevant to modules that ship with Windows, which are located in $env:SystemRoot\System32\WindowsPowerShell\v1.0\Modules
Modules in other locations are considered PowerShell 7-compatible by default, irrespective of whether a CompatiblePSEditions
module-manifest entry is present or not, and, if present, what its value is. However, you can force loading such modules via the Windows compatibility feature via Import-Module -UseWindowsPowerShell
.
You cannot generally expect -SkipEditionCheck
to work.
As of this writing, older modules that ship with Windows - created at a time when only Windows PowerShell existed - are in the process of being evaluated for PowerShell 7 compatibility and, if they are, will be marked as such, via the new CompatiblePSEditions
module-manifest entry.
Older modules that - invariably - were created for Windows PowerShell only and lack a CompatiblePSEditions
declaration, may also work in PowerShell 7:
While PowerShell 7 is mostly backward-compatible with Windows PowerShell, differences in behavior do exist.
Similarly, binary cmdlets, which invariably come as part of (invariably compiled) .NET *assemblies, and/or contain helper DLLs (assemblies) may or may not work, depending on the differences between .NET Framework and .NET.
That said, as new Windows versions / updates are released, the list of modules that ship with Windows that do not explicitly indicate their edition compatibility will continue to shrink, and as of Windows 11 22H2, none of the ones that lack edition-compatibility information can be loaded directly into PowerShell 7, with -SkipEditionCheck
.
If you're unsure about the compatibility of a given older module (that doesn't explicitly (yet) indicate which editions it is compatible with), you can use trial and error with -SkipEditionCheck
.
Conversely, if a ships-with-Windows module does have a CompatiblePSEditions
entry and indicates that the running edition is not supported, it's safe to assume that it will not work.
The PowerShellModuleCoverage
GitHub repository [update: now obsolete] is dedicated to tracking issues with in-box modules once they've been marked as cross-edition and possibly modified to that end, which is an ongoing process as of this writing.
(For third-party modules, it is up to their maintainers to update them in that fashion.)
However, you'll only see the fruits of these efforts if you use the most recent Windows 10 version (update channel) and updates.
On older versions, including all the way back to Windows 7, you can still use -SkipEditionCheck
to load older modules that you've tested and found to be implicitly compatible with PowerShell Core.
You have two options:
Option 1: Rely on the Windows PowerShell Compatibility feature, which uses implicit remoting to make Windows PowerShell-only modules available in PowerShell 7, by communicating with a hidden Windows PowerShell process on the same machine:
For ships-with-Windows modules that aren't marked as PowerShell Core (7) compatible, the compatibility feature is implicitly used.
For other incompatible modules, use Import-Module
with the -UseWindowsPowerShell
switch.
Caveat:
While implicit remoting may work as expected, it does have its limitations and is slower than in-process execution.
A notable limitation is that serialization and deserialization are involved, which means that only a limited number of types can be deserialized with type fidelity, whereas all others are deserialized as approximations of the original type, with static properties - see this answer for details.
Option 2: Ad-hoc: Call Windows PowerShell via its CLI, powershell.exe
, passing an arbitrary command via a script block ({ ... }
) - see example below.
This comes with the same limitations and caveats as using the Windows PowerShell Compatibility feature.
Also, since a new Windows PowerShell process is created for every invocation, you incur the overhead of starting it and importing the module of interest every time; if you need to run multiple commands, it's best to bundle them.
# Call the Windows PowerShell CLI from PowerShell Core, using a script block.
# (Add -noprofile to suppress $PROFILE loading.)
powershell { Get-NetFirewallProfile -Profile Domain, Public, Private | Select-Object Name, Enabled }
Upvotes: 2
Reputation: 27428
It looks like since Windows 10 version 1809, some of these missing commands are back in PS 6, like "get-netadapter" and "get-netfirewallrule". In fact 47 more modules available, mostly the "manifest" type.
Upvotes: 1
Reputation: 6860
NetSecurity is not supported in Core. If you are on a Windows OS you can however use the Param -SkipEditionCheck
Import-Module NetSecurity -SkipEditionCheck
You can use the same Param on Get-Module
Get-Module NetSecurity -ListAvailable -SkipEditionCheck
Upvotes: 3