Reputation: 24430
I'd like to run a command such as:
pushd \\myServer\share\scripts
myBatchFile.bat param1 param2 "parameter 3"
popd
Only initiating through powershell.
NB: The name of the batch file is held in a variable, as are each of the parameters.
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
I've also interested in capturing the output - though as at present the batch file's not being run I'll focus on that initially.
I've not yet tried the ProcessStartInfo solution (see link below) as it seems start-process
, or simply cmd.exe /c
should work (certainly when I've run tests outside of a ps1 file this has worked), but I'll resort to trying that method shortly.
ProcessStartInfo solution: Powershell: Capturing standard out and error with Process object
Upvotes: 2
Views: 2003
Reputation: 24430
Using @JNK's answer along with the below hack, I found a way to get this to work
$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
Upvotes: 2
Reputation: 65167
Is there a reason you can't use invoke-expression for this?
$MyCmd = "$batch $p1 $p2 $p3 *>&1"
$ReturnOutput = Invoke-Expression $MyCmd
The *>&1
puts all output from the StdErr and StdOut to the output stream.
More info on redirection operators here.
Upvotes: 1