0

我的脚本执行以下操作:

  1. 运行一个抓包进程(使用windump)1小时,数据保存为textFile1
  2. 1小时后将数据转储到数据库中
  3. 删除文本文件
  4. 运行另一个 Windump 并将数据保存到 textfile2(然后重复过程。同时在文本文件之间交替)。

问题是将数据转储到数据库需要很长时间。因此,数据包捕获过程只会在几个小时后再次运行。我无法使多线程工作,因为 Start-Job 不接受作为 ScriptBlock 的函数。这个想法是数据包捕获过程应该连续运行。(也许有转储到免费的数据库,这就是我们在两个文本文件之间交替的原因)

我已经尝试将整个 ParseDumpDB 放入 $Scriptblock 中,但它仍然无法正常工作。

脚本(删除了一些部分):

   #====Global Paramters====
$counter = 1
$hostname = hostname 
$Path = "D:\windump" #Update this. This should contain the windump.exe application. All results will dumped here.
$File = "$Path\hash.txt" #for secure credential
$FileSummary = "$Path\$hostname Summary.txt" #none yet 
$FilePathCheck = "$Path\$hostname HCCError $(get-date -f yyyy-MM-dd).txt" #Contains all dump database errors.
$FileBatProgram = "$Path\windumpbat.bat" #to run windump

$LogFile1 = "$Path\WinDumpLog1.txt"
$LogFile2 = "$Path\WinDumpLog2.txt"


$SleepTimeBefore = 3600 #Run Time of windump in seconds  -  1hour or 3600 seconds
$SleepTimeAfter = 10 #Pause before executing another windump 

#====Fucntion Stop and Start WinDump====
Function WinDumpProcessStart(){ 
    $DateTimeToday = Get-Date
    echo "$DateTimeToday" 
    echo " Waiting $SleepTimeBefore seconds"  
    Start-Sleep -Seconds $SleepTimeBefore

    if(Get-Process windump){
        echo " Process windump running" 
    }

    if(!$process.HasExited){    
        echo " Killing windump Process" 
        Stop-Process -name windump
    }

    echo " Waiting $SleepTimeAfter seconds" 
    Start-Sleep -Seconds $SleepTimeAfter
}

Function WinDumpProcessStop(){  
    if(Get-Process windump){
        echo " Process windump running" 
    }

    if(!$process.HasExited){    
        echo "Killing windump Process" 
        Stop-Process -name windump
    }

    echo "Waiting $SleepTimeAfter seconds" 
    Start-Sleep -Seconds $SleepTimeAfter
}


Function ParseDumpDB([string]$results){
    $results1 = Get-Content $results

    #Analyze each. Extract Time, source IP/Port, destionation IP/Port and Protocol 
    $Row = "" | select Time, SourceServer, SourcePort, DestionationServer, DestionationPort, Protocol 

    foreach ($line in $results1){       
        If($line -like '*bad-len*'){
            #Skip line. This is an invalid packet 
        }ElseIf($line -match "\d{1,2}\:\d{1,2}\:\d{1,2}\.\d{1,6}"){
            #echo "Match:" $line
            $Row.Time = ($line.Split(" "))[0] + " " + ($line.Split(" "))[1]    
            $time1 = (($Row.Time).Split("."))[0]
            $Row.Time = $time1 

            If(($line.Split(" "))[6] -match 'UDP'){
                $Row.Protocol = (($line.Split(" "))[6]).TrimEnd(",")
            }Else{
                $Row.Protocol = ($line.Split(" "))[6]
            }

            $Temp = ($line.Split(" "))[3]
            $return = ParseIP $Temp 
            $Row.SourceServer = $return[0]
            $Row.SourcePort = $return[1]

            $line = $line -replace ':',''

            $Temp = ($line.Split(" "))[5]
            $return = ParseIP $Temp 
            $Row.DestionationServer = $return[0]
            $Row.DestionationPort =  $return[1]

            #Get IPAddress
            try{
                $SourceHostNameIP = [System.Net.Dns]::GetHostAddresses($Row.SourceServer)
            }catch [Exception] {}

            $outputstr = ''''
            $outputstr += $SourceHostNameIP 
            $outputstr += ''','''
            $outputstr += $Row.SourceServer
            $outputstr += ''','''
            $outputstr += $Row.DestionationPort
            $outputstr += ''','''
            $outputstr += $Row.Protocol 
            $outputstr += ''','''
            $outputstr += $Row.Time 
            $outputstr += ''','''
            $outputstr += "DestHost= "
            $outputstr += $Row.DestionationServer 
            $outputstr += ''''

            #print results || insert to DB
            #echo $Row 

            $SqlCmd.CommandText = $SqlQuery
            $SqlQuery = "INSERT INTO PacketCaptures VALUES ('$hostname', $outputstr)"
            #write-host $SqlQuery
            $SqlCmd.CommandText = $SqlQuery
            $SqlAdapter.SelectCommand = $SqlCmd
            $DataSet = New-Object System.Data.DataSet
            try{
               $SqlAdapter.Fill($DataSet)
            }catch [Exception] {
                $_.Exception.Message  | Out-File -encoding ASCII $FilePathCheck -Append
            }

        }ElseIf($line -like '*packets*' -and $line -ne " "){ #get summary and save to file. NOT YET WORKING, total packets captured not in file 
            $outputstr1 += " $line -"
            $outputstr1 += "`n`r"
        }Else{
            #echo "skip:" $line
            #Skip line. This is an invalid packet 
        } 
    }
}

#====One Time Configuration of Database====
#initiate the DB connectionpart etcetc

#====Start of WinDump====
While($counter = 1){
    If ( (!(Test-Path $LogFile1)) -and (!(Test-Path $LogFile2)) ){ #First run. Both files doesn't exist yet 
        echo "`n Starting windump to LogFile1" 
        $process = Start-Process  "cmd.exe" "/c $FileBatProgram >  $LogFile1 2>&1"  -PassThru

        WinDumpProcessStart     
    }ElseIf( (Test-Path $LogFile1) -and (!(Test-Path $LogFile2)) ){ #Log 1 exits 
        echo "Parsing LogFile1 and dumping  to DB" 
        $ScriptBlock = { ParseDumpDB $LogFile1 } 

        Start-Job -ScriptBlock $ScriptBlock 

        While($(Get-Job -State 'Running')){
          echo "`n While parsing.. Start windump to LogFile2" 
          $process = Start-Process  "cmd.exe" "/c $FileBatProgram >  $LogFile2 2>&1"  -PassThru
        }

        echo "`n Once successful, stop windump process"
        WinDumpProcessStop
        echo "Delete LogFile2"
        Remove-Item $LogFile1

    }ElseIf( (!(Test-Path $LogFile1)) -and (Test-Path $LogFile2) ){ #Log 2 exits 
        echo "Parsing LogFile2 and dumping to DB" 
        $ScriptBlock = { ParseDumpDB $LogFile2 } 

        Start-Job -ScriptBlock $ScriptBlock 

        While($(Get-Job -State 'Running')){
            echo "`n While parsing..Starting windump to LogFile1" 
            $process = Start-Process  "cmd.exe" "/c $FileBatProgram >  $LogFile1 2>&1"  -PassThru
        }

        echo "`n Once successful, stop windump process2" 
        WinDumpProcessStop
        echo "Delete LogFile"
        Remove-Item $LogFile2
    }Else{
        echo "Error. Both LogFiles exists. Exiting Program.." 
        exit
    } 
} 
4

1 回答 1

0

您需要在脚本块内定义函数并将变量作为参数传递给它:

$ScriptBlock = {
  Function ParseDumpDB([string]$results){
    ...
  }

  ParseDumpDB $args[0]
} 

Start-Job -ScriptBlock $ScriptBlock -ArgumentList $LogFile2

附带说明:从 PowerShell 脚本运行批处理脚本会使您的脚本非常复杂。您最好将批处理脚本的内容合并到 PowerShell 脚本中并将它们作为后台作业运行,例如:

do {
  $job = Start-Job -ScriptBlock {
           & WinDump -i 1 -n -vv -w $args[0] ...
         } -ArgumentList $LogFile

  Start-Sleep -Seconds 3600

  Stop-Job -Id $job.Id
  Remove-Job -Id $job.Id

  Move-Item $LogFile $LogForImport
  Start-Job -ScriptBlock {
    ...
  } -ArgumentList $LogForImport
} until (...)
于 2014-06-17T09:17:06.600 回答