Why, when I run the Get-Command
powershell command within a .NET 5.0 application using the Microsoft.PowerShell.SDK
nuget package I get different results on different systems, and those results are different to running the same command manually within powershell, even on the same system?
This basically shows how the code runs commands, though it does have more output stream handling etc..
var initialState = InitialSessionState.CreateDefault();
initialState.ExecutionPolicy = ExecutionPolicy.Unrestricted;
using (var ps = PowerShell.Create(initialState))
{
ps.AddScript("Get-Command");
var pipelineObjects = await ps.InvokeAsync();
//**Snip code to interpret pipelineObjects here**
}
The app is explicitly published with a target runtime of win7-x86 if that makes any difference, but the intention is to never run it on anything older than win10 x64 systems really.
New-SelfSignedCertificate
and Export-PfxCertificate
Get-Command
in powershell manually on my system, whilst the list of commands is not quite the same, those PKI commands are still thereGet-Command
manually on the failing systems and I do see those commands - so the scripts work if I run them manually, just not via the app.I understand that using the SDK I'm in effect bundling a PowerShell 6 runtime with the app which might have different/limited commands available, but since these commands do appear on mine then I believe this indicates it's "falling back" to the cmdlets available on the system (they can't be bundled in with the SDK as then surely I'd not be having this issue at all)
I have found that on some older Windows 10 installs, if you fully update the system via windows update it can fix this apparent problem, but all Windows Server 2016/2019 systems I've so far found seem to exhibit this issue.... but there has been one Windows 10 machine which seems to still have this problem even post-updates.
Currently I can work around this by manually running the various scripts, but this is precisely the sort of time waste that running them via an app was meant to solve.
I've searched around quite a bit but I've not found an answer to this. So:
initialState.ImportPSModule("PKI");
prior to running but it had no effect (also didn't cause any error)Happy to accept I've done something stupid somewhere, but it's frustrating how it works on 90% of systems.
OK, I have found what appears to be a workaround, having cobbled together some bits of info from various sources.
The solution that seems to work is to inject this into the start of the script I'm trying to run:
Import-Module PKI -SkipEditionCheck;
The SDK means I'm effectively running Powershell Core, and the PKI module has apparently not been ported to this, so hence you need the -SkipEditionCheck
param.
Whilst as I said above I attempted to use the InitialSessionState.ImportPSModule()
method to do the same thing, this did not work - perhaps because there doesn't seem to be an overload equivalent to the -SkipEditionCheck
param? No idea.
This appears to have worked based on preliminary testing, I will come back and edit this answer should I find further issues with it.