Public/Start-FODStaticScan.ps1
function Start-FODStaticScan { <# .SYNOPSIS Starts a static scan in FOD. .DESCRIPTION Starts a Fortify On Demand static scan by uploading a Zip file with the source code to analyse. The scan options (such as lanaguage/technology etc) should have been set and saved in FOD prior to executing this function. .PARAMETER BSIToken The Build Server Integration (BSI) token found in Fortify on Demand Portal. Note: The BSI token is being deprecated, please use ReleaseId or ApplicationName and ReleaseName. .PARAMETER ReleaseId The Id of the release to import into. .PARAMETER ApplicationName The Name of the application to import into. .PARAMETER ReleaseName The Name of the release to import into. Note: Both ApplicationName and ReleaseName are required if not specifying ReleaseId .PARAMETER ZipFile The absolute path of the Zip file to upload. .PARAMETER IsRemediationScan Select to force a remediation scan. .PARAMETER EntitlementPreference The entitlement preference type. Valid values are: SingleScanOnly, SubscriptionOnly, SingleScanFirstThenSubscription, SubscriptionFirstThenSingleScan .PARAMETER PurchaseEntitlement Select if an entitlement should be purchased if one is not available. .PARAMETER RemediationScanPreference The remdiation scan preference type. Valid values are: RemediationScanIfAvailable, RemediationScanOnly, NonRemediationScanOnly .PARAMER InProgressScanPreference The action to perform if a scan is already running. Valid values are: DoNotStartScan, CancelInProgressScan .PARAMETER Notes Any notes to be included with the scan. Optional. .PARAMETER Raw If specified, provide raw output and do not parse any responses. .PARAMETER Token FOD token to use. If empty, the value from PS4FOD will be used. .PARAMETER Proxy Proxy server to use. Default value is the value set by Set-FODConfig .EXAMPLE # Starts a static scan using the BSI Token $BsiToken and the Zip file "C:\Temp\upload\fod.zip" Start-FODStaticScan -BSIToken $BsiToken -ZipFile C:\Temp\upload\fod.zip ` -RemediationScanPreference NonRemediationScanOnly -EntitlementPreference SubscriptionOnly ` -InProgressScanPreference DoNotStartScan -Notes "some notes" .EXAMPLE # Starts a static scan using the release id 1000 and the Zip file "C:\Temp\upload\fod.zip" Start-FODStaticScan -ReleaseId 1000 -ZipFile C:\Temp\upload\fod.zip ` -RemediationScanPreference NonRemediationScanOnly -EntitlementPreference SubscriptionOnly ` -InProgressScanPreference DoNotStartScan -Notes "some notes" .LINK https://api.ams.fortify.com/swagger/ui/index#!/StaticScans/StaticScansV3_StartScanAdvanced .FUNCTIONALITY Fortify on Demand #> [CmdletBinding()] param ( [Parameter(Mandatory=$False)] [string]$BSIToken, [Parameter(Mandatory=$False)] [int]$ReleaseId, [Parameter(Mandatory=$False)] [string]$ApplicationName, [Parameter(Mandatory=$False)] [string]$ReleaseName, [Parameter(Mandatory)] [system.io.fileinfo]$ZipFile, [Parameter()] [switch]$IsRemediationScan, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet('SingleScanOnly', 'SubscriptionOnly', 'SingleScanFirstThenSubscription', 'SubscriptionFirstThenSingleScan', IgnoreCase = $false)] $EntitlementPreference, [Parameter()] [switch]$PurchaseEntitlement, [Parameter(Mandatory)] [ValidateSet('RemediationScanIfAvailable', 'RemediationScanOnly', 'NonRemediationScanOnly', IgnoreCase = $false)] $RemediationScanPreference, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet('DoNotStartScan', 'CancelInProgressScan', 'Queue', IgnoreCase = $false)] $InProgressScanPreference, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Notes, [switch]$Raw, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Token = $Script:PS4FOD.Token, [Parameter()] [ValidateNotNullOrEmpty()] [string]$ApiUri = $Script:PS4FOD.ApiUri, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Proxy = $Script:PS4FOD.Proxy, [switch]$ForceVerbose = $Script:PS4FOD.ForceVerbose ) begin { # If we don't have a ReleaseId we have to find it using API if (-not ($PSBoundParameters.ContainsKey('ReleaseId') -or $PSBoundParameters.ContainsKey('BSIToken'))) { if ($PSBoundParameters.ContainsKey('ApplicationName') -and $PSBoundParameters.ContainsKey('ReleaseName')) { try { $ReleaseId = Get-FODReleaseId -ApplicationName $ApplicationName -ReleaseName $ReleaseName Write-Verbose "Found Release Id: $ReleaseId" } catch { Write-Error $_ Break } } else { throw "Please supply a parameter for `"BSIToken`", `"ReleaseId`" or both `"ApplicationName`" and `"ReleaseName`"" } } # Get current module version $myModuleName = "PowerShellForFOD" $module = Get-Module -ListAvailable -Name $myModuleName $myModuleVer = $module.Version if ([string]::IsNullOrEmpty($myModuleVer)) { $myModuleVer = "1.0.0.0" } if (-not $ZipFile.Exists) { throw "Zip file '$ZipFile' does not exist" } $Params = @{} if ($Proxy) { $Params['Proxy'] = $Proxy } if ($ForceVerbose) { $Params.Add('ForceVerbose', $True) $VerbosePreference = "Continue" } $BSITokenObj = $null if ($BSIToken) { $BSITokenObj = Parse-FODBSIToken $BSIToken if ($BSITokenObj -eq $null) { throw "Unable to parse BSI token" } $ReleaseId = $BSITokenObj.releaseId } Write-Verbose "Start-FODStaticScan Bound Parameters: $( $PSBoundParameters | Remove-SensitiveData | Out-String )" $FileLength = $ZipFile.Length $Offset = 0 $FragmentNumber = 0 $ChunkSize = 1024 * 1024 # Create temporary file to store payload "chunks" in. $TempFile = New-TemporaryFile $TempFileName = $TempFile.FullName Write-Verbose "Created payload chunk temporary file: $TempFileName" $Params.Add('BodyFile', $TempFile.FullName) $Params.Add("ContentType", "application/octet-stream") $Response = $null } process { if ($IsRemediationScan.IsPresent) { $RemScanPrefVal = [RemediationScanPreferenceType]::RemediationScanOnly.value__ } elseif ($RemediationScanPreference -eq $null) { $RemScanPrefVal = [RemediationScanPreferenceType]::NonRemediationScanOnly.value__ } else { $RemScanPrefVal = [RemediationScanPreferenceType]::$RemediationScanPreference.value__ } $ScanPrefix = [string]::Format("/api/v3/releases/{0}/static-scans/start-scan-advanced?" + "releaseId={1}&entitlementPreferenceType={2}" + "&purchaseEntitlement={3}&remdiationScanPreferenceType={4}" + "&inProgressScanActionType={5}&scanTool={6}&scanToolVersion={7}&scanMethodType=CICD", $ReleaseId, $ReleaseId, [EntitlementPreferenceType]::$EntitlementPreference.value__, $PurchaseEntitlement.IsPresent, $RemScanPrefVal, [InProgressScanActionType]::$InProgressScanPreference.value__, $myModuleName, $myModuleVer) if (-not [string]::IsNullOrEmpty($BSIToken)) { $ScanPrefix = [string]::Format("{0}&bsiToken={1}", $ScanPrefix, $BSIToken) } if (-not [string]::IsNullOrEmpty($Notes)) { $ScanPrefix = [string]::Format("{0}¬es={1}", $ScanPrefix, $Notes) } # Open zip file for reading $stream = [System.IO.File]::OpenRead($ZipFile) $readByteArray = New-Object byte[] $ChunkSize while ($numBytesRead = $stream.Read($readByteArray, 0, $ChunkSize)){ if ($numBytesRead -lt $ChunkSize) { $FragmentNumber = -1 } if ($FragmentNumber -eq -1) { Write-Verbose "Sending last fragment" } else { Write-Verbose "Sending fragment: $FragmentNumber" } if ($PSVersionTable.PSVersion.Major -lt 6) { Set-Content -Path $TempFile.FullName -Value $readByteArray -Encoding Byte } else { Set-Content -Path $TempFile.FullName -Value $readByteArray -AsByteStream } $ScanUrl = "$ScanPrefix&fragNo=$FragmentNumber&offset=$Offset" Write-Verbose "Send-FODApi -Method Post -Operation $ScanUrl" #$Params $Response = Send-FODApi -Method Post -Operation $ScanUrl @Params $FragmentNumber++ $Offset += $numBytesRead Write-Verbose "Read bytes: $Offset / $FileLength" if ($FragmentNumber % 5 -eq 0) { Write-Host "Upload Status - Bytes sent: $Offset / $FileLength" } } } end { # Delete temporary file Write-Verbose "Deleting payload data temporary file: $TempFileName" $TempFile.Delete() if ($Raw) { $Response } else { $ScanId = $Response.scanId If ($ScanId) { Write-Host "Started static scan with scan id: $ScanId" } else { Write-Error "Error starting scan, could not extract scan id!" } } } } |