PowerShell scripts can change files, services, accounts, cloud resources, and system settings in seconds. A quick review before execution helps you catch syntax errors and fragile patterns while the code is still easy to change.
PSRafScan combines PowerShell's native parser with 58 focused rules. The parser catches syntax problems. The rules look for patterns related to error handling, destructive operations, credentials, portability, terminal paste behavior, and other common sources of trouble.
This guide shows a practical review process you can repeat before testing a script.
Start with the script's job
Before looking at individual commands, write down what the script is supposed to do:
- What inputs does it accept?
- What output should it produce?
- Which files, services, accounts, or settings can it change?
- Does it require a module, network connection, credential, or elevated session?
- What should happen when an operation fails?
These answers give you a reference for judging the code. A command can be valid PowerShell and still be wrong for the task.
Check the syntax with PowerShell's parser
PowerShell exposes a parser that reads source text and returns tokens, parse errors, and an abstract syntax tree. PSRafScan uses that parser before applying its own rules.
For example, this script is missing a closing brace:
if ($true) {
Write-Output 'The block never closes'Save it as ParserError.ps1, then run:
RSX -Path ./ParserError.ps1 -IntendedUse Ps1File -FailOn ErrorPSRafScan reports a PowerShellParseError with severity Error. Correct syntax errors first because the parser could not build a complete representation of the script.
You can also call the parser directly when you need a small syntax-only check:
$tokens = $null
$errors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
(Resolve-Path ./ParserError.ps1),
[ref] $tokens,
[ref] $errors
)
$errors | Select-Object Message, ExtentReview static findings in context
A script can parse cleanly and still contain code that deserves attention. Each PSRafScan finding includes a rule name, severity, category, source location, issue, and recommended change.
Hidden failures
This command suppresses a non-terminating error:
Get-ChildItem -LiteralPath $Path -ErrorAction SilentlyContinueThat can be intentional, but it can also make a failed operation look like an empty result. The SilentErrorAction rule asks you to decide whether the failure should be visible.
When failure matters, make it explicit:
try {
Get-ChildItem -LiteralPath $Path -ErrorAction Stop
}
catch {
Write-Error "Could not read '$Path': $($_.Exception.Message)"
}The change is useful because the caller can distinguish an empty directory from an operation that did not succeed.
Destructive file operations
Treat the next example as source to inspect, not a command to run:
$target = Join-Path ([System.IO.Path]::GetTempPath()) 'PSRafScanDemo'
Remove-Item -LiteralPath $target -Recurse -ForceThe RecursiveForceDelete rule calls attention to Remove-Item with both -Recurse and -Force when -WhatIf is absent. Before allowing a deletion, inspect how the path is created, whether it can become a root or unexpected directory, which identity runs the command, and what recovery is available.
A preview-oriented revision can add validation and -WhatIf:
$target = Join-Path ([System.IO.Path]::GetTempPath()) 'PSRafScanDemo'
$resolvedTarget = [System.IO.Path]::GetFullPath($target)
$root = [System.IO.Path]::GetPathRoot($resolvedTarget)
if ([string]::IsNullOrWhiteSpace($resolvedTarget) -or $resolvedTarget -eq $root) {
throw 'Refusing an empty or root deletion target.'
}
Remove-Item -LiteralPath $resolvedTarget -Recurse -Force -WhatIf-WhatIf previews the command's supported action. Continue to inspect the surrounding path and control logic before any real deletion.
Document markup inside a script
Code copied from documentation or a chat response may still contain Markdown fences:
```powershell
Get-Process
```The fence lines are formatting, not PowerShell. Copy only the code into the .ps1 file. PSRafScan's MarkdownCodeFence rule catches raw fence lines left in executable source.
Choose the intended use
PSRafScan offers two modes because saved scripts and terminal input do not have the same context.
| Intended use | Choose it when | Example |
|---|---|---|
Ps1File | The code will remain a saved .ps1 file | RSX -Path ./script.ps1 -IntendedUse Ps1File |
TerminalPaste | The code will be entered directly into a live terminal | RSX -Path ./paste.ps1 -IntendedUse TerminalPaste |
The choice changes which rules apply. For example, a top-level param() block is normal in a saved script but does not provide the same invocation behavior when pasted directly into a terminal.
Run a repeatable scan
For a saved script, start with an explicit command:
RSX -Path ./candidate.ps1 -IntendedUse Ps1File -FailOn WarningFor structured output, add JSON and a destination:
RSX -Path ./candidate.ps1 `
-IntendedUse Ps1File `
-FailOn Warning `
-OutputFormat Json `
-OutputPath ./candidate.psrafscan.jsonWork through the result in this order:
- Correct parser errors.
- Read Error findings in their surrounding code.
- Review Warning and Information findings, even when they are below the selected threshold.
- Make a focused edit that you can explain.
- Compare the revision with the previous version.
- Run the same scan again.
Understand the process result
| Code | Status | Meaning |
|---|---|---|
0 | Pass | Parsing succeeded and no finding met the selected FailOn threshold. |
1 | Fail | At least one rule finding met the threshold. |
2 | ParseError | PowerShell reported one or more syntax errors. |
FailOn controls the process result, not the contents of the report. A lower-severity finding can still be present when the process returns 0.
Plan the runtime test separately
Static analysis helps you understand source before execution. Runtime testing still answers questions about real modules, permissions, data, services, network responses, timing, and side effects.
Use known inputs, minimal privileges, and a test environment appropriate to the script. Define the expected output before running it, and make recovery or cleanup part of the plan when the script changes state.
Continue the review
- Run a PSRafScan review
- Choose between Ps1File and TerminalPaste
- Browse all 58 rules
- Compare saved scripts with terminal input
