Certutil.exe在启动进程升高的情况下运行时错误退出代码



我试图用脚本导入certutil.exe证书。此脚本以非admin用户启动,当到达Start-Process命令时,windows UAC要求管理员凭据。

$cmd="certutil.exe -addstore TrustedPeople C:some_pathmyCertif.cer"
$ret = Start-Process powershell -Verb RunAs -ArgumentList $cmd -Wait -PassThru
当我运行这段代码时,

$ret.exitCode = 1,并且在商店中找不到证书。

但是,如果我运行没有-ArgumentList的Start-Process(然后打开一个powershell窗口),并从这里运行certutil.exe命令,我没有得到错误,并且证书按预期添加到存储中。

差异在哪里?

在第一种情况下,你犯了一个错误:你调用一个新的PowerShell实例并传递$cmd字符串,这并不代表PowerShell的有效输入。

你调用

:

powershell.exe certutil.exe -addstore TrustedPeople C:some_pathmyCertif.cer

而PowerShell期望输入如下:

powershell.exe .somescript.ps1

powershell.exe -Command 'some_command'

powershell.exe -EncodedCommand 'base64_command'

…等等…

在第二种情况下,您只需启动一个新的提升的PowerShell实例,然后让您成功导入证书。

要从PowerShell导入证书,根据您的示例,我建议三个解决方案:

1)直接使用certutil.exe:

$arguments = '-addstore TrustedPeople C:some_pathmyCertif.cer'
$ret = Start-Process 'certutil.exe' -Verb RunAs -ArgumentList $arguments -Wait -PassThru

2)如果出于某种原因(以防万一)你想调用另一个PowerShell实例,你可以像这样使用Command选项:

$cmd = 'certutil.exe -addstore TrustedPeople C:some_pathmyCertif.cer'
$ret = Start-Process 'powershell.exe' -Verb RunAs -ArgumentList "-Command $cmd" -Wait -PassThru

3),最后为了完整起见,您可以使用EncodedCommand:

$cmd = 'certutil.exe -addstore TrustedPeople C:some_pathmyCertif.cer'
$bytes = [Text.Encoding]::Unicode.GetBytes($cmd)
$encodedCommand = [Convert]::ToBase64String($bytes)
$ret = Start-Process 'powershell.exe' -Verb RunAs -ArgumentList "-EncodedCommand $encodedCommand" -Wait -PassThru

同样在我的测试环境(Windows 7 Enterprise x64 with PowerShell v.2)中,当我以非提升的权限运行脚本时,我未能使用Start-Process cmdlet实际获得certutil.exe返回代码。我使用。net函数来解决这个问题:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = 'certutil.exe'
$pinfo.UseShellExecute = $true
$pinfo.Verb = 'runas'
$pinfo.Arguments = '-addstore TrustedPeople C:some_pathmyCertif.cer'
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
Write-Host $p.ExitCode

我希望这就是你需要的!

相关内容

  • 没有找到相关文章

最新更新