什么是过时的WMIC的cmd /批处理替代品?

时间:2019-09-25 21:36:26

标签: powershell batch-file wmic

我知道wmic自2012年起就已弃用,现在无论如何我通常都使用PowerShell,因此已经离开了它。

但是,我经常遇到需要在批处理文件中工作且无法选择将解决方案迁移到PowerShell的情况。

我的问题是:不建议使用wmic,从命令提示符和批处理文件继续访问Windows Management Instrumentation的推荐替代方法是什么?

目前我能想到的最好的方法是:

powershell -command "(Get-CimInstance Win32_Processor) | select *" | some_other_program.exe

(此示例获取处理器属性)

但是其中一个主要缺点是错误级别和环境不再可访问。也就是说,即使该命令没有成功,powershell命令也会成功完成。并且在powershell命令中对环境所做的更改不会传播到批处理文件。

欢迎提出任何有关如何专门解决这些问题的建议,或者关于从批处理中调用Powershell来访问WMI的更好选择,但是特别地,我想知道如何运行powershell命令并访问结果,而不是标准输出。

1 个答案:

答案 0 :(得分:0)

  

但是其中的一个主要缺点是错误级别和环境不再可访问。

使通过PowerShell CLI报告的PowerShell命令报告非零退出代码的最简单方法是引发脚本终止(线程终止)错误,从而导致错误代码1-您的批处理文件可以测试:

@echo off

:: # Simulate a failing CIM call
powershell -c "$ErrorActionPreference='Stop'; Get-CimInstance Win32_NoSuchClass" 

:: # Exit, if the PowerShell command failed.
if ERRORLEVEL 1 echo Error: Get-CimInstance failed>&2 & exit /b %ERRORLEVEL%

echo Moving on...

$ErrorActionPreference='Stop'位于命令开头,可确保所有后续错误均变为脚本终止错误。
要有选择地忽略非终止错误,请单独使用-ErrorAction Ignore命令。
如果没有错误发生,则退出代码隐式为0

PowerShell的错误处理非常复杂。请参阅this GitHub issue以获取全面的摘要。

注意:

  • 诸如Get-CimInstance之类的本地PowerShell命令未设置退出代码;最好的办法是将错误映射为退出代码1,并成功映射为退出代码0

  • 如果从PowerShell调用外部程序,则它们的退出代码将反映在自动变量$LASTEXITCODE中;您可以使用exit $LASTEXITCODE通过PowerShell命令字符串传递退出代码;但是,您通常可以直接从批处理文件中直接调用外部程序-无需通过PowerShell绕行。


  

powershell命令中对环境所做的更改不会传播到批处理文件中。

是的,PowerShell命令始终在子进程中运行,该子进程的环境对调用进程没有影响。

通常:

    从PowerShell命令中捕获
  • 捕获输出到文件中,或者使用for /f循环在内存中对其进行处理(请参见下面的示例)-除非将输出通过< / em>就足够了。

  • 如果您确实需要修改调用批处理文件的 environment ,请使PowerShell命令输出用于这些修改的 data 并将它们应用到批处理文件中

    • 例如,如果您希望PowerShell命令设置环境变量,则使其输出<name>=<value>字符串对,批处理文件可使用它们来设置这些变量。

从PowerShell命令定制输出以使用for /f解析批处理文件的示例;请注意,引用可能会很棘手:

@echo off

:: # Get the .Name and .MaxClockSpeed property values from the Win32_Processor instance.
for /f "tokens=1,* delims==" %%i in ('powershell -c "$ErrorActionPreference='Stop'; Get-CimInstance Win32_Processor | %% { foreach ($n in 'Name', 'MaxClockSpeed') { \""$n=$($_.$n)\"" } }"') do (
  echo [%%i]=[%%j]
)

:: # Exit, if the PowerShell command failed.
if ERRORLEVEL 1 echo Error: Get-CimInstance failed>&2 & exit /b %ERRORLEVEL%

上面的结果类似:

[Name]=[Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz]
[MaxClockSpeed]=[2304]