استخدام 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، لا تقم بتضمينها كقيمة في المعلمة الخطورة .

$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.

قمع القواعد

يمكنك منع قاعدة عن طريق تزيين برنامج نصي أو دالة أو معلمة ب . SuppressMessageAttribute من NET. يأخذ منشئ 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 لتقييد منع القاعدة على الوظائف أو الفئات ضمن نطاق السمة.

استخدم الدالة قيمة لمنع الانتهاكات في جميع الوظائف ضمن نطاق السمة. استخدم فئة القيمة لمنع الانتهاكات على جميع الفئات ضمن نطاق السمة:

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

function InternalFunction
{
    param()

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

يمكنك تقييد الكبت بناء على دالة أو معلمة أو فئة أو متغير أو اسم كائن عن طريق تعيين خاصية Targetفي SuppressMessageAttribute إلى تعبير منتظم أو نمط غير متوقع.

على سبيل المثال، لقمع انتهاك قاعدة 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. يمكن إكمال هذه الإعدادات المسبقة في علامة تبويب لمعلمة الإعدادات .

صريح

يستبعد المثال التالي قاعدتين من مجموعة القواعد الافتراضية وأي قاعدة ذات خطورة أخرى غير الخطأوالتحذير.

# 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 عند تمرير جذر المشروع كمعلمة المسار .

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

توفير الإعدادات بشكل صريح له أولوية أعلى على هذا الوضع الضمني. يمكنك العثور على ملفات إعدادات نموذجية في Settings مجلد وحدة PSScriptAnalyzer .

التحقق من توافق إصدار PowerShell

يمكن ل PSScriptAnalyzer التحقق من البرامج النصية ل PowerShell بحثا عن حالات عدم التوافق مع إصدارات وبيئات PowerShell الأخرى. يتضمن PSScriptAnalyzer أربع قواعد تتحقق من وجود مشكلات في التوافق:

  • يتحقق PSUseCompatibleCmdlets مما إذا كانت أوامر cmdlets المستخدمة في برنامج نصي متوفرة في بيئات 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-*'
    )
}

استخدام قواعد مخصصة في كود فيجوال ستوديو (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. نحن نقدم تصحيح مقترح صالح للقواعد التالية:

  • تجنب الاسم المستعار
  • تجنب UsesingPlainTextForPassword
  • مضللةBacktick
  • MissingModuleManifestField
  • UseToExportFieldsInManifest