Defined variable not outputting in batch script - batch-file

For asset stocktake purposes, I'm trying to create a script in batch that runs through the machine names of computers which are in a local .txt file, getting the last person who logged into the machine, and outputting that to a text file with the format of Machine Name: NAME | Last Login: USER
I've hit a bit of a wall and I can't figure out what's going on. The machine name is being correctly output but the 'last login' part is not. Here is my code:
#echo off
for /f %%a in (Assets.txt) do (
for /f %%b in ('wmic.exe /node:"%%a" computersystem get username') do set lastlogin=%%b
echo Machine Name: %%a Last Login: %lastlogin%)
pause
Any help would be greatly appreciated. Thank you.
Update 2
for /f "delims=" %%a in (Assets.txt) do (
for /f "skip=1 delims=" %%b in (
'WMIC /Node:"%%a" ComputerSystem Get UserName 2^>nul'
) do for %%c in (%%b) do echo Host: %%a Username: %%b >>Usernames.txt)

There really shouldn't be any need to set variables and therefore no need to enable delayed expansion.
You may be able to change your script to something like this:
#Echo Off
For /F "Delims=" %%A In (Assets.txt) Do (
For /F "Skip=1 Delims=" %%B In (
'WMIC /Node:"%%A" ComputerSystem Get UserName 2^>Nul'
) Do For %%C In (%%B) Do Echo Machine Name: %%A Last Login: %%B)
Pause
You may be able to so it like this too:
#Echo Off
For /F "Skip=1 Delims=" %%A In ('
"WMIC /Node:#Assets.txt ComputerSystem Get Name, UserName"
') Do Call :Sub %%A
Pause
Exit /B
:Sub
If Not "%1"=="" Echo Machine Name: %1 Last Login: %2

Related

adding the wmic bios get serialnumber to script

I have the following script
set ip_address_string="IPv4 Address"
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
#(Echo Status,Date,Time,Device,User,IP,SN & Echo Logon,%DATE%,%TIME%,%COMPUTERNAME%,%USERNAME%,%%f,%SerialNumber%))1>%RANDOM%.csv
goto :eof
The script works great but I need to capture the PC serialnumber within my script, for eg
for /F %%a in ('wmic bios get serialnumber') do call :Sub %%a
echo The serial number is %SerialNumber%
:Sub
if not "%*"=="" set SerialNumber=%*
So I can get the following "Logon,14/06/2021,22:03:18.28,LT6880,Testuser,192.168.0.46,B4Q4MN3"
but so far its been unsuccessful, can someone please point me in the correct direction?
Many Thanks
John

Missinng Operand For Loop Batch

Below is a piece of code that is "supposed" to be used to, ping all IP's on my network and return the Computer name to an .txt file on my desktop. Every time I run it gives me "missing operand" error. Any help would be nice, gracias!
#Echo Off
Title Getting all Computer Names from Network. . .
Color A
SETLOCAL EnableDelayedExpansion
REM Convert Current IPv4 Address to Variable.
For /F "skip=1 delims={}, " %%A in ('wmic nicconfig get ipaddress') do For /F "tokens=1" %%B in ("%%~A") do set "IP=%%~B"
SET "offsets=0.0.0.0"
For /F "tokens=1-4 delims=. " %%A in ("%IP%") do (
For /F "tokens=1-4 delims=." %%I in ("%offsets%") do (
set /A octetA=%%A+%%I, octetB=%%b+%%j, octetC=%%c+%%k, octetD=%%d+%%l
)
)
REM Do a Ping Sweep To Get Computer Name.
For /L %%B in (1,1,254) do For /F "Tokens=2 Delims== " %%A in ('wmic /node:"%octetA%.!octetB!.!octetC!.%%B" computersystem get name /value') do set "Host=%%A"
REM Output Computer Name In Text File
Echo %Host% >> "C:\Users\%username%\Desktop\ComputerNames.txt"
pause
set /A octetA=%%A+%%I, octetB=%%b+%%j, octetC=%%c+%%k, octetD=%%d+%%l
metavariables are case-sensitive.
set /A octetA=%%A+%%I, octetB=%%B+%%J, octetC=%%C+%%K, octetD=%%C+%%L

Get Windows version ,and edition, pass it to variable to use with findstr after

I'm noob it's my first question, but after searching tons of answers here I still can't quite get what I want. So the problem: need to get windows version ,and edition and pass it to variable to run findstr on it afterwards I get the variable with the edition however findstr can't use it to find string in txt file.
what I have done: I'm using this code to get the ver and save it as var
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=2 delims==" %%G in ('wmic os get Caption /value') do (
set winEdition=%%G
)
echo !winEdition!
endlocal
goto :eof
Output: Microsoft Windows 7 Enterprise
however if I run IF statement or findstr with !winEdition! var I get no result with IF and "string not found" with findstr also if I echo the var to a txt file I get "牣獯景⁴楗摮睯⁳‷湅整灲楲敳†਍" in the txt file so I think it's encoding problem, but I can't find a way to fix it.
More details: the full code suppose to take the var from the code above, search for the string in txt file and return the next line full code:
#echo OFF
setlocal EnableDelayedExpansion
set "winEdition="
for /f "tokens=2 delims==" %%G in ('wmic os get Caption /value') do (
set winEdition=%%G
)
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"!winEdition!" serials.txt') do (
set /A after=%%a+1
set "numbers=!numbers!!after!: "
)
rem Search for the lines
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" serials.txt ^| findstr /B "%numbers%"') do (
echo %%b
)
endlocal
goto :eof
The second part of the code works and tested with string and with var I want to automate it further. Thank you for help I am also open to alternative ways to get the result!
wmic prints some additional "empty" lines (1), which overwrites your value (watch with echo on)
#echo off
setlocal
set "winEdition="
for /f "tokens=2 delims==" %%G in ('wmic os get Caption /value') do (
if not defined winEdition set winEdition=%%G
)
echo %winEdition%
(1) on screen they appear to be empty, but technically they aren't. They contain a crippeled line break, which causes a lot of headache...
Hi again I found the answer!!! So I just used a different command to find the win version, and edition thanks to #LotPings, it's a bit slower than wmic but it works consistently every time.
Code:
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=4-6" %%a in ('"systeminfo | find /i "OS Name""') do (
set "ver=%%a %%b %%c"
)
set "numbers="
for /F "delims=:" %%a in ('findstr /I /N /C:"!ver!" serials.txt') do (
set /A after=%%a+1
set "numbers=!numbers!!after!: "
)
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" serials.txt ^| findstr /B "%numbers%"') do (
echo %%b
)
if "%ver%" equ "Windows 10 Pro" echo YES
endlocal
goto :eof
Thank you all for help, and suggestions!
ps. the serials.txt is just a normal text file created with notepad encoding UTF-8 and the content is just:
Windows 10 Pro
XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
Windows 7 Pro...
and IF is just another check that it works in original code the problem is not with the second part nor with serials.txt because I couldn't compare the !winEdition! with IF statement.
BTW found the problem with my original solution thx to the one I found above
the problem was wrong token= solution:
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=3-5 delims== " %%A in ('wmic os get Caption /value ^| find "Windows" ') do (
set "winVer=%%A %%B %%C"
)
echo !winVer!
set "numbers="
for /F "delims=:" %%a in ('findstr /I /N /C:"!winVer!" serials.txt') do (
set /A after=%%a+1
set "numbers=!numbers!!after!: "
)
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" serials.txt ^| findstr /B "%numbers%"') do (
echo %%b
)
endlocal
goto :eof

save wmic useraccount where name to variable

How can I save the SID of the current user to variable?
Based off of a similar question, the current code is as follows:
#echo off
for /f %%a in ('wmic useraccount where Name='%username%' get SID') do set "usersid=%%a"
echo %usersid%
exit /b
Is there a way I can save this to the variable %usersid%?
I believe this is an issue with the '' marks surrounding %username%.
#echo off
for /f "usebackq tokens=* delims=" %%a in (`wmic useraccount where Name^='%username%' get SID /format:value`) do (
for /f "tokens=* delims=" %%# in ("%%a") do set "%%#"
)
set sid
On my machine I have no username alias.Here's why the additional FOR is needed
I found an answered question with the code required to do this.
Npocmaka was close to the answer (had I not incorrectly typed my original wmic command).
#echo off
for /f "delims= " %%a in ('"wmic useraccount where name='%UserName%' get sid"') do (
if not "%%a"=="SID" (
set myvar=%%a
goto :loop_end
)
)
:loop_end
echo %myvar%
I have simplified the code provided by 7th Luke.
#echo off
For /f "tokens=2 delims==" %%# in (
'"wmic useraccount where name="%UserName%" get SID /value"') Do (
echo %%#) & Pause > nul

Speed up reading results in batch script

What I am trying to do, is speed up my reading results of batch file.
Am trying to get different values using netsh commands and then present them in my script console but it takes to long.
See below a small part of my script to get the idea. (this is just a small part, I'm actually getting around 50 different values and using more netsh commands)
Does anybody know a way to speed up the process?
.
.
.
netsh interface ipv4 show config %AdapterLAN% >temp
for /f "tokens=3" %%i in ('findstr "IP Address" temp') do set ip=%%i
echo. IP Address : %ip%
for /f "tokens=5 delims=) " %%i in ('findstr "Subnet Prefix" temp') do set mask=%%i
echo. Mask : %mask%
for /f "tokens=3" %%i in ('findstr "Gateway:" temp') do set gateway=%%i
echo. Gateway : %gateway%
for /f "tokens=1,5,6" %%a in ('findstr "DNS" temp') do set dns1=%%a&set dns5=%%b&set dns6=%%c
If "%dns1%"=="Statically" set dns=%dns5%
if "%dns1%"=="DNS" set dns=%dns6%
echo. DNS Server : %dns%
for /f "tokens=3" %%i in ('findstr "Gateway Metric" temp') do set GMetric=%%i
for /f "tokens=2" %%i in ('findstr "InterfaceMetric" temp') do set IMetric=%%i
set /a metricLAN=Gmetric + imetric
echo. Metric : %metricLAN%
for /f "tokens=3" %%i in ('find "DHCP enabled" temp') do set LANDHCP=%%i
If "%dns1%"=="Statically" set xx=Static
if "%dns1%"=="DNS" set xx=DHCP
If /i %LANDHCP%==No set LANDHCP=Static
if /i %LANDHCP%==YES set LANDHCP=DHCP
echo. Obtained IP : %LANDHCP%
echo. Obtained DNS : %xx%
for /f "tokens=3 delims=," %%a in ('getmac /v /fo csv ^| find """%AdapterLAN-without-Q%""" ') do set macLAN=%%a
echo. MAC-Addres : %macLAN%
del temp
.
.
.
netsh wlan show profile >temp
.
Do a similar process of getting values from another netsh command sent them
in the temp file …echo the one I want on the screen ..delete the file etc.
Next approach could be a bit faster (no temporary file(s), updated no multiple findstr):
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "AdapterLAN=wiredEthernet"
set "IMetric="
set "GMetric="
for /F "tokens=1,2* delims=:" %%G in ('
netsh interface ipv4 show config "%AdapterLAN%"^|findstr /N /R "^"
') do (
rem echo G="%%G" H="%%H" I="%%I"
if "%%I"=="" (
rem line 1 skip
rem line 2 = Configuration for interface
rem line 10 = DNS server #2 etc.
) else (
set "hh=%%H"
set "xx=!hh:IP Address=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "ip=%%i"
set "xx=!hh:Subnet Prefix=!"
if not "!hh!"=="!xx!" for /F "tokens=3 delims=) " %%i in ("%%I") do set "mask=%%i"
set "xx=!hh:Default Gateway=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "gateway=%%i"
set "xx=!hh:Gateway Metric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "GMetric=%%i"
set "xx=!hh:InterfaceMetric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "IMetric=%%i"
)
)
echo( IP Address : [%ip%]
echo( Mask : [%mask%]
echo( Gateway : [%gateway%]
set /a metricLAN=Gmetric + IMetric
echo( Metric : [%metricLAN%]
ENDLOCAL
goto :eof
Output:
==>D:\bat\SO\31356115.bat
IP Address : [192.168.1.100]
Mask : [255.255.255.0]
Gateway : [192.168.1.1]
Metric : [20]
==>
Edit
Here is another approach: unlike netsh, parsing the wmic command output seems to be a bit easier when used get verb together with /value switch as it's well defined and well structured. You could find here all the info as from netsh: next code snippet should read and make public a huge range of information about all enabled NIC adapter(s) in a defined local or remote computer:
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "NetCount=0"
set "compName=%computername%" :: local or remote computer name
set "compIDXs="
for /F "tokens=2 delims==" %%N in ('
wmic /node:"%compName%" NIC where "NetEnabled=TRUE" get InterfaceIndex /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%n in ("%%N") do (
for /F "tokens=*" %%G in ('
wmic /node:"%compName%" NIC where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%g in ("%%G") do set "_%%n%%g"
for /F "tokens=*" %%I in ('
wmic /node:"%compName%" NICCONFIG where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%i in ("%%I") do set "_%%n_%%i"
set /A "NetCount+=1"
set "compIDXs=!compIDXs! "%%n""
)
set _
rem sample of it:
echo compName=%compName% NetCount=%NetCount% compIDXs=%compIDXs%
for %%x in (%compIDXs%) do (
echo enabled InterfaceIndex=%%~x NetConnectionID=!_%%~xNetConnectionID!
for /F "tokens=1,2 delims={}," %%i in ("!_%%~x_IPAddress!") do echo ipv4=%%~i ipv6=%%~j
)
Read Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem to see why any wmic command output is parsed via a couple of nested for loops.

Resources