Page 1 of 1

netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 06:00
by atfon
Hello folks. I'm looking to see if there is a method to capture multiple variables with one for loop of the netsh command. I know that I can capture specific bits of data using find or findstr in a for /f loop like this:

Code: Select all

for /f  "tokens=2 delims=: " %%g in ('%__APPDIR__%netsh.exe interface ipv4 show interface "Ethernet" ^| %__APPDIR__%findstr.exe /i "IfLuid"') do set "ifLuid=%%g"
Is there a way to capture IfLuid, IFIndex, State and/or any other points of interest in a single for loop rather than creating multiple for loops to capture each bit of data? I'm looking to do this without resorting to exporting to a file.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 08:04
by Squashman
Use the TOKENS to your advantage. You are specifically not asking for TOKEN 1. If you asked for both TOKENS, then all you would need to do for your set command is:

Code: Select all

set "%%g=%%h"
The FINDSTR command can be modified for multiple search parameters a couple of different way.

Code: Select all

findstr /C:"IfLuid" /C:"IFIndex" /C:"State"
The overall code gets much trickier if you want to capture any of these metrics because there are spaces on the variable name and the variable value.

Code: Select all

Link MTU                           : 1500 bytes
Reachable Time                     : 21500 ms
Base Reachable Time                : 30000 ms
Retransmission Interval            : 1000 ms

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 08:20
by atfon
Squashman wrote:
05 Nov 2021 08:04
Use the TOKENS to your advantage. You are specifically not asking for TOKEN 1. If you asked for both TOKENS, then all you would need to do for your set command is:

Code: Select all

set "%%g=%%h"
The FINDSTR command can be modified for multiple search parameters a couple of different way.

Code: Select all

findstr /C:"IfLuid" /C:"IFIndex" /C:"State"
The overall code gets much trickier if you want to capture any of these metrics because there are spaces on the variable name and the variable value.

Code: Select all

Link MTU                           : 1500 bytes
Reachable Time                     : 21500 ms
Base Reachable Time                : 30000 ms
Retransmission Interval            : 1000 ms
Thanks @Squashman. I see what you mean about using findstr to locate multiple parameters, but how can I then use that to set each individual parameter as a variable? For instance, this can echo each of those values, but I want to then save them as variables:

Code: Select all

for /f  "tokens=2 delims=: " %%g in ('netsh interface ipv4 show interface "Ethernet" ^| findstr /r /i /C:"IfLuid" /C:"IFIndex" /C:"State\>"') do echo %%g
Also, what about those use cases where there are spaces in the name and value? I initially asked about netsh, but I'm looking to apply any learned technique to the output of other commands with multi-line output like fsutil, etc.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 08:37
by Squashman
atfon wrote:
05 Nov 2021 08:20
Thanks @Squashman. I see what you mean about using findstr to locate multiple parameters, but how can I then use that to set each individual parameter as a variable?
I literally addressed that in my first comment and code I provided in my first post.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 08:50
by atfon
Squashman wrote:
05 Nov 2021 08:37
I literally addressed that in my first comment and code I provided in my first post.
Thank you for your assistance, @Squashman. I apologize for being slow about this, but I guess I'm missing something here. In my example, I thought I was asking for token 2 when I used tokens=2? I'm not sure I understand how set "%%g=%%h" allows me to set the individual values as separate variables. If my question is too dense for this forum, please ignore.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 09:21
by Squashman
atfon wrote:
05 Nov 2021 08:50
Squashman wrote:
05 Nov 2021 08:37
I literally addressed that in my first comment and code I provided in my first post.
Thank you for your assistance, @Squashman. I apologize for being slow about this, but I guess I'm missing something here. In my example, I thought I was asking for token 2 when I used tokens=2? I'm not sure I understand how set "%%g=%%h" allows me to set the individual values as separate variables. If my question is too dense for this forum, please ignore.
In my first post I said, "If you asked for both TOKENS......."

Code: Select all

for /f  "tokens=1,2 delims=: " %%g in ('netsh interface ipv4 show interface "Ethernet" ^| findstr /BIC:"IfLuid " /BIC:"IFIndex " /BIC:"State "') do set "%%g=%%h"

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 09:33
by atfon
Squashman wrote:
05 Nov 2021 09:21
atfon wrote:
05 Nov 2021 08:50
Squashman wrote:
05 Nov 2021 08:37
I literally addressed that in my first comment and code I provided in my first post.
Thank you for your assistance, @Squashman. I apologize for being slow about this, but I guess I'm missing something here. In my example, I thought I was asking for token 2 when I used tokens=2? I'm not sure I understand how set "%%g=%%h" allows me to set the individual values as separate variables. If my question is too dense for this forum, please ignore.
In my first post I said, "If you asked for both TOKENS......."

Code: Select all

for /f  "tokens=1,2 delims=: " %%g in ('netsh interface ipv4 show interface "Ethernet" ^| findstr /BIC:"IfLuid " /BIC:"IFIndex " /BIC:"State "') do set "%%g=%%h"
Let me take an example and see if this makes any sense. Let's take this line of code:

Code: Select all

for /f  "tokens=1,2 delims=: " %%g in ('netsh interface ipv4 show interface "Ethernet" ^| findstr /BIC:"IfLuid " /BIC:"IFIndex " /BIC:"State "') do @echo %%h
Gives me this output:

ethernet_123456
16
connected

Now lets say I want to use any of these values later on. How does set "%%g=%%h" allow me to then use just the ifIndex at a later point as in?:

Code: Select all

echo ifIndex: %ifIndex% ^| ifLuid: %ifLuid%
Which should output as:

ifIndex: 16 | ifLuid: ethernet_123456

I apologize again if this is obvious and I'm just not getting it.

Edit: Oh, I see! Setting %%g=%%h means you are setting it to read multiple variables. Now I just need to learn how to work with the output. Thanks again.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 10:05
by Squashman
Watch the darn code execute.

Code: Select all

C:\Users\Squashman\Desktop>afton.bat

C:\Users\Squashman\Desktop>for /F "tokens=1,2 delims=: " %g in ('netsh interface ipv4 show interface "Ethernet" | findstr /BIC:"IfLuid " /BIC:"IFIndex " /BIC:"State "') do set "%g=%h"

C:\Users\Squashman\Desktop>set "IfLuid=ethernet_32770"

C:\Users\Squashman\Desktop>set "IfIndex=18"

C:\Users\Squashman\Desktop>set "State=disconnected"

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 10:12
by atfon
Squashman wrote:
05 Nov 2021 10:05
Watch the darn code execute.

Code: Select all

C:\Users\Squashman\Desktop>afton.bat

C:\Users\Squashman\Desktop>for /F "tokens=1,2 delims=: " %g in ('netsh interface ipv4 show interface "Ethernet" | findstr /BIC:"IfLuid " /BIC:"IFIndex " /BIC:"State "') do set "%g=%h"

C:\Users\Squashman\Desktop>set "IfLuid=ethernet_32770"

C:\Users\Squashman\Desktop>set "IfIndex=18"

C:\Users\Squashman\Desktop>set "State=disconnected"
Edit (for clarity): Now I see how it is setting the values from token 2 to the name of token 1. However, I can see how this could be potentially problematic when token 1 has more than one word, as you mentioned earlier or if token 1 is the same name as a value I had set previously in the script.

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 10:54
by Aacini
For example:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for /F "tokens=1,2 delims=:" %%g in ('netsh interface ipv4 show interfaces "Ethernet 2"') do (
   set "var="
   for %%v in (%%g) do set "var=!var!_%%v"
   set "value=%%h"
   set "netsh[!var:~1!]=!value:~1!"
)

set netsh
Output:

Code: Select all

netsh[Anunciar_ruta_predeterminada]=disabled
netsh[Anuncios]=disabled
netsh[Capacidad_ECN]=application
netsh[Coexistencia_de_DHCP_y_direcciones_IP_estáticas]=disabled
netsh[Configuración_de_dirección_administrada]=enabled
netsh[Configuración_de_DNS_basada_en_RA_(RFC_6106)]=disabled
netsh[Detección_de_enrutador]=dhcp
netsh[Detección_de_inaccesibilidad_de_vecinos]=enabled
netsh[Detección_de_vecinos]=enabled
netsh[Duración_de_enrutador_anunciada]=1800 segundos
netsh[Envíos_no_seguros_del_host]=disabled
netsh[Estado]=disconnected
netsh[Forzar_patrones_de_reactivación_de_ARPND]=disabled
netsh[Id._de_sitio]=1
netsh[IfIndex]=24
netsh[IfLuid]=ethernet_32772
netsh[Intervalo_de_retransmisión]=1000 ms
netsh[Longitud_de_prefijo_de_sitio]=64
netsh[Límite_de_saltos_actual]=0
netsh[MTU_del_vínculo]=1500 bytes
netsh[Métrica]=5
netsh[Omitir_rutas_predeterminadas]=disabled
netsh[Otra_configuración_con_estado]=enabled
netsh[Parámetros_de_la_interfaz_Ethernet_2]=~1
netsh[Patrones_de_reactivación_de_MAC_dirigida]=disabled
netsh[Recepciones_no_seguras_del_host]=disabled
netsh[Reenvío]=disabled
netsh[Tiempo_de_accesibilidad]=19000 ms
netsh[Tiempo_de_accesibilidad_base]=30000 ms
netsh[Transmisiones_DAD]=3
netsh[Usar_métrica_automática]=enabled
I defined elements of netsh array instead of individual variables in order to group them, but you may define the variables as you wish...

You may find several one-word variables this way:

Code: Select all

findstr /BI  "IfLuid IFIndex State"
You need to use the /C:"one two" form only when you want a two-or-more words variable.

Antonio

Re: netsh: capture multiple variables in one for loop

Posted: 05 Nov 2021 11:18
by atfon
Aacini wrote:
05 Nov 2021 10:54
I defined elements of netsh array instead of individual variables in order to group them, but you may define the variables as you wish...

You may find several one-word variables this way:

Code: Select all

findstr /BI  "IfLuid IFIndex State"
You need to use the /C:"one two" form only when you want a two-or-more words variable.

Antonio
Thanks, Antonio. I like the array technique you are using here.

Re: netsh: capture multiple variables in one for loop

Posted: 01 Dec 2021 07:02
by atfon
Hello Antonio (Aacini). Thanks again for this array technique. It works great and I have been adapting it to other commands, such as WMIC. However, I have run into a snag that I haven't been able to sort out. What if the delimiter you are using is also in the value? I will provide a small example:

Code: Select all

@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2 delims==" %%g in ('%__APPDIR__%wbem\WMIC.exe computersystem get /value') do  (
   set "var="
   for %%v in (%%g) do set "var=!var!_%%v"
   set "value=%%h"
   set "_wmicCS[!var!]=!value!"  
)
%__APPDIR__%wbem\WMIC.exe computersystem get OEMStringArray
echo %_wmicCS[_OEMStringArray]%
pause
For me, the results appear like this:

Code: Select all

OEMStringArray                                                                                                          
{"FBYTE#3X476J6S6b7B7J7M7Q7W7m7saBapaqauawbUbhdUdpdqfPk8.R4;", "BUILDID#19WWR4BT601#SABA#DABA;", "EDK2_1", "Buff=2", "HRDWFEATS=VTX:1;VTD:1;SGX:0;NONHPBATDET:1;", "MEFWRec"}

{"FBYTE#3X476J6S6b7B7J7M7Q7W7m7saBapaqauawbUbhdUdpdqfPk8.R4;","BUILDID#19WWR4BT601#SABA#DABA;","EDK2_1","Buff
As you can see, the equals sign (=) appears in the value of the OEMStringArray. If I use the equals sign as a delimiter, the resulting value for this instance is missing data. Is there a workaround for these types of situations?

Re: netsh: capture multiple variables in one for loop

Posted: 01 Dec 2021 08:47
by Squashman
Change the tokens to tokens=1,*

Re: netsh: capture multiple variables in one for loop

Posted: 01 Dec 2021 09:13
by atfon
Squashman wrote:
01 Dec 2021 08:47
Change the tokens to tokens=1,*
Perfect. Thank you.