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



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

  1. 设置一些逻辑来识别第一个和最后一个文件,并对它们采取相应的行动。
  2. 删除除第一个扫描文件外所有扫描文件的最后33个字符。
  3. 获取每个文件的内容,一次读取一个对象。如果没有匹配,则删除该行并继续移动到下一个对象。如果有匹配,删除该行并停止(因此是do until)。
在这一点上,我还没有成功地使第三步起作用。代码如下:
$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)
        }
    }
}

有什么想法或评论吗?

我觉得这看起来真的很复杂。相反,我会检查它是否是第一个文件,如果是,我会告诉它不要跳过任何行,如果它不是第一个文件,我会让它找到<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
}

最新更新