0

私のスクリプトは次のことを行います:

  1. パケットキャプチャ (windump を使用) のプロセスを 1 時間実行すると、データが保存されます textFile1
  2. 1 時間後にデータをデータベースにダンプする
  3. テキストファイルを削除
  4. 別の windump を実行し、データを textfile2 に保存します (その後、テキストファイルを交互に繰り返しながらプロセスを繰り返します)。

問題は、データをデータベースにダンプするのに時間がかかることです。したがって、パケット キャプチャ プロセスは、数時間後にのみ再度実行されます。Start-Job が ScriptBlock として関数を受け入れないため、マルチスレッドを機能させることができません。アイデアは、パケット キャプチャ プロセスが継続的に実行される必要があるということです。(そして、バックグラウンドでデータベースへのダンプを持っている可能性があります。そのため、2 つのテキスト ファイルを交互に使用しています)

私はすでに 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 に答える