嵌套for循环,设置变量以及是否在批处理脚本中

时间:2016-06-30 09:59:07

标签: python windows batch-file vbscript cmd

我正在尝试制作一个批处理脚本,它将在文件中写入特定的IP地址。 我有一个txt文件(由一个python脚本创建)有一个IP地址列表(每个新行一个),现在我需要使用for循环ping每个IP,检查TTL值是否在100到128之间(Windows主机)并将IP地址写入新文件。我一直试图调整设置变量和循环,但这一切都变得太复杂而无法运行 到目前为止,我已经达成了: - 编辑:纠正以下命令

for /f %i in (ip.txt) do ping -n 1 %i | find "TTL"

这将给我多行Ping输出,这里仅显示单行(我仅使用4.2.2.2)

Reply from 4.2.2.2: bytes=32 time=1 ms ttl=45

如果我对单个IP执行ping操作,我可以选择TTL字段,但不能选择TTL的确切值

for /f "tokens=6 delims= " %a in ('ping -n 1 4.2.2.2 ^| find "TTL"') do echo %a

它给了我TTL=45的值,而我需要45来进行比较。 我读到了有用的setlocal enabledelayedexpansion,但我无法将这些全部合并为一行并使用set个变量并使用IF-ELSE个循环。 Plz对如何实现IP选择进行了一些描述。

在制作批量书写解决方案后由我编辑: -
此批处理脚本将ping ips.txt 文件中给出的每个IP地址。找到TTL值,如果TTL值等于128,它将运行命令 NBTSTAT -A ip-address (用于查找GROUP信息)并存储它位于 nbt_query_op.txt 文件中。
在为每个IP地址触发NBTSTAT命令之前,将搜索此文件以查找现有结果,以及是否在文件中找不到特定IP的结果,NBTSTAT将被解雇。
注意 变量应引用字符,!TTL! ,!ip1! ,!ERRORLEVEL!。此外,感谢RGuggisberg先生也提供了指示。

@echo off
setlocal EnableDelayedExpansion
for /f %%i in (ips.txt) do (
for /f "tokens=6 delims= " %%a in ('ping -n 1 %%i ^| find "TTL"') do (
    for /f "tokens=2 delims==" %%b in ('echo.%%a') do set ttl=%%b
    echo %%i has TTL:- !ttl!
    if !TTL! == 128      (set ip1=%%i
                 echo        SELECTED IP- !ip1! TTL- !TTL!
                 findstr /c:!ip1! nbt_query_op.txt
                 if not !ERRORLEVEL! ==0 echo !ip1!>>nbt_query_op.txt && nbtstat -A !ip1! | find "GROUP">>nbt_query_op.txt
                     )
                                          )
)


谢谢,
kriss

5 个答案:

答案 0 :(得分:1)

这将满足您的要求。迁移到第一个示例时,根据需要进行修改。

for /f "tokens=6 delims= " %a in ('ping -n 1 4.2.2.2 ^| find "TTL"') do for /f "tokens=2 delims==" %b in ('echo.%a') do echo %b

BTW,你帖子中的第一个FOR循环是不完整的。我想你的意思是

for /f %i in (ip.txt) do ping -n 1 %i | find "TTL"

答案 1 :(得分:1)

在vbscript中,您可以执行以下操作:

strHost = "4.2.2.2"
if Ping(strHost) = True then
    Wscript.Echo "Host " & strHost & " contacted"
Else
    Wscript.Echo "Host " & strHost & " could not be contacted"
end if
'***************************************************************************************
Function Ping(strHost)
    dim objPing, objRetStatus
    set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strHost & "'")
    for each objRetStatus in objPing
        if IsNull(objRetStatus.StatusCode) or objRetStatus.StatusCode <> 0 then
            Ping = False
            WScript.Echo "Status code is " & objRetStatus.StatusCode
        else
            Ping = True
            Msg = Msg & " Pingging " & strHost & vbCrlf & vbCrlf 
            Msg = Msg & "Bytes = " & objRetStatus.BufferSize & vbCrlf 
            Msg = Msg & "Time (ms) = " & objRetStatus.ResponseTime & vbCrlf 
            Msg = Msg & "TTL (s) = "  & objRetStatus.ResponseTimeToLive 
        end if
    next
    Wscript.echo Msg
End Function 
'***************************************************************************************

编辑:2016年6月30日@ 19:11

我测试了这个文件:file.txt

4.2.2.2
www.google.com
www.google.fr
www.facebook.com
www.stackoverflow.com
www.yahoo.com
www.yahoo.fr
www.developpez.net

这个批处理文件:

@echo off
Title Get TTL from IP adress
set vbsfile=%Tmp%\%~n0.vbs
set IP_File=E:\vb-ping\ip.txt
set LogFile=Log.txt
If Exist %LogFile% Del %LogFile%
For /f %%a in ('Type %IP_File%') Do ( 
    echo TTL for "%%a" is : & Call:VBS "%%a"
    ( echo TTL for "%%a" is : & Call:VBS "%%a" )>> %LogFile%
)
echo.
color 0A
echo Hit any key to open the LogFile "%LogFile%"
pause>nul
Start "" %LogFile%
Exit /b

:VBS 
(
    echo wscript.echo TTL(WScript.Arguments(0^)^)
    echo '**********************************************************************************************************
    echo Function TTL(strHost^)
    echo     dim objPing, objRetStatus
    echo     set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}"^).ExecQuery _
    echo       ("select * from Win32_PingStatus where address = '" ^& strHost ^& "'"^)
    echo     for each objRetStatus in objPing
    echo         if IsNull(objRetStatus.StatusCode^) or objRetStatus.StatusCode ^<^> 0 then
    echo            Ping = False
    echo           WScript.Echo "Status code is " ^& objRetStatus.StatusCode
    echo        else
    echo            Ping = True
    echo            TTL = objRetStatus.ResponseTimeToLive 
    echo        end if
    echo     next
    echo End Function 
    echo '**********************************************************************************************************
)> "%vbsfile%"
Cscript /Nologo "%vbsfile%" "%~1"
Exit /b

我得到了输出结果:

TTL for "4.2.2.2" is : 
53
TTL for "www.google.com" is : 
51
TTL for "www.google.fr" is : 
51
TTL for "www.facebook.com" is : 
81
TTL for "www.stackoverflow.com" is : 
53
TTL for "www.yahoo.com" is : 
48
TTL for "www.yahoo.fr" is : 
48
TTL for "www.developpez.net" is : 
48

答案 2 :(得分:1)

所以,我的回答似乎与我所寻求的有些不同。它是在python 2.x我刚写完。虽然它在执行方面并不是非常复杂和隐秘(弹出大量的CMD窗口并写入文件,然后读取以形成结果)。但仍然完成了工作。我想我将不得不对DOS命令进行更多研究并开始学习VB脚本;)。笑。
感谢@RGuggisberg和@Hackoo的支持

import os
import re
cwd = os.getcwd()
ip_file = cwd+"\\ip.txt"     ## IPs written in this file, one in each line, or the filename can be taken through command-line args (more portable)
ip = []
win_hosts = []
for line in open(ip_file).readlines():
    ip.append(line.rstrip())
del_cmd = "del "+cwd+"\\response.txt"    ## Delete response.txt file
os.system(del_cmd)                       ## as PING output keeps appending to it
for i in ip:
    cmd = "ping -n 1 "+str(i)+' | find "TTL" >> response.txt'    ## write PING response to response.txt
    os.system(cmd)
response_file = cwd+"\\response.txt"
for line in open(response_file).readlines():
    regs = r'Reply from\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*TTL=(\d{1,3})'   ## Regular Expression to catch IP and TTL-value
    obj = re.search(regs,line.rstrip('\n'))  ## also right-strip any possible new-lines, it'll probably be '\r\n' on Linux host
    if obj:
        ip = obj.group(1)
        ttl = obj.group(2)
        print ip," has TTL= ",ttl
        ttl = int(ttl)
        if (127<ttl<129):                ## change this to (54<ttl<65) to get Linux hosts
            win_hosts.append(ip)         ## Add the windows hosts to win_hosts list
print "\n[+][+] Windows Hosts = ",str(win_hosts)

我的ip.txt文件有: -

192.168.1.1
192.168.1.2
192.168.1.4
192.168.1.5

结果是: -

>>> 
192.168.1.1  has TTL=  30
192.168.1.2  has TTL=  64
192.168.1.4  has TTL=  64
192.168.1.5  has TTL=  128

[+][+] Windows Hosts =  ['192.168.1.5']

我不完全记得但是无法获得对命令模块(Windows不支持)和子进程模块的支持(虽然它们完美无缺地工作Linux盒子)。如果有人知道如何将结果存储到任何列表/字典/变量,请更新plz。我不喜欢在CMD中使用输出重定向。

答案 3 :(得分:1)

尝试使用此批处理文件以获取具有IP地址的同一行中的cancelUrl: "http://localhost:55182/Booking/InitialBookingRequest?StartDate=7/1/2016 1:15:00 AM&EndDate=7/1/2016 2:15:00 AM&ListingId=119295&bookingId=90802" string clientDetails: null currencyCode: "USD" dateOfMonth: null dayOfWeek: null displayMaxTotalAmount: null endingDate: "2016-07-15" feesPayer: null ipnNotificationUrl: "http://localhost:55182/home/handler" maxAmountPerPayment: 5.00 maxNumberOfPayments: 1 maxNumberOfPaymentsPerPeriod: 1 maxTotalAmountOfAllPayments: 5.00 memo: null paymentPeriod: null pinType: null requireInstantFundingSource: null returnUrl: "http://localhost:55182/booking/Success?StartDate=7/1/2016 1:15:00 AM&EndDate=7/1/2016 2:15:00 AM&ListingId=119295&bookingId=90802" string sender: null senderEmail: null startingDate: "2016-06-30"

TTL

答案 4 :(得分:0)

因此,我为所有不属于我的Org域名的Windows客户端创建了完整的扫描脚本。已经足够长了,但我想把它贴在这里。

此脚本依赖于初始客户端扫描,使用 nmap 的ping扫描。由于使用多处理模块创建脚本并不适用于Windows框,因此最好的镜头是 nmap 。 NMAP在几秒钟内对255个主机的完整子网进行ping扫描,并返回网络中存活的客户端的FQDN(完全限定域名)。

注意:您应该使用扫描仪PC中定义的DNS服务器。

下一步,脚本执行的操作是,nmap扫描输出到文件 nmap_op.txt 。然后脚本读取此文件的输出并使用regular-expression取出IP和FQDN。如果任何IP不具有FQDN,则将其ping一次并将输出写入文件 response.txt 。读取该文件,取出TTL值在100-129之间的IP。

add_to_db 函数负责返回实际不属于Domain的IP列表。此功能将IP与3个列表进行交叉检查,并从最终列表中删除IP,该列表位于数据库文件中,但后来加入了域,并且当它们联机时,还会不断向DB添加新的非域IP。登记/> 将此python文件保存在脚本可以写入文件的目录中。您应查找两个文件 non-domain-ips.txt (所有非域IP)和 [subnet_value] -result.txt 以获取最终结果。

用法 - 在命令提示符下运行此文件,如下所示: - python scanner.py 192.168.1.0/24 192.168.2.0/24
您可以添加任意数量的网络进行扫描。 Plz不会改变网络arg的模式。您必须仅使用&#34; /&#34; 来定义网络的掩码值(不要使用*代替/)。传递的参数没有异常处理。运行脚本时,将了解其余的输出。

另外我想添加一个或两个以上的函数,根据供应商的MAC位将某些IP定义为异常-地址。例如 - 一些瘦客户端类型的设备(因为它们将仅以独立模式运行),它们给出Windows范围的TTL值。
脚本是在不使用类的情况下非常匆忙制作的(此外我和#39;我不太喜欢他们),所以它是最丑陋的形式;)

import os
import time
import re
import sys
import pickle
import commands
import subprocess

def add_to_db(nondomain_ips, pickled_ips, domainIPs):
    print "NON domain IPs= ", str(nondomain_ips)
    #raw_input("....")
    print "PICKLED IPs= ",str(pickled_ips)
    #raw_input("....")
    print "Length of PICKLED IPs= ",len(pickled_ips)
    print "domain IPs:- ",str(domainIPs)
    #raw_input("....")
    if (len(pickled_ips) == 0):
        pickled_ips= nondomain_ips
        return pickled_ips
    for new_ip in nondomain_ips:
        print "comparing- ",str(new_ip)
        if new_ip not in pickled_ips:
            print "APPENDING ",str(new_ip),"  to PICKLED IPs"
            pickled_ips.append(new_ip)           
        else:   pass
    for pickled_ip in pickled_ips:
        #print "CHECKING - ",pickled_ip," in domain and in DB file or not"
        if pickled_ip in domainIPs:
            print pickled_ip," JOINED domain, removing from DB file"
            pickled_ips.remove(pickled_ip)
    #print "PICKLED IPs:- ",str(pickled_ips)
    #raw_input("...")
    return pickled_ips
def main():
    if (len(sys.argv)<2):
        print "Wrong args, Give the subnet to scan, Example- \n\npython script.py 192.168.1.0/24 192.168.2.0/24 [more subnets...]\n\nExiting...\n"
        exit(3)
    print "TOTAL SUBNETS TO SCAN:- ",len(sys.argv)
    cwd = os.getcwd()
    print "Current Directory= ",cwd
    outfile = cwd+"\\nmap_op.txt"
    for i in range(1,len(sys.argv)):
    time_now = time.ctime()
        net = sys.argv[i]
        #print i
        #cmd = "nmap -sn " + str(sys.argv[i]) + " -oG "+str(outfile)
        cmd = "nmap -sn " + str(net) + " -oG "+str(outfile)
        print cmd
        try:
            os.remove(outfile)
        except Exception, e:
            print "Error deleting file",str(e)
        #raw_input("SENDING -sn SCAN....\n")
        print "SENDING -sn SCAN....\n"
        os.system(cmd)

        #print "Argv[i]= ",sys.argv[i].split('/')[0]
        print "Argv[i]= ",net.split('/')[0]
        result_file = str(cwd)+"\\"+net.split('/')[0]+"-result.txt"
        print "result file= ",result_file
        #raw_input(" ... ")
        if os.path.exists(outfile):
            print outfile," - oG file created\n\n-------------------------------------\n"
        fp = open(outfile)
        hostlist=[]
        domainIPs = []
        nondomain = []
        ping_file = cwd+"\\response.txt"
        try:
            os.remove(ping_file)
        except Exception, e:
            e=e
        for line in fp.readlines():
            #print line
            #reg = r'Host:(.*\)).*Status.*Up'
            reg = r'Host:\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s(\(.*\)).*Status.*Up'
            res = re.match(reg,line)
            if res:
                #print "\t\t",res.group()
                ip = res.group(1)
                if ('()' in res.group(2)):
                    name = 0
                    nondomain.append([ip,name])
                    ping_cmd = 'ping -n 1 '+str(ip)+'| find "TTL" >>'+cwd+"\\response.txt"
                    os.system(ping_cmd)
                else:
                    name = res.group(2)
                    domainIPs.append(ip)
                hostlist.append([ip,name])
            else:   pass #print "No object"
        fp.close()      ## CLOSE THE NMAP OUTPUT FILE-HANDLE
        print "[+][+] All HOSTS:- ",str(hostlist),"\n"
        #print "domain IPs:- ",str(domainIPs)
        print "TOTAL unresolved IPs:- ",nondomain,"\n"
        nondomain_ip = []
        #print "\n\nIP and TTL from RegExp\n"
        regs = r'Reply from\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*TTL=(\d{1,3})'
        for line in open(ping_file).readlines():
            #print line
            obj = re.search(regs,line)
            if obj:
                ip = obj.group(1)
                ttl = obj.group(2)
                print str(ip)+" --- " + str(ttl)
                if (100<int(ttl)<129):
                    nondomain_ip.append(ip)
        #print "non domain IPs = ",str(nondomain_ip)
        fp_result = open(result_file,'a')
        fp_result.write("\n\n"+time_now+"\n")
        fp_result.write(str(nondomain_ip))
        fp_result.close()

        db_file = cwd+"\\dbfile"
        if not os.path.exists(db_file):
            fpdb = open(db_file,'w')
            fpdb.close()
            if os.path.exists(db_file):
                print "DB_FILE created"
        with open(db_file,'rb') as fpdb:
            try:
                pickled_ips = pickle.load(fpdb)
            except Exception, error:
                print "Error in loading pickeled list"
                pickled_ips = []
                print "Formed new pickled list= ",str(pickled_ips)
        fpdb.close()
        new_list = add_to_db(nondomain_ip, pickled_ips, domainIPs)
        #print "\nNEW IP-ADDRESSES ESTABLISHED AFTER COMPARING ALL LISTS:- \n",str(new_list)
        with open(db_file, 'wb') as fpdb:
            pickle.dump(new_list, fpdb)
        fpdb.close()
        with open(db_file, 'rb') as fpdb:
            ips = pickle.load(fpdb)
            print "\n\n\t\tTHE NON-domain IPs:- \n",str(ips)
            with open("non-domain-ips.txt",'wb') as handle:
                for ip in ips:
                    handle.write(ip)
                    handle.write("\r\n")
            handle.close()
        print "SLEEPING FOR 10 SECONDS..."
        time.sleep(10)
if __name__ == '__main__':
    while True:
        main()
        print "\n\n\n\t\tSCAN COMPLETED...sleep for 5 minutes before running another loop of scan...\n\n\n"
        time.sleep(300)