Forum Discussion
ahinterl
May 13, 2025Brass Contributor
PowerShell implicit remoting without connection to server
When I start a PowerShell session on my local computer, and then run:
Get-Module -Name FailoverClusters
I can see that implicit remoting is used (and I can see the temporary files generated for this), and an output is generated. Needless to say that I don't have the FailoverClusters module installed anywhere on the local machine (I've verified $Env:PSModulePath as well).
I don't have any connection to a server when running the command. Maybe somebody can explain to me what PowerShell is doing to find the FailoverClusters module and the cmdlets contained therein?
8 Replies
Sort By
- ahinterlBrass Contributor
I need to add that the modules where the Compatibility feature is applied are locally installed.
- ahinterlBrass Contributor
My problem was that I didn't understand that PowerShell uses the Compatibility feature and thus implicit remoting for all modules where the variable CompatiblePSEditions is either missing in the module's manifest, or the word Core is not explicitly stated in the variable (for example: CompatiblePSEditions = @('Desktop', 'Core').
What I still don't know is why modules in %SYSTEMROOT%\system32\WindowsPowerShell\v1.0\Modules that are for Desktop only aren't listed with Get-Module; maybe it's a combination of a) the fact that the module is not for Core, and b) the file DACL (TrustedInstaller is the owner of the files and folders). When I copy such modules to the CurrentUser scope folder ($HOME\Documents\PowerShell\Modules), then new files and folders have a different owner than TrustedInstaller (and, I didn't verify this, even the DACL may have changed a bit), and Get_Module successfully lists them even though the manifest files didn't change.
- LainRobertsonSilver Contributor
Implicit remoting is a broad PowerShell topic that spans more than this one scenario relating to compatibility.
You're nearly correct in your first paragraph, however, implicit remoting is not applied to "all modules", only those located under %windir%\system32\WindowsPowerShell\v1.0\Modules, as described in the documentation:
As a demonstration that this is indeed the case, here's the output from a few commands in PowerShell (not Windows PowerShell) that I'll refer back to:
Note: I've had to use the All parameter in the Get-Module to override the default PowerShell behaviour of excluding incompatible modules (which even includes libraries) from the list. Both PowerShell and Windows PowerShell use this behaviour of filtering out the things they feel don't matter, but it's not due to permissions as you've suggested above.
The first Get-Module command lists modules that have a manifest where only Desktop has been specified. Unsurprisingly, nearly all of them live in the WindowsPowerShell directory meaning they'd be automatically subjected to the compatibility-driven implicit remoting documented above.
Focusing on the single module - PackageManagement - that exists outside of the WindowsPowerShell directory, the next command tells us we have three different versions installed on the local machine. As the Desktop-only version is old, we have to load it using the RequiredVersion parameter to specify the version we want.
The result of this loading is that the desktop-only PackageManagement module has been directly loaded into PowerShell, i.e. implicit remoting has not been used. The reason it has not been used is simply because the module does not exist in the WindowsPowerShell directory - there's no other reason. This is in line with the documentation above.
Even though the module has loaded successfully, when we try to use the Find-Package commandlet, we receive an error from PowerShell due to the incompatibility of the module.
Here's a new screenshot showing how implicit remoting is triggered manually, which is required for modules that do not support PowerShell (aka the "Core" value featuring in the manifest):
The first command is simply showing we have the desktop-only version of PackageManagement loaded, while the second command unloads it.
The third command re-imports the PackageManagement module, but this time using the UseWindowsPowerShell parameter, which instructs PowerShell to create the implicit remoting session. This is precisely the same action as PowerShell takes automatically for the modules living inside the WindowsPowerShell directory.
We can now successfully run the earlier Find-Package commandlet since PowerShell is actually calling Windows PowerShell in the background.
The final command shows the presence of the behind-the-scenes remoting session that acts as the broker between PowerShell and Windows PowerShell, which simply confirms that the documented implicit remoting is being leveraged.
As I opened with, implicit remoting is a broader topic where it's commonly seen when using commandlets such as Import-PSSession to work with remote hosts. These session management commandlets can also feature in the Windows PowerShell and PowerShell configuration files so that remote sessions are created whenever you open a new PowerShell session (not something I'd recommend, but I've seen others do it), which is worth being aware of when you're diagnosing remoting more broadly.
In summary, Get-Module only lists what it considers relevant by default - to make our lives easier, but you can force it to list everything using the All parameter.
Implicit remoting is not automatically used for all modules, only those that reside under %windir%\system32\WindowsPowerShell\v1.0\Modules. It has nothing to do with file system permissions.
Cheers,
Lain
- ahinterlBrass Contributor
Sorry to have bothered someone here. Research should be done correctly.
I guess I have finally found the answer to most of my questions.
The reason for PowerShell to use implicit remoting seems to be that the Compatibility feature is used as described in https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_windows_powershell_compatibility.My interpretation:
If CompatiblePSEditions is not present in the module manifest, PowerShell Compatibility feature is used; the module is not listed with Get-Module -Listavailable.
If CompatiblePSEditions is either @('Desktop', 'Core') or @('Core'), the module is natively compatible with PowerShell.
If CompatiblePSEditions is @('Desktop'), the module is incompatible with PowerShell and not listed with Get-Module -Listavailable.
- LainRobertsonSilver Contributor
Hi ahinterl,
What you're describing isn't related to the PowerShell edition given you mentioned you don't have the failover clustering module installed locally. You were correct a few posts above when you said it relates to remoting.
If you run Get-PSSession, you should see one or more, where one of those is allowing you to resolve the remote FailoverCluster commands.
The directory structure you've outlined two posts up is indicative that Import-PSSession was run to import the commands across from the remote host to your local client.
As to how the PowerShell session came about, it'd either be because you have left a remote session open in your current session or potentially have the relevant *-PSSession commandlets in one of the PowerShell start-up profiles:
Edited:
I've re-read your follow-up posts and I'm unclear on if you do have the FailoverClusters module installed locally or not.
If you run the following command in PowerShell (not to be confused with Windows PowerShell) and you do see that FailoverClusters is installed, then your earlier comments around compatibility-drive implicit remoting is correct.
However, if FailoverClusters is still missing after running this command, then it has nothing to do with compatibility and will be related to the *-PSSession commandlets as mentioned above.
Get-Module -ListAvailable -All -Name "FailoverClusters";
Cheers,
Lain
- ahinterlBrass Contributor
I've done some more research, and made some changes to my local computer. I was somehow confused by what I discovered, so I wasn't precise enough in what I wrote above. I hope I have all what's needed now:
The FailoverClusters module is now installed locally in:
%SYSTEMROOT%\system32\WindowsPowerShell\v1.0\Modules.
Get-Module -ListAvailable
doesn't list the FailoverClusters module in the above folder.
Get-Command -Name 'Get-Cluster'
initiates an implicit remote session, I can see the progress bar, and the folder:
Env:UserProfile\AppData\Local\Temp\remoteIpMoProxy_FailoverClusters_2.0.0.0_localhost_58329299-5d1e-4b26-8cb5-7dbb1f130650
is created.
(Get-Module -Name 'FailoverClusters').Name
returns:
C:\Users\admin.hinterleitner\AppData\Local\Temp\remoteIpMoProxy_FailoverClusters_2.0.0.0_localhost_58329299-5d1e-4b26-8cb5-7dbb1f130650\remoteIpMoProxy_FailoverClusters_2.0.0.0_localhost_58329299-5d1e-4b26-8cb5-7dbb1f130650.psm1
To me, this looks like PowerShell doesn't use the FailoverClusters module directly, but rather uses the implicit remoting technique to create a proxy module. I find this very confusing. The fact that Get-Module (see above) doesn't list the FailoverClusters module, though it exists in the %SYSTEMROOT%\system32\WindowsPowerShell\v1.0\Modules folder, puzzles me too.
I hope that somebody can explain what PowerShell does here, and if it does the same for other modules as well (and, maybe, why and how at least the FailoverClusters module causes PowerShell to do what it does).
- ahinterlBrass Contributor
Unfortunately, my answer above is wrong.
As soon as I run the command, a temp folder is created anew, and the FailoverClusters module becomes available via implicit remoting... - ahinterlBrass Contributor
Guess I found the answer. It's a leftover of a previous remote session. I deleted the temp folder, now PowerShell behaves the way I expect.