I have a block of output that looks like this:
- KB3167679 (MS16-101) (2 vulnerabilities)The following CVEs would be covered: CVE-2016-3300, CVE-2016-3237 - KB3114340 (MS16-099) (16 vulnerabilities)The following CVEs would be covered: CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2014-6362
I'm able to get the KB and MS values easily but I'm having a harder time pulling all the CVE numbers that follow. Is it possible to split my output based on the string "- " so that I'll get strings like this:
- KB3167679 (MS16-101) (2 vulnerabilities)The following CVEs would be covered: CVE-2016-3300, CVE-2016-3237
- KB3114340 (MS16-099) (16 vulnerabilities)The following CVEs would be covered: CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, CVE-2014-6362
From here I think I could do a regex with -AllMatches
to get what I want.
I assume you'd want to preserve the relationship between the KB/MS identifier and the CVE codes.
For that purpose, I would populate a hashtable, by simply reading the text line by line, updating the key every time a KB line is encountered:
# This hashtable will hold our data
$CVECoverage = @{}
$KB = 'Unknown'
# Read file line by line
Get-Content D:\test\nessus.txt |ForEach-Object {
# Check if line is a "header" line, grab the KB/MS ID
if($_ -like '- *')
{
$KB = $_.Substring(2, $_.IndexOf(')') - 1)
# If we don't already have a record of CVEs for this KB, create a new array
if(-not $CVECoverage.ContainsKey($KB)){
$CVECoverage[$KB] = @()
}
}
else
{
# Find CVEs and add to respective hashtable entry
foreach($CVE in $_ | Select-String -Pattern 'CVE-\d{4}-\d{4,}' -AllMatches)
{
$CVECoverage[$KB] += $CVE.Matches.Value
}
}
}
If the input is already one big string, use the following to split it into individual lines:
$bigString -split "`r?`n" |ForEach-Object { ... }