0
votes

I have become responsible for a couple of dozen PC's, that I need to check for internal hard- and software. Our CMDB system isn't up to date, therefore I need to find out what we actually have. I have spent several hours trying to figure a way to make a batch script that is easy to use and generates easy to read output. I wanted to get started with the physical memory/RAM.

I found the wmic command, and was able to specify it to get only the information I need and use a text file and FOR loop to cycle through a list of SNs and output the RAM of each computer into a text file:

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

This only works when the PC's are online.

So far, so good.

To also see the serial number of the computer, to - for example - use Excel to warp the text file into a table, I added an ECHO line:

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" Why does this happen?

If I manually remove all " " characters from the output file, it transforms back into what i would expect: Everything back to neat lines

I hoped I could directly remove the "space" characters from the wmic function's output, but I couldn't. For example, I found this trick to get the output of wmic into variables, which I though I could then manipulate:

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

But I can't get it to be filled with the serial numbers from the input.txt file. If I try this code, it still prints the serial number lines, but apparently skips the second FOR loop:

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

If I look at what is actually happening, it seems that in some cases, the second FOR does get the correct serial number passed into the wmic command, but it still doesn't work, I only get the lines of the first ECHO.

I found another forum's thread about WMIC posting unicode outcomes, which can't be interpreted correctly, and some attempts to solve this. I tried integrating this into my code, but it doesn't work 100%, it now adds extra "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
)

If I could get to write the WMIC outcome to separate variables, there might be a way to integrate this line of code to remove the spaces:

set str=%str: =%

A final step would be, to reduce the RAM space in bytes to a more readable GB number. I have seen some things that might achieve that, I only need to get the strings into variables to manipulate them.

But as I said, I'm an utter noob, with only a decade-old knowledge of some visual basic and C++ and some HTML/JAVA/CSS programming. There's probably a simple solution to this problem...

Any help would be immensely appreciated! Also, if anyone can recommend a website or a book that takes you through cmd/batch scripting step by step with general explanation of syntax structure, information how variables work, etc, that would also be immensely helpful :)

3
Too long, didn't read. I suspect you'll get assistance more quickly if you reduce your post. Remove the irrelevant back story and focus on one specific question.Jonathon Reinhart
Short version: i'm trying to use the wmic with an input text file which contains host names of pc's to get their system specs, especially RAM. If i use it as a single line FOR loop, nothing is wrong and i can output the wanted data into a neat text file. as soon as I try to add more lines to neaten up the output file, it goes wonky. extra spaces added, extra "echo is on" lines added, depending on my approaches. can't find the answer. for code that i've been using: see Original post, it's been edited a bit, thanks to @Kevin_KinseyThomas Moll
Just wondering why you couldn't use, WMIC /Output:output.txt /Node:@input.txt MemoryChip Get CapacityCompo
@compo2 I didn't know this exists. Also, I didn't have any idea how this works. Turns out, that WMIC in itself, with the right parameters, contains a looping function apparently. Now the question is, how do i get it to also write the node information into the output file? all i get is a looong list of memory numbers. i guess i need to use something else to also put the current node into the output file, but how do i get that into the loop that's integrated in WMIC itself?Thomas Moll
user1016274's script works brilliantly, i'll take that :) thanks for the answer though!!Thomas Moll

3 Answers

0
votes

It's hard to tell from your story exactly what you want, so here's my best guess:

@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
0
votes

This script collects multiple values from different WMIC calls, where each data source is handled in a subroutine. To illustrate, total memory size and BIOS serial number are collected. The nodelist file contains hostnames which in OP's case happen to be identical to the host's serial number (if I have understood this right).
WMIC output often has a trailing control character. To get rid of it, a temporary file is used:

@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

edit:
I've added a quick check if the node is online, using a ping. The host needs to have an IPv4 IP address (not IPv6) to keep it simple. Additionally, each WMIC call returns a success flag (OK). If one call fails no other is attempted on this host. Lastly, now the node name can contain a trailing space without disturbing the process.

0
votes

But all the wmic output lines got weird spaces between each character [...] Why does this happen?

wmic outputs Unicode (two Bytes Character encoding).

You can "convert" to ASCII with type or more:

wmic  memorychip get capacity|more >>output.txt

respective:

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