使用参数在UNC路径上运行批处理文件,并将输出捕获到不带社区扩展的变量

时间:2014-12-08 18:15:05

标签: powershell batch-file parameter-passing

我想运行如下命令:

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

2 个答案:

答案 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的所有输出都放到输出流中。

More info on redirection operators here.