Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Este conjunto de documentación contiene una referencia de cmdlet para los módulos
siguientes.
Microsoft.PowerShell.Crescendo
Microsoft.PowerShell.SecretManagement
Microsoft.PowerShell.SecretStore
PlatyPS
PSScriptAnalyzer
Microsoft. Introducción a
PowerShell.Crescendo
Artículo • 14/12/2022
Requisitos:
Crescendo se puede usar para crear módulos que se ejecutan en Windows PowerShell
5.1 y versiones posteriores.
PowerShell
PowerShell
Los parámetros Force o Reinstall solo son necesarios cuando tiene instalada una versión
anterior de Crescendo. Sin embargo, estos parámetros funcionan tanto si tiene una
versión anterior como si no.
El módulo Crescendo incluye contenido de ayuda completo. Para instalar la ayuda más
reciente, ejecute el siguiente comando:
PowerShell
El uso del parámetro Force garantiza que obtenga el contenido de ayuda disponible
más reciente.
Paso siguiente
Elección de la herramienta de línea de comandos para ajustar
Elección de la herramienta de línea de
comandos para Crescendo
Artículo • 13/12/2022
Prácticas recomendadas
Optimice su inversión de tiempo centrándose en lo que necesita.
Para ver los ejemplos de este artículo, se usa la herramienta de agente de Azure
Connected Machine ( azcmagent ). Hemos elegido esta herramienta porque:
Sugerencia
Resultados
...
Usage:
azcmagent [command]
Available Commands:
check Runs connectivity checks
config Change configuration settings for this machine
connect Connects this machine to Azure
disconnect Disconnects this machine from Azure
help Help about any command
license Display the End-user license agreement file
logs Creates a .zip file containing relevant logs. This is
primarily useful for troubleshooting.
show Gets machine metadata and Agent status. This is primarily
useful for troubleshooting.
version Display the Hybrid Management Agent version
...
Cada uno de los subcomandos puede tener sus propios subcomandos y parámetros. Por
ejemplo, el config subcomando tiene cinco subcomandos.
PowerShell
Usage:
azcmagent config [command]
Available Commands:
clear Clear a configuration property's value
get Get a configuration property's value
info Describes the config properties users can set
list List all configuration properties and values
set Set a value for a configuration property
Flags:
-h, --help help for config
--version version for config
Global Flags:
--config string config file (default is $HOME/.azcmagent.yaml)
-j, --json Output in JSON format
--log-stderr Redirect error and verbose messages to stderr
-v, --verbose Increase logging verbosity to show all logs
Use la ayuda de la línea de comandos para detectar los posibles casos de uso. Puede
redirigir la salida de cada comando de ayuda a un archivo que puede usar para una
referencia posterior al crear los cmdlets de Crescendo.
Sugerencia
Si el contenido de la ayuda está estructurado de forma coherente, puede ser
posible crear código que compile cmdlets mediante el análisis de esta salida de
ayuda. Crescendo viene con algunos analizadores de ayuda experimental para
ilustrar cómo se puede lograr esto. Consulte la Experimental carpeta en la carpeta
raíz del módulo Microsoft.PowerShell.Crescendo .
Tome nota de los formatos de salida que ofrece la herramienta de línea de comandos.
Muchas herramientas de línea de comandos pueden generar información en formatos
como CSV o JSON. Estos formatos estructurados se convierten fácilmente en objetos de
PowerShell.
A medida que inspecciona la salida de ejemplo, piense en los tipos de datos devueltos.
A medida que construya los objetos, debe convertir las cadenas de salida de la
herramienta de línea de comandos en tipos de .NET. Por ejemplo, la información de
marca de tiempo se puede convertir en tipos de .NET [DateTime] . Además, examine el
formato de la salida para los marcadores que separan los campos de datos. Esos
marcadores se pueden usar para analizar la información a medida que construye los
objetos para la salida.
PowerShell
Para obtener ejemplos más complejos de análisis de la salida, consulte esta entrada de
blog del blog de la comunidad de PowerShell.
7 Nota
Paso siguiente
Creación de una configuración de cmdlet
Creación de un cmdlet de Crescendo
Artículo • 03/02/2023
Como se ha explicado anteriormente, hay varias razones por las que es posible que
quiera ampliar una herramienta de línea de comandos:
PowerShell
$parameters = @{
Verb = 'Show'
Noun = 'AzCmAgent'
OriginalName = "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe"
}
New-CrescendoCommand @parameters | Format-List *
Resultados
FunctionName : Show-AzCmAgent
Verb : Show
Noun : AzCmAgent
OriginalName : c:/program
files/AzureConnectedMachineAgent/azcmagent.exe
OriginalCommandElements :
Platform : {Windows, Linux, MacOS}
Elevation :
Aliases :
DefaultParameterSetName :
SupportsShouldProcess : False
ConfirmImpact :
SupportsTransactions : False
NoInvocation : False
Description :
Usage :
Parameters : {}
Examples : {}
OriginalText :
HelpLinks :
OutputHandlers :
PowerShell
$parameters = @{
Verb = 'Show'
Noun = 'AzCmAgent'
OriginalName = "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe"
}
$CrescendoCommands += New-CrescendoCommand @parameters
Export-CrescendoCommand -command $CrescendoCommands -fileName
.\AzCmAgent.json
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": [
{
"Verb": "Show",
"Noun": "AzCmAgent",
"OriginalName": "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe",
"Platform": [
"Windows",
"Linux",
"MacOS"
],
"SupportsShouldProcess": false,
"SupportsTransactions": false,
"NoInvocation": false,
"Parameters": [],
"Examples": []
}
]
}
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": [
{
"Verb": "Show",
"Noun": "AzCmAgent",
"OriginalName": "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe",
"OriginalCommandElements": [
"show",
"--json"
],
"Platform": [
"Windows",
],
"Description": "Gets machine metadata and Agent status. This is
primarily useful for troubleshooting.",
"Aliases": [
"azinfo"
],
"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "Inline",
"Handler": "$args[0] | ConvertFrom-Json"
}
],
"SupportsShouldProcess": false,
"SupportsTransactions": false,
"NoInvocation": false,
"Parameters": [],
"Examples": []
}
]
}
JSON
{
"Verb": "Get",
"Noun": "AzCmAgentConfigProperty",
"Platform": [
"Windows"
],
"OriginalCommandElements": [
"config",
"--json"
],
"OriginalName": "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe",
"Description": " Get a configuration property's value",
"DefaultParameterSetName": "Default",
"Parameters": [
{
"OriginalName": "get",
"Name": "Property",
"ParameterType": "string",
"ParameterSetName": [
"Default"
],
"Mandatory": true,
"Description": "Specify the name of the property to return"
}
],
"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "Inline",
"Handler": "$args[0] | ConvertFrom-Json"
}
],
"SupportsShouldProcess": false,
"SupportsTransactions": false,
"NoInvocation": false,
"Parameters": [],
"Examples": []
}
Pasos siguientes
Ahora que ha definido los cmdlets, está listo para generar el nuevo módulo.
En el artículo anterior hemos creado configuraciones para dos nuevos cmdlets. Con esta
configuración, Crescendo puede generar un nuevo módulo de script de PowerShell.
PowerShell
ConfigurationFile puede tomar una matriz de nombres de archivo. Esto le permite crear
archivos JSON independientes para cada cmdlet. El parámetro ModuleName especifica
la ruta de acceso completa y el nombre de archivo para el archivo de módulo que se va
a crear. En este ejemplo, los archivos se crean en el directorio actual.
Resultados
Directory: D:\temp\azcmagent
PowerShell
Import-Module .\AzCmAgent.psd1
Get-Command -Module AzCmAgent
Resultados
) Importante
PowerShell
Show-AzCmAgent
Resultados
resourceName :
resourceGroup :
resourceNamespace :
subscriptionId :
tenantId :
vmId :
correlationId :
vmUuid :
location :
privateLinkScope :
cloud :
agentVersion : 1.15.01879.114
logs : C:\ProgramData\AzureConnectedMachineAgent\Log\himds.log
status : Disconnected
lastHeartbeat :
agentErrorCode :
agentErrorDetails :
agentErrorTime :
httpsProxy :
proxyBypass :
cloudProvider : N/A
cloudMetadata :
manufacturer : LENOVO
model : 30BFS07500
sql : false
services : {@{displayName=GC Service; serviceName=gcarcservice;
status=running},
@{displayName=Extension Service;
serviceName=extensionservice; status=running},
@{displayName=Agent Service; serviceName=himds;
status=running}}
PowerShell
Resultados
PowerShell
Resultados
Resultados
Module: AzCmAgent
7 Nota
Próximos artículos
Todavía estamos trabajando en más documentación para Crescendo. Vuelva a buscar
contenido nuevo que abarque los temas siguientes:
Esta versión preliminar incluye un nuevo cmdlet, un nuevo esquema, compatibilidad con
la transformación de valor de argumento, la capacidad de omitir el controlador de salida
y un control de errores mejorado.
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": []
}
PowerShell
7 Nota
JSON
"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "ByPass"
}
]
JSON
"OutputHandlers": [
{
"ParameterSetName": "Default",
"StreamOutput": true,
"HandlerType": "Inline",
"Handler": "PROCESS { $_ } END { Pop-CrescendoNativeError -
EmitAsError }"
}
]
JSON
"Parameters": [
{
"Name": "mult2",
"OriginalName": "--p3",
"ParameterType": "int",
"OriginalPosition": 2,
"ArgumentTransform": "param([int]$v) $v * 2"
}
]
JSON
"Parameters": [
{
"Name": "hasht2",
"OriginalName": "--p1ordered",
"ParameterType": "System.Collections.Specialized.OrderedDictionary",
"OriginalPosition": 0,
"ArgumentTransform":
"param([System.Collections.Specialized.OrderedDictionary]$v)
$v.Keys.ForEach({''{0}={1}'' -f $_,$v[$_]}) -join '',''"
}
]
JSON
"Parameters": [
{
"Name": "join",
"OriginalName": "--p2",
"ParameterType": "string[]",
"OriginalPosition": 1,
"ArgumentTransform": "param([string[]]$v) $v -join '',''"
}
]
JSON
"Parameters": [
{
"Name" : "Param1",
"ArgumentTransform": "myfunction",
"ArgumentTransformType" : "function"
}
]
Instalación de Crescendo
Requisitos:
PowerShell
PowerShell
El módulo Crescendo incluye un conjunto de cmdlets que crean varios tipos de objetos
Crescendo. Puede usar estos cmdlets para crear una configuración de Crescendo sin
necesidad de editar manualmente un archivo JSON.
) Importante
Dado que las herramientas de desarrollo como Visual Studio Code (VS Code)
proporcionan IntelliSense basado en el esquema JSON, la creación de la
configuración mediante la edición del archivo JSON es el método preferido para
crear una configuración. Este artículo se proporciona como ejemplo de cómo se
pueden usar los cmdlets.
Al inspeccionar la ayuda de estos dos comandos, puede ver que vssadmin list
providers no toma parámetros adicionales, pero vssadmin list shadows tiene una
PowerShell
Output
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool
(C) Copyright 2001-2013 Microsoft Corp.
List Providers
- List registered volume shadow copy providers.
Para el vssadmin list shadows comando , puede ver que el /For parámetro es opcional
y se puede usar solo o con cualquiera de los /Shadow parámetros o /ShadowSetId . Esto
da como resultado tres conjuntos de parámetros posibles.
El código de script
El siguiente script define la configuración de dos nuevos cmdlets. Los comentarios del
script proporcionan el siguiente esquema de tareas:
PowerShell
Puede usar estos analizadores de ayuda en una canalización de CI/CD para compilar
nuevas versiones de un módulo cuando cambia la herramienta de línea de comandos.
Control de errores en Crescendo
Artículo • 08/04/2023
JSON
"OutputHandlers": [
{
"ParameterSetName": "Default",
"StreamOutput": true,
"HandlerType": "Inline",
"Handler": "PROCESS { $_ } END { Pop-CrescendoNativeError -
EmitAsError }"
}
]
Ejemplo correcto
Esta es una invocación de ejemplo de la herramienta que debe realizarse correctamente:
Output
{
"fizz": "buzz"
}
PowerShell
Output
fizz
----
buzz
Ejemplo de error
Esta es una invocación de ejemplo de la herramienta que genera un error:
Output
PowerShell
Output
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": [
{
"Verb": "Get",
"Noun": "FizzBuzz",
"OriginalName": "fizztool",
"Parameters": [
{
"Name": "Key",
"OriginalName": "--key",
"ParameterType": "string",
"OriginalPosition": 0,
"Required": true
},
],
"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "Function",
"Handler": "FizzToolParser"
}
]
}
]
}
PowerShell
function FizzToolParser {
param(
[Parameter(Mandatory)]
[AllowNull()]
$cmdResults = ''
)
Los errores se filtran para seleccionar los mensajes que comienzan por ERROR: .
Los mensajes informativos, como el aviso de copyright, se omiten.
Puede inspeccionar los errores y controlarlos o pasarlos al autor de la llamada,
como se muestra en la función .
Output
fizz
----
buzz
PowerShell
Output
Hay muchos escenarios en los que los valores de entrada entregados a un comando
ajustado de Crescendo deben traducirse a un formato diferente para el comando nativo
subyacente. Crescendo 1.1 agregó dos nuevos miembros a la clase
ArgumentTransform Parameter y ArgumentTransformType para admitir estos escenarios.
Estos miembros son similares a los Handler miembros y HandlerType .
se encuentra en el disco.
En este ejemplo, el comando nativo espera una lista separada por comas de valores para
el parámetro --p2 . El parámetro del cmdlet , ValueList, es una matriz de cadenas.
Crescendo pasa $ValueList al scriptblock en ArgumentTransform como una matriz de
cadenas. El scriptblock combina los valores de la matriz con una coma y devuelve el
resultado.
JSON
"Parameters": [
{
"Name": "ValueList",
"OriginalName": "--p2",
"ParameterType": "string[]",
"OriginalPosition": 1,
"ArgumentTransform": "param([string[]]$v) $v -join ','"
}
]
Ejemplo: Adición de variables de entorno a una
imagen de Docker
La siguiente configuración de Crescendo define el Start-DockerRun cmdlet que
encapsula el docker run comando. El Environment parámetro es una tabla hash que
contiene pares clave-valor que deben transformarse en argumentos para el --env
parámetro del docker run comando. Al definir varias variables de entorno, los docker
run comandos esperan una instancia de --env key=value para cada variable. Esto no es
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": [
{
"Verb": "Start",
"Noun": "DockerRun",
"OriginalName": "docker",
"OriginalCommandElements": [
"run",
"--rm",
"-it"
],
"Parameters": [
{
"Name": "Environment",
"OriginalName": "",
"ParameterType": "Hashtable",
"OriginalPosition": 0,
"ArgumentTransform": "param([Hashtable]$v)
$v.Keys|Foreach-Object {''--env''; ''{0}={1}'' -f $_, $v[$_]}"
},
{
"Name": "Image",
"OriginalName": "",
"ParameterType": "string",
"DefaultValue": "ubuntu:latest",
"OriginalPosition": 10
}
],
"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "ByPass"
}
]
}
]
}
El transformador de argumentos --env key=value genera para cada par clave-valor de
la tabla hash.
JSON
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": [
{
"Verb": "Connect",
"Noun": "WindowsShare",
"OriginalName": "NET.exe",
"Platform": [
"Windows"
],
"OriginalCommandElements": [ "USE" ],
"Parameters": [
{
"Name": "DriveName",
"OriginalName": "",
"DefaultValue": "*",
"ParameterType": "string",
"OriginalPosition": 0
},
{
"Name": "Share",
"OriginalName": "",
"Mandatory": true,
"OriginalPosition": 1,
"ParameterType": "string"
},
{
"Name": "Credential",
"OriginalName": "",
"ParameterType": "PSCredential",
"Mandatory": true,
"OriginalPosition": 10,
"ArgumentTransform":
"\"/USER:$($Credential.UserName)\";$Credential.GetNetworkCredential().Passwo
rd",
"ArgumentTransformType": "Inline"
}
]
}
]
}
¿Qué es PlatyPS?
PlatyPS es una herramienta de código abierto que se inició como un proyecto de
hackathon para facilitar la creación y el mantenimiento de MAML. PlatyPS documenta la
sintaxis de los conjuntos de parámetros y los parámetros individuales para cada cmdlet
del módulo. PlatyPS crea archivos Markdown estructurados que contienen la
información de la sintaxis. No puede crear descripciones ni proporcionar ejemplos.
Puede incluir los archivos de ayuda de texto y MAML con el módulo. También puede
usar PlatyPS para compilar los archivos de ayuda en un paquete CAB que se puede
alojar para obtener ayuda actualizable.
PowerShell
2. Use PlatyPS para generar archivos Markdown para la página de módulo y todos los
cmdlets asociados en el módulo. Repita este paso para cada módulo que necesite
documentar.
PowerShell
1. Importe el nuevo módulo a la sesión. Repita este paso para cada módulo que
necesite documentar.
PowerShell
PowerShell
$parameters = @{
Path = <folder with Markdown>
RefreshModulePage = $true
AlphabeticParamsOrder = $true
UpdateInputOutput = $true
ExcludeDontShow = $true
LogPath = <path to store log file>
Encoding = [System.Text.Encoding]::UTF8
}
Update-MarkdownHelpModule @parameters
7 Nota
PlatyPS tiene un esquema específico que se usa para la referencia de cmdlet. Ese
esquema solo permite determinados bloques Markdown en secciones específicas
del documento. Si coloca el contenido en la ubicación incorrecta, se produce un
error en el paso de compilación de PlatyPS. Para obtener más información, consulte
la documentación del esquema en el repositorio de PlatyPS. Para obtener un
ejemplo completo de la referencia de cmdlets bien formada, vea Get-Item.
Después de proporcionar el contenido necesario para cada uno de los cmdlets, debe
actualizar la página de aterrizaje del módulo. Compruebe que el módulo tiene los
valores Module Guid y Download Help Link correctos en los metadatos de YAML del
archivo de <module-name>.md . Agregue los metadatos que faltan.
Además, es posible que observe que en algunos cmdlets puede faltar el elemento
Synopsis (descripción breve). El siguiente comando actualiza la página de aterrizaje del
módulo con el texto de descripción de Synopsis. Abra la página de aterrizaje del
módulo para comprobar las descripciones.
PowerShell
Ahora que ha escrito todo el contenido, puede crear los archivos de ayuda de MAML
que se muestran mediante Get-Help en la consola de PowerShell.
PowerShell
archivos MAML. Los archivos about se convierten en archivos de texto sin formato con
el formato de nombre about_topic_name.help.txt . El contenido Markdown debe
cumplir el requisito del esquema PlatyPS. New-ExternalHelp se cierra con errores cuando
el contenido no sigue el esquema. Debe modificar los archivos para corregir las
infracciones del esquema.
U Precaución
los convierta.
Una vez completado este paso, verá los archivos *-help.xml y about_*.help.txt en la
carpeta de salida de destino.
PowerShell
Publicación de la ayuda
Ahora que ha compilado los archivos Markdown en los archivos de ayuda de
PowerShell, está a punto para poner los archivos a disposición de los usuarios. Hay dos
opciones para proporcionar ayuda en la consola de PowerShell.
Para obtener más información, vea Creación de la Ayuda actualizable: paso a paso.
HelpInfoURI es una dirección URL que apunta a la ubicación donde se hospedan los
archivos de ayuda en Internet. Este valor se configura en el manifiesto del módulo.
Update-Help lee el manifiesto del módulo para obtener esta dirección URL y descargar
) Importante
HelpInfoURI debe terminar con un carácter de barra diagonal ( / ). Sin ese carácter,
Update-Help no puede construir las rutas de acceso de archivo correctas para
descargar el contenido. Además, la mayoría de los servicios de archivo basados en
HTTP distinguen mayúsculas de minúsculas. Es importante que los metadatos del
módulo del archivo HelpInfo XML sean correctos en cuanto a mayúsculas y
minúsculas.
El cmdlet New-ExternalHelpCab crea archivos ZIP y CAB que contienen los archivos
MAML y about_*.help.txt que compiló. Los archivos CAB son compatibles con todas
las versiones de PowerShell. PowerShell 6 y versiones posteriores pueden usar archivos
ZIP.
PowerShell
$helpCabParameters = @{
CabFilesFolder = $MamlOutputFolder
LandingPagePath = $LandingPage
OutputFolder = $CabOutputFolder
}
New-ExternalHelpCab @helpCabParameters
Después de crear los archivos ZIP y CAB, cargue los archivos ZIP, CAB y HelpInfo XML en
su servidor de archivos HTTP. Coloque los archivos en la ubicación indicada por
HelpInfoURI.
Problemas conocidos
PlatyPS es muy sensible al esquema para la estructura de los archivos Markdown que
crea y compila. Es muy fácil escribir un Markdown válido que infrinja este esquema. Para
obtener más información, consulte la guía de estilo de PowerShell y los artículos de
referencia de edición.
Módulo PSScriptAnalyzer
Artículo • 13/12/2022
Puede elegir qué reglas incluir o excluir para los módulos y scripts. PSScriptAnalyzer
también tiene la capacidad de corregir el formato del código. Esto le ayuda a generar
código que se ajusta a un estilo estándar, es más fácil de leer y es más fácil de
mantener.
Instalación de PSScriptAnalyzer
Versiones y plataformas de PowerShell compatibles
PowerShell
PowerShell
PowerShell
Output
PowerShell
Output
Suprimir reglas
Puede suprimir una regla mediante la decoración de 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:
PowerShell
function SuppressMe()
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp',
'', Justification='Just an example')]
param()
Dentro del ámbito del script, la función o el parámetro que decora, se suprimen todas
las infracciones de reglas.
PowerShell
function SuppressTwoVariables()
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParamete
rValue', 'b')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParamete
rValue', '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.
Use el valor Function para suprimir infracciones en todas las funciones dentro del
ámbito del atributo. Use el valor Class para suprimir infracciones en todas las clases
dentro del ámbito del atributo:
PowerShell
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp',
'', Scope='Function')]
param(
)
function InternalFunction
{
param()
Puede restringir aún más la supresión en función, parámetro, clase, variable o nombre
del objeto estableciendo la propiedad Target de SuppressMessageAttribute en una
expresión regular o un patrón de caracteres comodín.
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWrite
Host', '', 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 infracciones en todas las funciones:
PowerShell
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost',
'', Scope='Function', Target='*')]
Param()
PowerShell
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost',
'', Scope='Function', Target='start-b*')]
Param()
7 Nota
PowerShell
Explícito
En el ejemplo siguiente se excluyen dos reglas del conjunto predeterminado de reglas y
cualquier regla con una gravedad distinta de *Error y Advertencia.
PowerShell
# PSScriptAnalyzerSettings.psd1
@{
Severity=@('Error','Warning')
ExcludeRules=@('PSAvoidUsingCmdletAliases',
'PSAvoidUsingWriteHost')
}
PowerShell
En el ejemplo siguiente se seleccionan algunas reglas para ejecutar en lugar de todas las
reglas predeterminadas.
PowerShell
# PSScriptAnalyzerSettings.psd1
@{
IncludeRules=@('PSAvoidUsingPlainTextForPassword',
'PSAvoidUsingConvertToSecureStringWithPlainText')
}
PowerShell
Implícita
Si coloca un archivo de configuración denominado PSScriptAnalyzerSettings.psd1 en la
raíz del proyecto, PSScriptAnalyzer lo detecta al pasar la raíz del proyecto como
parámetro Path .
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 de acceso apunten a la carpeta
de un módulo, que usa 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
mediante Export-ModuleMember para que estén disponibles para PSScriptAnalyzer.
PowerShell
@{
CustomRulePath = @(
'.\output\RequiredModules\DscResource.AnalyzerRules'
'.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
)
IncludeRules = @(
'Measure-*'
)
}
PowerShell
@{
CustomRulePath = @(
'.\output\RequiredModules\DscResource.AnalyzerRules'
'.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
)
IncludeDefaultRules = $true
IncludeRules = @(
# Default rules
'PSAvoidDefaultValueForMandatoryParameter'
'PSAvoidDefaultValueSwitchParameter'
# Custom rules
'Measure-*'
)
}
JSON
{
"powershell.scriptAnalysis.settingsPath":
".vscode/analyzersettings.psd1",
"powershell.scriptAnalysis.enable": true,
}
C#
using Microsoft.Windows.PowerShell.ScriptAnalyzer;
public System.Collections.Generic.IEnumerable<DiagnosticRecord>
AnalyzePath(string path,
[bool searchRecursively = false])
Corrección de infracciones
Puede usar el modificador Corregir para reemplazar automáticamente el contenido que
causa la infracción por una alternativa sugerida. Además, dado Invoke-ScriptAnalyzer
que implementa SupportsShouldProcess, puede usar WhatIf o Confirm para averiguar
qué correcciones se aplicarían. Debe usar el control de código fuente al aplicar
correcciones como algunos cambios, como el de AvoidUsingPlainTextForPassword,
podría requerir modificaciones de script adicionales que no se pueden realizar
automáticamente. Dado que la codificación inicial no siempre se puede conservar al
aplicar automáticamente sugerencias, debe comprobar la codificación del archivo si los
scripts dependen de una codificación determinada.
AvoidAlias
AvoidUsingPlainTextForPassword
MisleadingBacktick
MissingModuleManifestField
UseToExportFieldsInManifest
Recomendaciones y reglas de
PSScriptAnalyzer
Artículo • 13/12/2022
Gravedad: error
No hay reglas definidas.
Gravedad: advertencia
Usar solo verbos aprobados UseApprovedVerbs
Nombres de cmdlets con caracteres no utilizables AvoidReservedCharInCmdlet
Nombres de parámetros que no se pueden usar AvoidReservedParams
Solicitudes de confirmación de soporte técnico
UseShouldProcessForStateChangingFunctions y
UseShouldProcessForStateChangingFunctions
Debe llamar a ShouldProcess cuando el atributo ShouldProcess esté presente y
viceversa UseShouldProcess
Los nombres deben ser singulares UseSingularNouns
Faltan campos de manifiesto de módulo MissingModuleManifestField
Versión
Autor
Descripción
LicenseUri (para Galería de PowerShell)
Los parámetros switch no deben tener como valor predeterminado true
AvoidDefaultValueSwitchParameter
Gravedad: información
No hay reglas definidas.
Gravedad: TBD
Parámetro Force para sesiones interactivas. Si el cmdlet se usa de forma
interactiva, proporcione siempre un parámetro Force para invalidar las acciones
interactivas, como mensajes o líneas de entrada. Esto es importante porque
permite que el cmdlet se use en hosts y scripts no interactivos. Un host interactivo
puede implementar los métodos siguientes.
Objetos de salida del documento
El módulo debe ser cargable
Sin errores de sintaxis
Las dependencias no resueltas son un error
Derivar de las clases cmdlet o PSCmdlet
Especificación del atributo de cmdlet
Invalidar un método de procesamiento de entrada
Especificar el atributo OutputType
Escritura de registros únicos en la canalización
Hacer que los cmdlets no distinguen mayúsculas de minúsculas y conservan
mayúsculas de minúsculas
Gravedad: error
No hay reglas definidas.
Gravedad: advertencia
Evitar el uso de alias AvoidUsingCmdletAliases
Evitar el uso de cmdlets WMI en desuso AvoidUsingWMICmdlet
Evitar el uso de bloques catch vacíos AvoidUsingEmptyCatchBlock
Invocación de cmdlets existentes con parámetros correctos
UseCmdletCorrectamente
Los cmdlets deben tener el parámetro ShouldProcess/ShouldContinue y Force si
se usan determinados verbos modificados por el sistema (Update, Set, Remove,
New): UseShouldProcessForStateChangingFunctions
Evitar el uso de parámetros posicionales AvoidUsingPositionalParameters
Evitar el uso de variables globales AvoidGlobalVars
Las variables declaradas se deben usar después de su asignación
UseDeclaredVarsMoreThanAssignments
Evite usar Invoke-Expression AvoidUsingInvokeExpression
Gravedad: información
No hay reglas definidas.
Gravedad: TBD
Evitar el uso Clear-Host
Evitar el uso de rutas de acceso de archivos UNC
Tratamiento de errores
Uso -ErrorAction Stop al llamar a cmdlets
Uso $ErrorActionPreference = 'Stop'/'Continue' al llamar a cmdlets que no
son
Evitar el uso de marcas para controlar errores
Evitar el uso $?
Evitar pruebas de una variable nula como condición de error
Copiar $Error[0] en su propia variable
Evitar el uso de canalizaciones en scripts
Si se declara un tipo de valor devuelto, el cmdlet debe devolver ese tipo. Si se
devuelve un tipo, se debe declarar un tipo de valor devuelto.
Estilo de scripting
Gravedad: error
No hay reglas definidas.
Gravedad: advertencia
Evite usar a Write-Host menos que escribir en el host sea todo lo que desea hacer
AvoidUsingWriteHost
Gravedad: información
Escribir ayuda basada en comentarios ProvideCommentHelp
Gravedad: TBD
Proporcionar ejemplos de uso
Use la sección Notas para obtener más información sobre cómo funciona la
herramienta.
Todos los comandos exportados deben tener ayuda (incluida la documentación de
parámetros)
Documentar la versión de PowerShell para la que se escribió el script
Sangría del código
Evitar acentos versos
Gravedad: error
Evite usar contraseñas de texto sin formato AvoidUsingPlainTextForPassword
Evite -Username los parámetros y -Password (use PSCredential en su lugar):
UsePSCredentialType
Evitar codificar de forma hardcoding un -ComputerName argumento de parámetro
(divulgación de información): AvoidUsingComputerNameHardcoded
Evitar el uso ConvertTo-SecureString con texto no cifrado (divulgación de
información): AvoidUsingConvertToSecureStringWithPlainText
Gravedad: advertencia
Evite usar $Password = 'string' (divulgación de información).
AvoidUsingUsernameAndPasswordParams
Gravedad: información
No hay reglas definidas.
Gravedad: TBD
Evite inicializar las variables APIKey y Credentials (divulgación de información)
Gravedad: advertencia
No hay reglas definidas.
Gravedad: información
Las tres recomendaciones siguientes se tratan en la regla
ReturnCorrectTypesForDSCFunctions .
Evite devolver cualquier objeto de una Set-TargetResource función o Set
(basada en clases)
Devolver un valor booleano de una Test-TargetResource función o test (basada
en clases)
Devolver un objeto de una Get-TargetResource función o Get (basada en clases)
Los recursos de DSC deben tener pruebas DSCTestsPresent
Los recursos de DSC deben tener ejemplos de DSCExamplesPresent
Gravedad: TBD
Para Windows PowerShell v4, los módulos de recursos deben tener un .psd1
archivo y schema.mof para cada recurso.
Las MOF deben tener una descripción para cada elemento; vea Problema n.º
131 .
Los módulos de recursos deben tener un .psd1 archivo (siempre) y schema.mof
(para recursos que no son de clase), vea Problema n.º 116 .
Usar ShouldProcess para un método Set DSC
El módulo de recursos contiene la carpeta DscResources que contiene los recursos;
vea Problema n.º 130 .
Referencias
Directrices de desarrollo del cmdlet
Lista de comprobación de pruebas y diseño de recursos de DSC de PowerShell
Las directrices de DSC también se pueden encontrar en el repositorio de recursos
de DSC.
Procedimientos recomendados de las directrices & de estilo de recurso de
DSC
Nomenclatura de recursos de DSC
Creación de un módulo de recursos de DSC de alta calidad
Guía de estilos y procedimientos recomendados de PowerShell no oficiales
Creación de reglas personalizadas
Artículo • 13/12/2022
PSScriptAnalyzer usa el Managed Extensibility Framework (MEF) para importar todas las
reglas definidas en el ensamblado. También puede consumir reglas escritas en scripts de
PowerShell.
En este artículo se proporciona una guía básica para crear sus propias reglas
personalizadas.
Requisitos básicos
PowerShell
<#
.SYNOPSIS
Name of your rule.
.DESCRIPTION
This would be the description of your rule. Please refer to Rule
Documentation
for consistent rule messages.
.EXAMPLE
.INPUTS
.OUTPUTS
.NOTES
#>
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticR
ecord[]])]
Cada función debe tener una matriz token o un
parámetro Ast.
El nombre del parámetro Ast debe terminar con Ast.
PowerShell
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$testAst
)
PowerShell
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.Token[]]
$testToken
)
Mensaje
Extensión
RuleName
Gravedad
PowerShell
$result =
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]@{
"Message" = "This is a sample rule"
"Extent" = $ast.Extent
"RuleName" = $PSCmdlet.MyInvocation.InvocationName
"Severity" = "Warning"
}
Desde la versión 1.17.0, puede incluir una propiedad SuggestedCorrections de tipo
IEnumerable<CorrectionExtent>. Asegúrese de especificar el tipo correcto. Por
ejemplo:
PowerShell
[int]$startLineNumber = $ast.Extent.StartLineNumber
[int]$endLineNumber = $ast.Extent.EndLineNumber
[int]$startColumnNumber = $ast.Extent.StartColumnNumber
[int]$endColumnNumber = $ast.Extent.EndColumnNumber
[string]$correction = 'Correct text that replaces Extent text'
[string]$file = $MyInvocation.MyCommand.Definition
[string]$optionalDescription = 'Useful but optional description text'
$objParams = @{
TypeName =
'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent'
ArgumentList = $startLineNumber, $endLineNumber, $startColumnNumber,
$endColumnNumber, $correction, $optionalDescription
}
$correctionExtent = New-Object @objParams
$suggestedCorrections = New-Object
System.Collections.ObjectModel.Collection[$($objParams.TypeName)]
$suggestedCorrections.add($correctionExtent) | Out-Null
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
"Message" = "This is a rule with a suggested correction"
"Extent" = $ast.Extent
"RuleName" = $PSCmdlet.MyInvocation.InvocationName
"Severity" = "Warning"
"Severity" = "Warning"
"RuleSuppressionID" = "MyRuleSuppressionID"
"SuggestedCorrections" = $suggestedCorrections
}
<#
.SYNOPSIS
Uses #Requires -RunAsAdministrator instead of your own methods.
.DESCRIPTION
The #Requires statement prevents a script from running unless the
Windows PowerShell
version, modules, snap-ins, and module and snap-in version prerequisites
are met.
From Windows PowerShell 4.0, the #Requires statement let script
developers require that
sessions be run with elevated user rights (run as Administrator). Script
developers does
not need to write their own methods any more. To fix a violation of this
rule, please
consider using #Requires -RunAsAdministrator instead of your own
methods.
.EXAMPLE
Measure-RequiresRunAsAdministrator -ScriptBlockAst $ScriptBlockAst
.INPUTS
[System.Management.Automation.Language.ScriptBlockAst]
.OUTPUTS
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
.NOTES
None
#>
function Measure-RequiresRunAsAdministrator
{
[CmdletBinding()]
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticR
ecord[]])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$ScriptBlockAst
)
Process
{
$results = @()
try
{
#region Define predicates to find ASTs.
# Finds specific method, IsInRole.
[ScriptBlock]$predicate1 = {
param ([System.Management.Automation.Language.Ast]$Ast)
[bool]$returnValue = $false
if ($Ast -is
[System.Management.Automation.Language.MemberExpressionAst])
{
[System.Management.Automation.Language.MemberExpressionAst]$meAst = $Ast
if ($meAst.Member -is
[System.Management.Automation.Language.StringConstantExpressionAst])
{
[System.Management.Automation.Language.StringConstantExpressionAst]$sceAst =
$meAst.Member
if ($sceAst.Value -eq 'isinrole')
{
$returnValue = $true
}
}
}
return $returnValue
}
[System.Management.Automation.Language.AssignmentStatementAst]$asAst = $Ast
if ($asAst.Right.ToString() -eq
'[system.security.principal.windowsbuiltinrole]::administrator')
{
$returnValue = $true
}
}
return $returnValue
}
#endregion
#region Finds ASTs that match the predicates.
[System.Management.Automation.Language.Ast[]]$methodAst =
$ScriptBlockAst.FindAll($predicate1, $true)
[System.Management.Automation.Language.Ast[]]$assignmentAst =
$ScriptBlockAst.FindAll($predicate2, $true)
if ($null -ne $ScriptBlockAst.ScriptRequirements)
{
if
((!$ScriptBlockAst.ScriptRequirements.IsElevationRequired) -and
($methodAst.Count -ne 0) -and ($assignmentAst.Count -ne 0))
{
$result =
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
'Message' =
$Messages.MeasureRequiresRunAsAdministrator
'Extent' = $assignmentAst.Extent
'RuleName' = $PSCmdlet.MyInvocation.InvocationName
'Severity' = 'Information'
}
$results += $result
}
}
else
{
if (($methodAst.Count -ne 0) -and ($assignmentAst.Count -ne
0))
{
$result =
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
'Message' =
$Messages.MeasureRequiresRunAsAdministrator
'Extent' = $assignmentAst.Extent
'RuleName' = $PSCmdlet.MyInvocation.InvocationName
'Severity' = 'Information'
}
$results += $result
}
}
return $results
#endregion
}
catch
{
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}
}
AlignAssignmentStatement Advertencia No Sí
AvoidAssignmentToAutomaticVariable Advertencia Sí
AvoidDefaultValueForMandatoryParameter Advertencia Sí
AvoidDefaultValueSwitchParameter Advertencia Sí
AvoidGlobalAliases1 Advertencia Sí
AvoidGlobalFunctions Advertencia Sí
AvoidGlobalVars Advertencia Sí
AvoidInvokingEmptyMembers Advertencia Sí
AvoidLongLines Advertencia No Sí
AvoidMultipleTypeAttributes1 Advertencia Sí
AvoidNullOrEmptyHelpMessageAttribute Advertencia Sí
AvoidOverwritingBuiltInCmdlets Advertencia Sí Sí
AvoidSemicolonsAsLineTerminators Advertencia No
AvoidShouldContinueWithoutForce Advertencia Sí
AvoidTrailingWhitespace Advertencia Sí
AvoidUsingBrokenHashAlgorithms Advertencia Sí
AvoidUsingComputerNameHardcoded Error Sí
AvoidUsingConvertToSecureStringWithPlainText Error Sí
AvoidUsingDeprecatedManifestFields Advertencia Sí
AvoidUsingDoubleQuotesForConstantString Información No
Regla severity Habilitado de Configurable
forma
predeterminada
AvoidUsingEmptyCatchBlock Advertencia Sí
AvoidUsingInvokeExpression Advertencia Sí
AvoidUsingPlainTextForPassword Advertencia Sí
AvoidUsingPositionalParameters Advertencia Sí
AvoidUsingUsernameAndPasswordParams Error Sí
AvoidUsingWMICmdlet Advertencia Sí
AvoidUsingWriteHost Advertencia Sí
DSCDscExamplesPresent Información Sí
DSCDscTestsPresent Información Sí
DSCReturnCorrectTypesForDSCFunctions Información Sí
DSCStandardDSCFunctionsInResource Error Sí
DSCUseIdenticalMandatoryParametersForDSC Error Sí
DSCUseIdenticalParametersForDSC Error Sí
DSCUseVerboseMessageInDSCResource Error Sí
MisleadingBacktick Advertencia Sí
MissingModuleManifestField Advertencia Sí
PlaceCloseBrace Advertencia No Sí
PlaceOpenBrace Advertencia No Sí
PossibleIncorrectComparisonWithNull Advertencia Sí
PossibleIncorrectUsageOfAssignmentOperator Advertencia Sí
PossibleIncorrectUsageOfRedirectionOperator Advertencia Sí
ProvideCommentHelp Información Sí Sí
ReservedCmdletChar Error Sí
ReservedParams Error Sí
ReviewUnusedParameter Advertencia Sí
Regla severity Habilitado de Configurable
forma
predeterminada
ShouldProcess Advertencia Sí
UseApprovedVerbs Advertencia Sí
UseBOMForUnicodeEncodedFile Advertencia Sí
UseCompatibleCommands Advertencia No Sí
UseCompatibleSyntax Advertencia No Sí
UseCompatibleTypes Advertencia No Sí
UseConsistentIndentation Advertencia No Sí
UseConsistentWhitespace Advertencia No Sí
UseCorrectCasing Información No Sí
UseDeclaredVarsMoreThanAssignments Advertencia Sí
UseLiteralInitializerForHashtable Advertencia Sí
UseProcessBlockForPipelineCommand Advertencia Sí
UsePSCredentialType Advertencia Sí
UseShouldProcessForStateChangingFunctions Advertencia Sí
UseSingularNouns Advertencia Sí
UseSupportsShouldProcess Advertencia Sí
UseToExportFieldsInManifest Advertencia Sí
UseUsingScopeModifierInNewRunspaces Advertencia Sí
UseUTF8EncodingForHelpFile Advertencia Sí
1
La regla no está disponible en todas las versiones, ediciones o plataformas del
sistema operativo de PowerShell. Consulte la documentación de la regla para
obtener más información.
2
La regla es una propiedad configurable, pero la regla no se puede deshabilitar
como otras reglas configurables.
AlignAssignmentStatement
Artículo • 15/05/2023
Descripción
Las instrucciones de asignación consecutivas son más legibles si están alineadas. Al
alinearse, implicamos que el equal signo de todas las instrucciones de asignación debe
estar en la misma columna.
La regla busca pares de valor de clave (propiedad) en una tabla hash (configuración de
DSC) para comprobar si están alineados o no. Considere el ejemplo siguiente en el que
los pares clave-valor no están alineados.
PowerShell
$hashtable = @{
property1 = 'value'
anotherProperty = 'another value'
}
PowerShell
$hashtable = @{
property1 = 'value'
anotherProperty = 'another value'
}
La regla omite las tablas hash en las que las instrucciones de asignación están en la
misma línea. Por ejemplo, la regla omite $h = {a = 1; b = 2} .
Configuración
PowerShell
Rules = @{
PSAlignAssignmentStatement = @{
Enable = $true
CheckHashtable = $true
}
}
Parámetros
Descripción
PowerShell tiene variables integradas conocidas como variables automáticas. Muchos de
ellos son de solo lectura y PowerShell produce un error al intentar asignar un valor en
ellos. Solo se deben asignar otras variables automáticas en determinados casos
especiales para lograr un efecto determinado como técnica especial.
Para obtener más información sobre las variables automáticas, consulte Get-Help
about_Automatic_Variables .
Cómo
Use nombres de variable en funciones o sus parámetros que no entren en conflicto con
variables automáticas.
Ejemplo
Incorrecto
La variable es una variable $Error automática que existe en el ámbito global y, por
tanto, nunca se debe usar como variable o nombre de parámetro.
PowerShell
function foo($Error){ }
PowerShell
Correcto
PowerShell
Descripción
Los parámetros obligatorios no deben tener valores predeterminados porque no hay
ningún escenario en el que se pueda usar el valor predeterminado. PowerShell solicita
un valor si no se especifica el valor del parámetro al llamar a la función.
Ejemplo
Incorrecto
PowerShell
function Test
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
$Parameter1 = 'default Value'
)
}
Correcto
PowerShell
function Test
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
$Parameter1
)
}
AvoidDefaultValueSwitchParameter
Artículo • 13/12/2022
Descripción
Cambiar los parámetros de los comandos debe ser false de forma predeterminada.
Cómo
Cambie el valor predeterminado del parámetro switch para que sea false.
Ejemplo
Incorrecto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[String]
$Param1,
[switch]
$Switch=$True
)
...
}
Correcto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[String]
$Param1,
[switch]
$Switch=$False
)
...
}
AvoidGlobalAliases
Artículo • 15/05/2023
Descripción
Los alias con ámbito global invalidan los alias existentes dentro de las sesiones con
nombres coincidentes. Esta colisión de nombres puede provocar problemas difíciles de
depurar para los consumidores de módulos y scripts.
Cómo
Use otros modificadores de ámbito para nuevos alias.
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Las funciones con ámbito global invalidan las funciones existentes dentro de las
sesiones con nombres coincidentes. Esta colisión de nombres puede causar problemas
difíciles de depurar para los consumidores de módulos.
Cómo
Use otros modificadores de ámbito para las funciones.
Ejemplo
Incorrecto
PowerShell
function global:functionName {}
Correcto
PowerShell
function functionName {}
AvoidGlobalVars
Artículo • 13/12/2022
Descripción
Una variable es una unidad de memoria en la que se almacenan los valores. PowerShell
controla el acceso a variables, funciones, alias y unidades a través de un mecanismo
conocido como ámbito. Las variables y funciones que están presentes cuando se inicia
PowerShell se han creado en el ámbito global.
Variables automáticas
Variables de preferencia
Variables, alias y funciones que se encuentran en los perfiles de PowerShell
Cómo
Use otros modificadores de ámbito para variables.
Ejemplo
Incorrecto
PowerShell
$Global:var1 = $null
function Test-NotGlobal ($var)
{
$a = $var + $var1
}
Correcto
PowerShell
$var1 = $null
function Test-NotGlobal ($var1, $var2)
{
$a = $var1 + $var2
}
AvoidInvokingEmptyMembers
Artículo • 15/05/2023
Descripción
La invocación de miembros que no son constantes puede provocar posibles errores.
Compruebe la sintaxis para asegurarse de que los miembros invocados son constantes.
Cómo
Proporcione los miembros solicitados para un tipo o clase determinado.
Ejemplo
Incorrecto
PowerShell
$MyString = 'abc'
$MyString.('len'+'gth')
Correcto
PowerShell
$MyString = 'abc'
$MyString.('length')
AvoidLongLines
Artículo • 13/12/2022
Descripción
Las líneas no deben superar un número configurado de caracteres (valor
predeterminado: 120), incluido el espacio en blanco inicial (sangría).
Nota: Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo
a través de la configuración.
Configuración
PowerShell
Rules = @{
PSAvoidLongLines = @{
Enable = $true
MaximumLineLength = 120
}
}
Parámetros
Descripción
Los parámetros no deben tener más de un especificador de tipo. Varios especificadores
de tipo en parámetros pueden provocar errores en tiempo de ejecución.
Cómo
Asegúrese de que cada parámetro solo tiene un especificador de tipo.
Ejemplo
Incorrecto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[switch]
[int]
$Switch
)
}
Correcto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[switch]
$Switch
)
}
AvoidNullOrEmptyHelpMessageAttribut
e
Artículo • 13/12/2022
Descripción
El valor del HelpMessage atributo no debe ser una cadena vacía o un valor NULL, ya que
esto hace que el intérprete de PowerShell produzca un error al ejecutar la función o el
cmdlet.
Cómo
Especifique un valor para el HelpMessage atributo .
Ejemplo
Incorrecto
PowerShell
Function BadFuncEmptyHelpMessageEmpty
{
Param(
[Parameter(HelpMessage='')]
[String]
$Param
)
$Param
}
Function BadFuncEmptyHelpMessageNull
{
Param(
[Parameter(HelpMessage=$null)]
[String]
$Param
)
$Param
}
Function BadFuncEmptyHelpMessageNoAssignment
{
Param(
[Parameter(HelpMessage)]
[String]
$Param
)
$Param
}
Correcto
PowerShell
Function GoodFuncHelpMessage
{
Param(
[Parameter(HelpMessage='This is helpful')]
[String]
$Param
)
$Param
}
AvoidOverwritingBuiltInCmdlets
Artículo • 16/05/2023
Descripción
Esta regla marca los cmdlets que están disponibles en una versión o edición
determinada de PowerShell en un sistema operativo determinado que se sobrescribe
mediante una declaración de función. Funciona comparando declaraciones de función
con un conjunto de listas de permitidos que se incluyen con PSScriptAnalyzer. Otras
reglas de PSScriptAnalyzer usan estos archivos de lista de permitidos. Puede encontrar
más información en la documentación de la regla UseCompatibleCmdlets .
Configuración
Para habilitar la regla para comprobar si el script es compatible con PowerShell Core en
Windows, coloque el siguiente archivo de configuración.
PowerShell
@{
'Rules' = @{
'PSAvoidOverwritingBuiltInCmdlets' = @{
'PowerShellVersion' = @('core-6.1.0-windows')
}
}
}
Parámetros
PowerShellVersion
El parámetro PowerShellVersion es una lista de listas de permitidos que se incluyen con
PSScriptAnalyzer.
Descripción
Las líneas no deben terminar con un punto y coma.
7 Nota
Ejemplo
Incorrecto
PowerShell
PowerShell
Correcto
PowerShell
PowerShell
Rules = @{
PSAvoidSemicolonsAsLineTerminators = @{
Enable = $true
}
}
Parámetros
Descripción
Las funciones que usan ShouldContinue deben tener un parámetro de fuerza booleana
para permitir que el usuario lo omita.
Cómo
Llame al ShouldContinue método en funciones avanzadas cuando ShouldProcess el
método devuelve $true .
Ejemplo
Incorrecto
PowerShell
Function Test-ShouldContinue
{
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
$MyString = 'blah'
)
Correcto
PowerShell
Function Test-ShouldContinue
{
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
$MyString = 'blah',
[Switch]$Force
)
Descripción
Las líneas no deben terminar con caracteres de espacio en blanco. Esto puede causar
problemas con el retroceso de continuación de línea y también desordena las
confirmaciones futuras en el control de código fuente.
AvoidUsingBrokenHashAlgorithms
Artículo • 13/12/2022
Descripción
Evite usar los algoritmos rotos MD5 o SHA-1.
Cómo
Reemplace los algoritmos rotos por alternativas seguras. MD5 y SHA-1 deben
reemplazarse por SHA256, SHA384, SHA512 u otros algoritmos más seguros siempre
que sea posible, por lo que MD5 y SHA-1 solo se usan por necesidad para la
compatibilidad con versiones anteriores.
Ejemplo 1
Incorrecto
PowerShell
Correcto
PowerShell
Ejemplo 2
Incorrecto
PowerShell
Get-FileHash foo.txt
AvoidUsingCmdletAliases
Artículo • 13/12/2022
Descripción
Un alias es un nombre o alias alternativo para un cmdlet o para un elemento de
comando, como una función, un script, un archivo o un archivo ejecutable. Puede usar el
alias en lugar del nombre del comando en cualquier comando de PowerShell.
También hay alias implícitos. Cuando PowerShell no encuentra el nombre del cmdlet,
intentará anexar Get- al comando como último recurso. Por lo tanto, el uso del
comando verb ejecutará Get-Verb .
Cada autor de PowerShell aprende los nombres de comando reales, pero los distintos
autores aprenden y usan alias diferentes. Los alias pueden hacer que el código sea difícil
de leer, comprender y afectar a la disponibilidad.
El uso del nombre de comando completo hace que sea eaiser mantener los scripts en el
futuro.
El uso de los nombres de comando completos también permite resaltar sintaxis en sitios
y aplicaciones como GitHub y Visual Studio Code.
Solución
Use el nombre completo del cmdlet y no un alias.
PowerShell
# PSScriptAnalyzerSettings.psd1
@{
'Rules' = @{
'PSAvoidUsingCmdletAliases' = @{
'allowlist' = @('cd')
}
}
}
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Los nombres de los equipos nunca deben codificarse de forma rígida, ya que esto
expondrá información confidencial. El ComputerName parámetro nunca debe tener un
valor codificado de forma rígida.
Cómo
Quite los nombres de equipo codificados de forma rígida.
Ejemplo 1
Incorrecto
PowerShell
Function Invoke-MyRemoteCommand ()
{
Invoke-Command -Port 343 -ComputerName hardcoderemotehostname
}
Correcto
PowerShell
Ejemplo 2
Incorrecto
PowerShell
Function Invoke-MyLocalCommand ()
{
Invoke-Command -Port 343 -ComputerName hardcodelocalhostname
}
Correcto
PowerShell
Function Invoke-MyLocalCommand ()
{
Invoke-Command -Port 343 -ComputerName $env:COMPUTERNAME
}
AvoidUsingConvertToSecureStringWithP
lainText
Artículo • 15/05/2023
Descripción
El uso del AsPlainText parámetro con el ConvertTo-SecureString comando puede
exponer información segura.
Cómo
Use una variable cifrada estándar para realizar cualquier conversión secureString.
Recomendaciones
Si necesita una capacidad para recuperar la contraseña desde algún lugar sin preguntar
al usuario, considere la posibilidad de usar el módulo SecretStore de la Galería de
PowerShell.
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
En PowerShell 5.0, se han cambiado varios campos en los archivos de manifiesto del
módulo ( .psd1 ).
Cómo
Reemplace por ModuleToProcess RootModule en el manifiesto del módulo.
Ejemplo
Incorrecto
PowerShell
ModuleToProcess ='psscriptanalyzer'
ModuleVersion = '1.0'
Correcto
PowerShell
RootModule ='psscriptanalyzer'
ModuleVersion = '1.0'
AvoidUsingDoubleQuotesForConstantSt
ring
Artículo • 13/12/2022
Descripción
Las comillas simples se deben usar cuando el valor de una cadena es constante. Una
cadena constante no contiene variables ni expresiones diseñadas para insertar valores
en la cadena, como "$PID-$(hostname)" ).
Esto hace que la intención sea más clara que la cadena es una constante y facilita el uso
de algunos caracteres especiales, como $ dentro de esa expresión de cadena sin
necesidad de escaparlas.
Hay excepciones a que, cuando las cadenas entre comillas dobles son más legibles. Por
ejemplo, cuando el propio valor de cadena debe contener una comilla simple u otros
caracteres especiales, como newline ( "`n" ), ya se están escapando. La regla no advierte
en estos casos.
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Los bloques catch vacíos se consideran una opción de diseño deficiente porque no se
puede controlar ningún error en un try bloque.
Cómo
Use Write-Error instrucciones o throw dentro del bloque catch.
Ejemplo
Incorrecto
PowerShell
try
{
1/0
}
catch [DivideByZeroException]
{
}
Correcto
PowerShell
try
{
1/0
}
catch [DivideByZeroException]
{
Write-Error 'DivideByZeroException'
}
try
{
1/0
}
catch [DivideByZeroException]
{
throw 'DivideByZeroException'
}
AvoidUsingInvokeExpression
Artículo • 15/05/2023
Descripción
Se debe tener cuidado al usar el Invoke-Expression comando . Invoke-Expression
ejecuta la cadena especificada y devuelve los resultados.
Cómo
Quite el uso de Invoke-Expression .
Ejemplo
Incorrecto
PowerShell
Invoke-Expression 'Get-Process'
Correcto
PowerShell
Get-Process
AvoidUsingPlainTextForPassword
Artículo • 13/12/2022
Descripción
Los parámetros de contraseña que toman texto no cifrado exponen contraseñas y
ponen en peligro la seguridad del sistema. Las contraseñas deben almacenarse en el
tipo SecureString .
Contraseña
Aprobado
Contraseñas
Passphrase
Contraseñas
PasswordParam
Si un parámetro se define con un nombre en la lista anterior, debe declararse con el tipo
SecureString.
Cómo
Cambie el tipo a SecureString.
Ejemplo
Incorrecto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[string]
$Password
)
...
}
Correcto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[SecureString]
$Password
)
...
}
AvoidUsingPositionalParameters
Artículo • 13/12/2022
Descripción
El uso de parámetros posicionales reduce la legibilidad del código y puede introducir
errores. Es posible que una versión futura del cmdlet cambie de forma que interrumpa
los scripts existentes si las llamadas al cmdlet se basan en la posición de los parámetros.
En el caso de cmdlets simples con solo unos pocos parámetros posicionales, el riesgo es
mucho menor. Para evitar que esta regla sea demasiado ruidosa, esta regla solo se
desencadena cuando se proporcionan 3 o más parámetros. Un ejemplo sencillo en el
que el riesgo de usar parámetros posicionales es insignificante, es Test-Path $Path .
Configuración
PowerShell
Rules = @{
AvoidUsingPositionalParameters = @{
CommandAllowList = 'az', 'Join-Path'
Enable = $true
}
}
Parámetros
Cómo
Use nombres de parámetro completos al llamar a comandos.
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Para estandarizar los parámetros de comando, las credenciales deben aceptarse como
objetos de tipo PSCredential. Las funciones no deben usar parámetros de nombre de
usuario o contraseña.
Cómo
Cambie el parámetro a tipo PSCredential.
Ejemplo
Incorrecto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[String]
$Username,
[SecureString]
$Password
)
...
}
Correcto
PowerShell
function Test-Script
{
[CmdletBinding()]
Param
(
[PSCredential]
$Credential
)
...
}
AvoidUsingWMICmdlet
Artículo • 15/05/2023
Descripción
A partir de PowerShell 3.0, los cmdlets CIM deben usarse a través de los cmdlets de
WMI.
Get-WmiObject
Remove-WmiObject
Invoke-WmiObject
Register-WmiEvent
Set-WmiInstance
Get-CimInstance
Remove-CimInstance
Invoke-CimMethod
Register-CimIndicationEvent
Set-CimInstance
Los cmdlets CIM cumplen con los estándares WS-Management (WSMan) y con el
estándar Common Information Model (CIM), lo que permite la administración de
sistemas operativos Windows y no Windows.
Cómo
Cambie al cmdlet basado en CIM equivalente.
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Se desaconseja en gran medida el uso de Write-Host comandos con el Show verbo. El
Show verbo significa explícitamente "mostrar en la pantalla, sin otras posibilidades".
Cómo
Reemplace Write-Host por Write-Output o Write-Verbose en función de si la intención
es registrar o devolver uno o varios objetos.
Ejemplo
Incorrecto
PowerShell
function Get-MeaningOfLife
{
...
Write-Host 'Computing the answer to the ultimate question of life, the
universe and everything'
...
Write-Host 42
}
Correcto
PowerShell
function Get-MeaningOfLife
{
[CmdletBinding()]Param() # to make it possible to set the
VerbosePreference when calling the function
...
Write-Verbose 'Computing the answer to the ultimate question of life,
the universe and everything'
...
Write-Output 42
}
function Show-Something
{
Write-Host 'show something on screen'
}
DscExamplesPresent
Artículo • 13/12/2022
Descripción
Comprueba que hay ejemplos de DSC para un recurso determinado.
Cómo
Para corregir una infracción de esta regla, asegúrese de que Examples el directorio está
presente:
Ejemplo
xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof
xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof
Ejemplos
MSFT_xAzureSubscription_AddSubscriptionExample.ps1
MSFT_xAzureSubscription_RemoveSubscriptionExample.ps1
MyDscResource
MyDscResource.psm1
MyDscResource.psd1
MyDscResource
MyDscResource.psm1
MyDscResource.psd1
Ejemplos
MyDscResource_Example1.ps1
MyDscResource_Example2.ps1
DscTestsPresent
Artículo • 13/12/2022
Descripción
Comprueba que hay pruebas de DSC para un recurso determinado.
Cómo
Para corregir una infracción de esta regla, asegúrese de que Tests el directorio está
presente:
Para los recursos no basados en clases, debe existir en el mismo nivel de carpeta
que DSCResources la carpeta.
Para los recursos basados en clases, debe estar presente en el mismo nivel de
carpeta que el archivo de recursos .psm1 .
Ejemplo
xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof
En este caso, para corregir esta advertencia, debemos agregar pruebas de la siguiente
manera:
xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof
Pruebas
MSFT_xAzureSubscription_Tests.ps1
MyDscResource
MyDscResource.psm1
MyDscResource.psd1
En este caso, para corregir esta advertencia, debemos agregar pruebas de la siguiente
manera:
MyDscResource
MyDscResource.psm1
MyDscResource.psd1
Pruebas
MyDscResource_Tests.ps1
ReturnCorrectTypesForDSCFunctions
Artículo • 13/12/2022
Descripción
Las funciones de los recursos de DSC tienen objetos devueltos específicos.
Cómo
Asegúrese de que cada función devuelve el tipo correcto.
Ejemplo 1
Incorrecto
PowerShell
function Get-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Test-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
Correcto
PowerShell
function Get-TargetResource
{
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Test-TargetResource
{
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
Ejemplo 2
Incorrecto
PowerShell
[DscResource()]
class MyDSCResource
{
[DscProperty(Key)]
[string] $Name
[String] Get()
{
...
}
[String] Set()
{
...
}
[bool] Test()
{
...
}
}
Correcto
PowerShell
[DscResource()]
class MyDSCResource
{
[DscProperty(Key)]
[string] $Name
[MyDSCResource] Get()
{
...
}
[void] Set()
{
...
}
[bool] Test()
{
...
}
}
StandardDSCFunctionsInResource
Artículo • 13/12/2022
Descripción
Todos los recursos de DSC son necesarios para implementar las funciones correctas.
Set-TargetResource
Test-TargetResource
Get-TargetResource
Set
Test
Get
Cómo
Agregue las funciones que faltan al recurso.
Ejemplo 1
Incorrecto
PowerShell
function Get-TargetResource
{
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
Correcto
PowerShell
function Get-TargetResource
{
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Test-TargetResource
{
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
Ejemplo 2
Incorrecto
PowerShell
[DscResource()]
class MyDSCResource
{
[DscProperty(Key)]
[string] $Name
[void] Set()
{
...
}
[bool] Test()
{
...
}
}
### Correct
```powershell
[DscResource()]
class MyDSCResource
{
[DscProperty(Key)]
[string] $Name
[MyDSCResource] Get()
{
...
}
[void] Set()
{
...
}
[bool] Test()
{
...
}
}
UseIdenticalMandatoryParametersForD
SC
Artículo • 13/12/2022
Descripción
En el caso de los recursos de DSC basados en scripts, si una propiedad se declara con
atributos Key de en un archivo mof, debe estar presente como un parámetro
obligatorio en las funciones y Set-TargetResource Test-TargetResource
correspondientes Get-TargetResource Required .
Cómo
Asegúrese de que todas las propiedades con Key atributos y Required tienen
parámetros obligatorios equivalentes en las Get/Set/Test funciones.
Ejemplo
Tenga en cuenta el siguiente mof archivo.
PowerShell
Incorrecto
PowerShell
function Get-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message
)
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
)
}
function Test-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
)
}
Correcto
PowerShell
function Get-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
)
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
)
}
function Test-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
)
}
UseIdenticalParametersForDSC
Artículo • 13/12/2022
Descripción
Las Get-TargetResource funciones , Test-TargetResource y Set-TargetResource del
recurso de DSC deben tener los mismos parámetros.
Cómo
Corrija los parámetros de las funciones en el recurso de DSC.
Ejemplo
Incorrecto
PowerShell
function Get-TargetResource
{
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name,
[String]
$TargetResource
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
function Test-TargetResource
{
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name
)
...
}
Correcto
PowerShell
function Get-TargetResource
{
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name,
[String]
$TargetResource
)
...
}
function Set-TargetResource
{
param
(
[parameter(Mandatory = $true)]
[String]
$Name,
[String]
$TargetResource
)
...
}
function Test-TargetResource
{
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[String]
$Name,
[String]
$TargetResource
)
...
}
UseVerboseMessageInDSCResource
Artículo • 15/05/2023
Descripción
El procedimiento recomendado recomienda que se proporcione información adicional
del usuario dentro de comandos, funciones y scripts mediante Write-Verbose .
Cómo
Use el Write-Verbose comando .
Ejemplo
Incorrecto
PowerShell
Function Test-Function
{
[CmdletBinding()]
Param()
...
}
Correcto
PowerShell
Function Test-Function
{
[CmdletBinding()]
Param()
Write-Verbose 'Verbose output'
...
}
MisleadingBacktick
Artículo • 13/12/2022
Descripción
Comprueba que las líneas no terminen con un retroceso seguido de un espacio en
blanco.
MissingModuleManifestField
Artículo • 13/12/2022
Descripción
Un manifiesto de módulo es un .psd1 archivo que contiene una tabla hash. Las claves y
los valores de la tabla hash describen el contenido y los atributos del módulo, definen
los requisitos previos y determinan cómo se procesan los componentes.
ModuleVersion
Todas las demás claves son opcionales. El orden de las entradas no es importante.
Cómo
Considere la posibilidad de agregar los campos que faltan al manifiesto.
Ejemplo
Incorrecto
PowerShell
@{
Author = 'PowerShell Author'
NestedModules = @('.\mymodule.psm1')
FunctionsToExport = '*'
CmdletsToExport = '*'
VariablesToExport = '*'
}
Correcto
PowerShell
@{
ModuleVersion = '1.0'
Author = 'PowerShell Author'
NestedModules = @('.\mymodule.psm1')
FunctionsToExport = '*'
CmdletsToExport = '*'
VariablesToExport = '*'
}
PlaceCloseBrace
Artículo • 16/05/2023
Descripción
La colocación de llaves de cierre debe seguir un estilo coherente. Debe estar en una
nueva línea por sí misma y no debe seguirse por una línea vacía.
Nota: Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo
a través de la configuración.
Configuración
PowerShell
Rules = @{
PSPlaceCloseBrace = @{
Enable = $true
NoEmptyLineBefore = $false
IgnoreOneLineBlock = $true
NewLineAfter = $true
}
}
Parámetros
Cree una infracción si hay una línea vacía antes de una llave de cierre.
Descripción
La colocación de llaves abiertas debe seguir un estilo coherente. Puede seguir el estilo
K&R (en la misma línea) o el estilo Allman (no en la misma línea).
Nota: Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo
a través de la configuración.
Configuración
PowerShell
Rules = @{
PSPlaceOpenBrace = @{
Enable = $true
OnSameLine = $true
NewLineAfter = $true
IgnoreOneLineBlock = $true
}
}
Parámetros
Exigir que la llave abierta esté en la misma línea que la de su palabra clave anterior.
Indica si las llaves abiertas de un bloque de línea deben omitirse o no. Por ejemplo, $x =
if ($true) { 'blah' } else { 'blah blah' } si la propiedad se establece en true, la
Descripción
Para asegurarse de que PowerShell realiza las comparaciones correctamente, el $null
elemento debe estar en el lado izquierdo del operador.
Cómo
Vaya $null al lado izquierdo de la comparación.
Ejemplo
Incorrecto
PowerShell
function Test-CompareWithNull
{
if ($DebugPreference -eq $null)
{
}
}
Correcto
PowerShell
function Test-CompareWithNull
{
if ($null -eq $DebugPreference)
{
}
}
# Both expressions below return 'false' because the comparison does not
return an
# object and therefore the if statement always falls through:
if (@() -eq $null) { 'true' } else { 'false' }
if (@() -ne $null) { 'true' } else { 'false' }
Así funciona el operador de comparación por diseño. Pero, como se muestra, esto
puede conducir a un comportamiento no intuitivo, especialmente cuando la intención
es una prueba sencilla para null.
PowerShell
Descripción
En muchos lenguajes de programación, el operador de igualdad se indica como == o = ,
pero PowerShell usa -eq . Por lo tanto, puede ocurrir fácilmente que el operador
incorrecto se usa involuntariamente. Esta regla detecta algunos casos especiales en los
que la probabilidad de que sea bastante alta.
La regla busca los usos de los operadores y = dentro if de == las instrucciones , y do-
while , while else if pero no advierte si se usa algún tipo de comando o expresión en
el lado derecho, ya que probablemente esto es por diseño.
Ejemplo
Incorrecto
PowerShell
if ($a = $b)
{
...
}
PowerShell
if ($a == $b)
{
Correcto
PowerShell
if ($a -eq $b) # Compare $a with $b
{
...
}
PowerShell
PowerShell
if (($shortVariableName = $SuperLongVariableName['SpecialItem']
['AnotherItem']))
{
...
}
PossibleIncorrectUsageOfRedirectionOp
erator
Artículo • 13/12/2022
Descripción
En muchos lenguajes de programación, el operador de comparación para "mayor que"
es pero usa para él y -ge (mayor o igual) para >= . -gt PowerShell > Por lo tanto, puede
ocurrir fácilmente que el operador incorrecto se usa involuntariamente. Esta regla
detecta algunos casos especiales en los que la probabilidad de que sea bastante alta.
La regla busca usos de operadores o >= dentro if de > las instrucciones , elseif while
y do-while porque es probable que esto vaya a ser un uso accidental.
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Se debe proporcionar ayuda basada en comentarios para todos los comandos de
PowerShell. Esta prueba solo comprueba la presencia de ayuda basada en comentarios y
no en la validez o el formato.
Para obtener ayuda sobre la ayuda basada en comentarios, use el comando Get-Help
about_comment_based_help o los artículos siguientes:
Configuración
PowerShell
Rules = @{
PSProvideCommentHelp = @{
Enable = $true
ExportedOnly = $false
BlockComment = $true
VSCodeSnippetCorrection = $false
Placement = 'before'
}
}
Parámetros
Los valores posibles son: before , begin y end . Si se da algún valor no válido, el valor
predeterminado de la propiedad es before .
significa que la ayuda se coloca al principio del cuerpo de la definición de función. end
significa que la ayuda está colocando el final del cuerpo de la definición de función.
Ejemplo
Incorrecto
PowerShell
function Get-File
{
[CmdletBinding()]
Param
(
...
)
}
Correcto
PowerShell
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Get-File
{
[CmdletBinding()]
Param
(
...
)
}
ReservedCmdletChar
Artículo • 13/12/2022
Descripción
No puede usar los siguientes caracteres reservados en un nombre de función o cmdlet,
ya que pueden provocar errores de análisis o tiempo de ejecución.
Cómo
Quite los caracteres reservados de los nombres.
Ejemplo
Incorrecto
PowerShell
function MyFunction[1]
{...}
Correcto
PowerShell
function MyFunction
{...}
ReservedParams
Artículo • 13/12/2022
Descripción
No se pueden usar parámetros comunes reservados en una función avanzada.
Cómo
Cambie el nombre del parámetro.
Ejemplo
Incorrecto
PowerShell
function Test
{
[CmdletBinding]
Param
(
$ErrorVariable,
$Parameter2
)
}
Correcto
PowerShell
function Test
{
[CmdletBinding]
Param
(
$Err,
$Parameter2
)
}
ReviewUnusedParameter
Artículo • 13/12/2022
Descripción
Esta regla identifica los parámetros declarados en un ámbito de script, scriptblock o
función que no se han usado en ese ámbito.
Cómo
Considere la posibilidad de quitar el parámetro sin usar.
Ejemplo
Incorrecto
PowerShell
function Test-Parameter
{
Param (
$Parameter1,
Get-Something $Parameter1
}
Correcto
PowerShell
function Test-Parameter
{
Param (
$Parameter1,
Descripción
Si un cmdlet declara el SupportsShouldProcess atributo , también debe llamar a
ShouldProcess . Una infracción es cualquier función que declara el
about_Functions_Advanced_Methods
about_Functions_CmdletBindingAttribute
Todo lo que le interesa saber sobre ShouldProcess
Cómo
Para corregir una infracción de esta regla, llame al ShouldProcess método cuando un
cmdlet declare el SupportsShouldProcess atributo . O bien, agregue
SupportsShouldProcess el argumento de atributo al llamar a ShouldProcess .
Ejemplo
Incorrecto
PowerShell
function Set-File
{
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
# Path to file
[Parameter(Mandatory=$true)]
$Path
)
'String' | Out-File -FilePath $Path
}
Correcto
PowerShell
function Set-File
{
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
# Path to file
[Parameter(Mandatory=$true)]
$Path,
[Parameter(Mandatory=$true)]
[string]$Content
)
Descripción
Todos los cmdlets deben usar verbos aprobados.
Cómo
Cambie el verbo del nombre del cmdlet a un verbo aprobado.
Ejemplo
Incorrecto
PowerShell
function Change-Item
{
...
}
Correcto
PowerShell
function Update-Item
{
...
}
UseBOMForUnicodeEncodedFile
Artículo • 13/12/2022
Descripción
Para un archivo codificado con un formato distinto de ASCII, asegúrese de que la marca
de orden de bytes (BOM) esté presente para asegurarse de que cualquier aplicación que
consuma este archivo pueda interpretarlo correctamente.
Cómo
Asegúrese de que el archivo está codificado con la lista BOM presente.
UseCmdlet Incorrectamente
Artículo • 13/12/2022
Descripción
Cada vez que llamamos a un comando, se debe tener cuidado de que se invoca con la
sintaxis y los parámetros correctos.
Cómo
Especifique todos los parámetros obligatorios al llamar a comandos.
Ejemplo
Incorrecto
PowerShell
Function Set-TodaysDate ()
{
Set-Date
...
}
Correcto
PowerShell
Function Set-TodaysDate ()
{
$date = Get-Date
Set-Date -Date $date
...
}
UseCompatibleCmdlets
Artículo • 15/05/2023
Descripción
Esta regla marca los cmdlets que no están disponibles en una determinada edición o
versión de PowerShell en un sistema operativo determinado. Funciona comparando un
cmdlet con un conjunto de listas de permitidos que se incluyen con PSScriptAnalyzer. Se
pueden encontrar en /path/to/PSScriptAnalyzerModule/Settings . Estos archivos tienen
el formato , <psedition>-<psversion>-<os>.json donde <psedition> puede ser Core o
Desktop , <os> puede ser Windows , Linux o MacOS , y <psversion> es la versión de
PowerShell. Para habilitar la regla para comprobar si el script es compatible con
PowerShell Core en Windows, coloque el siguiente archivo de configuración:
PowerShell
@{
'Rules' = @{
'PSUseCompatibleCmdlets' = @{
'compatibility' = @('core-6.1.0-windows')
}
}
}
desktop-2.0-windows
desktop-3.0-windows
desktop-4.0-windows (tomado de Windows Server 2012R2)
desktop-5.1.14393.206-windows
core-6.1.0-windows (tomado de Windows 10 - 1803)
core-6.1.0-linux (tomado de Ubuntu 18.04)
core-6.1.0-linux-arm (tomado de Raspbian)
core-6.1.0-macos
Normalmente, las versiones revisadas de PowerShell tienen los mismos datos de cmdlet,
por lo que solo se proporcionan configuraciones de versiones principales y secundarias
de PowerShell. También puede crear un archivo de configuración personalizado con el
script New-CommandDataFile.ps1 . Coloque el archivo creado .json en la Settings
carpeta de la PSScriptAnalyzer carpeta del módulo. A continuación, los compatibility
valores de parámetro son solo el nombre de archivo. Tenga en cuenta que los core-
6.0.2-* archivos se quitaron en PSScriptAnalyzer 1.18 desde que PowerShell 6.0 llegó a
su fin de vida.
UseCompatibleCommands
Artículo • 16/05/2023
Descripción
Esta regla identifica los comandos que no están disponibles en una plataforma de PowerShell de destino.
<os-name>_<os-arch>_<os-version>_<ps-version>_<ps-arch>_<dotnet-version>_<dotnet-edition>
Donde:
<os-name> : el nombre del sistema operativo en el que se ejecuta PowerShell. En Windows, esto incluye el número de SKU.
En Linux, este es el nombre de la distribución.
<os-arch> : la arquitectura de la máquina en la que se ejecuta el sistema operativo (normalmente x64 es ).
<os-version> : la versión autoinformó del sistema operativo (en Linux, esta es la versión de distribución).
System.Environment.Version ).
<dotnet-edition> : el tipo de entorno de ejecución de .NET en el que Se ejecuta PowerShell (actualmente framework o
core ).
Por ejemplo:
operativo.
ubuntu_x64_18.04_6.2.0_x64_4.0.30319.42000_core es PowerShell 6.2.0 que se ejecuta en Ubuntu 18.04.
Algunas plataformas se incluyen con PSScriptAnalyzer como archivos JSON, denominados de esta manera para el destino en la
configuración.
La configuración del perfil de compatibilidad toma una lista de plataformas de destino en TargetProfiles . Se puede especificar
una plataforma como:
El análisis de compatibilidad compara un comando usado para un perfil de destino y un perfil de "unión" (que contiene todos
los comandos disponibles en cualquier perfil del dir de perfil). Si un comando no está presente en el perfil de unión, se supone
que se crea y se omite localmente. De lo contrario, si un comando está presente en el perfil de unión pero no está presente en
un destino, se considera incompatible con ese destino.
Parámetros de configuración
Clave de Significado Valores Mandatory Ejemplo
configuración aceptados
PowerShell
@{
Rules = @{
PSUseCompatibleCommmands = @{
Enable = $true
TargetProfiles = @(
'ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core'
'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework'
'MyProfile'
'another_custom_profile_in_the_profiles_directory.json'
'D:\My Profiles\profile1.json'
)
# You can specify commands to not check like this, which also will ignore its parameters:
IgnoreCommands = @(
'Install-Module'
)
}
}
}
Supresión
Los diagnósticos de compatibilidad de comandos se pueden suprimir con un atributo en el param bloque de un scriptblock
como con otras reglas.
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', '')]
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Start-Service')]
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Import-
Module/FullyQualifiedName')]
UseCompatibleSyntax
Artículo • 15/05/2023
Descripción
Esta regla identifica los elementos de sintaxis incompatibles con las versiones de
PowerShell de destino.
PowerShell
@{
Rules = @{
PSUseCompatibleSyntax = @{
Enable = $true
TargetVersions = @(
'6.0',
'5.1',
'4.0'
)
}
}
}
UseCompatibleTypes
Artículo • 16/05/2023
Descripción
Esta regla identifica los tipos que no están disponibles (cargados de forma predeterminada) en las plataformas de PowerShell
de destino.
<os-name>_<os-arch>_<os-version>_<ps-version>_<ps-arch>_<dotnet-version>_<dotnet-edition>
Donde:
<os-name> : el nombre del sistema operativo en el que se ejecuta PowerShell. En Windows, esto incluye el número de SKU.
<os-version> : la versión autoinformó del sistema operativo (en Linux, esta es la versión de distribución).
<dotnet-edition> : el tipo de entorno de ejecución de .NET en el que Se ejecuta PowerShell (actualmente framework o
core ).
Por ejemplo:
Algunas plataformas se incluyen con PSScriptAnalyzer como archivos JSON, denominados de esta manera para el destino en la
configuración.
La configuración del perfil de compatibilidad toma una lista de plataformas de destino en TargetProfiles . Se puede especificar
una plataforma como:
El análisis de compatibilidad compara un tipo usado para un perfil de destino y un perfil de "unión" (que contiene todos los
tipos disponibles en cualquier perfil del dir de perfil). Si un tipo no está presente en el perfil de unión, se supone que se crea y
se omite localmente. De lo contrario, si un tipo está presente en el perfil de unión pero no está presente en un destino, se
considera incompatible con ese destino.
Parámetros de configuración
Clave de Significado Valores Mandatory Ejemplo
configuración aceptados
PowerShell
@{
Rules = @{
PSUseCompatibleTypes = @{
Enable = $true
TargetProfiles = @(
'ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core'
'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework'
'MyProfile'
'another_custom_profile_in_the_profiles_directory.json'
'D:\My Profiles\profile1.json'
)
# You can specify types to not check like this, which will also ignore methods and members on it:
IgnoreTypes = @(
'System.IO.Compression.ZipFile'
)
}
}
}
PowerShell
PS> $settings = @{
Rules = @{
PSUseCompatibleTypes = @{
Enable = $true
TargetProfiles = @('win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')
}
}
}
PS> Invoke-ScriptAnalyzer -Settings $settings -ScriptDefinition
'[System.Management.Automation.SemanticVersion]'1.18.0-rc1''
Supresión
Los diagnósticos de compatibilidad de comandos se pueden suprimir con un atributo en el param bloque de un bloque de
scriptblock como con otras reglas.
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes', '')]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes',
'System.Management.Automation.Security.SystemPolicy')]
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands',
'System.Management.Automation.LanguagePrimitives/ConvertTypeNameToPSTypeName')]
UseConsistentIndentation
Artículo • 13/12/2022
Descripción
La sangría debe ser coherente en todo el archivo de origen.
Nota: Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo
a través de la configuración.
Configuración
PowerShell
Rules = @{
PSUseConsistentIndentation = @{
Enable = $true
IndentationSize = 4
PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
Kind = 'space'
}
}
Parámetros
PowerShell
foo |
bar |
baz
PowerShell
foo |
bar |
baz
PowerShell
foo |
bar |
baz
Representa el tipo de sangría que se va a usar. Los valores posibles son: space , tab . Si
se da algún valor no válido, el valor predeterminado de la propiedad es space .
Descripción
Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo a
través de la configuración.
Configuración
PowerShell
Rules = @{
PSUseConsistentWhitespace = @{
Enable = $true
CheckInnerBrace = $true
CheckOpenBrace = $true
CheckOpenParen = $true
CheckOperator = $true
CheckPipe = $true
CheckPipeForRedundantWhitespace = $false
CheckSeparator = $true
CheckParameter = $false
IgnoreAssignmentOperatorInsideHashTable = $false
}
}
Descripción
Se trata de una regla de estilo y formato. PowerShell no distingue mayúsculas de
minúsculas si procede. El uso de mayúsculas y minúsculas de los nombres o parámetros
de los cmdlets no importa, pero esta regla garantiza que el uso de mayúsculas y
minúsculas coincida con la coherencia y, además, porque la mayoría de los cmdlets o
parámetros empiezan por un mayúscula y usan que mejora la legibilidad al ojo humano.
Cómo
Use mayúsculas y minúsculas exactas del cmdlet y sus parámetros, por ejemplo, Invoke-
Command { 'foo' } -RunAsAdministrator .
Ejemplo
Incorrecto
PowerShell
Correcto
PowerShell
Descripción
Las variables que se asignan pero no se usan no son necesarias.
7 Nota
Para esta regla, la variable debe usarse en el mismo bloque de scripts que se
declaró o no se considerará "usado".
Cómo
Quite las variables declaradas pero no usadas.
Ejemplo
Incorrecto
PowerShell
function Test
{
$declaredVar = 'Declared just for fun'
$declaredVar2 = 'Not used'
Write-Output $declaredVar
}
Correcto
PowerShell
function Test
{
$declaredVar = 'Declared just for fun'
Write-Output $declaredVar
}
Caso especial
En el ejemplo siguiente se desencadena la advertencia
PSUseDeclaredVarsMoreThanAssignments porque $bar no se usa en el scriptblock
donde se definió.
PowerShell
$foo | ForEach-Object {
if ($_ -eq $false) {
$bar = $true
}
}
if($bar){
Write-Host 'Collection contained a false case.'
}
UseLiteralInitializerForHashtable
Artículo • 13/12/2022
Descripción
La creación de una tabla hash mediante [hashtable]::new() o New-Object -TypeName
hashtable sin pasar un IEqualityComparer objeto al constructor crea una tabla hash en
la que se buscan las claves de una manera que distingue mayúsculas de minúsculas. Sin
embargo, PowerShell no distingue mayúsculas de minúsculas por naturaleza y es mejor
crear tablas hash con búsqueda de claves que no distinguen mayúsculas de minúsculas.
Esta regla está pensada para advertir al autor de la naturaleza que distingue mayúsculas
de minúsculas de la tabla hash cuando se crea con el new método o el New-Object
cmdlet .
Solución
Cree la tabla hash mediante una expresión de tabla hash literal.
Ejemplo
Incorrecto
PowerShell
$hashtable = [hashtable]::new()
Incorrecto
PowerShell
Correcto
PowerShell
$hashtable = @{}
UseOutputType Incorrectamente
Artículo • 13/12/2022
Descripción
Un comando debe devolver el mismo tipo que se declara en OutputType .
Cómo
Especifique que las listas de atributos OutputType y los tipos devueltos en el cmdlet
coinciden.
Ejemplo
Incorrecto
PowerShell
function Get-Foo
{
[CmdletBinding()]
[OutputType([String])]
Param(
)
return 4
}
Correcto
PowerShell
function Get-Foo
{
[CmdletBinding()]
[OutputType([String])]
Param(
)
return "four"
}
UseProcessBlockForPipelineCommand
Artículo • 13/12/2022
Descripción
Las funciones que admiten la entrada de canalización siempre deben controlar la
entrada de parámetros en un bloque de proceso. El comportamiento inesperado puede
dar lugar si la entrada se controla directamente en el cuerpo de una función donde los
parámetros declaran la compatibilidad con la canalización.
Ejemplo
Incorrecto
PowerShell
Function Get-Number
{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline)]
[int]
$Number
)
$Number
}
Resultado
Correcto
PowerShell
Function Get-Number
{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline)]
[int]
$Number
)
process
{
$Number
}
}
Resultado
Descripción
Si el cmdlet o la función tiene un parámetro Credential , el parámetro debe aceptar el
tipo PSCredential .
Cómo
Cambie el tipo del parámetro Credential para que sea PSCredential.
Ejemplo
Incorrecto
PowerShell
function Credential([String]$Credential)
{
...
}
Correcto
PowerShell
function Credential([PSCredential]$Credential)
{
...
}
UseShouldProcessForStateChangingFun
ctions
Artículo • 13/12/2022
Descripción
Funciones cuyos verbos cambian el estado del sistema deben admitir ShouldProcess .
New
Set
Remove
Start
Stop
Restart
Reset
Update
Cómo
Incluya el SupportsShouldProcess argumento en el CmdletBinding atributo .
Ejemplo
Incorrecto
PowerShell
function Set-ServiceObject
{
[CmdletBinding()]
param
(
[string]
$Parameter1
)
...
}
Correcto
PowerShell
function Set-ServiceObject
{
[CmdletBinding(SupportsShouldProcess = $true)]
param
(
[string]
$Parameter1
)
...
}
UseSingularNouns
Artículo • 13/12/2022
Descripción
Los cmdlets de estado de procedimientos recomendados del equipo de PowerShell
deben usar nombres singulares y no plurales.
Cómo
Cambie plurales a singular.
Ejemplo
Incorrecto
PowerShell
function Get-Files
{
...
}
Correcto
PowerShell
function Get-File
{
...
}
UseSupportsShouldProcess
Artículo • 14/12/2022
Descripción
Esta regla desaconseja la declaración manual de WhatIf los parámetros y Confirm en
una función o cmdlet. Sin embargo, estos parámetros se proporcionan
automáticamente cuando una función declara un CmdletBinding atributo con
SupportsShouldProcess como argumento con nombre. El uso SupportsShouldProcess de
no solo proporciona estos parámetros, sino también algunas funcionalidades genéricas
que permiten a los autores de funciones o cmdlets proporcionar la experiencia
interactiva deseada mientras se usa el cmdlet .
Ejemplo
Erróneo:
PowerShell
function foo {
param(
$param1,
$Confirm,
$WhatIf
)
}
Correcto:
PowerShell
function foo {
[CmdletBinding(SupportsShouldProcess)]
param(
$param1
)
}
UseToExportFieldsInManifest
Artículo • 13/12/2022
Descripción
Para mejorar el rendimiento de la detección automática del módulo, los manifiestos de
módulo no deben usar caracteres comodín () o null ( '*' $null ) en las siguientes
entradas:
AliasesToExport
CmdletsToExport
FunctionsToExport
VariablesToExport
El uso de caracteres comodín o null hace que PowerShell realice un trabajo costoso para
analizar un módulo durante la detección automática del módulo.
Cómo
Use una lista explícita en las entradas.
Ejemplo 1
Supongamos que no hay funciones en el módulo para exportar. A continuación,
Incorrecto
PowerShell
FunctionsToExport = $null
Correcto
PowerShell
FunctionToExport = @()
Ejemplo 2
Supongamos que solo hay dos funciones en el módulo Get-Foo y Set-Foo que desea
exportar. A continuación,
Incorrecto
PowerShell
FunctionsToExport = '*'
Correcto
PowerShell
Descripción
Si un scriptblock está pensado para ejecutarse en un nuevo espacio de ejecución, las
variables dentro de ella deben usar el $using: modificador de ámbito o inicializarse
dentro del scriptblock. Esto se aplica a lo siguiente:
Start-ThreadJob
Solución
Dentro de ScriptBlock, en lugar de simplemente usar una variable del ámbito primario,
debe agregarle el using: modificador de ámbito.
Ejemplo
Incorrecto
PowerShell
$var = "foo"
1..2 | ForEach-Object -Parallel { $var }
Correcto
PowerShell
$var = "foo"
1..2 | ForEach-Object -Parallel { $using:var }
$bar = "bar"
Invoke-Command -ComputerName "foo" -ScriptBlock { $using:bar }
PowerShell
$bar = "bar"
$s = New-PSSession -ComputerName "foo"
Invoke-Command -Session $s -ScriptBlock { $using:bar }
PowerShell
PowerShell
$foo = "foo"
Start-ThreadJob -ScriptBlock { $using:foo }
Start-Job -ScriptBlock {$using:foo }
UseUTF8EncodingForHelpFile
Artículo • 13/12/2022
Descripción
Compruebe si el archivo de ayuda usa la codificación UTF-8.
Información general de los módulos
SecretManagement y SecretStore
Artículo • 13/12/2022
Es fundamental que solo use módulos del almacén de extensiones publicados por
orígenes conocidos y de confianza, y que tengan firmas de paquete válidas.
El almacén de extensiones SecretStore usa las API de criptografía de .NET para cifrar los
datos secretos y almacenarlos en el sistema de archivos local. La información de
configuración del almacén y los metadatos secretos también se almacenan en formato
cifrado para evitar la divulgación involuntaria o lectura casual.
Para obtener la mejor seguridad, use una contraseña que no esté almacenada en el
equipo local para que no se pueda detectar si alguna vez se ha infringido la máquina.
PowerShell
Install-Module Microsoft.PowerShell.SecretManagement
Install-Module Microsoft.PowerShell.SecretStore
Una vez instalados los módulos, puede cargar los módulos y empezar a usar o crear
nuevos secretos.
PowerShell
Import-Module Microsoft.PowerShell.SecretManagement
Import-Module Microsoft.PowerShell.SecretStore
PowerShell
PowerShell
En este ejemplo se pasa una cadena de texto no cifrado para el valor del secreto. El
valor del secreto puede ser uno de los cinco tipos admitidos:
byte[]
String
SecureString
PSCredential
Hashtable
La primera vez que acceda al almacén, debe proporcionar una contraseña para el nuevo
almacén. Esta contraseña se usa para bloquear y desbloquear el almacén.
Output
PowerShell
PowerShell
PS> Get-SecretInfo
Vínculos relacionados
Register-SecretVault
Get-Secret
Set-Secret
Descripción del módulo
SecretManagement
Artículo • 13/12/2022
Introducción a SecretManagement
Una vez que haya instalado SecretManagement , puede ejecutar Get-SecretVault para
ver qué almacenes secretos ha registrado. Si es la primera vez que usa el módulo, este
comando no devuelve nada. Una vez registrado un almacén, puede usar los cmdlets
SecretManagement para ver, obtener, establecer y quitar secretos. Para ver un ejemplo
de registro de un almacén, consulte Introducción al módulo SecretStore.
PowerShell
) Importante
PowerShell
Get-SecretVault
Configuración de un almacén
Use el cmdlet para ver la Get-SecretStoreConfiguration configuración de un almacén.
PowerShell
Get-SecretStoreConfiguration
Adición de metadatos
El módulo SecretStore permite agregar metadatos no confidenciales a los secretos. Los
metadatos se pueden usar para documentar el propósito previsto de un secreto. Por
ejemplo, para indicar que un secreto está pensado para una suscripción o un escenario
de aplicación concretos. También puede agregar metadatos sobre la fecha de creación
del secreto, la hora de expiración u otra información usada para administrar el ciclo de
vida del secreto.
Los metadatos pueden ser cualquier par clave-valor arbitrario. El módulo SecretStore
admite los siguientes tipos de valor para los metadatos:
string
int
DateTime
PowerShell
$metadata = @{
Purpose = 'Testing'
Expires = (Get-Date).AddDays(30)
Limit = 5
}
Set-Secret -Name TestSecret -Secret NewSecret -Metadata $metadata
Name : TestSecret
Type : String
VaultName : SecretStore
Metadata : {[Limit, 5], [Expires, 6/23/2022 1:45:09 PM], [Purpose,
Testing]}
PowerShell
Metadata
--------
{[Purpose, showing the new cmdlet]}
U Precaución
Vínculos relacionados
Get-SecretInfo
Get-SecretStoreConfiguration
Register-SecretVault
Reset-SecretStore
Set-Secret
Set-SecretInfo
Set-SecretStoreConfiguration
Set-SecretStorePassword
Unlock-SecretStore
Uso de SecretStore en la automatización
Artículo • 02/03/2023
PowerShell
También debe crear una contraseña como SecureString que se exporte de forma segura
a un archivo XML y que se cifre mediante La protección de datos de Windows (DPAPI). El
siguiente comando le pide una contraseña. En este ejemplo, username no es
importante.
PowerShell
Una vez que tenga la contraseña, puede guardarla en un archivo XML cifrado.
PowerShell
$securePasswordPath = 'C:\automation\passwd.xml'
$credential.Password | Export-Clixml -Path $securePasswordPath
PowerShell
$storeConfiguration = @{
Authentication = 'Password'
PasswordTimeout = 3600 # 1 hour
Interaction = 'None'
Password = $password
Confirm = $false
}
Set-SecretStoreConfiguration @storeConfiguration
Ahora que tiene el almacén instalado y configurado, puede usar Set-Secret para
agregar los secretos que necesita para los scripts de automatización.
7 Nota
Se trata de una solución solo de Windows, pero otra opción es usar una variable
segura proporcionada por un sistema de CI como Acciones de GitHub.
PowerShell
En primer lugar, debe crear un Key Vault en la suscripción de Azure y agregar los
secretos. Para más información, consulte Inicio rápido: Establecimiento y recuperación
de una clave de Azure Key Vault mediante Azure PowerShell.
Para usar azure Key Vault con SecretManagement, asegúrese primero de que tiene el
módulo Az.KeyVault .
PowerShell
$VaultParameters = @{
AZKVaultName = $vaultName
SubscriptionId = $subID
}
Register-SecretVault -Module Az.KeyVault -Name AzKV -VaultParameters
$VaultParameters
Uso de secretos de Azure Key Vault en la
automatización
Ahora que ha registrado la instancia de Azure Key Vault con SecretManagement, puede
ver secretos con Get-SecretInfo , obtener secretos con Get-Secret , crear y actualizar
secretos con y quitar secretos con Set-Secret Remove-Secret .