windowsfor-loopbatch-filetext-parsingnslookup

For loop is only outputting one nslookup result, when there are multiple


I'm using nslookup.exe in a batch script, to print out all of the available IPv4 Adresses for an entered domain. But it is only printing out one of them, even if there are multiple.

I think I'm incorrectly parsing the results with my for loop, but I can't seem to figure out how to fix it.

For example, if I enter amazon.com or microsoft.com as the domain name, then my output is like:

Domain Name: amazon.com
IPv4 Address: 205.251.242.103
Domain Name: microsoft.com
IPv4 Address: 20.112.250.133

But if I do a nslookup directly in cmd.exe, it prints out all of the addresses available, both IPv4 & IPv6:

C:\Users>nslookup amazon.com
Server:  xxxxxxxxx
Address:  xxx.xx.xxx.xx

Non-authoritative answer:
Name:    amazon.com
Addresses:  54.239.28.85
          52.94.236.248
          205.251.242.103


C:\Users>nslookup microsoft.com
Server:  xxxxxxxxx
Address:  xxx.xx.xxx.xx

Non-authoritative answer:
Name:    microsoft.com
Addresses:  2603:1030:c02:8::14
          2603:1020:201:10::10f
          2603:1010:3:3::5b
          2603:1030:b:3::152
          2603:1030:20e:3::23c
          20.231.239.246
          20.76.201.171
          20.70.246.20
          20.236.44.162
          20.112.250.133

I want all of the available IPv4 Addresses only for the entered domain.

for /f "tokens=2" %%b in ('nslookup -type=A !domain_name! 2^>nul ^| findstr /C:"Address"') do (
    if not "%%b"=="" (  
        echo Domain Name: !domain_name!
        echo IPv4 Address: %%b
    ) else (
        echo I encountered an error while looking up the domain name, or no Address records were found.
    )
)

I tried removing the findstr, and added delims, but it didn't work because it was printing an UnKnown as an IPv4 Address before printing the real IPv4 Address.

My for loop:

for /f "tokens=2 delims=:" %%b in ('nslookup -type=A !domain_name! 2^>nul') do (
  if not "%%b"=="" (
    echo Domain Name: !domain_name!
    echo IPv4 Address: %%b
  )
)

if defined b (
  rem something was found
) else (
  echo No IPv4 addresses found
)

See the output:

Domain Name: microsoft.com
IPv4 Address:  UnKnown
Domain Name: microsoft.com
IPv4 Address:  20.231.239.246

I also used both delims, and findstr, creating another variable,ipv4_addresses, but for some reason, this also didn't work.

set "ipv4_addresses="
for /f "tokens=2 delims=: " %%b in ('nslookup -type=A !domain_name! 2^>nul ^| findstr /R /C:"Address"') do (
  echo Domain Name: !domain_name!
  echo IPv4 Address: %%b
  set "ipv4_addresses=!ipv4_addresses! %%b"
)

rem If no IPv4 addresses are found, display a message
if not defined ipv4_addresses echo No IPv4 addresses were found for !domain_name!

Output was same, with just one IPv4:

Domain Name: microsoft.com
IPv4 Address: 20.236.44.162

This script is fine for a domain like youtube.com, or google.com, with only one IPv4 Address, but not for a domain with multiple.


Solution

  • That's actually a single line. Filter for IPv4 address patterns and take care of the additional first token in the first line:

    for /f "tokens=1*" %%a in ('NSLOOKUP amazon.com 2^>nul ^|more +3 ^|findstr /Rc:" [1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*"') do if not "%%b" == "" (echo %%b) else echo %%a
    

    or more readable (and adapted to your additional requirement in the comments):

    @echo off
    setlocal enabledelayedexpansion
    set "domain_name=amazon.com"
    echo Domain Name: %domain_name%
    for /f "tokens=1*" %%a in (
      'NSLOOKUP %domain_name% 2^>nul ^|more +3 ^|findstr /Rc:" [1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*"
     ') do (
        if not "%%b" == "" (
          echo IPv4 Address: %%b
        ) else ( 
          echo IPv4 Address: %%a
        )
    )
    

    Output:

    Domain Name: amazon.com
    IPv4 Address: 54.239.28.85
    IPv4 Address: 52.94.236.248
    IPv4 Address: 205.251.242.103