Get a hostname and IP from a list of file names

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Get a hostname and IP from a list of file names

#1 Post by autoamerican » 04 Jul 2012 12:06

I'm working on a script right now and am stuck. What I've got is a script that reads a list of filenames in a directory and converts those filenames to hostnames (each file is named HOSTNAME.log) and dumps these to a log, then runs another command on that log to get the IP addresses for the host names and puts this in a second log, and then finally goes through that second log to strip out addresses in a certain subnet and give me the final output in a third log.

So far, this part all works - I get a clean list of IPs. What I would LIKE it to do is give me a final list of not just the IP addresses, but hostnames as well (preferably something formatted like 255.255.255.1 HOSTNAME.domain.net), and I'd like it to create only one single file, not two interim files and a final clean output.

I've been modifying my script to try and add the hostname part, but so far haven't had any luck. What am I missing? This is the error I keep getting:

L:\>if exist c:\ipaddresses.log del c:\ipaddresses.log
i` was unexpected at this time.

L:\> for /f "skip=3 delims=: tokens=2 usebackq" i`) do @echo j >> c:\ipaddres
ses.log

Code:

REM @ECHO OFF
REM ^^ watching the code

REM ------------------------------------------------------
REM Read the file names in the log directory on the server,
REM convert those file names to a list of hostnames.
REM ------------------------------------------------------

cd %1
if exist c:\names.log del c:\names.log
for /F "delims=" %%j in ('dir c:\Directory /A-D /B /O:GEN') do echo %%~nj >> c:\names.log

REM ------------------------------------------------------
REM Read the list of hostnames, convert them to a list of
REM hostnames / IP addresses.
REM ------------------------------------------------------

if exist c:\ipaddresses.log del c:\ipaddresses.log
for /f %%i in (c:\names.log) do (
for /f "skip=3 delims=: tokens=2 usebackq" %j in (`nslookup %i`) do @echo %i %j >> c:\ipaddresses.log
)

REM ------------------------------------------------------
REM Clean up our IP address file to strip out IPs within
REM the local group
REM ------------------------------------------------------

if exist c:\conlog.log del c:\conlog.log
type c:\ipaddresses.log |findstr /V /E 192.168.*.* >> c:\conlog.log

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: Get a hostname and IP from a list of file names

#2 Post by Squashman » 04 Jul 2012 14:55

In a batch file you need to double up on the percent signs with your FOR variables. You are missing the double percent signs on 4 variables.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get a hostname and IP from a list of file names

#3 Post by foxidrive » 04 Jul 2012 20:11

This seems to work here.

You would launch it like this: Batch.bat "c:\folder\with the IP files\"

Code: Select all

@echo off
pushd "%~1"
set "file=c:\names.log"
del "%file%" 2>nul
for /F "delims=" %%a in ('dir /A-D /B /O:GEN') do (
for /F "tokens=2" %%b in ('nslookup %%~na') do (
echo %%b|findstr /r "^192.168">nul || >>"%file%" echo %%~na %%b
)
)
popd

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#4 Post by autoamerican » 05 Jul 2012 11:45

That works great! I made a small tweak to the output formatting so I get my IP first, then host name. It ends up giving me three lines per host, which is just fine - the third line for each host gives me something I can scan with our log monitoring tool. The file ends up looking like this:

dnsserver.domain.net HOSTNAME1
HOSTNAME1.domain.net HOSTNAME1
192.168.1.1 HOSTNAME1
dnsserver.domain.net HOSTNAME2
HOSTNAME1.domain.net HOSTNAME2
192.168.1.2 HOSTNAME2
dnsserver.domain.net HOSTNAME3
HOSTNAME1.domain.net HOSTNAME3
192.168.1.3 HOSTNAME3
dnsserver.domain.net HOSTNAME4
HOSTNAME4.domain.net HOSTNAME4


(the section in red is a host within the subnet that I do NOT want to see - the findstr strips that IP / host combination so it won't give me the final line that I'm using to scan).

One last question - what's the easiest way to add a quick error catch at the start of this so that if that directory is empty it will end without an error? As it is now, it returns a generic "File Not Found." I don't really need it to give an intelligent error if the directory is empty, I just need it to not bomb out (not return an error state).

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: Get a hostname and IP from a list of file names

#5 Post by Squashman » 05 Jul 2012 12:04

Code: Select all

@echo off
pushd "%~1"
for /f "tokens=1" %%a in ('dir ^| find " File(s)"') do IF "%%a"=="0" EXIT /b
set "file=c:\names.log"
del "%file%" 2>nul
for /F "delims=" %%a in ('dir /A-D /B /O:GEN') do (
for /F "tokens=2" %%b in ('nslookup %%~na') do (
echo %%b|findstr /r "^192.168">nul || >>"%file%" echo %%~na %%b
)
)
popd

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#6 Post by autoamerican » 10 Jul 2012 12:05

One last question ... I just found out that the information I'm filtering is about 99% on IP address, but occasionally there's a hostname within the "good" IP range we also want to filter.

I've been trying to nest another layer of findstr into the script, but can't get it to work. Here's the script I'm using with my own modifications for output and portability, and below is an example of my output, including one line that is not filtered on IP but I need to filter based on hostname (it's a case of filter on IP subnet or hostname contains a certain string, and both could be on the same line, but not necessarily).

Code: Select all

@echo off
pushd \\server\ourlogs
for /f "tokens=1" %%a in ('dir ^| find " File(s)"') do IF "%%a"=="0" EXIT /b
set "file=c:\names.log"
del "%file%" 2>nul
for /F "delims=" %%a in ('dir /A-D /B /O:GEN') do (
   for /F "tokens=2" %%b in ('nslookup %%~na') do (
      echo %%b|findstr /R /I "^192.168">nul || >>"%file%" echo %%b %%~na
   )
)
popd


Output:

server1.domain.net SERVER1
server2.domain.net SERVER2
255.255.255.0 BADSERVER3.domain.net
server4.domain.net SERVER4


The red one is a host not being filtered on IP range, but we need to filter based on hostname (host name contains "BAD")

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#7 Post by autoamerican » 10 Jul 2012 13:46

Actually, I think I may have just figured it out - how does this look to everyone? This should scan the direcory, get the file names, get the IP addresses, and then filter them so that ONLY combinations of IPs / hostnames that DO NOT contain either 192.168 OR the string FILTERED- anywhere in the line OR both conditions are written to output. That way I'm able to catch both conditions but not filter anything I may actually want. It also ignores / dumps the "junk" lines from NSLOOKUP that just give me the hostname / IP of my DNS server (don't need that).

Does anyone see any holes in my logic I'm missing?

Code: Select all

@echo off
pushd \\OURSERVER\ourlogs
for /f "tokens=1" %%a in ('dir ^| find " File(s)"') do IF "%%a"=="0" EXIT /b
set "file=c:\names.log"
del "%file%" 2>nul
for /F "delims=" %%a in ('dir /A-D /B /O:GEN') do (
   for /F "tokens=2" %%b in ('nslookup %%~na') do (
      echo %%b %%~na|findstr /R /I "^192.168 ^.*FILTERED-.* ^DNSSERVER.domain.net">nul || >>"%file%" echo %%b %%~na
   )
)
popd


Sample output:

HOST1.domain.net HOST1
HOST2.domain.net HOST2

HOST3.domain.net HOST3
255.255.255.0 HOST3.domain.net
HOST4.domain.net HOST4
255.255.255.1 HOST4.domain.net


Lines in green are hosts with "good" names that are in the subnet I don't care about; lines in blue are hosts with "good" names that are in the subnet I DO care about. Also, in the directory \\OURSERVER\ourlogs I have files with names containig "FILTERED-HOSTNAME.log" which the script is completely ignoring (ones we don't want to see based on hostname).

Is it possible with my filtering here I may "miss" something in the IP range I care about?

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get a hostname and IP from a list of file names

#8 Post by foxidrive » 10 Jul 2012 21:27

It's not clear to me what you need to filter out but you can use another command after the above script runs.

find /v "BAD" <"file.txt" > "fileout.txt"

That will remove all the lines containing BAD but only you know what the filter terms are and where they are in the lines.

findstr is another tool which can accept regular expressions to finetune the filtering by text position too.

Both tools can be run more than once to filter out extra terms, and findstr can filter out multiple items in one pass.

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#9 Post by autoamerican » 11 Jul 2012 11:37

Once the script goes through the file directory and extracts the hostnames, and then runs the nslookup to attach IP addresses to the hostnames, I need to filter out anything in the 192.168 subnet OR any hostname that contains a certain string (for testing purposes, I've just called it "FILTERED-", as in "FILTERED-HOSTNAME" as one I want stripped out vs. just HOSTNAME).

The OR in this case is not an exclusive OR; If it turns out that I have a host within the 192.168 subnet that has a hostname that contains the filtered string, it should be stripped out (remove it based on IP or hostname, either one). Once there is a final output, I have a tool that will read the names.log file and look for any line that starts off with an IP address, so as long as the script drops anything in the 192.168 subnet, my tool will work. What I'm trying to prevent with this last layer of filtering is the possibility of a "bad" hostname (FILTERED-HOSTNAME) ending up in the log if it just happens to reside outside the "bad" IP address range I'm trying to ignore.

The only problem with adding a second output is it creates two output files, something I was trying to avoid (my original script actually created three output files; two preliminary ones, and one final).

I'm also unable to filter multiple strings on a single findstr line because each one of my loops only contains one of the two output strings that are concatenated in the final output:

FOR #1: Go through a directory, get a hostname from each filename, put it in a variable.
FOR #2: Take each hostname from FOR #1, get an IP address, ignore any IPs within the 192.168 subnet, put it in a variable, and then output variables from FOR #2 (IP, as long as it's not in the bad subnet) and FOR #1.

I've tried putting hostname filtering within the FOR loops, but it seems to get "stuck" when I do so every time it hits a hostname that contains FILTERED-. It's almost like when I tell it to ignore those hostnames, it doesn't know what to do next and won't go through the loop condition.

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: Get a hostname and IP from a list of file names

#10 Post by Squashman » 11 Jul 2012 12:49

You could just do an IF statement to see if your IP address begins with 192.168 as well.
Couple of different ways you could set that up. Either put your 4 octets into Tokens with your For Loop or assign your loop variable to another variable and substring that variable to see if it equals 192.168. Then do conditional processing.

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#11 Post by autoamerican » 11 Jul 2012 14:35

The IP address filtering is working fine right now, the only thing I'm stuck on is adding this one last layer of filtering on hostname.

I tried doing an IF NOT statement to try and match my %%~na (hostname) against anything containing FILTERED- (only execute my entire looping process to obtain an IP and output hostname & IP to a file IF hostname does not contain FILTERED-), but I don't think that string comparison gives you a fuzzy / "contains" option (it will only match entire string to entire string, not %%~na contains part of a filtered string).

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get a hostname and IP from a list of file names

#12 Post by foxidrive » 11 Jul 2012 15:48

echo %%b %%~na|findstr /R /I "^192.168 ^.*FILTERED-.* ^DNSSERVER.domain.net">nul || >>"%file%" echo %%b %%~na


From this line of yours and your very muddy description, you want to filter out the three terms.
Try including this.

Code: Select all

echo %%b %%~na| findstr /v /b "192.168" |  findstr /v /i "FILTERED" | findstr /b /v /i "DNSSERVER" >>"%file%" echo %%b %%~na 

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#13 Post by autoamerican » 11 Jul 2012 17:52

That ends up blowing it up - I get this for each file in the directory (where the IP and hostname are unique for each iteration, so it's reading the filenames properly), and a blank names.log:

C:\TEST>(echo 192.168.1.1 FILTERED-HOST2 | findstr /v /b "192.168" | find
str /v /i "FILTERED-" | findstr /b /v /i "DNSSERVER.domain.net" echo 192.168.1.1 FILTERED-HOST2 1>>"c:\names.log" )
FINDSTR: Cannot open echo
FINDSTR: Cannot open 192.168.1.1
FINDSTR: Cannot open FILTERED-HOST2

The iteration output is the same whether the host has a "good" or "bad" hostname, and whether it's in the "bad" IP subnet or not (same output for everything, nothing going to names.log).

I think the code I posted last time is correct (reproduced below), but I'm having trouble conceptualizing how my filtering works. I'm not afraid to admit that I think I wrote something that does what exactly I expect it to do (below), and I did some testing which appears to do what I want (remove anything with a "bad" hostname, a "bad" IP subnet, or is an extraneous line for the DNS server), but I'm having trouble conceptualizing how I "made it work." It was really a shot in the dark that appeared to be the magic bullet I was looking for.

Code: Select all

@echo off
pushd \\OURSERVER\ourlogs
for /f "tokens=1" %%a in ('dir ^| find " File(s)"') do IF "%%a"=="0" EXIT /b
set "file=c:\names.log"
del "%file%" 2>nul
for /F "delims=" %%a in ('dir /A-D /B /O:GEN') do (
   for /F "tokens=2" %%b in ('nslookup %%~na') do (
      echo %%b %%~na|findstr /R /I "^192.168 ^.*FILTERED-.* ^dnsserver.domain.net">nul || >>"%file%" echo %%b %%~na
   )
)
popd


If I break down my filtering, here's how I understand it to work:

echo %%b %%~na (start by outputting every IP address / hostname combination) |findstr /R /I "^192.168 ^.*FILTERED-.* ^dnsserver.domain.net">nul (only capture lines that do not contain the "bad" subnet OR contain the "bad" string somewhere in their hostname OR do not have the DNS server address in them) || >>"%file%" echo %%b %%~na (only output combinations of %%b %%~na that made it through the findstr)

When I tested that, I got the output I expected, but wanted to make sure I 100% grasp what I did and didn't miss anything that may "over-filter" (remove something I actually want to see).

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get a hostname and IP from a list of file names

#14 Post by foxidrive » 11 Jul 2012 17:55

try this

Code: Select all

echo %%b %%~na| findstr /v /b "192.168" |  findstr /v /i "FILTERED" | findstr /b /v /i "DNSSERVER" >>"%file%"

autoamerican
Posts: 10
Joined: 02 Jul 2012 13:23

Re: Get a hostname and IP from a list of file names

#15 Post by autoamerican » 11 Jul 2012 18:25

Yes! That gave me the output I was expecting.

Actually, it gave me the exact same output I got from my most recent attempt at solving this myself (above), but got me there in a way that I could actually follow and understand! I guess there is more than one way to skin a cat in this case, but your way is a lot more straight forward and actually made sense.

Thanks!

Post Reply