Access and use Windows PowerShell cmdlets from your PowerShell Core session on a Windows computer.
Missing cmdlets from PowerShell Core
In the last post, we installed PowerShell Core on a Windows computer. However, if you were to try using some common Windows PowerShell cmdlets from the session or via script, such as Get-WmiObject, you would get an error (below) because Get-WmiObject is a Windows PowerShell cmdlet and not part of PowerShell Core.
PS C:\Users\Demo> Get-WmiObject -Class Win32_ComputerSystem Get-WmiObject : The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program. At line:1 char:1 + Get-WmiObject -Class Win32_ComputerSystem + ~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Get-WmiObject:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
Install Windows PowerShell Compatibility Module
Recognizing that in order to get Windows users to start installing and using PowerShell Core it had to be on par with Windows PowerShell, Microsoft released the Windows PowerShell Compatibility Module. This module makes Windows PowerShell cmdlets available from a PowerShell Core session.
Install the module using the Install-Module cmdlet. This will download and install the module from the PowerShell Gallery.
PS C:\Users\Demo> Install-Module WindowsCompatibility Untrusted repository 'PSGallery'? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): a
PS C:\Users\Demo>
And that’s it for installation! Let’s try running Get-WinModule to see the available modules. Depending on your current computer config, you may get the error below about being unable to connect. Why? Because the Windows PowerShell Compatibility Module uses implicit remoting.
PS C:\Users\Demo> Get-WinModule New-PSSession : [localhost] Connecting to remote server localhost failed with the following error message : The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig". For more information, see the about_Remote_Troubleshooting Help topic. At C:\Users\Demo\Documents\PowerShell\Modules\WindowsCompatibility\1.0.0\WindowsCompatibility.psm1:232 char:20 + $session = New-PSSession @newPSSessionParameters | Select-Obj ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ motingTransportException + FullyQualifiedErrorId : CannotConnect,PSSessionOpenFailed
What is implicit remoting?
Explicit remoting is when you run Invoke-Command, where you are intentionally connecting to a remote computer and running cmdlets within a defined -ScriptBlock {}.
Implicit remoting is a method of taking a remote session (and its related modules) and exporting it to your local session. You can then transparently run cmdlets in your local session as if the cmdlets were installed locally. However they are not; when you run a cmdlet that was part of the remote session, it is seamlessly running them using the exported remote session.
Local WinRM required for Windows PowerShell Compatibility Module
Since the Windows PowerShell Compatibility Module depends on implicit remoting, and implicit remoting depends on WinRM, we need to ensure WinRM is enabled and configured on the local computer we are using PowerShell Core.
The quickest way to configure WinRM is to run the command winrm quickconfig.
PS C:\WINDOWS\system32> winrm quickconfig
WinRM is not set up to receive requests on this machine.
The following changes must be made:
Start the WinRM service.
Set the WinRM service type to delayed auto start.
Make these changes [y/n]? y
WinRM has been updated to receive requests.
WinRM service type changed successfully.
WinRM service started.
Using Windows PowerShell Compatibility Module
Once enabled, run Get-Module again to return the list of predefined modules that the Windows PowerShell Compatibility Module exposes:
PS C:\Users\Demo> Get-WinModule Name Version Description ---- ------- ----------- AppBackgroundTask 1.0.0.0 AppLocker 2.0.0.0 AppvClient 1.0.0.0 Microsoft Application Virtualization Client Module Appx 2.0.1.0 AssignedAccess 1.0.0.0 BitLocker 1.0.0.0 BitsTransfer 2.0.0.0 BranchCache 1.0.0.0 CimCmdlets 1.0.0.0 ConfigCI 1.0 ConfigDefender 1.0 Defender 1.0 DeliveryOptimization 1.0.2.0 DirectAccessClientComponents 1.0.0.0 Dism 3.0 DnsClient 1.0.0.0 EventTracingManagement 1.0.0.0 International 2.0.0.0 iSCSI 1.0.0.0 ISE 1.0.0.0 Kds 1.0.0.0 Microsoft.PowerShell.Diagnostics 3.0.0.0 Microsoft.PowerShell.LocalAccounts 1.0.0.0 Provides cmdlets to work with local users and local groups Microsoft.PowerShell.Management 3.1.0.0 Microsoft.PowerShell.ODataUtils 1.0
Microsoft.PowerShell.Operation.Validation 1.0.1
Microsoft.PowerShell.Security 3.0.0.0
Microsoft.PowerShell.Utility 3.1.0.0
Microsoft.WSMan.Management 3.0.0.0
MMAgent 1.0
MsDtc 1.0.0.0
NetAdapter 2.0.0.0
NetConnection 1.0.0.0
NetDiagnostics 1.0.0.0
NetEventPacketCapture 1.0.0.0
NetLbfo 2.0.0.0
NetNat 1.0.0.0
NetQos 2.0.0.0
NetSecurity 2.0.0.0
NetSwitchTeam 1.0.0.0
NetTCPIP 1.0.0.0
NetworkConnectivityStatus 1.0.0.0
NetworkSwitchManager 1.0.0.0
NetworkTransition 1.0.0.0
PcsvDevice 1.0.0.0
PersistentMemory 1.0.0.0
Pester 3.4.0 Pester provides a framework for running BDD style Tests to execute… PKI 1.0.0.0
PnpDevice 1.0.0.0
PrintManagement 1.1
ProcessMitigations 1.0.11
Provisioning 3.0
PSDesiredStateConfiguration 1.1
PSDiagnostics 1.0.0.0
PSScheduledJob 1.1.0.0
PSWorkflow 2.0.0.0
PSWorkflowUtility 1.0.0.0
ScheduledTasks 1.0.0.0
SecureBoot 2.0.0.0
SmbShare 2.0.0.0
SmbWitness 2.0.0.0
StartLayout 1.0.0.0
Storage 2.0.0.0
StorageBusCache 1.0.0.0
TLS 2.0.0.0
TroubleshootingPack 1.0.0.0
TrustedPlatformModule 2.0.0.0
UEV 2.1.639.0 User Experience Virtualization management commands.
VpnClient 2.0.0.0
Wdac 1.0.0.0
Whea 2.0.0.0
WindowsDeveloperLicense 1.0.0.0
WindowsErrorReporting 1.0
WindowsSearch 1.0.0.0
WindowsUpdate 1.0.0.0
WindowsUpdateProvider 1.0.0.2
Using Get-Command, we can demonstrate that some Windows PowerShell cmdlets are now available directly, such as Get-ScheduledTask:
PS C:\Users\Demo> Get-Command *ScheduledTask* CommandType Name Version Source
----------- ---- ------- ------
Function Disable-ScheduledTask 1.0.0.0 ScheduledTasks
Function Enable-ScheduledTask 1.0.0.0 ScheduledTasks
Function Export-ScheduledTask 1.0.0.0 ScheduledTasks
Function Get-ClusteredScheduledTask 1.0.0.0 ScheduledTasks
Function Get-ScheduledTask 1.0.0.0 ScheduledTasks
Function Get-ScheduledTaskInfo 1.0.0.0 ScheduledTasks
Function New-ScheduledTask 1.0.0.0 ScheduledTasks
Function New-ScheduledTaskAction 1.0.0.0 ScheduledTasks
Function New-ScheduledTaskPrincipal 1.0.0.0 ScheduledTasks
Function New-ScheduledTaskSettingsSet 1.0.0.0 ScheduledTasks
Function New-ScheduledTaskTrigger 1.0.0.0 ScheduledTasks
Function Register-ClusteredScheduledTask 1.0.0.0 ScheduledTasks
Function Register-ScheduledTask 1.0.0.0 ScheduledTasks
Function Set-ClusteredScheduledTask 1.0.0.0 ScheduledTasks
Function Set-ScheduledTask 1.0.0.0 ScheduledTasks
Function Start-ScheduledTask 1.0.0.0 ScheduledTasks
Function Stop-ScheduledTask 1.0.0.0 ScheduledTasks
Function Unregister-ClusteredScheduledTask 1.0.0.0 ScheduledTasks
Function Unregister-ScheduledTask 1.0.0.0 ScheduledTasks
We can then run Get-ScheduledTask directly:
PS C:\Users\Demo> Get-ScheduledTask TaskPath TaskName State
-------- -------- -----
\ OneDrive Standalone Update Task-… Ready
\Microsoft\Windows\.NET Framework\ .NET Framework NGEN v4.0.30319 Ready
\Microsoft\Windows\.NET Framework\ .NET Framework NGEN v4.0.30319 64 Ready
\Microsoft\Windows\.NET Framework\ .NET Framework NGEN v4.0.30319 6… Disabled
\Microsoft\Windows\.NET Framework\ .NET Framework NGEN v4.0.30319 C… Disabled
\Microsoft\Windows\Active Directory Rights Ma… AD RMS Rights Policy Template Ma… Disabled
\Microsoft\Windows\Active Directory Rights Ma… AD RMS Rights Policy Template Ma… Ready
\Microsoft\Windows\AppID\ PolicyConverter Disabled
\Microsoft\Windows\AppID\ VerifiedPublisherCertStoreCheck Disabled
\Microsoft\Windows\Application Experience\ Microsoft Compatibility Appraiser Ready
\Microsoft\Windows\Application Experience\ ProgramDataUpdater Ready
...
Some cmdlets require using Invoke-WinCommand
When you run Get-WinModule, we still don’t see Get-WmiObject. While we can’t run that directly within PowerShell Core, the Windows Compatibility Module adds the Invoke-WinCommand cmdlet to enable running additional Windows cmdlets.
Invoke-WinCommand takes a script block and runs it within the compatibility runspace. By default when executing, the current compatibility session is used.
To demonstrate, let’s try to run Get-WmiObject directly again:
Windows TerminalPS C:\Users\Demo> Get-WmiObject -Class Win32_ComputerSystem
Get-WmiObject : The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable p
rogram.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-WmiObject -Class Win32_ComputerSystem
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WmiObject:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Now let’s use Invoke-WinCommand, wrapping Get-WmiOjbect in a ScriptBlock:
PS C:\Users\Demo> Invoke-WinCommand -ScriptBlock {Get-WmiObject -Class Win32_ComputerSystem} Domain : WORKGROUP Manufacturer : Microsoft Corporation Model : Virtual Machine Name : DESKTOP-D17T4N5 PrimaryOwnerName : Demo TotalPhysicalMemory : 3547197440 PSComputerName : localhost
It works! You can store the result of Invoke-WinCommand in a variable for later use in your script:
PS C:\Users\Demo> $result = Invoke-WinCommand -ScriptBlock {Get-WmiObject -Class Win32_ComputerSystem}
PS C:\Users\Demo> $result Domain : WORKGROUP Manufacturer : Microsoft Corporation Model : Virtual Machine Name : DESKTOP-D17T4N5 PrimaryOwnerName : Demo TotalPhysicalMemory : 3547197440 PSComputerName : localhost
What’s next for Windows Compatibility Module
I started the initial draft for this post a while ago, and a LOT has changed since then. Microsoft recognized that they had to unify PowerShell Core and Windows PowerShell, and that is the intent with PowerShell 7 (note the lack of “Core” or “Windows” in the name).
PowerShell 7 should be available soon, as it will closely follow on the .NET Core release cycle (which will eventually become .NET 5). Eventually, the Windows Compatibility Module will no longer be required.
Thomas says
Hi Aaron
Just found your blog. I love PowerShell. I guess I have come to the right place 🙂
I was not familiar with the Get-ScheduledTask command. Always great to learn something new.