【发布时间】:2013-12-15 11:05:45
【问题描述】:
作为我们使用 Powershell 完成的服务器构建和配置的一部分,我需要在许多 Server 2012 机器上远程安装 .net framework 4.5.1。 The offline install 以 .exe 形式提供,运行时会解压缩许多 MSI 安装程序和安装程序。
我们用于运行安装程序的代码可以与 MSI 文件或 exe 一起使用。如果我们使用 MSI 文件,则调用 MSIEXEC,如果它是 EXE,则直接调用该程序。也可以传递所需的任何参数。
出于我们的目的,这是使用 Powershell cmdlet Start-Process 实现的。
我需要获取返回码以确定安装是否正确完成,并且还想在安装失败时捕获 stdout 和 stderr 以帮助诊断任何问题。
我有以下自定义编写函数来包装 Start-Process cmdlet。
Function Start-Proc()
{
[CmdletBinding()]
param (
[string][ValidateNotNullOrEmpty()][ValidateScript({Test-Path -Path $_ -Type Leaf})] $FilePath,
[string][ValidateNotNullOrEmpty()]$Arguments,
[switch] $Hidden,
[switch] $WaitForExit
)
#Create files to hold the output to avoid the deadlock issue that seems to arise when we read
#the output and error at the same time http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx
$errorFilePath = Join-Path -Path $env:TEMP -ChildPath ([system.guid]::NewGuid().ToString())
$outputFilePath = Join-Path -Path $env:TEMP -ChildPath ([system.guid]::NewGuid().ToString())
$process = Start-Process `
-FilePath $FilePath `
-ArgumentList $Arguments `
-RedirectStandardError $errorFilePath `
-RedirectStandardOutput $outputFilePath `
-NoNewWindow:$Hidden `
-PassThru `
-Wait:$WaitForExit
$errorOut = Get-Content -Path $errorFilePath
$stdOut = Get-Content -Path $outputFilePath
#Tidy up files
If ($process.HasExited)
{
Remove-Item $errorFilePath
Remove-Item $outputFilePath
}
#Create new object to send the messages and exit code back
$output = New-Object -TypeName PSObject
$output | Add-Member –MemberType NoteProperty -Name Message -Value $stdOut
$output | Add-Member –MemberType NoteProperty -Name ErrorMessage -Value $errorOut
$output | Add-Member –MemberType NoteProperty -Name ExitCode -Value $process.ExitCode
return $output
}
注意:我必须使用 -RedirectStandardOutput 和 -RedirectStandardInput 参数将输出发送到文件,然后使用 Get-Content 以避免将属性作为文本读取时出现死锁。
调用此函数来安装 .NET Framework 4.5.1 总是失败,错误代码为 5,即拒绝访问。
对此进行调查,您似乎需要使用 -动词 RunAs 带有 Start-Process 的参数以将命令提升为管理员,但是将该参数添加到 cmdlet 会导致以下错误:
Parameter set cannot be resolved using the specified named parameters.
这是因为 -Verb 和 -RedirectStandardOutput & -RedirectStandardError 在不同的参数集中。
因此我的问题是:
如何从 Powershell 运行执行以下操作的可执行文件:
- 捕获退出代码
- 捕获输出和错误消息
- 以提升的管理员身份运行
我已经尝试过直接使用 .NET System.Diagnostics.Process.Start 方法,但是这遇到了同样的问题。
感谢您的帮助,因为事实证明这是一个难题!
【问题讨论】:
标签: powershell