Powershell脚本 - 合并多个Nessus扫描 -

时间:2014-05-29 21:30:36

标签: xml powershell scripting nessus

因此,我尝试按照Ryker Exum中定义的手动指南自动执行合并多个Nessus扫描的过程。我遇到的挑战是我必须找到并删除文件中的行,直到并包括某个点(一旦找到特定的字符串)。我的目标是尽可能高效地完成这项工作,因为其中一些Nessus扫描结果(XML文件)可能超过100MB。因此,我的方法是:

  1. 使用一些逻辑来识别第一个和最后一个文件,并根据它们采取相应的行动。
  2. 删除我遇到的第一个扫描文件的最后33个字符。
  3. 获取每个文件的内容并一次读取一个对象。如果没有匹配项,请删除该行并转到下一个对象。如果匹配,则删除该行并停止(因此执行直到)。
  4. 此时,我没有成功完成第三步的工作。代码如下:

    $first = Get-ChildItem ".\" -Filter *.nessus | Select-Object -first 1
    $last = Get-ChildItem ".\" -Filter *.nessus | Select-Object -last 1
    
    if ($first -ne $last)
    {
        Get-ChildItem ".\" -Filter *.nessus | Foreach-Object {
    
            $filepath = $_.FullName
    
            if ($first -eq  $_ -and $last -ne $_)
            {
                $stream = [System.IO.File]::OpenWrite($_.FullName)
                $stream.SetLength($stream.Length - 33)
                $stream.Close()
                $stream.Dispose()
            }
    
            if ($first -ne  $_ -and $last -ne  $_)
            {
                $stream = [System.IO.File]::OpenWrite($_.FullName)
                $stream.SetLength($stream.Length - 33)
                $stream.Close()
                $stream.Dispose()
    
                $found = ""
    
                do
                {
                    Get-Content $_.FullName | Foreach-Object {
    
                        $found = $_.Contains("<Report name=")
    
                        if ($found)
                        {
                            Where-Object {$_ -match '<Report name='} | Set-Content $filepath
                        } else {
                            Where-Object {$_ -notmatch '<Report name='} | Set-Content $filepath
                        }
                    }
                } until ($found)
            }
    
            if ($last -eq  $_ -and $first -ne $_)
            {
                $found = ""
    
                do
                {
                    Get-Content $_.FullName | Foreach-Object {
    
                        $found = $_.Contains("<Report name=")
    
                        if ($found)
                        {
                            Where-Object {$_ -match '<Report name='} | Set-Content $filepath
                        } else {
                            Where-Object {$_ -notmatch '<Report name='} | Set-Content $filepath
                        }
                    }
                } until ($found)
            }
        }
    }
    

    任何人的想法或评论?

1 个答案:

答案 0 :(得分:0)

我觉得这看起来很复杂。相反,我会检查它是否是第一个文件,如果它是我告诉它不要跳过任何行,如果它不是我发现的第一个文件<Report name=字符串,并跳过所有行包括那个。

然后我会检查它是否是最后一个文件,如果是,我会让它读取整个文件的其余部分,但是如果它不是最后一个文件我会读取除了最后两行之外的所有文件该文件超出了它可能阅读的范围。

一旦我知道在文件的开头和/或结尾要跳过多少行,我就会读取相应的行,并输出到新文件,根据需要附加。所有这些的代码如下所示:

$First = GCI ".\" -Filter *.nessus|Select -First 1
$Last = GCI ".\" -Filter *.nessus|Select -Last 1
GCI GCI ".\" -Filter *.nessus|%{
    If($_.Name -ne $First.Name){$SkipLines = (Select-String -Path $_.FullName -SimpleMatch "<Report name="|select -expand LineNumber)+1}else{$SkipLines = 0}
    If($_.Name -ne $Last.Name){$ReadLines = (GC $_.FullName).Count - 2 - $SkipLines} else {$ReadLines = (GC $_.FullName).Count - $SkipLines}
    GC $_.FullName | Select -First $ReadLines -Skip $SkipLines | Out-File ".\Merged.nessus" -Append
}