使用 PSScriptAnalyzer

本文介绍 PSScriptAnalyzer 的各种功能以及如何使用它们。

解析器错误

从版本 1.18.0 开始, PSScriptAnalyzer 在输出流中将分析器错误作为诊断记录发出。

Invoke-ScriptAnalyzer -ScriptDefinition '"b" = "b"; function eliminate-file () { }'
RuleName            Severity   ScriptName Line Message
--------            --------   ---------- ---- -------
InvalidLeftHandSide ParseError            1    The assignment expression isn't
                                               valid. The input to an
                                               assignment operator must be an
                                               object that's able to accept
                                               assignments, such as a variable
                                               or a property.
PSUseApprovedVerbs  Warning               1    The cmdlet 'eliminate-file' uses an
                                               unapproved verb.

RuleName 设置为解析器错误的 ErrorId

若要禁止显示 ParseErrors,请勿将其作为值包含在 Severity 参数中。

$invokeScriptAnalyzerSplat = @{
    ScriptDefinition = '"b" = "b"; function eliminate-file () { }'
    Severity = 'Warning'
}
Invoke-ScriptAnalyzer @invokeScriptAnalyzerSplat
RuleName           Severity ScriptName Line Message
--------           -------- ---------- ---- -------
PSUseApprovedVerbs Warning             1    The cmdlet 'eliminate-file' uses an
                                            unapproved verb.

抑制规则

您可以通过使用 修饰脚本、函数或参数来禁止规则。NET 的 SuppressMessageAttributeSuppressMessageAttribute 的构造函数采用两个参数:类别和检查 ID。 将 categoryID 参数设置为要禁止的规则的名称,并将 checkID 参数设置为空或空字符串。 您可以选择添加第三个命名参数,其中包含禁止显示消息的理由:

function SuppressMe()
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '',
        Justification='Just an example')]
    param()

    Write-Verbose -Message "I'm making a difference!"

}

在您修饰的脚本、函数或参数的范围内,将禁止显示所有规则违规。

若要禁止显示特定参数上的消息,请将 SuppressMessageAttributeCheckId 参数设置为参数的名称:

function SuppressTwoVariables()
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParameterValue', 'b')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParameterValue', 'a')]
    param([string]$a, [int]$b)
    {
    }
}

使用 SuppressMessageAttributeScope 属性将规则抑制限制为属性范围内的函数或类。

使用值 Function 来抑制属性范围内所有函数的冲突。 使用值 Class 禁止对属性范围内所有类的冲突:

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '', Scope='Function')]
param()

function InternalFunction
{
    param()

    Write-Verbose -Message "I am invincible!"
}

你可以通过将 SuppressMessageAttributeTarget 属性设置为正则表达式或万用符模式,进一步限制基于函数、参数、类、变量或对象名称的抑制。

例如,若要禁止 和 start-barstart-baz 规则冲突,但不禁止 和 start-foostart-bam

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
    Scope='Function', Target='start-ba[rz]')]
param()
function start-foo {
    write-host "start-foo"
}

function start-bar {
    write-host "start-bar"
}

function start-baz {
    write-host "start-baz"
}

function start-bam {
    write-host "start-bam"
}

要禁止所有功能中的违规行为:

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
    Scope='Function', Target='*')]
Param()

要抑制 中的start-barstart-baz违规行为,但不start-bam禁止 中的违规start-foo行为:

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
    Scope='Function', Target='start-b*')]
Param()

注释

无法使用 SuppressMessageAttribute 抑制分析器错误。

ScriptAnalyzer 中的设置支持

可以创建描述要根据 严重性包含或排除的 ScriptAnalyzer 规则的设置。 使用 的 设置Invoke-ScriptAnalyzer 参数指定配置。 设置参数允许你为特定环境创建自定义配置。

该参数接受以下类型的对象:

  • 指向 .psd1 包含用户自定义配置文件的文件路径
  • 一个包含设置的哈希表对象
  • 内置预设的名称

内置预设

ScriptAnalyzer 附带了一组内置预设,可用于分析脚本。 PSScriptAnalyzer模块包含一套内置预设,你可以配合 设置 参数使用。 例如,如果要在模块上运行 PowerShell 库 规则,请使用以下命令:

Invoke-ScriptAnalyzer -Path /path/to/module/ -Settings PSGallery -Recurse

你可以用逗号分隔多个预设来指定它们。 你可以用制表补全功能查看可用的预设。 内置预设存储在SettingsPSScriptAnalyzer模块的文件夹中。 你可以通过执行以下命令列出内置预设:

Get-ChildItem "$($(Get-Module PSScriptAnalyzer).ModuleBase)\Settings\*.psd1"
    Directory: C:\Users\sewhee\Documents\PowerShell\Modules\psscriptAnalyzer\1.25.0\Settings

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           3/20/2026  6:41 PM          15025 CmdletDesign.psd1
-a---           3/20/2026  6:41 PM          16330 CodeFormatting.psd1
-a---           3/20/2026  6:41 PM          16331 CodeFormattingAllman.psd1
-a---           3/20/2026  6:41 PM          16331 CodeFormattingOTBS.psd1
-a---           3/20/2026  6:41 PM          16375 CodeFormattingStroustrup.psd1
-a---           3/20/2026  6:41 PM          14674 DSC.psd1
-a---           3/20/2026  6:41 PM          15735 PSGallery.psd1
-a---           3/20/2026  6:41 PM          15157 ScriptFunctions.psd1
-a---           3/20/2026  6:41 PM          14736 ScriptingStyle.psd1
-a---           3/20/2026  6:41 PM          14985 ScriptSecurity.psd1

要查看预设中包含的规则,可以在文本编辑器中打开文件 .psd1

Explicit

以下示例展示了如何调用脚本分析器,设置中排除默认规则集中的两个规则,以及任何严重性除 错误警告外的规则。

$pssaSettings = @{
    Severity=@('Error','Warning')
    ExcludeRules=@('PSAvoidUsingCmdletAliases', 'PSAvoidUsingWriteHost')
}
Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings $pssaSettings

你也可以把那个哈希表保存成 .psd1 一个文件,然后用该设置文件调用脚本分析器。

Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings PSScriptAnalyzerSettings.psd1

如果将名为 PSScriptAnalyzerSettings.psd1 的设置文件放置在项目根目录中,则 PSScriptAnalyzer 会在将项目根目录作为 Path 参数传递时发现该文件。

Invoke-ScriptAnalyzer -Path "C:\path\to\project" -Recurse

明确提供设置优先于这种隐式模式。 你可以在SettingsPSScriptAnalyzer模块的文件夹中找到示例设置文件。

检查 PowerShell 版本兼容性

PSScriptAnalyzer 可以检查 PowerShell 脚本是否与其他 PowerShell 版本和环境不兼容。 PSScriptAnalyzer 包括四个用于检查兼容性问题的规则:

有关如何使用这些规则的详细信息,请参阅 PowerShell 团队博客上的使用 PSScriptAnalyzer 检查 PowerShell 版本兼容性

自定义规则

可以在设置文件中提供自定义规则的一个或多个路径。 重要的是,这些路径指向模块的文件夹(隐式使用模块清单)或模块的脚本文件 ()。.psm1 模块必须导出 Export-ModuleMember 自定义规则函数,以便它们可供 PSScriptAnalyzer 使用。

在这个例子中, CustomRulePath 属性指向两个不同的模块。 这两个模块都导出带有谓词 Measure 的规则函数,因此 Measure-* 用于属性 IncludeRules

@{
    CustomRulePath      = @(
        '.\output\RequiredModules\DscResource.AnalyzerRules'
        '.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
    )

    IncludeRules        = @(
        'Measure-*'
    )
}

还可以通过在 IncludeRules 属性中列出规则来添加默认规则。 在包含默认规则时,请务必将 属性 IncludeDefaultRules 设置为 $true;否则将使用默认规则。

@{
    CustomRulePath      = @(
        '.\output\RequiredModules\DscResource.AnalyzerRules'
        '.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
    )

    IncludeDefaultRules = $true

    IncludeRules        = @(
        # Default rules
        'PSAvoidDefaultValueForMandatoryParameter'
        'PSAvoidDefaultValueSwitchParameter'

        # Custom rules
        'Measure-*'
    )
}

在Visual Studio Code中使用自定义规则(VS Code)

你也可以使用VS Code设置文件里提供的自定义规则。 添加一个VS Code工作区设置文件(),.vscode/settings.json内容如下。

{
    "powershell.scriptAnalysis.settingsPath": ".vscode/analyzersettings.psd1",
    "powershell.scriptAnalysis.enable": true,
}

ScriptAnalyzer 作为 .NET 库

您可以直接将 ScriptAnalyzer 的引擎和功能用作库。

以下是公共接口:

using Microsoft.Windows.PowerShell.ScriptAnalyzer;

public void Initialize(System.Management.Automation.Runspaces.Runspace runspace,
Microsoft.Windows.PowerShell.ScriptAnalyzer.IOutputWriter outputWriter,
[string[] customizedRulePath = null],
[string[] includeRuleNames = null],
[string[] excludeRuleNames = null],
[string[] severity = null],
[bool suppressedOnly = false],
[string profile = null])

public System.Collections.Generic.IEnumerable<DiagnosticRecord> AnalyzePath(string path,
    [bool searchRecursively = false])

public System.Collections.Generic.IEnumerable<IRule> GetRule(string[] moduleNames,
    string[] ruleNames)

违规纠正

您可以使用 修复 开关自动替换违规内容,使用建议的替代方案。 此外,由于实现了 Invoke-ScriptAnalyzer,因此可以使用 WhatIfConfirm 来找出将应用哪些更正。 应用修正时应使用源码控制,因为某些更改,比如 AvoidUsingPlainTextForPassword,可能需要其他脚本修改,无法自动完成。 当你自动应用建议时,初始编码并不总能保持。 如果你的脚本依赖某种特定的编码,你应该检查文件编码。

错误记录的 SuggestedCorrections 属性使得在 VS Code 等编辑器中实现快速修复场景。 我们为以下规则提供有效的 SuggestedCorrection

  • 避免别名
  • 避免使用PlainTextForPassword
  • 误导性反引号
  • MissingModuleManifestField
  • UseToExportFieldsInManifest