我想运行如下命令:
pushd \\myServer\share\scripts
myBatchFile.bat param1 param2 "parameter 3"
popd
仅通过powershell启动。
注意:批处理文件的名称保存在变量中,每个参数也是如此。
function Escape-StringForCmd($a)
{
if(($a -like '*"*') -or ($a -like '* *'))
{
('"{0}"' -f ($a -replace '"','""'))
}
else
{
$a
}
}
$batch = "myBatchFile.bat"
$p1 = "param1"
$p2 = "param2"
$p3 = "parameter 3"
$batch = Escape-StringForCmd($batch)
$p1 = Escape-StringForCmd($p1)
$p2 = Escape-StringForCmd($p2)
$p3 = Escape-StringForCmd($p3)
pushd \\myServer\share\scripts
cmd.exe /c $batch $p1 $p2 $p3
#above fails; no error returned; I think because cmd doesn't like the UNC path, so reverts to the system directory
Start-Process "cmd.exe" -ArgumentList "/c",$batch,$p1,$p2,$p3 -NoNewWindow -Wait -WorkingDirectory "\\myServer\share\scripts"
#above also fails; not sure why as looks healthy when running outside of ps1 file
popd
我也对捕获输出感兴趣 - 虽然目前批处理文件没有运行但我最初会关注它。
我还没有尝试过ProcessStartInfo解决方案(请参阅下面的链接),因为它似乎start-process
,或者只是cmd.exe /c
应该可以工作(当我在ps1文件之外运行测试时工作),但我很快就会尝试这种方法。
ProcessStartInfo解决方案:Powershell: Capturing standard out and error with Process object
答案 0 :(得分:2)
使用@JNK的答案以及下面的黑客攻击,我找到了一种方法让它工作
$tempBatchName = ".\~myTempBatchFile.bat" #put this in a variable so we can easily amend if required
"
pushd \\myServer\share\scripts
$batch $p1 $p2 $p3
popd
" | out-file $tempBatchName -encoding ascii
$MyCmd = ("{0} *>&1" -f $tempBatchName)
$ReturnOutput = Invoke-Expression $MyCmd
$ReturnOutput | out-file ("{0}.log" -f $tempBatchName)
remove-item $tempBatchName
答案 1 :(得分:1)
你有没有理由不能使用invoke-expression?
$MyCmd = "$batch $p1 $p2 $p3 *>&1"
$ReturnOutput = Invoke-Expression $MyCmd
*>&1
将StdErr和StdOut的所有输出都放到输出流中。