Public/Get-PSTenableSeverity.ps1
function Get-PSTenableSeverity { <# .SYNOPSIS Retrieves all vulnerabilities that are Critical, High, Medium, or Low in Tenable. .DESCRIPTION This function provides a way to retrieve all vulnerabilities in Tenable that are Critical, High, Medium, or Low. Revision 0.1, Sept 2019, jwmoss Revision 0.2, Nov 2019, aarong1234 .INPUTS None .PARAMETER Severity Option for any of "Critical", "High", "Medium", "Low", "All", "All with Info". Defaults to "Critical","High". All with Info will get ALL vuln data .PARAMETER MaxRecords Option for maximum records (rows of data) that should be requested (as a throttle), Default is 0 (all records) [note: sorted by score, descending] .PARAMETER Detailed Option to enable detailed data. Defaults to Summary Data. To determine how detailed the resulting data is by querying Tenable.sc "Vulnerability Summary" versus "Vulnerability Detail" .OUTPUTS PSCustomObject .NOTES None .EXAMPLE Get-PSTenableSeverity -Severity "Critical" Retrieves all critical vulnerabilities, Summary Data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)] .EXAMPLE Get-PSTenableSeverity -Detailed Retrieves all critical and high vulnerabilities, Detailed Data (return Tenable.sc Vulnerability Detail data instead of summary) [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)] .EXAMPLE Get-PSTenableSeverity -Severity "High","Medium" -Maxrecords 200 Retrieves high and medium vulnerabilities, up to 200 records, Summary Data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)] .EXAMPLE Get-PSTenableSeverity -Severity "All" -Detailed Retrieves all non-info vulnerabilities, Detailed data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)] #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory = $false)] [ValidateSet( 'Critical', 'High', 'Medium', 'Low', 'All', 'All with Info' )] [string[]] $Severity, [Parameter(Position = 1, Mandatory = $false)] [int]$MaxRecords = 0, [Parameter(Mandatory = $false)] [ValidateSet($true,$false)] [switch] $Detailed ) begin { $TokenExpiry = Invoke-PSTenableTokenStatus if ($TokenExpiry -eq $True) {Invoke-PSTenableTokenRenewal} if (-not $Severity) { $ID = @("4","3") #Magic Numbers for Critical & High } elseif ($Severity -contains "All with Info") { $ID = @("4","3","2","1","0") #all but info } elseif ($Severity -contains "All") { #if $severity has both All and All with Info.. All with Info will take precedence $ID = @("4","3","2","1") } else { #if Severity has All or All with info, other values are ignored $ID = @() switch ($Severity) { "Critical" { $ID += "4" } "High" { $ID += "3" } "Medium" { $ID += "2" } "Low" { $ID += "1" } } } $ID = $ID | Sort-Object -Descending } process { $APIresults = @() $CurrentStartOffset = 0 $ID | ForEach-Object { #because of lack of useful sorting data (scores, time) within a severity in summary data... we are going to query severities in order $Sev = $_ Do { if ($MaxRecords -ne 0 -and $MaxRecords -lt ($CurrentStartOffset + 2147483647)) { $CurrentEndOffset = $MaxRecords } else { $CurrentEndOffset = ($CurrentStartOffset + 2147483647) } $PreJSON = @{ "type" = "vuln" "sourceType" = "cumulative" "sortField" = "basescore" "sortDir" = "DESC" "query" = @{ "type" = "vuln" "startOffset" = $CurrentStartOffset "endOffset" = $CurrentEndOffset "tool" = & {if ($Detailed) {"vulndetails"} else {"listvuln"}} } } if ($ID) { $PreJSON.query.add("filters",[array]@{ "filterName" = "severity" "operator" = "=" "value" = "$Sev" }) } $Splat = @{ Method = "Post" Body = $(ConvertTo-Json $PreJSON -depth 5) Endpoint = "/analysis" } #Note: initially I was paginating every 2000, but frankly it was super inefficient, now we paginate on sizeof(Int32) $ThisResults = Invoke-PSTenableRest @Splat | Select-Object -ExpandProperty Response | Select-Object -ExpandProperty Results if ($ThisResults) { #non zero records came back $APIresults += $Thisresults #move pagination line (if you it is ever hit) $CurrentStartOffset = $CurrentEndOffset if ($Maxrecords -and ($CurrentStartOffset -ge $MaxRecords)) {$ThisResults = $Null} # we don't need to loop anymore } } While ($ThisResults) } $APIresults | Sort-object vprscore,basescore -Descending } end { } } |