次の方法で共有


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 の 2 つのパラメーターを取ります。 categoryID パラメーターを抑制するルールの名前に設定し、checkID パラメーターを null または空の文字列に設定します。 オプションで、メッセージを抑制する理由を含む 3 番目の名前付きパラメーターを追加できます。

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-bar では start-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-bazstart-bamでは違反を抑制し、start-fooでは抑制するには:

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

パーサー エラーは、 SuppressMessageAttribute では抑制できません。

ScriptAnalyzer でのサポート

重大 に基づいて含めたり除外したりする ScriptAnalyzer ルールを記述する設定を作成できます。 Invoke-ScriptAnalyzer] パラメーターを使用して、構成を指定します。 設定パラメータは特定の環境向けにカスタム設定を作成することを可能にします。 ScriptAnalyzerは設定ファイルの指定モードを以下以下でサポートしています。

ビルトインプリセット

ScriptAnalyzer には、スクリプトの分析に使用できる一連の組み込みプリセットが付属しています。 たとえば、モジュールで PowerShell ギャラリー ルールを実行する場合は、次のコマンドを使用します。

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

さらに、 DSCCodeFormatting などの他の組み込みプリセットを使用できます。 これらのプリセットは、[ 設定 ]パラメータのタブ入力で完了できます。

Explicit

次の例では、既定のルール セットから 2 つのルールと、 エラー警告以外の重大度のルールを除外します。

# PSScriptAnalyzerSettings.psd1
@{
    Severity=@('Error','Warning')
    ExcludeRules=@('PSAvoidUsingCmdletAliases', 'PSAvoidUsingWriteHost')
}

その後、次の Invoke-ScriptAnalyzerを使用してその設定ファイルを呼び出すことができます。

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

次の例では、すべてのデフォルト・ルールではなく、実行するいくつかのルールを選択します。

# PSScriptAnalyzerSettings.psd1
@{
    IncludeRules=@('PSAvoidUsingPlainTextForPassword',
                'PSAvoidUsingConvertToSecureStringWithPlainText')
}

その後、その設定ファイルを呼び出すことができます。

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

暗黙的

PSScriptAnalyzerSettings.psd1 という名前の設定ファイルをプロジェクト ルートに配置すると、PSScriptAnalyzer は、プロジェクト ルートを Path パラメーターとして渡すと、そのファイルを検出します。

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

設定の明示的な提供は、この暗黙のモードよりも優先されます。 サンプル設定ファイルはPSScriptAnalyzerモジュールのSettingsフォルダにあります。

PowerShell バージョンの互換性を確認する

PSScriptAnalyzer は、PowerShell スクリプトで他の PowerShell バージョンや環境との非互換性をチェックできます。 PSScriptAnalyzer には、互換性の問題をチェックする 4 つのルールが含まれています。

  • PSUseCompatibleCmdlets は、スクリプトで使用されるコマンドレットが他の PowerShell 環境で使用できるかどうかをチェックします
  • PSUseCompatibleCommands は、スクリプトで使用されるコマンドが他の PowerShell 環境で使用できるかどうかをチェックします
  • PSUseCompatibleSyntax は、スクリプトで使用される構文が他のPowerShellバージョンで互換性があるかどうかをチェックします
  • PSUseCompatibleTypes は、.NET 型と静的メソッドまたはプロパティが他の PowerShell 環境で使用できるかどうかをチェックします

これらのルールの使用方法の詳細については、PowerShell チーム ブログの「 PSScriptAnalyzer を使用して PowerShell バージョンの互換性を確認する 」を参照してください。

カスタム規則

設定ファイルでカスタムルールへのパスを 1 つ以上指定できます。 これらのパスは、モジュール マニフェストを暗黙的に使用するモジュールのフォルダー、またはモジュールのスクリプト ファイル (.psm1) のいずれかを指すことが重要です。 モジュールは、Export-ModuleMember で使用できるようにするために、を使用してカスタム ルール関数をエクスポートする必要があります。

この例では、 CustomRulePath プロパティが2つの異なるモジュールを示しています。 どちらのモジュールも、動詞 Measure を使用してルール関数をエクスポートし、プロパティ Measure-* に使用されるようにします。

@{
    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,
}

.NET ライブラリとしての ScriptAnalyzer

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-ScriptAnalyzerSupportsShouldProcess を実装しているため、 WhatIf または Confirm を使用して、適用される修正を確認できます。 修正を適用する際はソース管理を使うべきです。 例えばAvoidUsingPlainTextForPasswordのような変更は、自動で行えないスクリプトの変更を必要とする場合もあります。 自動的に提案を適用しても初期エンコーディングが必ずしも保持できるわけではありません。 スクリプトが特定のエンコーディングに依存しているなら、ファイルのエンコーディングをチェックすべきです。

エラーレコードの SuggestedCorrections プロパティにより、VS Codeのようなエディタでの迅速な修正シナリオが可能になります。 次のルールに対して有効な SuggestedCorrection を提供します。

  • エイリアスの回避
  • PlainTextForPassword の使用を避ける
  • 誤解を招くバッククォート
  • MissingModuleManifestフィールド
  • UseToExportFieldsInManifest