我的脚本执行以下操作:
问题是将数据转储到数据库需要很长时间。因此,数据包捕获过程只会在几个小时后再次运行。我无法进行多线程工作,因为Start-Job不能接受ScriptBlock的功能。这个想法是数据包捕获过程应该连续运行。 (并且可能在bacground中转储到数据库,这就是我们在两个文本文件之间交替的原因)
我已经尝试将整个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
}
}
答案 0 :(得分: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 (...)