Compartir a través de


Uso de PSScriptAnalyzer

En este artículo se describen varias características de PSScriptAnalyzer y cómo usarlas.

Errores del analizador

A partir de la versión 1.18.0, PSScriptAnalyzer emite errores del analizador como registros de diagnóstico en el flujo de salida.

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 se establece en el ErrorId del error del analizador.

Para suprimir ParseErrors, no lo incluya como un valor en el parámetro 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.

Supresión de reglas

Puede suprimir una regla decorando un script, una función o un parámetro con . SuppressMessageAttribute de NET. El constructor de SuppressMessageAttribute toma dos parámetros: una categoría y un identificador de comprobación. Establezca el parámetro categoryID en el nombre de la regla que desea suprimir y establezca el parámetro checkID en una cadena nula o vacía. Opcionalmente, puede agregar un tercer parámetro con nombre con una justificación para suprimir el mensaje:

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

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

}

Dentro del ámbito del script, la función o el parámetro que ha decorado, se suprimen todas las infracciones de las reglas.

Para suprimir un mensaje en un parámetro específico, establezca el parámetro CheckId de SuppressMessageAttribute en el nombre del parámetro:

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

Use la propiedad Scope de SuppressMessageAttribute para limitar la supresión de reglas a funciones o clases dentro del ámbito del atributo.

Utilice el valor Función para suprimir las infracciones en todas las funciones dentro del ámbito del atributo. Utilice el valor Class para suprimir las infracciones en todas las clases dentro del ámbito del atributo:

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

function InternalFunction
{
    param()

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

Puedes restringir aún más la supresión en función de una función, parámetro, clase, variable o nombre de objeto estableciendo la propiedad Target de SuppressMessageAttribute a una expresión regular o un patrón comodín.

Por ejemplo, para suprimir la infracción de la regla PSAvoidUsingWriteHost en start-bar y start-baz pero no en start-foo y 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"
}

Para suprimir las infracciones en todas las funciones:

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

Para suprimir las infracciones en start-bar, start-baz y start-bam pero no en start-foo:

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

Nota:

Los errores del analizador no se pueden suprimir con SuppressMessageAttribute.

Compatibilidad con la configuración en ScriptAnalyzer

Puede crear una configuración que describa las reglas de ScriptAnalyzer que se van a incluir o excluir en función de la gravedad. Utilice el parámetro Configuración de Invoke-ScriptAnalyzer para especificar la configuración. El parámetro Configuración te permite crear una configuración personalizada para un entorno específico. ScriptAnalyzer soporta los siguientes modos para especificar el archivo de configuración:

Ajustes preestablecidos incorporados

ScriptAnalyzer incluye un conjunto de ajustes preestablecidos integrados que se pueden usar para analizar scripts. Por ejemplo, si desea ejecutar reglas de la Galería de PowerShell en el módulo, use el siguiente comando:

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

Además, puede usar otros ajustes preestablecidos integrados, incluidos DSC y CodeFormatting. Estos ajustes preestablecidos se pueden completar con tabulación para el parámetro Configuración .

Explicit

En el ejemplo siguiente se excluyen dos reglas del conjunto predeterminado de reglas y cualquier regla con una gravedad distinta de Error y Advertencia.

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

A continuación, puede invocar ese archivo de configuración con Invoke-ScriptAnalyzer:

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

En el ejemplo siguiente se seleccionan algunas reglas para ejecutar en lugar de todas las reglas predeterminadas.

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

A continuación, puede invocar ese archivo de configuración:

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

Implícita

Si coloca un archivo de configuración denominado PSScriptAnalyzerSettings.psd1 en la raíz del proyecto, PSScriptAnalyzer lo detecta cuando pasa la raíz del proyecto como parámetro Path .

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

Proporcionar ajustes explícitamente tiene mayor prioridad sobre este modo implícito. Puedes encontrar archivos de configuración de ejemplo en la Settings carpeta del módulo PSScriptAnalyzer .

Comprobación de la compatibilidad de versiones de PowerShell

PSScriptAnalyzer puede comprobar si hay incompatibilidades en los scripts de PowerShell con otras versiones y entornos de PowerShell. PSScriptAnalyzer incluye cuatro reglas que comprueban si hay problemas de compatibilidad:

  • PSUseCompatibleCmdlets comprueba si los cmdlets usados en un script están disponibles en otros entornos de PowerShell
  • PSUseCompatibleCommands comprueba si los comandos usados en un script están disponibles en otros entornos de PowerShell
  • PSUseCompatibleSyntax comprueba si una sintaxis usada en un script es compatible en otras versiones de PowerShell
  • PSUseCompatibleTypes comprueba si los tipos de .NET y los métodos estáticos o las propiedades están disponibles en otros entornos de PowerShell

Para obtener más información sobre cómo usar estas reglas, consulte Uso de PSScriptAnalyzer para comprobar la compatibilidad de versiones de PowerShell en el blog del equipo de PowerShell.

Reglas personalizadas

Es posible proporcionar una o varias rutas de acceso a reglas personalizadas en el archivo de configuración. Es importante que estas rutas apunten a la carpeta de un módulo, que utiliza implícitamente el manifiesto del módulo, o al archivo de script del módulo (.psm1). El módulo debe exportar las funciones de regla personalizadas para Export-ModuleMember que estén disponibles para PSScriptAnalyzer.

En este ejemplo, la propiedad CustomRulePath apunta a dos módulos diferentes. Ambos módulos exportan las funciones de regla con el verbo Measure , por lo que Measure-* se usa para la propiedad IncludeRules.

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

    IncludeRules        = @(
        'Measure-*'
    )
}

También puede agregar reglas predeterminadas enumerando las reglas en la propiedad IncludeRules . Al incluir reglas predeterminadas, es importante que establezca la propiedad IncludeDefaultRules en $true; de lo contrario, se usan las reglas predeterminadas.

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

    IncludeDefaultRules = $true

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

        # Custom rules
        'Measure-*'
    )
}

Uso de reglas personalizadas en Visual Studio Code (VS Code)

También puedes usar las reglas personalizadas que se proporcionan en el archivo de configuración en VS Code. Añade un archivo de ajustes de espacio de trabajo de VS Code (.vscode/settings.json) con el siguiente contenido.

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

ScriptAnalyzer como biblioteca .NET

Puede consumir directamente el motor y la funcionalidad de ScriptAnalyzer como una biblioteca.

Aquí están las interfaces públicas:

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)

Corrección de infracciones

Puedes usar el interruptor Fix para reemplazar automáticamente el contenido que causa infracciones por una alternativa sugerida. Además, dado que Invoke-ScriptAnalyzer implementa SupportsShouldProcess, puede usar WhatIf o Confirm para averiguar qué correcciones se aplicarían. Deberías usar control de versiones al aplicar correcciones, ya que algunos cambios, como el de EvitarUsarTextoPlano ParaContraseña, pueden requerir otras modificaciones de script que no se pueden hacer automáticamente. La codificación inicial no siempre se puede preservar cuando aplicas sugerencias automáticamente. Deberías comprobar la codificación de archivos si tus scripts dependen de una codificación concreta.

La propiedad SuggestedCorrections del registro de error permite escenarios de corrección rápida en editores como VS Code. Proporcionamos SuggestedCorrection válida para las siguientes reglas:

  • AvoidAlias
  • EvitarUsarTextoPlanoForContraseña
  • EngañosoBacktick
  • MissingModuleManifestField
  • UseToExportFieldsInManifest