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의 SuppressMessageAttribute입니다. SuppressMessageAttribute의 생성자는 범주와 검사 ID라는 두 가지 매개 변수를 사용합니다. categoryID 매개 변수를 표시하지 않으려는 규칙의 이름으로 설정하고 checkID 매개 변수를 null 또는 빈 문자열로 설정합니다. 선택적으로 메시지를 표시하지 않는 근거와 함께 세 번째 명명된 매개 변수를 추가할 수 있습니다.

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 속성을 정규 표현식이나 와일드카드 패턴으로 설정하여 함수, 매개변수, 클래스, 변수 또는 객체 이름에 따라 억제를 추가로 제한할 수 있습니다.

예를 들어 PSAvoidUsingWriteHoststart-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-baz 에서 start-bam위반을 start-foo억제하려면:

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

비고

파서 오류는 SuppressMessageAttribute로 억제할 수 없습니다.

ScriptAnalyzer의 설정 지원

심각도에 따라 포함하거나 제외할 ScriptAnalyzer 규칙을 설명하는 설정을 만들 수 있습니다. 의 Invoke-ScriptAnalyzer 매개 변수를 사용하여 구성을 지정합니다. 설정 매개변수는 특정 환경에 맞는 맞춤형 구성을 만들 수 있게 해줍니다. 스크립트애널라이저는 설정 파일을 지정하기 위해 다음과 같은 모드를 지원합니다:

내장 사전 설정

ScriptAnalyzer는 스크립트를 분석하는 데 사용할 수 있는 기본 제공 사전 설정 세트를 제공합니다. 예를 들어 모듈에서 PowerShell 갤러리 규칙을 실행하려면 다음 명령을 사용합니다.

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

또한 DSCCodeFormatting을 포함한 다른 기본 제공 사전 설정을 사용할 수 있습니다. 이러한 사전 설정은 설정 매개변수에 대해 탭으로 완료될 수 있습니다.

Explicit

다음 예제에서는 기본 규칙 집합에서 두 개의 규칙과 오류경고 이외의 심각도를 가진 규칙을 제외합니다.

# 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 에는 호환성 문제를 확인하는 네 가지 규칙이 포함되어 있습니다.

  • PSUseCompatibleCmdlet 은 스크립트에 사용된 cmdlet을 다른 PowerShell 환경에서 사용할 수 있는지 여부를 확인합니다
  • PSUseCompatibleCommands 는 스크립트에 사용된 명령을 다른 PowerShell 환경에서 사용할 수 있는지 확인합니다
  • PSUseCompatibleSyntax 는 스크립트에 사용되는 문법이 다른 PowerShell 버전과 호환되는지 확인합니다
  • PSUseCompatibleTypes 는 다른 PowerShell 환경에서 .NET 형식 및 정적 메서드 또는 속성을 사용할 수 있는지 여부를 확인합니다

이러한 규칙을 사용하는 방법에 대한 자세한 내용은 PowerShell 팀 블로그에서 PSScriptAnalyzer를 사용하여 PowerShell 버전 호환성 확인 을 참조하세요.

사용자 지정 규칙

설정 파일에서 사용자 지정 규칙에 대한 하나 이상의 경로를 제공할 수 있습니다. 이러한 경로는 모듈 매니페스트를 암시적으로 사용하는 모듈의 폴더 또는 모듈의 스크립트 파일(.psm1)을 가리키는 것이 중요합니다. 모듈은 Export-ModuleMember에서 사용할 수 있도록 사용자 지정 규칙 함수를 내 보내야 합니다.

이 예시에서 CustomRulePath 속성은 두 개의 다른 모듈을 가리킵니다. 두 모듈 모두 동사 Measure so가 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-ScriptAnalyzer를 구현하므로 WhatIf 또는 Confirm을 사용하여 적용될 수정 사항을 확인할 수 있습니다. 수정 적용 시 소스 컨트롤을 사용해야 합니다. 예를 들어 AvoidUsingPlainTextForPassword와 같은 변경은 자동으로 할 수 없는 다른 스크립트 수정이 필요할 수 있습니다. 제안을 자동으로 적용할 때 초기 인코딩을 항상 유지할 수는 없습니다. 스크립트가 특정 인코딩에 의존한다면 파일 인코딩을 꼭 확인하세요.

오류 레코드의 SuggestedCorrections 속성은 VS Code와 같은 편집기에서 빠른 수정 시나리오를 가능하게 합니다. 다음 규칙에 대해 유효한 SuggestedCorrection 을 제공합니다.

  • 별칭 회피
  • AvoidUsingPlainTextForPassword
  • 오해의 소지가 있는 백틱
  • MissingModuleManifest필드
  • UseToExportFieldsInManifest