Использование 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 принимает два параметра: категорию и идентификатор проверки. Задайте для параметра categoryID имя правила, которое вы хотите подавить, а для параметра checkID — пустую или пустую строку. При необходимости вы можете добавить третий именованный параметр с обоснованием для подавления сообщения:

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

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

}

В пределах области действия скрипта, функции или параметра, которые вы декорировали, все нарушения правил подавляются.

Чтобы подавить сообщение по определенному параметру, задайте для параметра CheckId атрибута SuppressMessageAttribute имя параметра:

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

Используйте свойство Scope объекта SuppressMessageAttribute , чтобы ограничить подавление правил функциями или классами в области атрибута.

Используйте значение Function для подавления нарушений всех функций в области атрибута. Используйте значение Class для подавления нарушений по всем классам в области атрибута:

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

function InternalFunction
{
    param()

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

Вы можете дополнительно ограничить подавление на основе имени функции, параметра, класса, переменной или объекта, установив свойство TargetSuppressMessageAttribute на регулярное выражение или шаблон wildcard.

Например, чтобы подавить нарушение правила PSAvoidUsingWriteHost в start-bar и, start-baz но не в start-foo и start-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-bar, start-baz и start-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

Кроме того, вы можете использовать другие встроенные пресеты, включая DSC и CodeFormatting. Эти пресеты могут быть заполнены вкладкой для параметра Settings .

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

Явное предоставление настроек имеет более высокий приоритет по сравнению с этим неявным режимом. Примеры файлов настроек можно найти в Settings папке модуля PSScriptAnalyzer .

Проверка совместимости версий PowerShell

PSScriptAnalyzer может проверять скрипты PowerShell на несовместимость с другими версиями и средами PowerShell. PSScriptAnalyzer включает четыре правила, которые проверяют наличие проблем совместимости:

  • PSUseCompatibleCmdlets проверяет, доступны ли командлеты, используемые в скрипте, в других средах PowerShell
  • PSUseCompatibleCommands проверяет, доступны ли команды, используемые в скрипте, в других средах PowerShell
  • PSUseCompatibleSyntax проверяет, совместим ли синтаксис, используемый в скрипте, с другими версиями PowerShell
  • PSUseCompatibleTypes проверяет, доступны ли типы .NET и статические методы или свойства в других средах PowerShell

Дополнительные сведения об использовании этих правил см. в статье Использование PSScriptAnalyzer для проверки совместимости версий PowerShell в блоге группы 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)

Исправление нарушений

Вы можете использовать переключатель Fix , чтобы автоматически заменить контент, вызывающий нарушения, на предложенную альтернативу. Кроме того, поскольку Invoke-ScriptAnalyzer в нем реализован SupportsShouldProcess, вы можете использовать WhatIf или Confirm , чтобы узнать, какие исправления будут применены. При внесении исправлений следует использовать контроль версий, так как некоторые изменения, например для AvoidUsingPlainTextForPassword, могут требовать других изменений скриптов, которые нельзя сделать автоматически. Начальное кодирование не всегда можно сохранить, если вы автоматически применяете предложения. Стоит проверить кодирование файлов, зависят ли ваши скрипты от конкретного кодирования.

Свойство SuggestedCorrections в записи ошибки позволяет быстро исправлять сценарии в редакторах, таких как VS Code. Мы предоставляем действующую SuggestedCorrection для следующих правил:

  • AvoidAlias (ИзбежатьПсевдонима)
  • AvoidUsingPlainTextForPassword
  • Вводящая в заблуждениеОбратная кавычка
  • ОтсутствующийModuleManifestField
  • UseToExportFieldsInManifest