how can I execute the following example in a PowershellScript?
@echo off
REM Maintenance Mode on
"C:\ProgramFiles\vdogServer\VDogMasterService.exe" /at:s /rd:C:\vdServerArchive /maintenance:on
if ERRORLEVEL 1 ECHO "versiondog Server wurde nicht ordnungsgemäß in den Wartungsmodus versetzt." >> d:\log.txt
if ERRORLEVEL 0 ECHO "versiondog Server wurde ordnungsgemäß in den Wartungsmodus versetzt." >> d:\log.txt
I tried that without success:
$command = @'
@echo off
REM Maintenance Mode on
"D:\vdogServer\VdogMasterService.exe" /at:s /rd:E\vdServerArchive /maintenace :on
if ERRORLEVEL 1 ECHO "NOK" >> d:\MMLOG.txt
if ERRORLEVEL 0 ECHO "OK" >> d:\MMLOG.txt
'@
Invoke-Expression -Command:$command
Im a Beginner in Powershell yet, would be nice if someone has a solution for that, BR
Edited to test exit code per comment:
#Maintenance Mode on
& "C:\ProgramFiles\vdogServer\VDogMasterService.exe" /at:s /rd:C:\vdServerArchive /maintenance:on
if ($LASTEXITCODE -eq 0) {
"versiondog Server wurde ordnungsgemäß in den Wartungsmodus versetzt." | out-file d:\log.txt -append
} else {
"versiondog Server wurde nicht ordnungsgemäß in den Wartungsmodus versetzt." | out-file d:\log.txt -append
}
You cannot directly execute batch-file ( cmd
) commands from PowerShell (which speaks a very different language), but you can pipe a series of batch-file commands to cmd
, the (legacy) Windows command processor:
$commands = @'
@echo off
REM Maintenance Mode on
"D:\vdogServer\VdogMasterService.exe" /at:s /rd:E\vdServerArchive /maintenace :on
if ERRORLEVEL 1 ECHO "NOK" >> d:\MMLOG.txt
if ERRORLEVEL 0 ECHO "OK" >> d:\MMLOG.txt
'@
# Simply sends the commands via stdin.
# /q suppresses printing the prompt between commands, and
# /d suppresses autorun entries - see cmd /?
$commands | cmd /q /d
but it comes with caveats :
With this invocation style, cmd
will not reflect the last command's exit code in its own exit code, and PowerShell's $LASTEXITCODE
will therefore NOT reflect failure . (Contrast this with invoking a batch file containing the same commands.)
PowerShell by default uses ASCII as the output encoding ( $OutputEncoding
); ie, it sends ASCII characters only to external commands and simply replaces non-ASCII characters with literal ?
.
$OutputEncoding = [text.encoding]::Default
to address that, which addresses the input side of things and redirecting to output files, but note that console output is a separate issue, and will still misrepresent non-ASCII characters (you'd have to (temporarily) set [Console]::OutputEncoding
as well). On a more subtle, but possibly much more insidious note, the commands are parsed with interactive command-line syntax , not batch-file syntax , which - regrettably, and for historical reasons - differ subtly.
%
signs (using them as literals ): for instance, inside a batch file you could use %%PATH%%
to produce literal %PATH%
on output (ie, doubling metacharacter %
causes it to be treated literally); on the command line - and when piping via stdin - this does NOT work: you end up with %<contents of variable %PATH%>%
. Thus, you're generally better off writing the commands to a (temporary) batch file and invoking that :
function Invoke-AsBatchFile([string] $batchFileContents, $ArgumentList) {
# Determine a unique file path to serve as a temp. batch file.
$tempBatchFile = "$(Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())).cmd"
# Write the commands to the batch file.
# Note: Not specifying an -Encoding value means that the Default Windows code page
# (e.g., Windows 1252 on a en-US system) is used as the output file's encoding.
# Note that echoing string literals contained in $batchFileContents to files using
# `>` (output redirection) therefore also creates output files that are encoded that way.
$batchFileContents | Set-Content -LiteralPath $tempBatchFile
# Execute the temp. batch file with optional arguments.
# Note that output sent to the *console* is by default still interpreted as
# *OEM* codepage-encoded; to change that, also (temporarily) set
# [Console]::OutputEncoding = [text.encoding]::Default
& $tempBatchFile $ArgumentList
# Remove the temp. batch file.
Remove-Item $tempBatchFile
# $LASTEXITCODE now contains the temp. batch file's exit code
# (whereas $? should be ignored).
}
$command = @'
@echo off
REM Maintenance Mode on
"D:\vdogServer\VdogMasterService.exe" /at:s /rd:E\vdServerArchive /maintenace :on
if ERRORLEVEL 1 ECHO "NOK" >> d:\MMLOG.txt
if ERRORLEVEL 0 ECHO "OK" >> d:\MMLOG.txt
'@
Invoke-AsBatchFile $command
if ($LASTEXITCODE -ne 0) { Write-Error "Something went wrong." }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.