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.
Related
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
I am trying to store my local ip into a system variable but I am struggling with that batch file. I am already able to parse my IP and extract the right substring. However declaring the variable and passing it to SETX seems to be harder than I thought....
Any help would be very much appreciated. :)
#echo off
setlocal enabledelayedexpansion
::just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
set adapterfound=false
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do (
set "item=%%f"
if /i "!item!"=="!adapter!" (
set adapterfound=true
) else if not "!item!"=="!item:IPv4-Address=!" if "!adapterfound!"=="true" (
echo %%g | cut -d"(" -f 1 | tr -d "[:space:]" <-- this echos my ip correctly
set ipadress=%%g | cut -d"(" -f 1 | tr -d "[:space:]"
echo %ipadress% <-- this echos empty string
setx MY_IP %ipadress% <-- this doesnt work as well
set adapterfound=false
)
)
Improved script (might be locale-dependent):
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
::just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
set "adapterfound=false"
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do (
set "item=%%f"
if not "!item!"=="!item:%adapter%=!" (
set "adapterfound=true"
echo %adapter%
) else if not "!item!"=="!item:IPv4 Address=!" if "!adapterfound!"=="true" (
rem ↑↑↑↑↑↑↑↑↑↑↑↑ might be locale-dependent
for /F "delims=( " %%G in ("%%g") do set "ipadress=%%G"
echo !ipadress!
rem setx MY_IP !ipadress!
set "adapterfound=false"
)
)
echo %ipadress%
Another approach:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
:: just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
echo Network Connection Test
:: get adapter index
set "_where=where "NetConnectionID = '%adapter%'""
for /F "tokens=1,* delims==" %%G in ('
wmic path Win32_NetworkAdapter %_where% get InterfaceIndex /value ^| findstr "="
') do for /F %%g in ("%%H") do set "_ii=%%~g"
:: get adapter's IP addresses
set "_where=where "InterfaceIndex = '%_ii%'""
for /F "tokens=1,* delims==" %%G in ('
wmic path Win32_NetworkAdapterConfiguration %_where% get IPAddress /value ^| findstr "="
') do for /F "tokens=1,2 delims={,}" %%g in ("%%H") do (
set "_IPv4=%%~g"
set "_IPv6=%%~h"
)
set _ip
Here the for loops are
%%G to retrieve the desired value;
%%g to remove the ending carriage return in the value returned: wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).
See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem
My Script (a.bat):
SETLOCAL ENABLEDELAYEDEXPANSION
if "%1"=="on" (
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (set lanst=%%a)
set lanst=%lanst: =%
echo Local Area Connection: %lanst%
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (set curwifi=%%b)
set curwifi=%curwifi: =%
echo Current Wifi: %curwifi%
)
When I run this script in commandline, seems the set dosen't work in for + if:
But when I remove if-statement, the script is:
SETLOCAL ENABLEDELAYEDEXPANSION
echo %1
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (set lanst=%%a)
set lanst=%lanst: =%
echo Local Area Connection: %lanst%
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (set curwifi=%%b)
set curwifi=%curwifi: =%
echo Current Wifi: %curwifi%
the result shows:
According the output, I found, in the situation of if+for, seems the statement in do() will not be executed.
Why's that, and how to fix?
try with:
SETLOCAL ENABLEDELAYEDEXPANSION
if "%1"=="on" (
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (
set lanst=%%a
)
set lanst=!lanst: =!
echo Local Area Connection: !lanst!
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (
set curwifi=%%b
)
set curwifi=!curwifi: =!
echo Current Wifi: !curwifi!
)
here's more info about the delayed expansion
I have a program to ping computers, check there registry, and tell me the results.
I am now trying to script it so that I don't have to know the ip address just the host name of the computer.
I found a script to give me the ip off of a hostname
for /f "tokens=1,2 delims=[]" %%a in ('ping -4 %%a ^| find "Pinging"') do set ip=%%c >nul
I have tried to simply insert this into a biger loop that uses a file to give it the host names.
for /f %%A in (%1) do (
for /f "tokens=1,2 delims=[]" %%a in ('ping -4 %%a ^| find "Pinging"') do (
set host=%%a
set ip=%%c
echo "."
echo %ip% %host%
pause
) >>%2
)
I have also tried it like this,
for /f %%a in (%1) do (
set /p hostname=%%a
for /f "tokens=1,2 delims=[]" %%b in ('ping -4 %%a ^| find "Pinging"') do set ip=%%c >nul
echo %ipaddress% %hostname%
)
Please any help on this would be greatly appreciated.
Thank you.
AFTER MUTCH HEAD BANGING
#echo off
SETLOCAL EnableDelayedExpansion
for /f %%A in (%1) do (
for /f "tokens=1,2 delims=[]" %%a in ('ping /4 /n 1 %%A ^| findstr "Pinging"') do echo "%%A %%b"
)
What I'm trying to do is have a batch script return the uninstall link for a program. So basically I want something like this:
Select UninstallString from HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall where DisplayName='Sublime Text 1.0"
I'm using
reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S^|find " DisplayName"
to initially get a list of programs, which then get put in a menu, then I select the program to uninstall and it's supposed to go to that program's registry in HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall and get it's UninstallString value
Try this:
#echo off&setlocal enabledelayedexpansion
set "regroot=HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
set "file=%~dpn0.txt"
set /a fcount=0
for /f "delims==" %%i in ('set $ 2^>nul') do set "%%i="
if exist "%file%" (
for /f "usebackqtokens=1*delims=|" %%i in ("%file%") do (
set /a fcount+=1
set "$d%%j=%%j"
set "$u%%j=%%i"
)
goto:menu
)
echo(building "%file%", please wait
for /f "delims=" %%i in ('reg query "%regroot%"') do (
set "DN="& set "US="
for /f "tokens=2*" %%j in ('reg query "%regroot%\%%~ni" /v DisplayName 2^>nul^|find /i "DisplayName"') do set "DN=%%~k"
for /f "tokens=2*" %%j in ('reg query "%regroot%\%%~ni" /v UninstallString 2^>nul^|find /i "UninstallString"') do set "US=%%~k"
if not "!DN!"=="" if not "!US!"=="" if not defined $d!DN! (
>>"%file%" echo(!US!^|!DN!
set /a fcount+=1
set "$d!DN!=!DN!"
set "$u!DN!=!US!"
<nul set/p"=."
)
)
echo(
:menu
echo(%fcount% programs with uninstall strings found.
:loop
set /a pcount=0
set "program="
set /p "program=type a program name (q=quit): "
if not defined program goto:loop
if "%program%"=="q" goto:eof
echo(
for /f "tokens=2delims==" %%i in ('set $d ^|findstr !program! 2^>nul') do (
echo(%%i
echo(!$u%%i!
echo(
set /a pcount+=1
)
if %pcount% equ 0 (echo(!program! not found.) else echo(%pcount% program(s^) found.
goto:loop
You can use some of findstr's REGEX capabilities (eg. /i for case insensitive search). Please note: to search for all programs starting with "M" you can use "^$dM" or /b $dM. Searchable strings have always a leading $d.
Try this "two-liner":
for /f "tokens=7 delims=\" %%a in ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S /F "MySoftware" ^| find "{"') do set ProgramUninstallRegKey=%%a
for /f "skip=1 tokens=3*" %%a in ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\%ProgramUninstallRegKey% /V "UninstallString"') do set ProgramUninstallString=%%a %%b