Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ECHO在Powershell中运行CMD代码_Powershell_Batch File_Cmd - Fatal编程技术网

使用ECHO在Powershell中运行CMD代码

使用ECHO在Powershell中运行CMD代码,powershell,batch-file,cmd,Powershell,Batch File,Cmd,如何在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 ve

如何在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
我试过了,但没有成功:

$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

我还不是Powershell的初学者,如果有人能解决这个问题,那就太好了,BR

编辑以测试每条评论的退出代码:

#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
}
您不能直接从PowerShell(讲一种非常不同的语言)执行批处理文件(
cmd
)命令,但是 您可以通过管道将一系列批处理文件命令发送到
cmd
(旧版)Windows命令处理器:

$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
但它附带了一些警告:

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." }
  • 使用此调用样式,
    cmd
    不会在其自身的退出代码中反映最后一个命令的退出代码,因此PowerShell的
    $LASTEXITCODE
    不会反映失败。(这与调用包含相同命令的批处理文件形成对比。)

  • 默认情况下,PowerShell使用ASCII作为输出编码(
    $outpuntencoding
    );i、 例如,它只向外部命令发送ASCII字符,并简单地用文本
    替换非ASCII字符

    • 您可以(临时)设置
      $outpunecoding=[text.encoding]::默认设置
      ,以解决问题的输入端和重定向到输出文件的问题,但请注意,控制台输出是一个单独的问题,仍然会误报非ASCII字符(您必须(临时)设置
      [console]::输出编码(也可以是
  • 更微妙但可能更隐晦的是,命令是用交互式命令行语法解析的,而不是批处理文件语法,遗憾的是,由于历史原因,的语法有细微的不同

    • 这在转义
      %%
      符号(将它们用作文字)时最为重要:例如,在批处理文件中,您可以使用
      %%PATH%%
      在输出时生成文字
      %PATH%%
      (即,将元字符
      %%
      加倍会导致按字面处理);在命令行上,当通过stdin进行管道传输时,这是不起作用的:您将以
      %%
      结束
    • 关于整个可怕的故事,请看我的
因此,通常最好将命令写入(临时)批处理文件并调用该文件:

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." }

我认为最简单的解决方案是将所有批处理文件代码放在批处理文件中,并让您的powershell脚本执行批处理文件。最好的解决方案是将批处理代码重写到powershell。外部命令不会引发终止错误,因此,
try..catch
不起作用。在命令后选中
$LASTEXITCODE