无法从C#中的托管Powershell会话导出证书

问题描述 投票:0回答:1

我正在尝试运行Powershell脚本来从C#应用程序中创建和操作证书。我正在使用https://github.com/PowerShell/PowerShell/tree/master/docs/host-powershell上的Powershell Github repo中描述的库,让我可以访问运行脚本的Powershell环境。

脚本如下:

$derPath = "C:\Certs\derRootCert.cer";
$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=P2SRootCert" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign;
New-SelfSignedCertificate -Type Custom -DnsName P2SChildCert -KeySpec Signature -Subject "CN=P2SChildCert" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -Signer $cert -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2");
Export-Certificate -FilePath $derPath -Type CERT -NoClobber -Cert $cert;

如果我自己在Powershell控制台中运行此脚本,它工作正常,我看到文件输出到目录。

如果我在下面的C#中运行它,我从来没有看到创建的文件:

using (var ps = PowerShell.Create()) {
  ps.AddScript(stringContainingScript).Invoke();
}

为什么在此托管上下文中运行时不写入文件,我该怎么做才能使其按预期显示?

谢谢!

编辑:在评论的建议,我查看了错误流,发现以下消息:

术语“New-SelfSignedCertificate”未被识别为cmdlet,函数,脚本文件或可操作程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。

所以这引出了一个相关的问题 - 为什么一个非升级的PowerShell窗口能够找到该cmdlet,但我的托管控制台无法解决?

c# powershell
1个回答
0
投票

最终,我走了另一条路。在深入研究为什么New-SelfSignedCertificate不可用时,我尝试在我的脚本开头显式添加“Import-Module pki”。这产生了另一个错误:

模块'C:\ WINDOWS \ system32 \ WindowsPowerShell \ v1.0 \ Modules \ pki \ pki.psd1'不支持当前的PowerShell版本'Core'。其支持的版本是“桌面”。使用'Import-Module -SkipEditionCheck'忽略此模块的兼容性。

所以,我修改了我的导入,无论如何都要添加-SkipEditionCheck以查看会发生什么。这次我得到了很多非特定的异常,表明各种模块都无法加载。

我走向了另一个方向。由于我的脚本没有向控制台写出任何我需要的东西,只是简单地将我的证书写到目录中,而是将脚本从我的程序写入临时文件并启动Powershell作为进程,传递将脚本位置放入参数中,然后在继续执行其余操作之前对脚本进行一些清理,如下所示:

var fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".ps1";
var tempFile = Path.Combine(Path.GetTempPath(), fileName);

var sb = new StringBuilder();
//Build the script
using (var sw = new StreamWriter(tempFile)) {
  sw.Write(sb.ToString());
}

var pi = new ProcessStartInfo("powershell.exe", $"-File {tempFile}") {
  CreateNoWindow = true,
  UseShellExecute = false
};
var p = Process.Start(pi);
p.WaitForExit();

var errorLevel = process.ExitCode; //If 0, the script ran without errors
p.Close()
File.Delete(tempFile);
© www.soinside.com 2019 - 2024. All rights reserved.