1

What I need: Convert ~45 ReportGenerator.bat .fpr Fortify Report output files (to XML then parse) into SCA issue counts by severity. Output to a CSV (or at least screen output as a table) with one line per Project.

Desired output:

BuildFolder,ProjectName,Critical,High,Medium,Low
ScaBuild1,Project1,1,1,2,13
ScaBuild1,Project2,0,0,7,500
ScaBuild2,Project3,0,0,5,10
...

Questions (Issues with my current script below):

1: How do I sort change parsed XML node order Critical, High, Medium, Low (inserting 0 where result is missing)?

Note the default XML output is tricky to parse (GroupingSection has count attribute followed by groupTitle Element containing the severity title).
Example:  <GroupingSection count="4484"><groupTitle>Low</groupTitle></GroupingSection>

Q1 is what I'll use for valid answer (but comments/answers for #2 and #3 is strong bonus and upvote-worthy)

2: Transform current "Select-XML … Select-Object … | Format-Table" piped output to instead populate an array object (to merge with BuildFolder and ProjectName)?

3: Once results array is built how do I output to a .csv file and then output to screen (as nicely tabbed table)?

Thanks in advance for your helpful input!

MORE INFORMATION

Example Path & file structure (for 45 projects):

c:\FortifyResults\ScaBuild1\  Project1.fpr, Project2.fpr
c:\FortifyResults\ScaBuild2\  Project3.fpr, Project4.fpr, Project5.fpr
…

Script currently used (converts each .fpr file to XML (default Fortify template) and outputs counts from GroupingSection as table for each .xml)

#Parameters
$FprFilePath="d:\HPFortifyBuild1\2019.02.06"

#HPF References
    $FortifyInstallPath       ="C:\Program Files\HP_Fortify\HP_Fortify_SCA_and_Apps_16.11"
    $FortifyReportGenerator   ="$FortifyInstallPath\ReportGenerator.bat"
    $FortifyXmlReportTemplate ="$FortifyInstallPath\Core\config\reports\DefaultReportDefinition.xml"

CD $FprFilePath
    Get-ChildItem "$FprFilePath" -Filter *.fpr | 
    Foreach-Object {
        $NameFpr=$_.Name
        $NameXml=($_.BaseName+".xml")

        Write-Host "$NameFpr - Generating $NameXml report..."
        & "C:\Program Files\HP_Fortify\HP_Fortify_SCA_and_Apps_16.11\bin\ReportGenerator.bat" -format xml -f $NameXml -source $NameFpr -template DefaultReportDefinition.xml

        #Write-Host "$FprFilePath\$NameXml RESULTS:"
        Select-XML -Path $FprFilePath\$NameXml -Xpath "/ReportDefinition[1]/ReportSection[1]/SubSection[2]/IssueListing[1]/Chart[1]/GroupingSection" | Select-Object -ExpandProperty Node | Format-Table -AutoSize
        #Write-Host " "
    }

Current script output sample:

Project1.fpr - Generating Project1.xml report...

count groupTitle
----- ----------
13    Low       
2     Medium    
1     Critical  
1     High      


Project2.fpr - Generating Project2.xml report...

count groupTitle
----- ----------
500   Low       
7     Medium
…

Excerpt from Project1.xml (parsed from Project1.fpr via script)

Script Command: ReportGenerator.bat" -format xml -f $NameXml -source $NameFpr -template DefaultReportDefinition.xml

Project1.xml excerpt:

<Description>A table summarizing the number of issues found and the breakdown of issues in each Fortify Priority Level</Description>
    <IssueListing listing="false" limit="-1">
    <Refinement/>
        <Chart chartType="table">
            <Axis>Fortify Priority Order</Axis>
            <MajorAttribute>Analysis</MajorAttribute>
            <GroupingSection count="4484"><groupTitle>Low</groupTitle></GroupingSection>
            <GroupingSection count="431"><groupTitle>Medium</groupTitle></GroupingSection>
            <GroupingSection count="114"><groupTitle>High</groupTitle></GroupingSection>
            <GroupingSection count="13"><groupTitle>Critical</groupTitle></GroupingSection>
        </Chart>
    </IssueListing>

Note the default XML output is tricky to parse (GroupingSection has count attribute followed by groupTitle Element containing the severity title). Example:

<GroupingSection count="4484"><groupTitle>Low</groupTitle></GroupingSection>

SSC is NA: I don't have SSC available for this isolated build environment so SSC APIs or related solutions do not apply to this question.

Related StackOverflow questions reviewed (so far):

Zephan Schroeder
  • 695
  • 6
  • 12
  • 1
    This question - well, there's multiple questions - is far too broad, but one suggestion is to try Python; it can do many of these tasks easily, and is a lot less painful to read than Powershell. – Ken Y-N Feb 13 '19 at 01:46
  • I edited to focus on Question#1. PowerShell is already in the target environment. Also currently I am slightly more familiar with PS than Python. Thanks for the suggestion Ken. – Zephan Schroeder Feb 13 '19 at 04:50
  • OK, I've [found this answer](https://stackoverflow.com/a/18035655/1270789) and [this one](https://stackoverflow.com/a/34519859/1270789) and [this one](https://stackoverflow.com/a/9683142/1270789) that suggests something like `[xml]$foo = Get-Content Project1.xml; $foo.SelectNodes -Xpath '//GroupingSection[groupTitle="Critical"]'`, perhaps? If I have more time I'll investigate further and make an answer. – Ken Y-N Feb 13 '19 at 07:51

1 Answers1

0

This appears to answer your initial question:

$xml = [xml]Get-Content Project1.xml
Foreach ($status in @("Critical", "High", "Medium", "Low"))
{
    $node = $xml.SelectNodes("//GroupingSection[groupTitle=""$status""]").Item(0)
    Write-Host $node.groupTitle, ",", $node.count;
}

This gives rather poorly-formatted output, but it will get you started:

Critical , 13
High , 114
Medium , 431
Low , 4484
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • Thanks for this sample which shows how to iterate and order. Per *desired Output" i need output to build table/csv matching BuildFolder,ProjectName,Critical,High,Medium,Low. A bit more variable/object work is needed before it answers question#1. Instead of Write-Host perhaps build on a PSCustomObject or 2 dimensional array variable populated with one row per parsed file? (Answer also needs to perform OK for 45 files (rows) - ideally append to object/array for each file rather than rebuilding entire variable each time.) – Zephan Schroeder Feb 13 '19 at 16:06