简体   繁体   English

.Net Powershell SDK 6.2.6 - 为什么 PKI 模块命令在某些系统上不可用?

[英].Net Powershell SDK 6.2.6 - Why are PKI module commands unavailable on some systems?

The short question简短的问题

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? 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同一个系统?

Example code示例代码

This basically shows how the code runs commands, though it does have more output stream handling etc..这基本上显示了代码如何运行命令,尽管它确实有更多的 output stream 处理等。

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.如果这有什么不同的话,该应用程序会以 win7-x86 的目标运行时显式发布,但目的是永远不要在任何早于 win10 x64 系统的系统上运行它。

The basic problem基本问题

  • I need to run some powershell scripts from a .NET 5.0 Application which targets multiple OSes我需要从针对多个操作系统的 .NET 5.0 应用程序运行一些 powershell 脚本
  • these scripts rely on some PKI module commands eg New-SelfSignedCertificate and Export-PfxCertificate这些脚本依赖于一些 PKI 模块命令,例如New-SelfSignedCertificateExport-PfxCertificate
  • running this code on my system, I can see the PKI commands are output在我的系统上运行此代码,我可以看到 PKI 命令是 output
  • running Get-Command in powershell manually on my system, whilst the list of commands is not quite the same, those PKI commands are still there在我的系统上手动运行 powershell 中的Get-Command ,虽然命令列表不完全相同,但那些 PKI 命令仍然存在
  • running this code on some systems results in no PKI commands, which means if I try to use this code to run those scripts, it fails.某些系统上运行此代码会导致没有PKI 命令,这意味着如果我尝试使用此代码运行这些脚本,它会失败。
  • running Get-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.失败的系统上手动运行Get-Command并且我确实看到了这些命令 - 因此,如果我手动运行脚本,而不是通过应用程序运行它们,脚本就可以工作。

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)我知道使用 SDK 我实际上是在将 PowerShell 6 运行时与可能有不同/有限命令可用的应用程序捆绑在一起,但由于这些命令确实出现在我的身上,所以我相信这表明它“回退”到可用的 cmdlet在系统上(它们不能与 SDK 捆绑在一起,因为我肯定根本不会遇到这个问题)

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.我发现在一些较旧的 Windows 10 安装中,如果您通过 windows 更新完全更新系统,它可以解决这个明显的问题,但所有 Windows 系统似乎都出现了这个问题......'我发现到目前为止我发现了这个问题。/但是有一台 Windows 10 机器即使在更新后似乎仍然存在这个问题。

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:所以:

  • if a cmdlet is not natively supported by the SDK, what are the rules for how it might "search" for other commands?如果 SDK 本身不支持 cmdlet,那么它如何“搜索”其他命令的规则是什么?
  • how can I explicitly Import the PKI module within the code above?如何在上面的代码中显式导入 PKI 模块? I've attempted adding initialState.ImportPSModule("PKI");我尝试添加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.很高兴接受我在某处做了一些愚蠢的事情,但令人沮丧的是它在 90% 的系统上的工作方式。

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. SDK 意味着我正在有效地运行 Powershell 核心,并且 PKI 模块显然没有被移植到这个,因此你需要-SkipEditionCheck参数。

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?虽然正如我上面所说,我尝试使用InitialSessionState.ImportPSModule()方法来做同样的事情,但这不起作用 - 可能是因为似乎没有与-SkipEditionCheck参数等效的重载? 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.根据初步测试,这似乎已经奏效,如果我发现更多问题,我会回来编辑这个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM