I'm just trying to figure out why this block of code is giving me an unexpected variable..
#echo off
FOR /F "Skip=1Delims=" %%a IN (
'"wmic nic where (MacAddress="00:00:00:00:00:00") GET NetConnectionId"'
) DO FOR /F "Tokens=1" %%b IN ("%%a") DO SET nicName=%%b
echo Adding all IP ranges for X in 10.10.X.118 on adapter %nicName%
netsh interface ipv4 set address name=%nicName% static 192.168.1.118 255.255.255.0 192.168.1.1
FOR /L %A IN (0,1,255) DO netsh interface ipv4 add address %nicName% 10.10.%A%.118 255.255.255.0 10.10.%A%.1
netsh interface ipv4 add dnsserver %nicName% address=208.67.222.222 index=1
netsh interface ipv4 add dnsserver %nicName% address=208.67.220.220 index=2
exit
I think it has something to do with the first FOR loop interfering with the second, but I'm very new to using this type of search in a batch file.
The output I get is:
Adding all IP ranges for X in 10.10.X.118 on adapter Local Area Connection
nicNameAA.1 was unexpected at this time.
Thanks in advance!
FOR /L %A IN (0,1,255) DO netsh interface ipv4 add address %nicName% 10.10.%A%.118 255.255.255.0 10.10.%A%.1
As in the previous two for commands, the metavariable A must be specified as %%A.
As in the previous two for commands, the value substituted into the string must be specified as %%A - %A% is the value of an unspecified environment variable A.
The result of your code is this
FOR /L
%A IN (0,1,255) DO netsh interface ipv4 add address %
nicName
% 10.10.%
A
%.118 255.255.255.0 10.10.%
A
%.1
each %...% is interpreted as a non-existent environment variable, hence it's replaced by nothing
So the code appears to be
FOR /L nicNameAA%.1
So cmd sees nicNameAA%.1 where it's expecting %%? and complains.
BTW- since nicname's value contains spaces, you probably need "%nicname%" so that cmd will see one string. Can't vouch for it since I rarely use netsh...just be prepared.
As answered by #Magoo,
The resulting full code is as follows(In case anyone needs to do this in the future)
#echo off
FOR /F "Skip=1Delims=" %%a IN (
'"wmic nic where (MacAddress="00:00:00:00:00:00") GET NetConnectionId"'
) DO FOR /F "Tokens=1" %%b IN ("%%a") DO SET nicName=%%b
echo Adding all IP ranges for X in 10.10.X.118 on adapter "%nicName%"
netsh interface ipv4 set address name="%nicName%" static 192.168.1.118 255.255.255.0 192.168.1.1
FOR /L %%c IN (0,1,255) DO netsh interface ipv4 add address "%nicName%" 10.10.%%c.118 255.255.255.0 10.10.%%c.1
netsh interface ipv4 add dnsserver "%nicName%" address=208.67.222.222 index=1
netsh interface ipv4 add dnsserver "%nicName%" address=208.67.220.220 index=2
exit
Thanks again #Magoo!
Related
I need to configure multiple machines to automatically set their IP addresses from dynamic to static.
I have a batch file to set the IP address to static like this :
netsh interface ipv4 set address name="Ethernet" source=static ^
addr=192.168.200.200 mask=255.255.255.0 gateway=192.168.200.1
pause
exit /b 0
But I have to manually write the IP address, mask and gateway in the .bat file.
How can I retrieve the current IP address of the machine (as well as the current mask and gateway) and automatically set them to static, without modifying the .bat file every time?
First you need to retrieve the current ip address.
Probably this is easy, if you use always the same name for the interface.
setlocal
set "interface_name=Ethernet"
REM *** Convert the output lines from netsh into variables
for /F "tokens=1,* delims=:" %%a in ('"netsh interface ipv4 show addresses name="%interface_name%""') do (
REM *** Get rid of leaing spaces and TABS
for /F %%a in ("%%a") DO for /F %%b in ("%%b") DO (
set "__%%a=%%b"
)
)
REM *** Show all variables beginning with "__"
set __
if "%__DHCP%" NEQ "Yes" goto :no_dhcp
:check_ip_prefix
set "ip_addr=%__IP-address%"
if "%ip_addr:192.168.=%" EQU "%ip_addr%" goto :wrong_ip_prefix
netsh interface ipv4 set address name="%interface_name%" source=static ^
addr=%ip_addr% mask=255.255.255.0 gateway=%__default_gateway%
Probably you need to change some variable names, because the names are language dependent (and I'm using a German version).
I need to save a filtered multi-line output into a single batch variable but so far without success.
I can't use Powershell in this stripped down version of POS Terminal and the use of a temporary file is impracticable because the OS runs from a ultra slow SD card.
With this, I need the following output in a single variable:
C:\Users\medUser> route print | findstr "127 10 192"
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
In this case, I need to capture this 5 lines (but in reality will be more than 15) as displayed into a single variable.
Is it possible without resorting to external tools?
I'm aware of some approaches like this, this, or this, but I'm unable to make it work.
I've tried the solution bellow, but unfortunately it only stores the last line.
FOR /F "tokens=* USEBACKQ" %F IN (`route print ^| findstr "127\."`) DO (SET var=%F)
ECHO %var%
Note: The end goal is to have a big string that I can parse multiple times through findstr without heaving to run the same command over and over again.
If not feasible, I'll also accept a solution where a variable has a counter, like var1 for the first line, var2 for the second, etc. Thanks!
Inefficient sample code in use:
:loop
SET _ror2="NOK"
route print | findstr "10\.16\.0\.0.*255\.255\.0\.0.*10\.147\.1\.3" && route print | findstr "192\.168\.47\.0.*255\.255\.255\.0.*192\.168\.46\.3" && route print | findstr "10\.16\.0\.0.*255\.255\.0\.0.*10\.147\.1\.3" && route print | findstr "xxxxx" && route print | findstr "repeat with 15 more conditions to test" && SET _ror2=ok
if "%_ror2%" == "ok" (
timeout 20 >NUL
goto loop
)
ECHO One of our 15 comparisons above wasn't found, hence re-apply routes
route change 10.16.0.0 mask 255.255.255.0 10.147.1.3 metric 10
route change 192.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
route change xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Your idea with numbered variables is not that bad:
#echo off
setlocal enabledelayedexpansion
REM get the output into numbered variables:
set i=1
for /f "delims=" %%a in ('route print^|findstr "127 10 192"') do (
set /a i+=1
set "_myvar_!i!=%%a"
)
ECHO search within those variables:
set _myvar_ |find "127"
ECHO or:
(for /f "tokens=1* delims==" %%a in ('set _myvar_') do #echo %%b) |find "127"
Note: this doesn't keep the order when i>10 (probably not a problem for you)
My goal is to have a batch script that whenever launched if the machine is connected to my home wifi (SSID = The Sanctum Sanctorum - 5GHz) will launch Kodi from one folder ("C:\Program Files (x86)\Kodi at Home") but otherwise will launch Kodi from another ("C:\Program Files (x86)\Kodi").
Any help is much appreciated and thanks for your time I have attached updates with my code progress!
Edit #3 - Thanks to #treintje
Code Attempt #3
#echo off
set "ssid=The Sanctum Sanctorum - 5GHz"
netsh wlan show interfaces | findstr /r /c:"^ *SSID *: %ssid%$" 1>nul
if %errorlevel% equ 0 (
set "kodi=Kodi at Home\Kodi.exe" "-p"
) else (
set "kodi=Kodi\Kodi.exe"
)
"%programfiles(x86)%\%kodi%"
Now it seems even when connected to the specified network it always launches the "kodi=Kodi\Kodi.exe" version. I bet it's just a tiny syntax error I don't know to see as I'm sure treintje is right this is the way to do it!
Assuming your machine only has a single wireless network interface card installed, you could try something like this:
#echo off
set "ssid=The Sanctum Sanctorum"
netsh wlan show interfaces | findstr /r /c:"^ *SSID *: %ssid%$" 1>nul
if %errorlevel% equ 0 (
set "kodi=Kodi at Home\Kodi.exe" "-p"
) else (
set "kodi=Kodi\Kodi.exe"
)
"%programfiles(x86)%\%kodi%"
The netsh wlan show interfaces command lists information about all wireless network interfaces including the SSID of any wireless network that they might be connected with. If the findstr command finds the SSID specified by the ssid variable, the errorlevel is set to zero.
If the target application cannot handle command-line switches that are encapsulated within quotes, you could set the kodi variable and call the application as such:
set "kodi=Kodi at Home\Kodi.exe" -p"
"%programfiles(x86)%\%kodi%
Currently, I'm using this:
netsh wlan add filter permission=block ssid="WLAN1" networktype=infrastructure
to hide specific WLAN SSIDs from showing up in the systray. Since there's usually more than one of them available, I've decided to put them all in a *.bat file, like so
#echo off
netsh wlan add filter permission=block ssid="WLAN1" networktype=infrastructure
netsh wlan add filter permission=block ssid="WLAN2" networktype=infrastructure
netsh wlan add filter permission=block ssid="AnotherWLAN" networktype=infrastructure
etc
and to block them all with a single click.
However, this keeps them hidden only while the blocked WLANs have those predefined SSIDs. If they change their SSID, they show up again, and I have to change my file. This isn't a problem when there's a few of them, but there's usually more than 20 showing up.
WHAT I WOULD LIKE TO DO
Is there a way for me to use netsh and, say, an if, for, or while loop, to block everything BUT the one SSID I choose? For example, in (broken) pseudo code
SET myWLAN = Home // e.g. home WLAN SSID = Home
if (! SSID == myWLAN) {
loop through the available SSID, and block them via netsh
}
Or, would you recommend that I just go with:
netsh wlan add filter permission=denyall networktype=infrastructure
and then create a special whitelist filter for my home WLAN
netsh wlan delete filter permission=block ssid="myWLAN SSID" networktype=infrastructure
I'm pretty much new to all of this, so any help would be more than welcome.
#ECHO OFF
SETLOCAL
SET "allow=WLAN1"
FOR /f "tokens=3*" %%a IN ('netsh wlan show all^|findstr /i /b /L /c:"SSID "') DO (
IF "%%b" neq "%allow%" ECHO(netsh wlan add filter permission=block ssid="%%b" networktype=infrastructure
)
GOTO :EOF
This batch searches the netsh wlan show all output for lines /b beginning /i regardless of case /L the literal /c: this constant string.
The tokenising is performed using tokens 3 and * (the remainder of the line) using default delimiters hich include space, so a typical SSID line filtered would be
SSID 5 : WLAN2
Token 1 is SSID, 2 is 5, 3 is : and 4 is WLAN2
Since the first nominated token is 3, that token is assigned to %%a and the next token is assigned to %%b.
Then if the token now in %%b does not match the allowed string, block it (well, the command is simply echoed for debugging - change the echo(netsh to netsh to activate.
If you were to use
set "allow=%~1" instead of `...WLAN1` then you could run<br>
thisbatch WLAN4
to block all except WLAN4.
I've written a Windows script to change NIC interface metrics, and need to condense it to two commands, because of the manner in which it is executed. To render a long story short, I support an application (BladeLogic Server Automation [BSA]) that uses remote agents to call system commands.
I've hypothesized that when BSA runs the script, each command executes in a separate Command Prompt environment, so the environment variables used to store the route strings aren't persistent.
for /f "delims=" %a in ('netsh interface ipv4 dump ^| find "nexthop=1.1.1.1"') do #set VAR1=%a
netsh interface ipv4 set %VAR1:~4% metric=200
for /f "delims=" %a in ('netsh interface ipv4 dump ^| find "nexthop=2.2.2.1"') do #set VAR2=%a
netsh interface ipv4 set %VAR2:~4% metric=500
I've condensed the script as such and am testing it at the Command Prompt.
for /f "delims=" %a in ('netsh interface ipv4 dump ^| find "nexthop=1.1.1.1"') do #set VAR1=%a && netsh interface ipv4 set %VAR1:~4% metric=200
for /f "delims=" %a in ('netsh interface ipv4 dump ^| find "nexthop=2.2.2.1"') do #set VAR2=%a && netsh interface ipv4 set %VAR2:~4% metric=500
Unfortunately, it doesn't seem to recognize the proper syntax for the second command:
The following command was not found: interface ipv4 set %VAR1:~4% metric=200
Is there another way I could append the second command, so it's interpreted as being syntactically correct? I'm open to suggestions!
Matt,
You're correct that BladeLogic fires up separate shells for each statement, however, depending on what you're trying to achieve, it may be possible to "persuade" it to run a complete script remotely on your target.
If you're still facing this issue, please respond with a little more info about what you're trying to achieve and which approaches you've tried, and we can look a the alternatives.
-John.