使用wmic和修改输出文件生成计算机列表中的RAM概述

时间:2017-11-17 14:52:47

标签: batch-file redirect wmic

我已经负责几十台PC,我需要检查内部硬件和软件。我们的CMDB系统不是最新的,因此我需要找出我们实际拥有的内容。我花了几个小时试图找到一种方法来制作易于使用的批处理脚本,并生成易于阅读的输出。我想开始使用物理内存/ RAM。

我找到了wmic命令,并且能够指定它以仅获取我需要的信息并使用文本文件和FOR循环来遍历SN列表并将每台计算机的RAM输出到文本文件中: / p>

IF EXIST output.txt DEL /Q output.txt >NUL
FOR /F "tokens=*" %%i IN (input.txt) DO (
wmic /node:%%i memorychip get capacity >> output.txt
)
EXIT /B

仅在PC上线时才有效。

到目前为止,这么好。

要查看计算机的序列号,例如 - 使用Excel将文本文件转换为表格,我添加了一个ECHO行:

IF EXIST output.txt DEL /Q output.txt >NUL
FOR /F "tokens=*" %%i IN (input.txt) DO (
@Echo Serialnumber %%i >> output.txt
wmic /node:%%i memorychip get capacity >> output.txt
)
EXIT /B

But all the wmic output lines got weird spaces between each character and cramped into one line, whereas before they were nicely split into as many lines as there were different "words"为什么会这样?

如果我从输出文件中手动删除所有“”字符,它会转换回我期望的内容:Everything back to neat lines

我希望我能直接从wmic函数的输出中删除“space”字符,但我不能。例如,我发现这个技巧可以将wmic的输出转换为变量,然后我可以操作它:

SETLOCAL ENABLEDELAYEDEXPANSION
@echo off
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`wmic /node:2CMFFY1 memorychip get capacity`) DO (
SET var!count!=%%F
SET /a count=!count!+1
)
ECHO %var1%
ECHO %var2%
ECHO %var3%
ECHO %var4%
ECHO %var5%
ENDLOCAL

This piece of code neatly creates separate lines if I add a serial number manually

但我不能让它填充input.txt文件中的序列号。如果我尝试这个代码,它仍会打印序列号行,但显然会跳过第二个FOR循环:

SETLOCAL ENABLEDELAYEDEXPANSION
IF EXIST output.txt DEL /Q output.txt >NUL
FOR /F "tokens=*" %%i IN (input.txt) DO (
@Echo Serialnumber %%i >> output.txt
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`wmic /node:%%i memorychip get capacity`) DO (
  SET var!count!=%%F
  SET /a count=!count!+1
)
ECHO %var1% 
ECHO %var2%
ECHO %var3%
ECHO %var4%
ECHO %var5%
)
ENDLOCAL
EXIT /B

如果我查看实际发生的情况,似乎在某些情况下,第二个FOR确实获得了正确的序列号passed into the wmic command,但它仍然不起作用I only get the lines of the first ECHO

我发现另一个论坛的thread关于WMIC发布unicode结果,这些结果无法正确解释,有些尝试解决这个问题。我尝试将其集成到我的代码中,但它不能100%工作,现在增加了额外的"Echo is ON" lines to the results

IF EXIST output.txt DEL /Q output.txt >NUL
FOR /F "tokens=*" %%i IN (input.txt) DO (
ECHO Serialnumber %%i>>output.txt
FOR /F "tokens=*" %%j IN ('wmic /node:%%i memorychip get capacity') DO @echo %%j>>output.txt 2>&1
)

如果我可以将WMIC结果写成单独的变量,可能有一种方法可以整合这行代码来删除空格:

set str=%str: =%

最后一步是将RAM空间(以字节为单位)减少到更可读的GB数。我已经看到了一些可能实现的东西,我只需要将字符串变成变量来操纵它们。

但正如我所说,我是一个完全的菜鸟,只有十年的知识,一些视觉基础和C ++以及一些HTML / JAVA / CSS编程。对这个问题可能有一个简单的解决方案......

任何帮助都会非常感激!此外,如果任何人都可以推荐一个网站或一本书,一步一步地通过cmd /批处理脚本,语法结构的一般解释,变量如何工作的信息等,这也将是非常有帮助:)

3 个答案:

答案 0 :(得分:0)

很难从你的故事中准确地说出你想要的东西,所以这是我最好的猜测:

@Echo Off
(For /F "Delims=" %%A In (input.txt) Do (Echo Serialnumber %%A
    For /F "Skip=1" %%B In ('WMIC /Node:%%A MemoryChip Get Capacity'
    ) Do For /F %%C In ("%%B") Do Echo %%C))>output.txt
Exit/B

答案 1 :(得分:0)

此脚本从不同的WMIC调用中收集多个值,其中每个数据源都在子例程中处理。为了说明,收集了总内存大小和BIOS序列号。节点列表文件包含主机名,在OP的情况下恰好与主机的序列号相同(如果我已理解这一点)。
WMIC输出通常具有尾随控制字符。要摆脱它,使用临时文件:

@echo off
REM 8:12:49 PM Saturday 18/11/2017
REM get serial number and memory size for all hosts in a hostname list file
REM output is in CSV format

REM 1:43:58 PM Tuesday 21/11/2017
REM added: check if host is online, using ping

setlocal EnableDelayedExpansion

set nodelist=nodelist.txt
REM needs write permissions for next 2 paths
set out=output.txt
set temppath=%TEMP%

echo node,serial,memsize> %out%
for /F "delims=" %%N in (%nodelist%) do (
   set "node=%%N"
   set "node=!node: =!"
   set "memsize=" & set "getserial="

   CALL :checkonline !node!
   if defined OK CALL :getmem !node!
   if defined OK CALL :getserial !node!
   REM ... and so on
) & echo !node!,!serial!,!memsize!>> %out%
type %out%
goto :EOF


:checkonline
   set "OK="
   if "%~1"=="" goto :EOF
   ping -4 -w 200 -n 2 %~1 | find "TTL" 2>&1 >nul && set "OK=1"
goto :EOF


:getmem
   set "OK="
   set "out1=%temppath%\%RANDOM%.tmp"
   WMIC /Node:%~1 /output:%out1% ComputerSystem get TotalPhysicalMemory /value 2>&1 >nul|| goto :EOF
   for /F "tokens=1,2 delims==" %%A in ('find "=" ^< %out1%') do @set memsize=%%B

   rem memsize is in bytes now
   rem calc size in MB, need to truncate by 1000, cannot use SET /A
   set "memsize=!memsize:~0,-3!"
   rem div by 1048 (1024 * 1,024) in 2 steps
   set /A memsize *= 42
   set /A memsize /= 44016
   rem assume Windows itself is using 132 MB
   set /A memsize += 132 

   set "OK=1"
   del %out1%
 goto :EOF

:getserial
   set "OK="
   set "out1=%temppath%\%RANDOM%.tmp"
   WMIC /Node:%1 /output:%out1% Bios get SerialNumber /value 2>&1 >nul || goto :EOF
   for /F "tokens=1,2 delims==" %%A in ('find "=" ^< %out1%') do @set serial=%%B

   set "OK=1"
   del %out1%
 goto :EOF

编辑:
我已经使用ping添加了一个快速检查节点是否在线的信息。主机需要具有IPv4 IP地址(而不是IPv6)才能保持简单。此外,每个WMIC调用都返回一个成功标志(OK)。如果一个呼叫失败,则不会在此主机上尝试其他呼叫。最后,现在节点名称可以包含尾随空格而不会干扰进程。

答案 2 :(得分:0)

  

但是所有wmic输出行在每个字符之间都有奇怪的空格   [...]为什么会这样?

wmic输出Unicode(两个字节字符编码)。

您可以使用typemore

“转换”为ASCII
wmic  memorychip get capacity|more >>output.txt

各自:

FOR /F "tokens=* USEBACKQ" %%F IN (`wmic /node:%%i memorychip get capacity ^|more`) DO ( ...