My script does the following:
- Run a process for packet capture (using windump) for 1 hour, data are saved textFile1
- Dump data into database after 1 hour
- Delete text file
- Run another windump and save data to textfile2 (Then Repeat process. while alternating between textfiles).
The problem is it takes a long time to dump the data to the database. Therefore, the packet capture process will only run again after a few hours. I am unable to make multithreading work because Start-Job won't accept a function as ScriptBlock. The idea is packet capture process should run continuously. (and maybe have the dumping to database in the bacground, that is why we are alternating between two text files)
I have already tried to put the whole ParseDumpDB into $Scriptblock and it is still not working.
Script (some parts removed):
#====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
}
}