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 :)
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.