Windows Batch file split string %%i was unexpected at this time - windows

I'm trying to set few variables from systeminfo command in Windows. I read all kinds of similar threads and tried various things, but always keep getting the same error:
%%G was unexpected at this time.
or
%%i was unexpected at this time.
I've been trying to get this done all day long. Can someone point me in the right direction please? This is what I have tried so far:
for /f "tokens=:" %%i in ('systeminfo ^| grep "OS Name"') do set OSname=%%i
for /f "usebackq delims=: tokens=2" %%i in ('systeminfo ^| grep "OS Name"') do set OSname=%%i
FOR /F "usebackq delims= tokens=2" %%i IN ('systeminfo ^| grep "OS Name"') DO set vers=%%i
for /f "tokens=* delims= " %%a in ('systeminfo ^|grep "OS Name"') do (set OS_Name=%%a)
systeminfo | find "OS Name" > osname.txt
for /f "usebackq delims=: tokens=2" %%i in (osname.txt) do set osname=%%i
FOR /F %%G IN (FINDSTR /L /C:"OS Name" systeminfo.txt) DO ECHO %%G
UPDATE: I got it to work like this:
FOR /F "usebackq delims=: tokens=2" %i IN (`FINDSTR /L /C:"OS Name" systeminfo.txt`) DO set osname=%i
Any way to remove the leading space in front of the string? Thanks.

This is all you need to get the OS name.
for /f "tokens=2* delims=: " %%i in ('systeminfo ^| find "OS Name"') do set OSname=%%j

Related

Converting CMD output into CSV file

I am currently using this quick batch file to get info that I need from a variety of computers. My problem is that it creates the CSV file, but it is all one column. I am planning to use python to manipulate the data, but it is difficult to do so if it is all one column.
#echo off
(systeminfo | findstr /c:"Host Name"
systeminfo | findstr /c:"OS Name"
systeminfo | findstr /c:"System Model"
systeminfo | findstr /c:"System type"
systeminfo | findstr /c:"Total Physical Memory"
ipconfig | findstr IPv4
wmic diskdrive get size
wmic bios get serialnumber
wmic cpu get name)>>in.csv
All output, single line, comma delimited, and sub-delimits on both IP address and disk drive, since there are multiple of those. Sub-delimit is a semi-colon.
Output:
MyBox,36527083,Packard Bell,3-2,Microsoft Windows 10,x64-based PC,17087881216,192.168.121.1;192.168.3.1;10.11.18.112,Intel(R) Core(TM) i7-4710HQ CPU # 2.50GHz,2000396321280;63992678400;4000784417280;512105932800;1500299297280
Cmd:
#echo off
setlocal EnableDelayedExpansion
set "zManufacturer="
set "zHostName="
set "zOsName="
set "zSystemModel="
set "zSystemType="
set "zTotalPhysicalMemory="
set "zIpAddresses="
set "zHddSizes="
set "zCpuName="
set "zBiosSerial="
for /f "skip=1 tokens=1-6 delims=," %%A in ('wmic computersystem get Manufacturer^,Model^,TotalPhysicalMemory^,SystemType^,Workgroup /format:csv ^| findstr ","') do (
set "zHostName=%%A"
set "zManufacturer=%%B"
set "zSystemModel=%%C"
set "zSystemType=%%D"
set "zTotalPhysicalMemory=%%E"
)
for /f "tokens=2 delims=:" %%A in ('ipconfig ^| findstr /i ipv4') do set "zIpAddresses=!zIpAddresses!%%A"
set "zIpAddresses=!zIpAddresses:~1!"
set "zIpAddresses=!zIpAddresses: =;!"
for /f "tokens=1 delims=|" %%A in ('wmic os get name ^|findstr "|"') do set "zOsName=%%A"
for /f "tokens=2 delims=," %%A in ('wmic bios get serialnumber^,version /format:csv') do set "zBiosSerial=%%A"
for /f "tokens=2 delims=," %%A in ('wmic cpu get name^,version /format:csv') do set "zCpuName=%%A"
for /f "skip=1 tokens=2 delims=," %%A in ('wmic diskdrive get size^,TracksPerCylinder /format:csv ^|findstr /v /r "^$"') do set "zHddSizes=!zHddSizes!;%%A"
set "zHddSizes=!zHddSizes:~1!"
echo !zHostName!,!zBiosSerial!,!zManufacturer!,!zSystemModel!,!zOsName!,!zSystemType!,!zTotalPhysicalMemory!,!zIpAddresses!,!zCpuName!,!zHddSizes!

store part of outcome command to variable

Hello dear people and others,
Today i wanted to create a simple script, thought it would be easy to store the outcome to var of the following command:
wmic bios get serialnumber | findstr /N /V SerialNumber
Outcome:
2:H3GK4S1
3:
The problem is when i try to get the serial with wmic, it returns the string as expected but also an empty string/line. When i try to store the serial to a variable it stores it and then directly overwrites it with the empty string. This is the function i nearly got working now:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber ^| FINDSTR /N /V SerialNumber') DO (SET serial=%g & ECHO %g)
And this gives the following output:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber ^| FINDSTR /N /V SerialNumber') DO (SET serial=%g & ECHO %g)
2:H3GK4S1
3:
As can be seen above, the loop overwrites the serial var, if someone can help me towards the right directon to get this working, would be mad.
At the Command Prompt:
For /F "Tokens=1* Delims==" %g In ('WMIC BIOS Get SerialNumber /Value') Do #For /F "Tokens=*" %i In ("%h") Do #Set "serial=%i" & Echo %i
Or in a batch file:
#For /F "Tokens=1* Delims==" %%g In ('WMIC BIOS Get SerialNumber /Value'
) Do #For /F "Tokens=*" %%i In ("%%h") Do #Set "serial=%%i" & Echo %%i
#Pause
EditIf you're happy to use a labelled section in your batch file:
#Echo Off
Set "serial="
For /F "Skip=1 Delims=" %%A In ('WMIC BIOS Get SerialNumber') Do If Not Defined serial Call :Sub %%A
Set serial 2>Nul
Pause
GoTo :EOF
:Sub
Set "serial=%*"
GoTo :EOF
Try like this:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber /format:value') DO for /f "tokens=* delims=" %# in ("%g") do set "serial=%#"
echo %serial%
Mind that's a command that should be executed in the command prompt directly.For a batch file you'll need to double the % in the for loop tokens.
In a batch file, you can also use a goto to end the loop after the first iteration :
#echo off
for /f "tokens=2 delims=:" %%a in ('wmic bios get serialnumber ^| findstr /N /V SerialNumber') do (
set "$var=%%a"
goto:next
)
exit/b
:next
echo Result=^> [%$var: =%]

Open and run commands in simultaneous windows

I have created a batch file to test IP addresses on the local network of the host. It looks to pull the operating systems of the other machines and write them to a text file.
FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.1 os get buildnumber,caption,CSDVersion /format:csv > C:\IP\IP.txt
FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.2 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt
FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.3 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt
(Note: I only show 3 lines here but the actual file runs through all 256 addresses.)
It runs through each line and writes to the file just fine. However if there is nothing at that IP, it takes 30 second to time out and move onto the next IP.
I would like to open a new cmd window for each line and run them simultaneously. Once I have this set up, I'd modify it to only run 10 at a time or something - but I need to reduce the total time it takes to run every line.
I have tried running them with CMD /c (as seen below) but it still seems to wait until each line is complete before moving to the next one. Is there a CMD parameter that I can add to make new window completely independent?
CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.1 os get buildnumber,caption,CSDVersion /format:csv > C:\IP\IP.txt"
CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.2 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt"
CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.3 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt"
Add START at te beginning of the line:
START CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.1 os get buildnumber,caption,CSDVersion /format:csv > C:\IP\IP.txt"
START CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.2 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt"
START CMD /c "FOR /F "tokens=1 delims=:" %%d IN ('ping %computername% -4 -n 1 ^| find /i "reply"') DO FOR /F "tokens=3 delims= " %%g IN ("%%d") DO FOR /F "tokens=1 delims=." %%h IN ("%%g") DO FOR /F "tokens=2 delims=." %%i IN ("%%g") DO FOR /F "tokens=3 delims=." %%j IN ("%%g") DO WMIC /node:%%h.%%i.%%j.3 os get buildnumber,caption,CSDVersion /format:csv >> C:\IP\IP.txt"
...
You can use START command. You may want to escape the double quotes.
START "FOR /F ""tokens=1 delims=:"" %%d IN ('ping %computername% -4 -n 1 ^| find /i ""reply""') DO FOR /F ""tokens=3 delims= "" %%g IN (""%%d"") DO FOR /F ""tokens=1 delims=."" %%h IN (""%%g"") DO FOR /F ""tokens=2 delims=."" %%i IN (""%%g"") DO FOR /F ""tokens=3 delims=."" %%j IN (""%%g"") DO WMIC /node:%%h.%%i.%%j.1 os get buildnumber,caption,CSDVersion /format:csv > C:\IP\IP.txt"
To make it clean, put the command in a separate batch file and execute it.
START "Path\to\batch\file.bat"
There are more options available with START command. As you may very well know, they can be seen by simply giving the command START /?.

How do i get a specific line from an output using a batch file?

I have the code below that returns the hostname and IP address of a given server. How can i only have the hostname as the output?
FOR /F %%i in (servers.txt) do FOR /F "skip=3 delims=: tokens=2 usebackq" %%j in (`nslookup %%i`) do #echo %%j >> Devices_With_IP.txt
Assuming your machine uses English:
FOR /F %%i in (servers.txt) do FOR /F "delims=: tokens=2" %%j in (
'nslookup %%i ^| find "Name:"'
) do #echo %%j >> Devices_With_IP.txt
Try using the findstr command on the output of your nslookup to get only the line containing "Name".
FOR /F %%i in (servers.txt) do FOR /F "tokens=2 usebackq delims=: " %%j in (`nslookup %%i ^| findstr Name`) do #echo %%j >> Devices_With_IP.txt
Note that I also rearranged the /F conditions in the second loop in order to include space as a deliminator, this removes the leading spaces before the output.
Using the find command instead of findstr -
FOR /F %%i in (servers.txt) do FOR /F "tokens=2 usebackq delims=: " %%j in (`nslookup %%i ^| find "Name"`) do #echo %%j >> Devices_With_IP.txt
Just realized that using find instead of findstr makes this (almost) exactly the same as dbenham's answer.

Batch file set wmi output as a variable

Hello having my first go with a BATCH script, I'm getting the size of the HDD as follow:
wmic diskdrive get size
Which works fine but I'd like to store this value into a variable for later use, such as using ECHO to display the value.
I'm not sure how I set the output of the above command to a variable. I went with:
SET hddbytes=wmic diskdrive get size
But this just sets the variable to the above text string and not the output.
For usage in batch file. From command line, replace %% with %
for /f "tokens=*" %%f in ('wmic diskdrive get size /value ^| find "="') do set "%%f"
echo %size%
Or, if you want to use you prefered variable
for /f "tokens=2 delims==" %%f in ('wmic diskdrive get size /value ^| find "="') do set "myVar=%%f"
echo %myVar%
You want:
for /f %%a in ('wmic diskdrive get size^|findstr [0-9]') do echo %%a
Updated:
WMIC's output could get a trailing Carriage Return in some environment:
Size <CR>
<CR><LF>
256052966400<CR>
<CR><LF>
500105249280<CR>
<CR><LF>
15496427520 <CR>
<CR><LF>
use csv format, and use FOR loop to truncate the wanted value from the wmic output:
For /F "tokens=2,3 delims=," %%a in ('"wmic diskdrive get size,Status
/format:csv |findstr "[0-9]" "') do (
echo "%%a"
)
Another Batch Script Example:
setlocal ENABLEDELAYEDEXPANSION
:: You can change active code page as well::
#chcp 936 >NUL
:: [example] Remove all network printers:
for /F "tokens=2,3 delims=," %%a in ('"wmic printer where 'local=FALSE' get Name,PrinterStatus /format:csv |findstr "." "') do (
echo "%%a"
rundll32 printui.dll,PrintUIEntry /n "%%a" /dn /q
)
for /f "delims=" %%w in ('wmic diskdrive get size /format:Textvaluelist.xsl') do for /f "usebackq delims=" %%a in ('%%w') do set %%a
echo %size%

Resources