CheckSolution.ps1
# # Filename: CheckSolution.ps1 # [CmdletBinding()] param( [string]$SolutionFile, #The absolute path to the solution file zip to be imported [string]$OutputPath, #The full path to where you want results to be stored [string]$TenantId , #The tenant Id where your instance resides [string]$ApplicationId , #The application Id used for the connection [string]$ApplicationSecret , #The application secret used for connection [string]$Ruleset , #The ruleset to be used when checking [string[]]$RuleCodes, #The Ids of the rules used when checking [string[]]$ExcludedFiles, #The Files/Patterns to be excluded from scanning [string]$RuleOverridesJson, #Json string containing rule overrides [string]$Geography, #The regional endpoint to hit [string]$LocaleName, #Specifies the language code that determines how the results are listed, such as es, for Spanish. The languages that are supported are included in the validation set of the parameter. [int]$MaxStatusChecks, #Maximum number of times in which status calls are made to the service. The default number is 20, which in most cases is sufficient. If the threshold is exceeded, then a timeout exception is thrown. [int]$SecondsBetweenChecks, #The number of seconds between status checks. The default is 15 seconds. [int]$MaxConnectionTimeOutMinutes, #Maximum number in minutes to wait before quitting a web based operation. [string]$PowerAppsCheckerPath, #The full path to the PowerApp Checker PowerShell Module [bool]$EnableThresholds, #Enables threshold checks [string]$ThresholdAction, # Warn, Error - The type of action to generate when number of issues exceeds threshold limit [int]$CriticalThreshold, #Number of critical severity issues [int]$HighThreshold, #Number of high severity issues [int]$MediumThreshold, #Number of medium severity issues [int]$LowThreshold #Number of low severity issues ) $ErrorActionPreference = "Stop" $InformationPreference = "Continue" Write-Verbose 'Entering CheckSolution.ps1' #Print Parameters Write-Verbose "SolutionFile = $SolutionFile" Write-Verbose "OutputPath = $OutputPath" Write-Verbose "TenantId = $TenantId" Write-Verbose "ApplicationId = $ApplicationId" Write-Verbose "Ruleset = $Ruleset" Write-Verbose "RuleCodes = $RuleCodes" Write-Verbose "ExcludedFiles = $ExcludedFiles" Write-Verbose "RuleOverridesJson = $RuleOverridesJson" Write-Verbose "Geography = $Geography" Write-Verbose "PowerAppsCheckerPath = $PowerAppsCheckerPath" Write-Verbose "Importing PowerApps Checker: $PowerAppsCheckerPath" Import-module "$PowerAppsCheckerPath\Microsoft.PowerApps.Checker.PowerShell.psd1" #Run PowerApps Checker if ($Ruleset) { $rulesets = Get-PowerAppsCheckerRulesets -Geography "$Geography" if ($rulesets.Length -gt 0) { $rulesetToUse = $rulesets | where Name -EQ "$RuleSet" if ($rulesetToUse) { Write-Verbose "Ruleset found" } else { throw "$RuleSet ruleset was not found" } } else { throw "No rule sets found" } } elseif ($RuleCodes) { $rules = @() foreach($ruleCode in $RuleCodes) { $rule = New-Object -TypeName "Microsoft.PowerApps.Checker.Client.Models.Rule" $rule.Code = $ruleCode $rules += $rule } } else { throw "Either RuleSet or RuleCodes is required" } $CheckParams = @{ FileUnderAnalysis = "$SolutionFile" OutputDirectory = "$OutputPath" Geography = "$Geography" TenantId = "$TenantId" ClientApplicationId = "$ApplicationId" ClientApplicationSecret = ConvertTo-SecureString "$ApplicationSecret" -AsPlainText -Force LocaleName = "$LocaleName" MaxStatusChecks = $MaxStatusChecks SecondsBetweenChecks = $SecondsBetweenChecks } if ($rulesetToUse) { $CheckParams.Ruleset = $rulesetToUse } if ($rules) { $CheckParams.Rule = $rules } if ($ExcludedFiles) { $CheckParams.ExcludedFileNamePattern = $ExcludedFiles } if ($RuleOverridesJson) { $overrides = @() #load json string into array $array = ConvertFrom-Json $RuleOverridesJson Write-Verbose ("Adding ({0}) Rule Overrides" -f $array.Count) #iterate through the configuration items and set secure configuration For ($i=0; $i -lt $array.Count; $i++) { $ruleId = $array[$i][0] $level = $array[$i][1] Write-Host "Adding override : $ruleId $level" $override = New-PowerAppsCheckerRuleLevelOverride -Id $ruleId -OverrideLevel $level $overrides += $override } if ($overrides.Count -gt 0) { $CheckParams.RuleLevelOverrides = $overrides Write-Host ("Added ({0}) Rule Overrides" -f $overrides.Count) } } if ($MaxConnectionTimeOutMinutes -ne 0) { $CheckParams.MaxConnectionTimeOutMinutes = $MaxConnectionTimeOutMinutes } $response = Invoke-PowerAppsChecker @CheckParams if( $response) { $CheckStatus = $response.Status Write-Host "PowerApps Check Status: $CheckStatus" Write-Host "Result File: $($response.DownloadedResultFiles)" Write-Host "Result File Uri: $($response.ResultFileUris)" if (($CheckStatus -eq "Finished") -or ($CheckStatus -eq "FinishedWithErrors")) { if ($CheckStatus -eq "FinishedWithErrors") { Write-Warning "PowerApp Checker finished with errors. Check results for more information" } Write-Host "============================================" -ForegroundColor DarkGreen $issues = $response.IssueSummary $critical = $issues.CriticalIssueCount $high = $issues.HighIssueCount $medium = $issues.MediumIssueCount $low = $issues.LowIssueCount $info = $issues.InformationalIssueCount Write-Host "Critical: $critical" -ForegroundColor Green Write-Host "High: $high" -ForegroundColor Green Write-Host "Medium: $medium" -ForegroundColor Green Write-Host "Low: $low" -ForegroundColor Green Write-Host "Informational: $info" -ForegroundColor Green Write-Host "============================================" -ForegroundColor DarkGreen $md = "| Severity | Count | `r`n" $md += "|:-----------|:-----------:| `r`n" $md += "| Critical | $critical | `r`n" $md += "| High | $high | `r`n" $md += "| Medium | $medium | `r`n" $md += "| Low | $low | `r`n" $md += "| Informational | $info | `r`n" Set-Content -Path "$OutputPath\CheckerResultsSummary.md" -Value "$md" if ($EnableThresholds) { $breached = ( ($critical -gt $CriticalThreshold) -or ($high -gt $HighThreshold) -or ($medium -gt $MediumThreshold) -or ($low -gt $LowThreshold) ) if ($breached) { $msg = "Number of issues detected above threshold limits" if ($ThresholdAction -eq "Warn") { Write-Warning $msg } elseif ($ThresholdAction -eq "Error") { Write-Error $msg } } } } elseif ($CheckStatus -eq "Failed") { throw "PowerApps Checker Failed" } else { Write-Warning "Unknown status return from PowerApps Checker" } } else { throw "Didn't recieve response from PowerApps Checker" } Write-Verbose 'Leaving CheckSolution.ps1' # End of script |