Direct answer: Review AI-generated PowerShell by first defining the task and allowed effects, preserving the original response, extracting code without silently rewriting it, selecting Ps1File or TerminalPaste, and running parser and static-rule checks. Send only a redacted finding and the smallest necessary excerpt for revision, reject unrelated changes in the diff, and rescan. A clean static checkpoint still requires a separate human decision about controlled runtime testing.

AI-generated code should begin as a candidate, not as a command. The useful question is not “Does this look plausible?” It is “What evidence would let a person accept this candidate for a controlled test?” That change in framing creates a review process with explicit inputs, bounded revisions, and a stop point.

The workflow below never asks an AI assistant to run the script or declare it safe. It uses native PowerShell parsing, PSRafScan-owned static rules, a human diff review, and a later runtime-test decision as separate checkpoints. In the preserved source snapshot, PSRafScan reads a script and does not intentionally execute the target during analysis; that is a static-analysis boundary, not a sandbox or a guarantee of safety.1

1. Define the task before reviewing the code

Write down the requested behavior independently of the generated script. If the intended result is vague, no parser or scanner can tell you whether the implementation solves the right problem.

For the benign example in this article, the review contract is:

Review questionAnswer for this candidate
What is the task?List file names and lengths in one caller-supplied directory.
What input is allowed?One existing directory path supplied through -Path.
What output is observable?Objects containing Name and Length, one for each file returned.
What privileges are expected?Only the caller's existing read access. No elevation.
What side effects are allowed?None: no file writes or deletes, configuration changes, network calls, process launches, package installation, or credential access.
How should failure appear?The caller must receive an error that identifies the failed directory operation.

Keep this contract next to the candidate. It becomes the basis for reviewing commands, parameters, privileges, output, and every proposed change.

2. Preserve the original response, then separate prose from code

Save the model's complete response unchanged before editing it. Record the prompt, model or service, date, and any supplied context allowed by your data-handling policy. A preserved original gives the diff a trustworthy starting point.

Model responses often wrap code in explanatory prose and Markdown fences. Fences such as ```powershell and ``` are document delimiters; they are not lines that belong in the .ps1 candidate. Remove the fence lines and surrounding prose, but do not “clean up” the code at the same time. Extraction and revision are different review events.

Here is the synthetic model-style response created and preserved for this walkthrough; it is not a transcript from a user, customer, or third-party AI session:

text
Here is a script that lists file names and sizes for a directory:

```powershell
param(
    [Parameter(Mandatory)]
    [string] $Path
)

Get-ChildItem -LiteralPath $Path -File -ErrorAction SilentlyContinue |
    Select-Object -Property Name, Length
```

Create candidate.ps1 by copying only the lines inside the fence, without changing them:

powershell
param(
    [Parameter(Mandatory)]
    [string] $Path
)

Get-ChildItem -LiteralPath $Path -File -ErrorAction SilentlyContinue |
    Select-Object -Property Name, Length

The pinned PSRafScan snapshot contains an enabled MarkdownCodeFence rule for both intended-use modes. Its preserved positive fixture reports an Error when raw fence lines remain in executable script text.2 Extraction removes that document-format problem; it does not approve the code inside the fence.

3. Choose the script's intended use

Select the context in which the text is meant to be used:

  • Choose Ps1File when the candidate will be saved and run as a .ps1 file.
  • Choose TerminalPaste when the candidate is meant to be pasted into a live PowerShell terminal.

This example has a top-level param block and is being preserved as candidate.ps1, so its intended use is Ps1File. If the request were to paste commands directly into a live terminal, review it as TerminalPaste instead. The modes select context-appropriate rules; they do not change the script's stated purpose. For a deeper comparison, see PowerShell Script vs. Terminal Paste: Why the Same Code Can Behave Differently and the intended-use documentation.

4. Run parser and PSRafScan rule review without running the target

PSRafScan's preserved analysis path uses PowerShell's Parser.ParseFile API and then evaluates PSRafScan-owned rules. Microsoft's API returns the script's tokens, parse errors, and abstract syntax tree (AST); parsing is not the same operation as invoking the script.3

In an environment where the reviewed PSRafScan module is already present, the file-path scan for this candidate is:

powershell
Invoke-PSRafScan -Path ./candidate.ps1 -IntendedUse Ps1File -FailOn Warning -NonInteractive

This command uses the verified public file-path interface. The reviewed source supports an existing file path or the clipboard as scan input; it does not establish a public raw-string input.1

Read the report, not only the process result. FailOn controls when findings produce a failing process result; it does not hide findings below that threshold. In the pinned implementation, result code 0 means the selected threshold passed, 1 means a finding met the threshold, and 2 means a parser error was present.4

For this walkthrough, the source-backed expected checkpoints are:

Candidate stateExpected targeted findingWhat to do
Raw code block saved with the Markdown fence linesMarkdownCodeFence - ErrorExtract the code from the document wrapper without altering the inner code, then scan again.
Extracted candidate.ps1 shown aboveSilentErrorAction - WarningDecide whether the failure is genuinely optional. Here it is not, because the review contract requires visible failure.
Revised candidate shown belowNo MarkdownCodeFence or SilentErrorAction finding expectedReview the full report and diff; the absence of these two findings is not proof that no other finding or runtime issue exists.

These targeted checkpoints were reproduced with PowerShell 7.4.17 and 7.6.3 on Ubuntu 24.04.3. The raw fenced block produced two MarkdownCodeFence Errors, one SilentErrorAction Warning, and three UnknownCommand Warnings with process result 1; it was never executed. The extracted candidate produced one SilentErrorAction Warning with process result 1 and was never executed. The revised candidate rescanned with process result 0 and no findings.

5. Turn a finding into a bounded revision request

The SilentErrorAction rule identifies -ErrorAction SilentlyContinue, which can hide a failure that should be handled. Microsoft's PowerShell documentation states that SilentlyContinue suppresses the error message and continues execution. It also states that Stop promotes a non-terminating error so a try/catch block can catch it.5

Do not respond by sending the entire script, full scan report, local path, or environment details to an external AI service. PSRafScan reports can contain line text and snippets, which may expose sensitive content.1

Privacy boundary: Follow your organization's data-handling rules and the AI service's current terms before sharing any source or report content. Remove credentials, tokens, connection strings, account names, host names, internal paths, customer data, and unrelated code. Prefer the rule name, severity, issue, fix guidance, stated behavior, and the smallest redacted excerpt. If redaction removes context needed to judge the change, stop and use an approved human review path.

The following handoff contains only what is needed to address this example's finding:

text
Task: Revise only the error handling in this read-only PowerShell snippet.

Required behavior:
- Accept a caller-supplied directory path.
- Return Name and Length for files in that directory.
- Make a directory-read failure visible to the caller.

Finding:
- Rule: SilentErrorAction
- Severity: Warning
- Issue: -ErrorAction SilentlyContinue can hide a failure that should be handled.
- Allowed direction: Use -ErrorAction Stop with a meaningful catch block.

Sanitized excerpt:
Get-ChildItem -LiteralPath $Path -File -ErrorAction SilentlyContinue |
    Select-Object -Property Name, Length

Constraints:
- Do not change parameters or output properties.
- Do not add file writes, deletes, network access, external processes, elevation, prompts, or dependencies.
- Return a revised snippet and a unified diff.
- Do not execute the code.

This handoff does not ask the model to redesign the script or “fix everything.” Its allowed edit is tied to one finding and one observable requirement.

6. Review the proposed diff, not just the revised script

A bounded revision for the example is:

powershell
param(
    [Parameter(Mandatory)]
    [string] $Path
)

try {
    Get-ChildItem -LiteralPath $Path -File -ErrorAction Stop |
        Select-Object -Property Name, Length
}
catch {
    Write-Error -Message "Could not list files at '$Path': $($_.Exception.Message)"
}

The before/after diff is deliberately small:

diff
 param(
     [Parameter(Mandatory)]
     [string] $Path
 )
 
-Get-ChildItem -LiteralPath $Path -File -ErrorAction SilentlyContinue |
-    Select-Object -Property Name, Length
+try {
+    Get-ChildItem -LiteralPath $Path -File -ErrorAction Stop |
+        Select-Object -Property Name, Length
+}
+catch {
+    Write-Error -Message "Could not list files at '$Path': $($_.Exception.Message)"
+}

Review each added and removed line against the contract:

  • The parameter and selected output properties did not change.
  • The file operation is still read-only.
  • No network, process, privilege, credential, prompt, or dependency behavior was added.
  • SilentlyContinue became Stop, and the catch block makes the failure visible.
  • The catch message includes the underlying exception message, rather than replacing it with an unexplained success or empty output.

Reject the revision if it changes unrelated commands, broadens paths, adds convenience behavior, introduces a new dependency, or cannot explain why each changed line is needed. Start a separate review request for any additional change.

7. Rescan and apply stop-or-escalate rules

Save the accepted revision as a new file or commit; do not overwrite the only copy of the original. Run the same scan configuration again:

powershell
Invoke-PSRafScan -Path ./candidate-revised.ps1 -IntendedUse Ps1File -FailOn Warning -NonInteractive

Confirm that:

  1. no parser errors were introduced;
  2. MarkdownCodeFence is absent because only executable code is in the file;
  3. SilentErrorAction is absent because the targeted construct changed;
  4. the full report has been reviewed, including findings below the selected FailOn threshold; and
  5. the diff still matches the task contract.

Stop and escalate to a qualified human reviewer when any of these conditions applies:

  • a parser Error or an unexplained Error/Warning remains;
  • the model repeatedly reintroduces the same finding;
  • the requested revision changes purpose, inputs, output, or side effects;
  • a command needs elevation, secrets, external downloads, network access, interactive approval, or a production endpoint;
  • the script changes files, accounts, services, policy, configuration, or infrastructure without an approved test and recovery plan;
  • a command or module cannot be identified from authoritative documentation;
  • the expected result cannot be observed independently; or
  • you cannot define a sufficiently isolated runtime test.

“Escalate” is a successful outcome of the review process. It prevents an uncertain candidate from being promoted simply because an AI assistant produced another plausible revision.

8. Keep static acceptance separate from runtime testing

Static review and runtime testing answer different questions:

Static acceptance can establishStatic acceptance cannot establish
Whether PowerShell reports parser errorsWhether the script produces the correct result with real data
Whether configured PSRafScan rules report known patternsWhether every risky or incorrect behavior has been detected
Whether a targeted finding disappeared after a bounded changeWhether the replacement behavior works in every host or environment
Whether the human-reviewed diff stayed within the stated scopeWhether permissions, modules, services, network conditions, and external systems behave as assumed
Whether the candidate is ready for a test decisionWhether the candidate is safe or production-ready

If the candidate reaches static acceptance, create a separate test record. For this read-only example, a controlled test would use a temporary directory containing known sample files, a nonprivileged account, an identified PowerShell 7.4+ host, and expected Name/Length output. It would also test a missing or unreadable path to confirm that failure is visible. Record the OS, PowerShell version, host, exact command, input, observed output, and cleanup.

That later test is intentional execution. It must not be folded into the scanner step or described as something PSRafScan performed.

Human review checklist

Use this checklist even when a scan reaches the selected threshold:

Review areaQuestions to answer before a controlled test
Files and system changesWhich paths, registry keys, services, packages, accounts, jobs, cloud resources, or settings can change? Are scope and recovery explicit?
PrivilegesDoes any command require elevation, delegated access, a broader role, or a different identity? Why?
Prompts and interactionCan the script wait for input, confirmation, credentials, UI, or host-specific behavior? What happens unattended?
Credentials and sensitive dataWhere do secrets and personal or customer data come from? Could they appear in source, output, logs, errors, reports, or an AI handoff?
External commands and modulesAre every executable, module, provider, API, and endpoint identified and approved? Are versions or paths ambiguous?
Error handlingAre failures visible, specific, and propagated appropriately? Could the script continue after a partial failure?
Output and successWhat exact objects, files, messages, or state changes prove success? How will partial or duplicate results be detected?
RepeatabilityWhat happens on a second run? Can the operation be retried or reversed without compounding damage?
EnvironmentWhich OS, PowerShell version, host, working directory, permissions, and dependencies are assumed?

Frequently asked questions

Does PSRafScan run the AI-generated script while scanning it?

The preserved source path reads the target, calls the native PowerShell parser, and evaluates PSRafScan-owned rules without intentionally invoking the target script.1 That does not make the scanner a sandbox, malware detector, or proof that the target is safe.

Does a passing scan mean the generated script is safe to run?

No. A passing process result means no reported finding met the selected FailOn threshold. It does not establish runtime correctness, safe side effects, complete rule coverage, trustworthy dependencies, or compatibility with a particular environment. Review all findings and make a separate controlled-test decision.

Should I send the complete report back to the AI assistant?

Usually not. Send the least information needed: the rule name, severity, issue, fix direction, required behavior, constraints, and a small redacted excerpt. Full reports can include source text and the scanned script path, so treat them as potentially sensitive. Use an approved human path when the necessary context cannot be shared safely.

Which intended use should I choose for generated code?

Choose Ps1File for a candidate intended to be saved as a .ps1 script. Choose TerminalPaste for commands intended to be pasted into a live PowerShell terminal. If the delivery method is undecided, decide it before scanning because the contexts are not interchangeable. See the saved-script versus terminal-paste guide.

Are Markdown fences part of the PowerShell script?

No. They delimit a code block in Markdown. Preserve the full response, then copy only the code inside the fence into the candidate file. Do not combine fence removal with silent code edits.

What if the revision introduces a new command or broader behavior?

Reject it from the current change. Identify the new command from authoritative documentation, update the task contract if the behavior is truly required, and begin a separate bounded review. A model should not expand scope merely to make one finding disappear.

Continue with the complete workflow

Use the AI-generated PowerShell workflow to turn this process into a repeatable review record, including preservation, intended use, findings, revision constraints, diff approval, rescanning, and the separate controlled-test decision.

Follow the AI-generated PowerShell review workflow

Sources

Sources were retrieved or preserved on 2026-07-12.

Verification and editorial record

Technical verification: The owner confirms successful PSRafScan and article testing on Windows, macOS, and Ubuntu. This readiness confirmation does not claim behavior in every environment, guarantee runtime correctness or safety, or represent independent human technical review.

AI assistance: Material AI assistance was used to organize evidence, draft, edit, and verify this article. Rafael Lucas is the named human author and is accountable for the article under the editorial policy.

Reviewed against: PSRafScan public source at commit c9d2a8588d042eef021d43edc2e4586318df1482, version 0.2.0-alpha1.

Corrections: Report a factual or technical error through the privacy-aware corrections process. Use the security route for a vulnerability.

Notes

  1. Reviewed PSRafScan public alpha source snapshot at commit c9d2a8588d042eef021d43edc2e4586318df1482: product definition, Invoke-PSRafScan, input resolution, native scan, parser analysis, reporting, thresholds, and security boundaries. The repository and release destinations are public first-party project resources.
  2. Reviewed MarkdownCodeFence.rule.ps1, SilentErrorAction.rule.ps1, and their positive self-test fixtures from the same pinned source snapshot. The source-defined expectations were checked with PowerShell 7.4.17 on Linux.
  3. Microsoft Learn, Parser.ParseFile(String, Token[], ParseError[]), retrieved 2026-07-12.
  4. Preserved Get-PSRafScanExitCode.ps1 and Invoke-PSRafScan.ps1 at the pinned snapshot. Only result codes 0, 1, and 2 are described here.
  5. Microsoft Learn, about_CommonParameters - -ErrorAction, retrieved 2026-07-12.