PowerShell PSScriptAnalyzer
PSScriptAnalyzer is a static analyser for PowerShell. Invoke-ScriptAnalyzer -Path .\script.ps1 checks your code against a set of rules and reports what it finds, without running anything.
Documentation: Microsoft Learn
Overview
The rules catch the things reviewers keep flagging: unapproved verbs, Write-Host used for output, variables assigned and never used, plaintext passwords in parameters, cmdlet aliases in scripts, and missing ShouldProcess support on functions that change state.
Not every finding needs fixing. Some rules do not fit every context, and there is a supported way to say so: suppress a specific rule on a specific function with [Diagnostics.CodeAnalysis.SuppressMessageAttribute()], or configure exclusions in a settings file passed with -Settings. What you should not do is ignore the output wholesale, because then the tool tells you nothing.
It belongs in CI. Invoke-ScriptAnalyzer -Path . -Severity Error and fail the build on any result gives you a floor that does not depend on anyone remembering to look.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$findings = @(
[pscustomobject]@{ Severity = 'Warning';RuleName = 'PSAvoidUsingWriteHost';Line = 12 }
[pscustomobject]@{ Severity = 'Warning';RuleName = 'PSUseDeclaredVarsMoreThanAssignments';Line = 31 }
[pscustomobject]@{ Severity = 'Error';RuleName = 'PSUseApprovedVerbs';Line = 3
})
$findings | Format-Table Severity, RuleName, Line- Stage 1$findings
Positional values or no named parameters - Stage 2Format-Table
Positional values or no named parameters
An example to inspect
Preview the example. Sign in for the full lesson and activities.
$findings = @(
[pscustomobject]@{ Severity = 'Warning';RuleName = 'PSAvoidUsingWriteHost';Line = 12 }
[pscustomobject]@{ Severity = 'Warning';RuleName = 'PSUseDeclaredVarsMoreThanAssignments';Line = 31 }
[pscustomobject]@{ Severity = 'Error';RuleName = 'PSUseApprovedVerbs';Line = 3
})
$findings | Format-Table Severity, RuleName, LineWhat happens
This shows the shape of an analyser report so the columns are familiar. Severity is Information, Warning or Error, RuleName is the stable identifier you would suppress or filter on, and Line points at the code. Filtering on Severity is how you set a CI threshold without drowning in style warnings.
Worth remembering
- Invoke-ScriptAnalyzer checks code without executing it.
- Suppress individual rules with the attribute or a settings file.
- Common catches: unapproved verbs, Write-Host, unused variables, aliases.
- Run it in CI and fail on Error severity.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Shows the columns an analyser report returns and how to filter them.
Show reference output
Illustrative output · values vary by environment
Severity RuleName Line -------- -------- ---- Warning PSAvoidUsingWriteHost 12 Warning PSUseDeclaredVarsMoreThanAssignments 31 Error PSUseApprovedVerbs 3