Está en la página 1de 220

Díganos qué opina sobre la experiencia de descarga del PDF.

Módulos de utilidad de PowerShell


Artículo • 13/12/2022

El equipo de PowerShell ha creado un conjunto de módulos de utilidad que amplían las


funcionalidades de PowerShell. Estos módulos se pueden instalar desde el Galería de
PowerShell y cargarse a petición. Los módulos no forman parte oficial del producto de
PowerShell, pero los mantiene el equipo de productos de PowerShell. El nivel de
compatibilidad de cada módulo varía. Para más información, consulte la página de
aterrizaje de cada módulo.

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

PowerShell, al igual que otros shells, es capaz de invocar herramientas de línea de


comandos. Sin embargo, mejoraría la experiencia si la herramienta de línea de
comandos pudiera participar en la canalización de PowerShell y aprovecharía los
comportamientos de parámetros que forman parte de PowerShell.

Crescendo proporciona un marco para crear rápidamente cmdlets de PowerShell que


amplían las herramientas de línea de comandos, independientemente de la plataforma.
El objetivo de un módulo basado en Crescendo es crear cmdlets de PowerShell que
usen una herramienta de línea de comandos y, a diferencia de esa herramienta,
devuelva objetos de PowerShell en lugar de texto sin formato.

Cómo funciona Crescendo


El marco crescendo tiene dos componentes principales:

Un archivo de configuración JSON que describe los cmdlets que desea


Funciones del controlador de salida que analizan la salida de la herramienta de
línea de comandos y devuelven objetos

El módulo Crescendo proporciona cmdlets para ayudarle a crear las configuraciones


JSON y a crear un módulo que contenga los cmdlets definidos. Debe escribir sus propias
funciones de controlador de salida que devuelvan objetos de PowerShell.

Terminología específica de Crescendo


La documentación de Crescendo incluye cierta terminología nueva.

herramienta de línea de comandos : un archivo ejecutable nativo instalado en el


sistema
Por ejemplo: ipconfig.exe
command : lo que escribe en la línea de comandos para invocar el ejecutable, que
puede incluir parámetros específicos.
Por ejemplo: ipconfig.exe /all
Comando amplified : el cmdlet que creó con Crescendo para encapsular un
comando en una función de PowerShell
Por ejemplo: Get-IpConfig -All
Esquema del archivo de configuración de Crescendo
Al crear un archivo de configuración de Crescendo, está escribiendo JSON. Para mayor
comodidad, validación y una experiencia de desarrollador mejorada, hay disponible un
archivo de esquema .

Puede revisar el esquema para ver las opciones de configuración necesarias y


opcionales, sus descripciones y los tipos de valor que aceptan. Al crear el archivo de
configuración en Visual Studio Code , obtendrá numerosas características útiles, como
IntelliSense, validación mientras edita y mucho más.
Instalación del módulo Crescendo
Artículo • 13/12/2022

Requisitos:

Microsoft.PowerShell.Crescendo requiere PowerShell 7.0 o posterior.

Crescendo se puede usar para crear módulos que se ejecutan en Windows PowerShell
5.1 y versiones posteriores.

Para instalar con PowerShellGet 2.x:

PowerShell

Install-Module Microsoft.PowerShell.Crescendo -Force

Para instalar con PowerShellGet 3.0 (beta):

PowerShell

Install-PSResource Microsoft.PowerShell.Crescendo -Reinstall

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

Update-Help -Module Microsoft.PowerShell.Crescendo -Force

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

El uso de Crescendo es una manera rápida y confiable de ampliar una herramienta de


línea de comandos para generar una experiencia similar a un cmdlet. Muchas veces, la
herramienta con la que necesita trabajar está directamente vinculada a la tecnología
que está intentando automatizar. Esto facilita la elección de la herramienta. Sin
embargo, no todas las herramientas funcionan de la misma manera. Para optimizar la
inversión al desarrollar un cmdlet, tenga en cuenta los siguientes criterios:

Herramientas de línea de comandos que hacen


buenos candidatos
La herramienta original es difícil de usar.

Si la herramienta es sencilla de usar y proporciona la información que necesita, no


es necesario crear un cmdlet. Sin embargo, esto no siempre es el caso de las
herramientas de línea de comandos. Muchas herramientas de línea de comandos
tienen su propia sintaxis, parámetros y salida únicos que dificultan que los
administradores desconocidos usen los comandos de la herramienta. La
conversión de un comando en un cmdlet proporciona todas las ventajas de la
detección de cmdlets, la coherencia de la sintaxis y la salida estructurada como
objetos.

La salida de la herramienta de línea de comandos es difícil de usar en la


automatización.

Las herramientas de línea de comandos generan su información en la pantalla


como datos de cadena. No es los datos estructurados (objetos) que PowerShell
espera en la canalización, lo que impide que use cmdlets de PowerShell, como
Where-Object y ForEach-Object . Crescendo le ayuda a ampliar la experiencia de la
herramienta de línea de comandos para que la herramienta pueda participar en la
canalización de PowerShell.

La herramienta de línea de comandos no proporciona ayuda adecuada.

Las herramientas de línea de comandos que carecen de información de ayuda


pueden ser difíciles de usar. Los cmdlets pueden tener información de ayuda
completa que incluye detalles sobre parámetros, descripciones y ejemplos.
Crescendo le ofrece la capacidad de crear la ayuda que falta para los comandos
amplificados.

Herramientas de línea de comandos que hacen


candidatos incorrectos
¿Ya existe un cmdlet?

PowerShell tiene un ecosistema bien establecido de módulos que amplían las


funcionalidades integradas de PowerShell. Antes de decidir amplificar una
herramienta de línea de comandos con Crescendo, compruebe primero si ya existe
un cmdlet que realice el objetivo previsto. Por ejemplo, ajustar el comando
ipconfig.exe de Windows para obtener la dirección IP actual es una opción

deficiente porque el módulo NetAdapter contiene Get-NetIPConfiguration , que


proporciona la misma información con la salida estructurada.

¿Hay mejores maneras?

A menudo, la información que necesita para la automatización se puede obtener


más rápido que hacer que un cmdlet. PowerShell le permite acceder a otros
marcos y bibliotecas, como WMI y .NET. En lugar de invertir tiempo amplificando
una herramienta de línea de comandos, es posible que pueda obtener la
información más rápidamente mediante una de estas bibliotecas.

¿La salida es trivial?

En algunas situaciones, la herramienta de línea de comandos puede generar una


salida que sea fácil de usar en la automatización. Si este es el caso, invertir tiempo
en la creación de un cmdlet con salida estructurada puede no merecer la pena
crear un cmdlet amplificado.

Prácticas recomendadas
Optimice su inversión de tiempo centrándose en lo que necesita.

Al examinar una herramienta de línea de comandos para la automatización,


recuerde que no es necesario replicar todas las características de la herramienta en
el cmdlet amplificado. Es decir, céntrese en las características de la herramienta
que necesita para lograr su objetivo. Si una herramienta tiene 12 casos de uso y
solo necesita la funcionalidad de dos, cree una configuración de Crescendo solo
para los dos escenarios que necesite.
Paso siguiente
Investigación de la sintaxis y salida de la herramienta de línea de comandos
Investigación de la sintaxis y salida de la
herramienta de línea de comandos
Artículo • 13/12/2022

En el artículo anterior se proporcionan criterios para seleccionar la herramienta de línea


de comandos que desea ampliar con Crescendo. En este artículo se describen formas de
recopilar información sobre la herramienta que le ayuda a diseñar cmdlets mediante
Crescendo.

Para ver los ejemplos de este artículo, se usa la herramienta de agente de Azure
Connected Machine ( azcmagent ). Hemos elegido esta herramienta porque:

Es fácil de instalar y quitar


No requiere una suscripción de Azure activa para el uso básico.
Tiene ayuda útil en la consola y documentación en línea
Genera una salida consumible fácilmente.

 Sugerencia

Si no tiene esta herramienta, no es necesario instalarla a menos que quiera probar


los ejemplos.

Para obtener más información, consulte la sección Instalación de la herramienta


azcmagent de este artículo.

Empezar con la ayuda y la documentación de la


línea de comandos
Muchas herramientas de línea de comandos incluyen un modificador o parámetro para
mostrar contenido de ayuda. La mayoría de las herramientas de línea de comandos
modernas proporcionan varios niveles de ayuda para los distintos escenarios de casos
de uso que proporciona la herramienta. Por ejemplo, la ejecución azcmagent sin
parámetros muestra la ayuda de nivel superior, que contiene una lista de subcomandos.

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

PS> azcmagent config --help


Change configuration settings for this machine

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 "azcmagent config [command] --help" for more information about a


command.

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.

Captura de la salida de ejemplo para el análisis


Una vez que haya decidido cuáles de los comandos de la herramienta se amplifican con
Crescendo, recopile la salida de ejemplo de esos comandos. Redirigir la salida a un
archivo para cada comando. Use estos datos de ejemplo para ayudarle a diseñar los
controladores de salida (analizadores) para los cmdlets de Crescendo.

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.

La azcmagent herramienta tiene la opción de generar información en formato JSON.


Esto hace que la conversión a un objeto de PowerShell sea muy sencilla. Por ejemplo:

PowerShell

PS> $agentStatus = azcmagent show --json | ConvertFrom-Json


PS> $agentStatus.services

displayName serviceName status


----------- ----------- ------
GC Service gcarcservice running
Extension Service extensionservice running
Agent Service himds running

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

La azcmagent herramienta debe ejecutarse con privilegios administrativos. Esto


también significa que el módulo que cree debe ejecutarse con privilegios
administrativos.

Instalación de la herramienta azcmagent


Puede descargar el paquete del agente de Azure Connected Machine para Windows y
Linux desde las ubicaciones que se indican a continuación.

Descargue el paquete de Windows Installer para el agente de Windows desde el


Centro de descarga de Microsoft.
El agente de Linux se distribuye desde el repositorio de paquetes de Microsoft.
Elija el formato de paquete preferido para la distribución (RPM o DEB).

Para más información sobre el agente de Azure Connected Machine, consulte


Administración y mantenimiento del agente de Connected Machine.

Paso siguiente
Creación de una configuración de cmdlet
Creación de un cmdlet de Crescendo
Artículo • 03/02/2023

Las herramientas modernas de línea de comandos proporcionan comandos para una


administración eficaz de tecnologías específicas del dominio. Los usuarios
administrativos pueden ejecutar con confianza estos comandos dentro de PowerShell y
obtener los resultados esperados. Sin embargo, los usuarios de PowerShell prefieren la
sintaxis, la legibilidad y la salida basada en objetos que proporcionan los cmdlets,
especialmente en la automatización.

Como se ha explicado anteriormente, hay varias razones por las que es posible que
quiera ampliar una herramienta de línea de comandos:

La salida de cadena es difícil de usar en la automatización.


La sintaxis del comando es difícil de usar o recordar
La herramienta carece de documentación de ayuda informativa

En el artículo anterior, hemos explicado cómo descubrir y elegir la característica de la


herramienta que desea ampliar con Crescendo. Para ver los ejemplos de este artículo,
seguimos usando la azcmagent herramienta de línea de comandos que se introdujo
anteriormente.

Creación de la configuración para un cmdlet de


Crescendo
Una configuración de Crescendo describe un nuevo cmdlet. La definición del cmdlet
incluye:

Ubicación de la herramienta de línea de comandos original


Subcomandos y parámetros pasados a la herramienta de línea de comandos
Nombre Verb-Noun del nuevo cmdlet
Parámetros usados por el cmdlet

Crescendo toma el archivo de configuración y genera cmdlets de proxy para la


herramienta de línea de comandos original. El código generado se almacena en un
módulo de script de PowerShell, listo para la implementación.

Puede crear su propio archivo de configuración, copiar un archivo existente y


modificarlo o iniciar una nueva configuración mediante el New-CrescendoCommand cmdlet
. Los archivos de configuración de Crescendo se escriben en JSON.
El parámetro Verb especifica el verbo para el nuevo cmdlet. Use Get-Verb para
obtener una lista de nombres de verbo aprobados.
El parámetro Sustantivo especifica el sustantivo en el que actúa el verbo.
El parámetro OriginalName especifica la ruta de acceso a la herramienta de línea
de comandos original.

PowerShell

$parameters = @{
Verb = 'Show'
Noun = 'AzCmAgent'
OriginalName = "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe"
}
New-CrescendoCommand @parameters | Format-List *

New-CrescendoCommand crea un objeto de comando Crescendo. El cmdlet rellena todos


los valores de propiedad posibles.

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 :

En el ejemplo siguiente se muestra cómo crear un nuevo archivo de configuración.

PowerShell

$parameters = @{
Verb = 'Show'
Noun = 'AzCmAgent'
OriginalName = "c:/program
files/AzureConnectedMachineAgent/azcmagent.exe"
}
$CrescendoCommands += New-CrescendoCommand @parameters
Export-CrescendoCommand -command $CrescendoCommands -fileName
.\AzCmAgent.json

El archivo de configuración de Crescendo tiene un esquema JSON y puede contener una


o varias definiciones de cmdlet en una matriz. En este ejemplo, $NewConfiguration es un
objeto que contiene el vínculo al esquema JSON y una matriz que contiene las
definiciones de cmdlet. La salida de New-CrescendoCommand se agrega a la matriz
Commands . $NewConfiguration se convierte en JSON y se escribe en un archivo. El
archivo AzCmAgent.json contiene el código siguiente:

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": []
}
]
}

Es importante tener el vínculo de esquema en el archivo de configuración de Crescendo.


El esquema proporciona herramientas como Visual Studio Code con IntelliSense y
información sobre herramientas durante la experiencia de creación.

Finalización de la configuración del comando


Crescendo
En este ejemplo, vamos a crear una configuración para el azcmagent show comando . El
cmdlet no requiere ningún parámetro adicional. Dado azcmagent que es una
herramienta moderna que proporciona salida JSON, el ejemplo incluye un controlador
de salida simple para convertir la salida JSON en objetos.

La definición de comando incluye las siguientes propiedades:

Verbo: nombre del verbo del cmdlet


Nombre: nombre del nombre del cmdlet
Plataforma: la plataforma en la que se ejecuta este comando crescendo (Windows,
Linux, MacOS)
OriginalName: nombre y ubicación del comando nativo original
OriginalCommandElements: algunos comandos de la CLI tienen modificadores
obligatorios adicionales para que se ejecuten correctamente en un escenario
determinado.
Descripción: descripción del cmdlet que se ve en la Ayuda
Alias: alias o nombre corto para el nuevo cmdlet
OutputHandlers: el controlador de salida que captura la salida de cadena de la
herramienta de línea de comandos y la transforma en objetos de PowerShell.
HandlerType: puede ser Inline , Function o Script . En este ejemplo se usa Inline

En el ejemplo siguiente se muestra la definición JSON completa del nuevo cmdlet


después de la edición adicional.

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": []
}
]
}

Definición de otro cmdlet que tiene parámetros


En este ejemplo, se crea una configuración de Crescendo para el comando que enumera
la azcmagent config get información de propiedades. Un parámetro denominado
Property se asigna al parámetro original de Get.

Una definición de parámetro incluye las siguientes propiedades:

DefaultParameterSetName: define el conjunto de parámetros predeterminado si


se implementan varios conjuntos de parámetros.
Parámetros: bloque de código que contiene la definición de los parámetros para el
comando
Nombre: este es el nombre del parámetro de PowerShell para el cmdlet generado.
OriginalName: nombre del parámetro
ParameterType: define el tipo de datos del valor del parámetro.
ParameterSetName: define el conjunto de parámetros que se incluye este
parámetro.
Obligatorio: configuración que determina si el parámetro es necesario para tener
un valor
Descripción: descripción del parámetro que se ve en la Ayuda

En el ejemplo siguiente se muestra la definición JSON completa del nuevo cmdlet.


Puede colocarlo en una definición en un nuevo archivo JSON o agregarlo a la matriz
Comandos del archivo JSON anterior.

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": []
}

Para obtener un ejemplo de configuración más detallado, consulte la entrada


https://devblogs.microsoft.com/powershell-community/a-closer-look-at-the-crescendo-
configuration/ de blog .

Pasos siguientes
Ahora que ha definido los cmdlets, está listo para generar el nuevo módulo.

Generación y prueba del módulo


Generación y prueba de un módulo
crescendo
Artículo • 13/12/2022

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.

Generación del nuevo módulo


Ahora estamos listos para crear el módulo. Use el Export-CrescendoModule cmdlet para
generar el nuevo módulo de script de PowerShell.

PowerShell

Export-CrescendoModule -ConfigurationFile AzCmAgent.json -ModuleName


AzCmAgent.psm1

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.

Como se ve en la salida siguiente, Export-CrescendoModule crea dos archivos: el archivo


del módulo (PSM1) y el archivo de manifiesto del módulo (PSD1). Estos son los únicos
archivos que el usuario final del módulo necesita instalar.

Resultados

Directory: D:\temp\azcmagent

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a--- 3/9/2022 1:59 PM 2167 AzCmAgent.json
-a--- 3/9/2022 2:33 PM 4365 AzCmAgent.psd1
-a--- 3/9/2022 2:33 PM 8017 AzCmAgent.psm1

Prueba de los cmdlets en el módulo


Para probar el módulo, impórtelo en la sesión de PowerShell y ejecute los cmdlets.

PowerShell
Import-Module .\AzCmAgent.psd1
Get-Command -Module AzCmAgent

Resultados

CommandType Name Version


Source
----------- ---- -------
------
Function Get-AzCmAgentConfigProperty 0.0.1
AzCmAgent
Function Show-AzCmAgent 0.0.1
AzCmAgent

En el artículo anterior definimos dos cmdlets.

) Importante

La azcmagent herramienta requiere la elevación para ejecutarse. Esto significa que


debe ejecutar el módulo en una sesión de PowerShell con privilegios elevados.

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}}

Ahora que hemos amplificado el azcmagent show comando, puede participar en la


canalización de PowerShell.

PowerShell

Show-AzCmAgent | Select-Object -ExpandProperty services

Resultados

displayName serviceName status


----------- ----------- ------
GC Service gcarcservice running
Extension Service extensionservice running
Agent Service himds running

A continuación, se prueba el Get-AzCmAgentConfigProperty cmdlet .

PowerShell

Get-AzCmAgentConfigProperty -Property proxy.url

Resultados

Type Status Messages Data


---- ------ -------- ----
0 success {proxy.url has not been set}

Búsqueda de cmdlets creados por Crescendo


A medida que crea e implementa más módulos basados en Crescendo, puede resultar
beneficioso determinar si Crescendo generó un cmdlet. Crescendo proporciona Test-
IsCrescendoCommand un cmdlet para ayudar.
PowerShell

Test-IsCrescendoCommand -Command Get-AzCmAgentConfigProperty

Resultados

Module: AzCmAgent

Name IsCrescendoCommand RequiresElevation


---- ------------------ -----------------
Get-AzCmAgentConfigProperty True False

7 Nota

Como se ha explicado anteriormente, el nuevo módulo debe ejecutarse en una


sesión con privilegios elevados. En este ejemplo, Test-IsCrescendoCommand devolvió
RequireElevation como False. Crescendo proporciona métodos para la elevación
de privilegios para todas las plataformas. Sin embargo, no hemos incluido la
elevación en nuestros ejemplos de configuración.

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:

Creación de cmdlets que requieren elevación de privilegios


Empaquetado del módulo para su distribución
Novedades de Crescendo 1.1
Artículo • 06/04/2023

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.

Nueva versión de esquema


El esquema crescendo se ha actualizado para incluir compatibilidad con dos miembros
nuevos en la clase Parameter y ArgumentTransform ArgumentTransformType . El esquema
funciona con herramientas admitidas como Visual Studio Code para proporcionar
Información sobre herramientas e IntelliSense durante la experiencia de creación.

Ubicación url del esquema Crescendo siempre disponible:

JSON

{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2022-06",
"Commands": []
}

Nuevo Export-CrescendoCommand cmdlet


Este cmdlet crea archivos de configuración JSON para los objetos Command de
Crescendo. Puede crear un archivo JSON por objeto Command o crear un archivo JSON
que contenga todos los objetos pasados.

Los objetos Command de Crescendo se pueden crear mediante New-CrescendoCommand o


importar desde una configuración existente mediante Import-CommandConfiguration .

Para obtener más información, vea Export-CrescendoCommand.

Impedir la sobrescritura del manifiesto del


módulo
Crescendo crea el módulo .psm1 y el manifiesto .psd1 del módulo cuando Export-
CrescendoModule se ejecuta. Esto puede crear problemas cuando haya personalizado el
manifiesto del módulo más allá del ámbito de Crescendo. El Export-CrescendoModule
cmdlet ahora proporciona un parámetro de modificador NoClobberManifest para evitar
que se sobrescriba el manifiesto.

PowerShell

Export-CrescendoModule -ConfigurationFile .\myconfig.json -ModuleName


.\Mymodule -NoClobberManifest

7 Nota

El parámetro NoClobberManifest impide que Crescendo actualice el manifiesto del


módulo. Usted es responsable de actualizar manualmente el manifiesto con los
nuevos cmdlets y configuraciones.

Omitir el control de salida por completo


Algunos comandos nativos crean una salida diferente en función de si la salida se envía
a la pantalla o a la canalización. Pastel es un ejemplo de un comando que cambia su
salida de una representación gráfica de pantalla a un único valor de cadena cuando se
usa en una canalización. El control de salida de Crescendo se basa en canalizaciones y
puede hacer que estas aplicaciones devuelvan resultados no deseados. Crescendo ahora
admite la capacidad de omitir completamente el controlador de salida.

Para omitir todo el control de salida de Crescendo:

JSON

"OutputHandlers": [
{
"ParameterSetName": "Default",
"HandlerType": "ByPass"
}
]

Control de la salida de errores


Anteriormente, los errores de comandos nativos se transmitían directamente al usuario.
Crescendo no los capturó. Esto le impedía crear un control mejorado de errores.
Crescendo captura ahora la salida de error de comando generada (stderr). Si no define
un controlador de salida, Crescendo usa el controlador predeterminado. El controlador
de salida predeterminado garantiza que los errores respetan los -ErrorVariable
parámetros y y -ErrorAction agregan errores a $Error .

Crescendo v1.1 agrega dos funciones internas para administrar errores.

Push-CrescendoNativeError agrega un error a una cola de errores. El controlador


de salida llama automáticamente a esta función. No tienes que llamarlo
directamente.
Pop-CrescendoNativeError quita un error de la cola de errores. Use esta función
para inspeccionar los errores en el controlador de salida.

Agregar un controlador de salida que incluya Pop-CrescendoNativeError le permite


inspeccionar los errores en el controlador de salida para que pueda controlarlos o
pasarlos al autor de la llamada.

La siguiente definición del controlador de salida usa Pop-CrescendoNativeError para


devolver errores al usuario.

JSON

"OutputHandlers": [
{
"ParameterSetName": "Default",
"StreamOutput": true,
"HandlerType": "Inline",
"Handler": "PROCESS { $_ } END { Pop-CrescendoNativeError -
EmitAsError }"
}
]

Transformación Valor de argumento


Es posible que encuentre situaciones en las que los valores de entrada entregados a un
comando ajustado de Crescendo deben traducirse a un valor diferente para el comando
nativo subyacente. Crescendo ahora admite la transformación de argumentos para
admitir estos escenarios. Hemos actualizado el esquema para agregar dos nuevos
miembros a la clase Parameter y ArgumentTransform ArgumentTransformType . Use estos
miembros para transformar argumentos de parámetro insertados o invocar un bloque
de script que tome el valor del parámetro como argumento. El valor predeterminado de
ArgumentTransformType es insertado.

Ejemplo: Multiplicación de un valor.

JSON
"Parameters": [
{
"Name": "mult2",
"OriginalName": "--p3",
"ParameterType": "int",
"OriginalPosition": 2,
"ArgumentTransform": "param([int]$v) $v * 2"
}
]

Ejemplo: Aceptar una tabla hash ordenada.

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 '',''"
}
]

Ejemplo: transformación argumento con combinación.

JSON

"Parameters": [
{
"Name": "join",
"OriginalName": "--p2",
"ParameterType": "string[]",
"OriginalPosition": 1,
"ArgumentTransform": "param([string[]]$v) $v -join '',''"
}
]

Ejemplo: llamada a una transformación basada en scripts.

JSON

"Parameters": [
{
"Name" : "Param1",
"ArgumentTransform": "myfunction",
"ArgumentTransformType" : "function"
}
]

Instalación de Crescendo
Requisitos:

Microsoft.PowerShell.Crescendo requiere PowerShell 7.0 o posterior

Para instalar Microsoft.PowerShell.Crescendo mediante el nuevo PowerShellGet v2.x:

PowerShell

Install-Module -Name Microsoft.PowerShell.Crescendo -AllowPreRelease

Para instalar Microsoft.PowerShell.Crescendo con el nuevo PowerShellGet v3 :

PowerShell

Install-PSResource -Name Microsoft.PowerShell.Crescendo -AllowPreRelease


Creación de una configuración de
Crescendo mediante los cmdlets de
Crescendo
Artículo • 03/02/2023

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.

Durante el diseño de Crescendo, creamos estos cmdlets antes de la decisión de que la


creación de módulos y cmdlets podría servir mejor mediante un enfoque declarativo. Su
utilidad sigue siendo apreciada, por lo que decidimos apoyar ambos enfoques.

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

Creación de una configuración para dos


cmdlets
En este ejemplo se muestra cómo crear la configuración de dos cmdlets que encapsulan
la herramienta VSSAdmin.exe de línea de comandos de Windows . En concreto, el script
crea cmdlets para los vssadmin list providers comandos y vssadmin list shadows .

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

combinación de parámetros opcionales que forman varios conjuntos de parámetros.

PowerShell

vssadmin list providers /?


vssadmin list shadows /?

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.

Example Usage: vssadmin List Providers

vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool


(C) Copyright 2001-2013 Microsoft Corp.

List Shadows [/For=ForVolumeSpec] [/Shadow=ShadowId|/Set=ShadowSetId]


- Displays existing shadow copies on the system. Without any options,
all shadow copies on the system are displayed ordered by shadow copy
set.
Combinations of options can be used to refine the list operation.
- The Shadow Copy ID can be obtained by using the List Shadows command.
When entering a Shadow ID, it must be in
the following format:
{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
where the X's are hexadecimal characters.

Example Usage: vssadmin List Shadows


/Shadow={c5946237-af12-3f23-af80-51aadb3b20d5}

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:

Creación de un objeto de configuración vacío


Cree el primer comando Crescendo y establezca sus propiedades.
Adición de un ejemplo al comando
Agregar un controlador de salida al comando
Agregue el comando a la colección Commands de la configuración.
Cree el segundo comando Crescendo y establezca sus propiedades
Agregar varios ejemplos al comando
Definición de los parámetros y los conjuntos de parámetros
Agregar un controlador de salida al comando
Agregue el comando a la colección Commands de la configuración.
Exportación de la configuración a un archivo JSON y creación del módulo
La configuración contiene referencias a funciones de controlador de salida. Estas
funciones están contenidas en un archivo de script independiente que debe cargarse en
la sesión de punto para poder exportar la configuración para crear un nuevo módulo de
PowerShell. Para obtener una explicación detallada de estos controladores de salida,
consulte esta serie de entradas en el blog de la comunidad de PowerShell .

PowerShell

# Create an empty array for Command object


$CrescendoCommands = @()

## Create first Crescendo command and set its properties


$cmdlet = @{
Verb = 'Get'
Noun = 'VssProvider'
OriginalName = '$env:Windir/system32/vssadmin.exe'
}
$newCommand = New-CrescendoCommand @cmdlet
$newCommand.OriginalCommandElements = @('list','providers')
$newCommand.Description = 'List registered volume shadow copy providers'
$newCommand.Usage = New-UsageInfo -usage $newCommand.Description
$newCommand.Platform = @('Windows')

### Add an example to the command


$example = @{
Command = 'Get-VssProvider'
Description = 'Get a list of VSS Providers'
OriginalCommand = 'vssadmin list providers'
}
$newCommand.Examples += New-ExampleInfo @example

### Add an Output Handler to the command


$handler = New-OutputHandler
$handler.ParameterSetName = 'Default'
$handler.HandlerType = 'Function'
$handler.Handler = 'ParseProvider'
$newCommand.OutputHandlers += $handler

## Add the command to the Commands collection of the configuration


$CrescendoCommands += $newCommand

## Create second Crescendo command and set its properties


$cmdlet = @{
Verb = 'Get'
Noun = 'VssShadow'
OriginalName = '$env:Windir/system32/vssadmin.exe'
}
$newCommand = New-CrescendoCommand @cmdlet
$newCommand.OriginalCommandElements = @('list','shadows')
$newCommand.Description = 'List existing volume shadow copies. Without any
options, ' +
'all shadow copies on the system are displayed ordered by shadow copy
set. ' +
'Combinations of options can be used to refine the output.'
$newCommand.Usage = New-UsageInfo -usage 'List existing volume shadow
copies.'
$newCommand.Platform = ,'Windows'

### Add multiple examples to the command


$example = @{
Command = 'Get-VssShadow'
Description = 'Get a list of VSS shadow copies'
OriginalCommand = 'vssadmin list shadows'
}
$newCommand.Examples += New-ExampleInfo @example
$example = @{
Command = 'Get-VssShadow -For C:'
Description = 'Get a list of VSS shadow copies for volume C:'
OriginalCommand = 'vssadmin list shadows /For=C:'
}
$newCommand.Examples += New-ExampleInfo @example
$example = @{
Command = "Get-VssShadow -Shadow '{c17ebda1-5da3-4f4a-a3dc-
f5920c30ed0f}"
Description = 'Get a specific shadow copy'
OriginalCommand = 'vssadmin list shadows /Shadow={3872a791-51b6-4d10-
813f-64b4beb9f935}'
}
$newCommand.Examples += New-ExampleInfo @example

### Define the parameters and parameter sets


$newCommand.DefaultParameterSetName = 'Default'

#### Add a new parameter to the command


$parameter = New-ParameterInfo -OriginalName '/For=' -Name 'For'
$parameter.ParameterType = 'string'
$parameter.ParameterSetName = @('Default','ByShadowId','BySetId')
$parameter.NoGap = $true
$parameter.Description = "List the shadow copies for volume name like 'C:'"
$newCommand.Parameters += $parameter

#### Add a new parameter to the command


$parameter = New-ParameterInfo -OriginalName '/Shadow=' -Name 'Shadow'
$parameter.ParameterType = 'string'
$parameter.ParameterSetName = @('ByShadowId')
$parameter.NoGap = $true
$parameter.Mandatory = $true
$parameter.Description = "List shadow copies matching the Id in GUID format:
" +
"'{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'"
$newCommand.Parameters += $parameter

#### Add a new parameter to the command


$parameter = New-ParameterInfo -OriginalName '/Set=' -Name 'Set'
$parameter.ParameterType = 'string'
$parameter.ParameterSetName = @('BySetId')
$parameter.NoGap = $true
$parameter.Mandatory = $true
$parameter.Description = "List shadow copies matching the shadow set Id in
GUID format: " +
"'{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'"
$newCommand.Parameters += $parameter

### Add an Output Handler to the command


$handler = New-OutputHandler
$handler.ParameterSetName = 'Default'
$handler.HandlerType = 'Function'
$handler.Handler = 'ParseShadow'
$newCommand.OutputHandlers += $handler

## Add the command to the Commands collection of the configuration


$CrescendoCommands += $newCommand

# Export the configuration to a JSON file and create the module


Export-CrescendoCommand -command $CrescendoCommands -fileName
.\vssadmin.json
Export-CrescendoModule -ConfigurationFile vssadmin.json -ModuleName
.\vssadmin.psm1 -Force

Casos de uso avanzados


Los cmdlets de Crescendo son herramientas eficaces que se pueden usar en escenarios
avanzados para crear configuraciones y compilar módulos. Hay varios ejemplos
avanzados en la Experimental\HelpParsers carpeta del módulo
Microsoft.PowerShell.Crescendo . Estos ejemplos experimentales muestran cómo
analizar la salida de ayuda de una herramienta de línea de comandos y usar esa
información para crear una configuración de Crescendo para un módulo que encapsula
la herramienta. El archivo README.md proporciona una explicación detallada del
diseño de estos analizadores de ayuda.

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

Antes de Crescendo 1.1, los errores de comandos nativos se transmitían directamente al


usuario, no capturados por Crescendo. Esto impedía crear un control mejorado de
errores. Ahora, Crescendo puede capturar la salida de error (stderr) desde el comando
nativo.

De forma predeterminada, cuando no se define un controlador de salida, Crescendo usa


el controlador predeterminado. El controlador de salida predeterminado garantiza que
los errores respetan los -ErrorVariable parámetros y y -ErrorAction agregan errores a
$Error . Si establece HandlerType ByPass en , Crescendo no captura errores y toda la
salida se transmite directamente al usuario.

Crescendo v1.1 agrega dos funciones internas para administrar errores.

Push-CrescendoNativeError agrega errores a una cola de errores. El controlador de


salida llama automáticamente a esta función. No tienes que llamarlo directamente.
Pop-CrescendoNativeError quita un error de la cola de errores. Use esta función
para inspeccionar los errores en el controlador de salida para que pueda
controlarlos o pasarlos al autor de la llamada.

La siguiente definición del controlador de salida usa Pop-CrescendoNativeError para


devolver errores al usuario.

JSON

"OutputHandlers": [
{
"ParameterSetName": "Default",
"StreamOutput": true,
"HandlerType": "Inline",
"Handler": "PROCESS { $_ } END { Pop-CrescendoNativeError -
EmitAsError }"
}
]

Ejemplo: el comando nativo escribe


información y errores en stderr.
Considere el siguiente escenario: Tiene una herramienta de línea de comandos que hace
lo siguiente:
Escribe mensajes informativos, como texto de banner, progreso y otros en stderr
Escribe mensajes de error en stderr
Escribe la salida correcta de los datos en stdout

Quiere crear un controlador de salida de Crescendo que pueda distinguir entre


mensajes informativos y errores, así como convertir los datos de una salida correcta en
objetos de PowerShell.

En los ejemplos siguientes se muestra una herramienta ficticia de línea de comandos


denominada fizztool.exe que tiene el comportamiento descrito anteriormente.

Ejemplo correcto
Esta es una invocación de ejemplo de la herramienta que debe realizarse correctamente:

fizztool.exe --key fizz

La línea de copyright se escribe en stderr y el objeto JSON se escribe en stdout.

Output

fizztool.exe v1.0.0 (c) 2021 Tailspin Toys, Ltd.

{
"fizz": "buzz"
}

Si lo ejecuta desde PowerShell, verá la siguiente salida:

PowerShell

fizztool.exe --key fizz | ConvertFrom-Json

Output

fizztool.exe v1.0.0 (c) 2021 Tailspin Toys, Ltd.

fizz
----
buzz
Ejemplo de error
Esta es una invocación de ejemplo de la herramienta que genera un error:

fizztool.exe --key buzz

La línea de copyright y el mensaje de error se escriben en stderr .

Output

fizztool.exe v1.0.0 (c) 2021 Tailspin Toys, Ltd.


ERROR: Key not found: buzz

Si lo ejecuta desde PowerShell, verá la siguiente salida:

PowerShell

fizztool.exe --key buzz | ConvertFrom-Json

Output

fizztool.exe v1.0.0 (c) 2021 Tailspin Toys, Ltd.


ERROR: Key not found: buzz

Control de los errores en Crescendo


La siguiente configuración de Crescendo define el cmdlet Get-FizzBuzz que llama a
fizztool.exe , procesa la salida y controla las condiciones de error.

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"
}
]
}
]
}

El controlador de salida usa la siguiente FizzToolParser función para procesar la salida.

PowerShell

function FizzToolParser {
param(
[Parameter(Mandatory)]
[AllowNull()]
$cmdResults = ''
)

if ($null -ne $cmdResults) {


$cmdResults | Out-String | ConvertFrom-Json
} else {
Pop-CrescendoNativeError |
Where-Object {$_ -like 'ERROR:*'} |
Write-Error
}
}

La FizzToolParser función realiza las siguientes acciones:

Si $cmdResults no es null, convierte la salida JSON en un objeto de PowerShell.


Si $cmdResults es null, comprueba si hay errores.
Pop-CrescendoNativeError recupera la salida de error de la cola.

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 .

Uso del nuevo cmdlet


PowerShell

Get-FizzBuzz -Key fizz

Output

fizz
----
buzz

PowerShell

Get-FizzBuzz -Key buzz

Output

Write-Error: ERROR: Key not found: buzz


Transformación de argumentos en
Crescendo
Artículo • 08/04/2023

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 .

El valor de ArgumentTransformType especifica cómo se interpreta el valor de


ArgumentTransform . Debe tener uno de los siguientes valores:

Inline - El valor de ArgumentTransform es una cadena que se va a evaluar como

un bloque de script. Este es el valor predeterminado cuando no se especifica


ningún valor.
Function : el valor de ArgumentTransform es el nombre de una función cargada en
la sesión actual.
Script - El valor de ArgumentTransform es el nombre de un archivo de script que

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

posible sin usar la transformación de argumentos.

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.

Ejemplo: convertir un objeto PSCredential en


un nombre de usuario y una contraseña
En este ejemplo, la configuración de Crescendo define el Connect-WindowsShare cmdlet
que encapsula el net use comando . El Credential parámetro es un objeto
PSCredential que se debe convertir en un nombre de usuario y una contraseña para el
net use comando.

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"
}
]
}
]
}

El transformador de argumentos conversa el objeto PSCredential en /USER:username


password para el net use comando .
Introducción a PlatyPS
Artículo • 13/12/2022

El módulo PlatyPS proporciona cmdlets que permiten crear contenido de ayuda de


PowerShell en Markdown. El módulo crea archivos markdown de código auxiliar para
cada cmdlet del módulo de destino que se documenta. Después, edite los archivos
Markdown para incluir descripciones y ejemplos. Después, Markdown se puede
convertir al formato MAML que usa el cmdlet de Get-Help PowerShell.
Creación de ayuda basada en XML
mediante PlatyPS
Artículo • 13/12/2022

Al crear un módulo de PowerShell, siempre se recomienda incluir ayuda detallada para


los cmdlets que cree. Si los cmdlets se implementan en código compilado, debe usar la
ayuda basada en XML. Este formato XML se conoce como lenguaje de marcado de
asistencia de Microsoft (MAML).

La documentación heredada del SDK de PowerShell cubre los detalles de la creación de


ayuda para los cmdlets de PowerShell empaquetados en módulos. Sin embargo,
PowerShell no proporciona ninguna herramienta para crear ayuda basada en XML. La
documentación del SDK explica la estructura de la ayuda de MAML, pero, en cuanto a la
creación del contenido de MAML, que es complejo y profundamente anidado, solo se
contempla hacerlo a mano.

Aquí es donde puede ser útil el módulo PlatyPS .

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

PlatyPS crea marcadores de posición para que pueda completar descripciones y


ejemplos. Después de agregar la información necesaria, PlatyPS compila los archivos
Markdown en archivos MAML. El sistema de ayuda de PowerShell también admite
archivos de ayuda conceptuales de texto sin formato (temas Acerca de). PlatyPS tiene un
cmdlet para crear una plantilla Markdown estructurada para un nuevo archivo about,
pero estos archivos about_*.help.txt deben mantenerse manualmente.

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.

Introducción al uso de PlatyPS


En primer lugar, debe instalar PlatyPS desde la Galería de PowerShell.
PowerShell

Install-Module platyps -Force


Import-Module platyps

En el siguiente diagrama de flujo se describe el proceso para crear o actualizar el


contenido de referencia de PowerShell.

Creación de contenido Markdown para un


módulo de PowerShell
1. Importe el nuevo módulo a la sesión. Repita este paso para cada módulo que
necesite documentar.

Ejecute el siguiente comando para importar los módulos:

PowerShell

Import-Module <your module name>

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

$OutputFolder = <output path>


$parameters = @{
Module = <ModuleName>
OutputFolder = $OutputFolder
AlphabeticParamsOrder = $true
WithModulePage = $true
ExcludeDontShow = $true
Encoding = [System.Text.Encoding]::UTF8
}
New-MarkdownHelp @parameters

New-MarkdownAboutHelp -OutputFolder $OutputFolder -AboutName


"topic_name"

Si la carpeta de salida no existe, New-MarkdownHelp la creará. En este ejemplo, New-


MarkdownHelp crea un archivo Markdown para cada cmdlet del módulo. También

crea la página del módulo en un archivo denominado <ModuleName>.md . Esta página


del módulo contiene una lista de los cmdlets incluidos en el módulo y los
marcadores de posición de la descripción del elemento Synopsis. Los metadatos
de la página de módulo proceden del manifiesto de módulo y se usan en PlatyPS
para crear el archivo XML HelpInfo (como se explica a continuación).

New-MarkdownAboutHelp crea un nuevo archivo about denominado


about_topic_name.md .

Para obtener más información, consulte New-MarkdownHelp y New-


MarkdownAboutHelp.

Actualización del contenido Markdown existente cuando


cambia el módulo
PlatyPS también puede actualizar archivos Markdown existentes para un módulo. Use
este paso para actualizar los módulos que tienen nuevos cmdlets, parámetros nuevos o
parámetros que han cambiado.

1. Importe el nuevo módulo a la sesión. Repita este paso para cada módulo que
necesite documentar.

Ejecute el siguiente comando para importar los módulos:

PowerShell

Import-Module <your module name>


2. Use PlatyPS para actualizar archivos Markdown para la página de aterrizaje del
módulo y todos los cmdlets asociados en el módulo. Repita este paso para cada
módulo que necesite documentar.

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

Update-MarkdownHelpModule actualiza el cmdlet y los archivos Markdown del


módulo en la carpeta especificada. No actualiza los archivos about_*.md . El archivo
de módulo ( ModuleName.md ) recibe todo texto nuevo de Synopsis que se ha
agregado a los archivos de cmdlet. En las actualizaciones de los archivos de cmdlet
se incluye el siguiente cambio:

Nuevos conjuntos de parámetros


Parámetros nuevos
Metadatos de parámetros seleccionados
Información actualizada del tipo de entrada y salida

Para obtener más información, vea Update-MarkdownHelpModule.

Edición de los archivos Markdown nuevos o


actualizados
PlatyPS documenta la sintaxis de los conjuntos de parámetros y cada uno de los
parámetros. No puede crear descripciones ni proporcionar ejemplos. Las áreas
específicas en las que se necesita contenido se encuentran entre llaves. Por ejemplo: {{
Fill in the Description }}
Debe agregar un resumen, una descripción del cmdlet, descripciones para cada
parámetro y, al menos, un ejemplo.

Para obtener información detallada sobre la escritura de contenido de PowerShell,


consulte los siguientes artículos:

Guía de estilo de PowerShell


Edición de los artículos de referencia

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

Update-MarkdownHelpModule -Path <full path output folder> -RefreshModulePage

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.

Creación de los archivos de ayuda externos


En este paso se crean los archivos de ayuda de MAML que se muestran mediante Get-
Help en la consola de PowerShell.

Ejecute el siguiente comando para compilar los archivos MAML:

PowerShell

New-ExternalHelp -Path <folder with MDs> -OutputPath <output help folder>

New-ExternalHelp convierte todos los archivos Markdown de cmdlet en uno (o varios)

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

PlatyPS realiza un trabajo deficiente al convertir los archivos about_*.md en texto


sin formato. Debe usar un Markdown muy simple para obtener resultados
aceptables. Puede que quiera mantener los archivos en el formato
about_topic_name.help.txt con texto sin formato, en lugar de permitir que PlatyPS

los convierta.
Una vez completado este paso, verá los archivos *-help.xml y about_*.help.txt en la
carpeta de salida de destino.

Para obtener más información, vea New-ExternalHelp

Prueba de los archivos de ayuda compilados


Puede comprobar el contenido con el cmdlet Get-HelpPreview:

PowerShell

Get-HelpPreview -Path "<ModuleName>-Help.xml"

El cmdlet lee el archivo MAML compilado y genera el contenido en el mismo formato


que se recibiría de Get-Help . Esto le permite inspeccionar los resultados para
comprobar que los archivos Markdown se compilan correctamente y generar los
resultados deseados. Si encuentra un error, vuelva a editar los archivos Markdown y
vuelva a compilar el MAML.

Ahora está a punto para publicar los archivos de ayuda.

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.

Empaquetado de los archivos de ayuda con el módulo


Creación de un paquete de ayuda actualizable que los usuarios instalen con el
cmdlet de Update-Help

Empaquetado de ayuda con el módulo


Los archivos de ayuda se pueden empaquetar con el módulo. Consulte Escritura de la
ayuda para los módulos para obtener más información sobre la estructura de carpetas.
Debe incluir la lista de archivos de ayuda en el valor de la clave FileList en el manifiesto
del módulo.

Creación de un paquete de ayuda actualizable


En un nivel alto, los pasos para crear la ayuda actualizable incluyen lo siguiente:
1. Búsqueda de un sitio de Internet para hospedar los archivos de ayuda
2. Adición de una clave de HelpInfoURI al manifiesto del módulo
3. Creación de un archivo HelpInfo XML
4. Creación de archivos CAB
5. Carga de los archivos

Para obtener más información, vea Creación de la Ayuda actualizable: paso a paso.

PlatyPS le ayuda con algunos de estos pasos.

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

el contenido de la ayuda actualizable. Esta dirección URL solo debe apuntar a la


ubicación de la carpeta, no a los archivos individuales. Update-Help construye los
nombres de archivo que se van a descargar basándose en otra información del
manifiesto del módulo y del archivo HelpInfo XML.

) 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-ExternalHelp crea el archivo HelpInfo XML en la carpeta de salida. El


archivo HelpInfo XML se crea mediante metadatos de YAML contenidos en los archivos
Markdown del módulo ( ModuleName.md ).

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.

Para obtener más información, vea New-ExternalHelpCab.

Otras opciones de publicación


Markdown es un formato versátil y fácil de transformar en otros formatos para la
publicación. Con una herramienta como Pandoc , puede convertir los archivos
Markdown de ayuda en muchos formatos de documento diferentes, como texto sin
formato, HTML, PDF y formatos de documentos de Office.

Además, los cmdlets ConvertFrom-MarkdownConvertFrom-Markdown] y Show-


Markdown de PowerShell 6 y versiones posteriores se pueden usar para convertir
Markdown en HTML o para crear una presentación multicolor en la consola de
PowerShell.

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

PSScriptAnalyzer es un comprobador de código estático para los módulos y scripts de


PowerShell. PSScriptAnalyzer comprueba la calidad del código de PowerShell mediante
la ejecución de un conjunto de reglas. Las reglas se basan en los procedimientos
recomendados de PowerShell identificados por el equipo de PowerShell y la comunidad.
Genera DiagnosticResults (errores y advertencias) para informar a los usuarios sobre
posibles defectos de código y sugiere posibles soluciones para mejorar.

PSScriptAnalyzer se incluye con una colección de reglas integradas que comprueban


varios aspectos del código de PowerShell, como:

Presencia de variables no inicializadas


Uso del tipo PSCredential
Uso de Invoke-Expression
Y mucho más

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

Windows PowerShell 3.0 o superior


PowerShell 7.0.11 o posterior en Windows/Linux/macOS

Instalación mediante PowerShellGet 2.x:

PowerShell

Install-Module -Name PSScriptAnalyzer -Force

Instalación mediante PowerShellGet 3.x:

PowerShell

Install-PSResource -Name PSScriptAnalyzer -Reinstall


Los parámetros Force o Reinstall solo son necesarios cuando tiene instalada una versión
anterior de PSScriptAnalyzer. Estos parámetros también funcionan incluso cuando no
tiene instalada una versión anterior.
Uso de PSScriptAnalyzer
Artículo • 13/12/2022

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

Errores del analizador


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

PowerShell

Invoke-ScriptAnalyzer -ScriptDefinition '"b" = "b"; function eliminate-file


() { }'

Output

RuleName Severity ScriptName Line Message


-------- -------- ---------- ---- -------
InvalidLeftHandSide ParseError 1 The assignment expression is
not
valid. The input to an
assignment operator must be
an
object that is able to accept
assignments, such as a
variable
or a property.
PSUseApprovedVerbs Warning 1 The cmdlet 'eliminate-file'
uses an
unapproved verb.

RuleName se establece en errorId del error del analizador.

Para suprimir ParseErrors, no lo incluya como un valor en el parámetro Severity .

PowerShell

Invoke-ScriptAnalyzer -ScriptDefinition '"b" = "b"; function eliminate-file


() { }' -Severity Warning

Output

RuleName Severity ScriptName Line Message


-------- -------- ---------- ---- -------
PSUseApprovedVerbs Warning 1 The cmdlet 'eliminate-file' uses
an
unapproved verb.

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()

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

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

Para suprimir un mensaje en un parámetro específico, establezca el parámetro CheckId


de SuppressMessageAttribute en el nombre del parámetro :

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()

Write-Verbose -Message "I am invincible!"


}

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.

Por ejemplo, para suprimir la infracción de la regla PSAvoidUsingWriteHost en start-


bar y start-baz , pero no en start-foo y start-bam :

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()

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


foo :

PowerShell

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

7 Nota

Los errores del analizador no se pueden suprimir con SuppressMessageAttribute.

Compatibilidad con la configuración en


ScriptAnalyzer
Puede crear configuraciones que describan las reglas de ScriptAnalyzer para incluir o
excluir en función de la gravedad. Use el parámetro Settings de Invoke-ScriptAnalyzer
para especificar la configuración. Esto le permite crear una configuración personalizada
para un entorno específico. Se admiten los siguientes modos para especificar el archivo
de configuración:

Valores preestablecidos integrados


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

PowerShell

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


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

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')
}

Después, puede invocar ese archivo de configuración con Invoke-ScriptAnalyzer :

PowerShell

Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings


PSScriptAnalyzerSettings.psd1

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

PowerShell

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

Después, puede invocar ese archivo de configuración:

PowerShell

Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings


PSScriptAnalyzerSettings.psd1

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

PowerShell

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

Tenga en cuenta que proporcionar la configuración explícitamente tiene mayor


prioridad sobre este modo implícito. Los archivos de configuración de ejemplo se
proporcionan en la Settings carpeta del módulo PSScriptAnalyzer .

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.

En este ejemplo, la propiedad CustomRulePath apunta a dos módulos diferentes.


Ambos módulos exportan las funciones de regla con el verbo Measure , por lo que
Measure-* se usa para la propiedad IncludeRules.

PowerShell

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

IncludeRules = @(
'Measure-*'
)
}

También puede agregar reglas predeterminadas enumerando las reglas en la propiedad


IncludeRules . Al incluir reglas predeterminadas, es importante establecer la propiedad
IncludeDefaultRules $true en ; de lo contrario, se usan las reglas predeterminadas.

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

IncludeDefaultRules = $true

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

# Custom rules
'Measure-*'
)
}

Uso de reglas personalizadas en Visual Studio Code


También es posible usar las reglas personalizadas que se proporcionan en el archivo de
configuración de Visual Studio Code. Esto se hace agregando un archivo de
configuración del área de trabajo Visual Studio Code ( .vscode/settings.json ).

JSON

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

ScriptAnalyzer como una biblioteca de .NET


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

Estas son las interfaces públicas:

C#

using Microsoft.Windows.PowerShell.ScriptAnalyzer;

public void Initialize(System.Management.Automation.Runspaces.Runspace


runspace,
Microsoft.Windows.PowerShell.ScriptAnalyzer.IOutputWriter outputWriter,
[string[] customizedRulePath = null],
[string[] includeRuleNames = null],
[string[] excludeRuleNames = null],
[string[] severity = null],
[bool suppressedOnly = false],
[string profile = null])

public System.Collections.Generic.IEnumerable<DiagnosticRecord>
AnalyzePath(string path,
[bool searchRecursively = false])

public System.Collections.Generic.IEnumerable<IRule> GetRule(string[]


moduleNames, string[] ruleNames)

Corrección de infracciones
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.

La propiedad SuggestedCorrections del registro de errores permite escenarios de


corrección rápida en editores como VSCode. Proporcionamos una suggestedCorrection
válida para las reglas siguientes:

AvoidAlias
AvoidUsingPlainTextForPassword
MisleadingBacktick
MissingModuleManifestField
UseToExportFieldsInManifest
Recomendaciones y reglas de
PSScriptAnalyzer
Artículo • 13/12/2022

Las siguientes directrices proceden de un esfuerzo combinado del equipo de PowerShell


y de la comunidad. Las instrucciones se organizan por tipo. Dentro de cada tipo hay una
lista de reglas. Las reglas se agrupan mediante la gravedad definida en la
implementación de la regla PSScriptAnalyzer . El nivel de gravedad etiquetado como
"TBD" significa "Para determinar". Estas son recomendaciones que no tienen definidas
actualmente reglas.

Reglas de diseño de cmdlets

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

Funciones del script

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

Seguridad del script

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)

Reglas relacionadas con DSC


Gravedad: error
Usar métodos estándar de DSC StandardDSCFunctionsInResource
Usar parámetros obligatorios idénticos para todos los métodos de DSC
UseIdenticalMandatoryParametersForDSC
Usar parámetros idénticos para los métodos DSC Set y Test
UseIdenticalParametersForDSC

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.

Al llamar a Invoke-ScriptAnalyzer , los usuarios pueden especificar reglas personalizadas


mediante el parámetro CustomizedRulePath .

En este artículo se proporciona una guía básica para crear sus propias reglas
personalizadas.

Requisitos básicos

Las funciones deben tener ayuda basada en comentarios


Incluya el .DESCRIPTION campo . Esto se convierte en la descripción de la regla
personalizada.

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
#>

El tipo de salida debe ser DiagnosticRecord.


PowerShell

[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
)

El nombre del parámetro token debe terminar con Token.

PowerShell

Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.Token[]]
$testToken
)

DiagnosticRecord debe tener las propiedades necesarias


DiagnosticRecord debe tener al menos cuatro propiedades:

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
}

Asegúrese de exportar las funciones.


PowerShell

Export-ModuleMember -Function (FunctionName)

Función de regla de ejemplo


PowerShell

<#
.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
}

# Finds specific value,


[system.security.principal.windowsbuiltinrole]::administrator.
[ScriptBlock]$predicate2 = {
param ([System.Management.Automation.Language.Ast]$Ast)
[bool]$returnValue = $false
if ($Ast -is
[System.Management.Automation.Language.AssignmentStatementAst])
{

[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)
}
}
}

Puede encontrar más ejemplos en la carpeta CommunityAnalyzerRules en GitHub.


Reglas de PSScriptAnalyzer
Artículo • 04/02/2023

PSScriptAnalyzer contiene las siguientes definiciones de regla.

Regla severity Habilitado de Configurable


forma
predeterminada

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í

AvoidUsingCmdletAliases Advertencia Sí Sí2

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í

UseCmdlet Incorrectamente Advertencia Sí

UseCompatibleCmdlets Advertencia Sí Sí2

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í

UseOutputType Incorrectamente Información 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

Nivel de gravedad: Advertencia

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'
}

La alineación en este caso sería similar a la siguiente.

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

Habilitar: bool (el valor predeterminado es $false )


Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

CheckHashtable: bool (el valor predeterminado es $false )


Aplique la alineación de las instrucciones de asignación en una tabla hash y en una
configuración de DSC. Solo hay un modificador para la configuración de DSC y
hasthable porque los pares de valores de propiedad de una configuración de DSC se
analizan como pares clave-valor de una tabla hash.
AvoidAssignmentToAutomaticVariable
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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

function Get-CustomErrorMessage($ErrorMessage){ $Error = "Error occurred:


$ErrorMessage" }

Correcto
PowerShell

function Get-CustomErrorMessage($ErrorMessage){ $FinalErrorMessage = "Error


occurred: $ErrorMessage" }
AvoidDefaultValueForMandatoryParame
ter
Artículo • 13/12/2022

Nivel de gravedad: Advertencia

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

Nivel de gravedad: advertencia

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

Nivel de gravedad: advertencia

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.

Para obtener más información sobre el ámbito, consulte Get-Help about_Scopes .

NOTA Esta regla no está disponible en La versión 3 o 4 de PowerShell porque usa la


StaticParameterBinder.BindCommand API.

Cómo
Use otros modificadores de ámbito para nuevos alias.

Ejemplo

Incorrecto
PowerShell

New-Alias -Name Name -Value Value -Scope Global

Correcto
PowerShell

New-Alias -Name Name1 -Value Value


AvoidGlobalFunctions
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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.

Para obtener más información sobre el ámbito, consulte Get-Help about_Scopes .

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

Nivel de gravedad: Advertencia

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.

Las variables de ámbito global incluyen:

Variables automáticas
Variables de preferencia
Variables, alias y funciones que se encuentran en los perfiles de PowerShell

Para obtener más información sobre el ámbito, consulte Get-Help about_Scopes .

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

Nivel de gravedad: advertencia

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

Nivel de gravedad: advertencia

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

Habilitar: bool (el valor predeterminado es $false )

Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

MaximumLineLength: int (el valor predeterminado es 120)


Parámetro opcional para invalidar la longitud máxima de línea predeterminada.
AvoidMultipleTypeAttributes
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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

Nivel de gravedad: advertencia

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

Nivel de gravedad: advertencia

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.

Nota: El valor predeterminado de PowerShellVersion es core-6.1.0-windows si


PowerShell 6 o posterior está instalado y desktop-5.1.14393.206-windows , si no es así.
Normalmente, las versiones revisadas de PowerShell tienen los mismos datos de cmdlet,
por lo que solo se proporcionan las configuraciones de las versiones principales y
secundarias de PowerShell. También puede crear un archivo de configuración
personalizado, así como con el script deNew-CommandDataFile.ps1 y usarlo
colocando el creado JSON en la Settings carpeta de la PSScriptAnalyzer carpeta de
instalación del módulo, el PowerShellVersion parámetro es solo su nombre de archivo
(que también se puede cambiar si lo desea). Tenga en cuenta que los core-6.0.2-*
archivos se quitaron en PSScriptAnalyzer 1.18 desde que PowerShell 6.0 alcanzó el final
de la vida útil.
AvoidSemicolonsAsLineTerminators
Artículo • 13/12/2022

Nivel de gravedad: Advertencia

Descripción
Las líneas no deben terminar con un punto y coma.

7 Nota

Esta regla no está habilitada de forma predeterminada. El usuario debe habilitarlo a


través de la configuración.

Ejemplo

Incorrecto
PowerShell

Install-Module -Name PSScriptAnalyzer; $a = 1 + $b;

PowerShell

Install-Module -Name PSScriptAnalyzer;


$a = 1 + $b

Correcto
PowerShell

Install-Module -Name PSScriptAnalyzer; $a = 1 + $b

PowerShell

Install-Module -Name PSScriptAnalyzer


$a = 1 + $b
Configuración
PowerShell

Rules = @{
PSAvoidSemicolonsAsLineTerminators = @{
Enable = $true
}
}

Parámetros

Habilitar: bool (el valor predeterminado es $false )

Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.


AvoidShouldContinueWithoutForce
Artículo • 15/05/2023

Nivel de gravedad: Advertencia

Descripción
Las funciones que usan ShouldContinue deben tener un parámetro de fuerza booleana
para permitir que el usuario lo omita.

Para obtener más detalles, ejecute Get-Help about_Functions_CmdletBindingAttribute y


Get-Help about_Functions_Advanced_Methods comando en PowerShell.

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'
)

if ($PsCmdlet.ShouldContinue('ShouldContinue Query', 'ShouldContinue


Caption'))
{
...
}
}

Correcto
PowerShell

Function Test-ShouldContinue
{
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
$MyString = 'blah',
[Switch]$Force
)

if ($Force -or $PsCmdlet.ShouldContinue('ShouldContinue Query',


'ShouldContinue Caption'))
{
...
}
}
AvoidTrailingWhitespace
Artículo • 13/12/2022

Nivel de gravedad: información

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

Nivel de gravedad: Advertencia

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

Get-FileHash foo.txt -Algorithm MD5

Correcto
PowerShell

Get-FileHash foo.txt -Algorithm SHA256

Ejemplo 2

Incorrecto
PowerShell

Get-FileHash foo.txt -Algorithm SHA1


Correcto
PowerShell

Get-FileHash foo.txt
AvoidUsingCmdletAliases
Artículo • 13/12/2022

Nivel de gravedad: Advertencia

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.

Lista de permitidos de alias


Para evitar PSScriptAnalyzer marcar los alias preferidos, cree una lista de permitidos de
los alias en el archivo de configuración y apunte PSScriptAnalyzer a usar el archivo de
configuración. Por ejemplo, para deshabilitar PSScriptAnalyzer la marca de cd , que es
un alias de , establezca el contenido del archivo de Set-Location configuración en lo
siguiente.

PowerShell

# PSScriptAnalyzerSettings.psd1
@{
'Rules' = @{
'PSAvoidUsingCmdletAliases' = @{
'allowlist' = @('cd')
}
}
}

Ejemplo

Incorrecto
PowerShell

gps | Where-Object {$_.WorkingSet -gt 20000000}

Correcto
PowerShell

Get-Process | Where-Object {$_.WorkingSet -gt 20000000}


AvoidUsingComputerNameHardcoded
Artículo • 15/05/2023

Nivel de gravedad: Error

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

Function Invoke-MyCommand ($ComputerName)


{
Invoke-Command -Port 343 -ComputerName $ComputerName
}

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

Nivel de gravedad: error

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

$UserInput = Read-Host 'Please enter your secure code'


$EncryptedInput = ConvertTo-SecureString -String $UserInput -AsPlainText -
Force

Correcto
PowerShell

$SecureUserInput = Read-Host 'Please enter your secure code' -AsSecureString


$EncryptedInput = ConvertFrom-SecureString -String $SecureUserInput
$SecureString = ConvertTo-SecureString -String $EncryptedInput
AvoidUsingDeprecatedManifestFields
Artículo • 13/12/2022

Nivel de gravedad: advertencia

Descripción
En PowerShell 5.0, se han cambiado varios campos en los archivos de manifiesto del
módulo ( .psd1 ).

El campo ModuleToProcess se ha reemplazado por el RootModule campo .

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

Nivel de gravedad: información

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

$constantValue = "I Love PowerShell"

Correcto
PowerShell

$constantValue = 'I Love PowerShell'


AvoidUsingEmptyCatchBlock
Artículo • 15/05/2023

Nivel de gravedad: Advertencia

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

Nivel de gravedad: advertencia

Descripción
Se debe tener cuidado al usar el Invoke-Expression comando . Invoke-Expression
ejecuta la cadena especificada y devuelve los resultados.

La inserción de código en la aplicación o el script puede producirse si la expresión


pasada como una cadena incluye los datos proporcionados por el usuario.

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

Nivel de gravedad: Advertencia

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 .

Los parámetros siguientes se consideran parámetros de contraseña (esto no distingue


mayúsculas de minúsculas):

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

** Nivel de gravedad: Información **

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

AvoidUsingPositionalParameters: string[] (el valor predeterminado


es 'az')
Comandos que se excluirán de esta regla. az se excluye de forma predeterminada
porque a partir de la versión 2.40.0, el punto de entrada de la CLI de AZ se convirtió en
un az.ps1 script, pero este script no tiene parámetros con nombre y simplemente los
pasa al proceso $args de Python que inicia, por lo tanto, sigue siendo una CLI y no un
comando de PowerShell.

Habilitar: bool (el valor predeterminado es $true )


Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

Cómo
Use nombres de parámetro completos al llamar a comandos.

Ejemplo

Incorrecto
PowerShell

Get-Command ChildItem Microsoft.PowerShell.Management

Correcto
PowerShell

Get-Command -Noun ChildItem -Module Microsoft.PowerShell.Management


AvoidUsingUsernameAndPasswordPara
ms
Artículo • 13/12/2022

Nivel de gravedad: Error

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

Nivel de gravedad: advertencia

Descripción
A partir de PowerShell 3.0, los cmdlets CIM deben usarse a través de los cmdlets de
WMI.

No se deben usar los siguientes cmdlets:

Get-WmiObject
Remove-WmiObject

Invoke-WmiObject
Register-WmiEvent

Set-WmiInstance

En su lugar, use los siguientes cmdlets:

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.

Get-WmiObject -> Get-CimInstance

Remove-WmiObject -> Remove-CimInstance


Invoke-WmiObject -> Invoke-CimMethod

Register-WmiEvent -> Register-CimIndicationEvent


Set-WmiInstance -> Set-CimInstance
Ejemplo

Incorrecto
PowerShell

Get-WmiObject -Query 'Select * from Win32_Process where name LIKE


"myprocess%"' | Remove-WmiObject
Invoke-WmiMethod -Class Win32_Process -Name 'Create' -ArgumentList @{
CommandLine = 'notepad.exe' }

Correcto
PowerShell

Get-CimInstance -Query 'Select * from Win32_Process where name LIKE


"myprocess%"' | Remove-CIMInstance
Invoke-CimMethod -ClassName Win32_Process -MethodName 'Create' -Arguments @{
CommandLine = 'notepad.exe' }
AvoidUsingWriteHost
Artículo • 16/05/2023

Nivel de gravedad: advertencia

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

Los comandos con el Show verbo no tienen aplicada esta comprobación.

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

Nivel de gravedad: información

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:

En el caso de 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 .

La Examples carpeta debe contener una configuración de ejemplo para un recurso


determinado. El nombre del archivo debe contener el nombre del recurso.

Ejemplo

Recurso no basado en clases


Supongamos que tenemos un recurso no basado en clases con una estructura de
archivos siguiente:

xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof

En este caso, para corregir esta advertencia, deberíamos agregar ejemplos de la


siguiente manera:

xAzure
DSCResources
MSFT_xAzureSubscription
MSFT_xAzureSubscription.psm1
MSFT_xAzureSubscription.schema.mof
Ejemplos
MSFT_xAzureSubscription_AddSubscriptionExample.ps1
MSFT_xAzureSubscription_RemoveSubscriptionExample.ps1

Recurso basado en clases


Supongamos que tenemos un recurso basado en clases con una estructura de archivos
siguiente:

MyDscResource
MyDscResource.psm1
MyDscResource.psd1

En este caso, para corregir esta advertencia, deberíamos agregar ejemplos de la


siguiente manera:

MyDscResource
MyDscResource.psm1
MyDscResource.psd1
Ejemplos
MyDscResource_Example1.ps1
MyDscResource_Example2.ps1
DscTestsPresent
Artículo • 13/12/2022

Nivel de gravedad: información

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 .

La Tests carpeta debe contener un script de prueba para un recurso determinado. El


nombre del archivo debe contener el nombre del recurso.

Ejemplo

Recurso no basado en clases


Supongamos que tenemos un recurso no basado en clases con una estructura de
archivos siguiente:

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

Recurso basado en clases


Supongamos que tenemos un recurso basado en clases con una estructura de archivos
siguiente:

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

Nivel de gravedad: información

Descripción
Las funciones de los recursos de DSC tienen objetos devueltos específicos.

Para recursos no basados en clases:

Set-TargetResource no debe devolver ningún valor.

Test-TargetResource debe devolver un valor booleano.


Get-TargetResource debe devolver una tabla hash.

Para los recursos basados en clases:

Set no debe devolver ningún valor.

Test debe devolver un valor booleano.

Get debe devolver una instancia de la clase DSC.

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

Nivel de gravedad: Error

Descripción
Todos los recursos de DSC son necesarios para implementar las funciones correctas.

Para recursos no basados en clases:

Set-TargetResource

Test-TargetResource
Get-TargetResource

Para los recursos basados en clases:

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

Nivel de gravedad: error

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

class WaitForAny : OMI_BaseResource


{
[key, Description("Name of Resource on remote machine")]
string Name;

[required, Description("List of remote machines")]


string NodeName[];
};

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

Nivel de gravedad: error

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

Nivel de gravedad: información

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

Nivel de gravedad: advertencia

Descripción
Comprueba que las líneas no terminen con un retroceso seguido de un espacio en
blanco.
MissingModuleManifestField
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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.

Los manifiestos de módulo deben contener las siguientes claves (y un valor


correspondiente) para que se consideren válidos:

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

Nivel de gravedad: advertencia

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

Habilitar: bool (el valor predeterminado es $false )

Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

NoEmptyLineBefore: bool (el valor predeterminado es $false )

Cree una infracción si hay una línea vacía antes de una llave de cierre.

IgnoreOneLineBlock: bool (el valor predeterminado es $true )


Indica si los pares de llaves cerradas 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 regla no desencadena una infracción.

NewLineAfter: bool (el valor predeterminado es $true )


Indica si una nueva línea debe seguir una llave de cierre. Si se establece en true, una
llave de cierre debe ir seguida de una nueva línea.
PlaceOpenBrace
Artículo • 16/05/2023

Nivel de gravedad: advertencia

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

Habilitar: bool (el valor predeterminado es $false )

Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

OnSameLine: bool (el valor predeterminado es $true )

Exigir que la llave abierta esté en la misma línea que la de su palabra clave anterior.

NewLineAfter: bool (el valor predeterminado es $true )


Aplicar un nuevo carácter de línea después de una llave abierta. El valor predeterminado
es true.
IgnoreOneLineBlock: bool (el valor predeterminado es $true )

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

regla no desencadena una infracción.


PossibleIncorrectComparisonWithNull
Artículo • 02/05/2023

Nivel de gravedad: Advertencia

Descripción
Para asegurarse de que PowerShell realiza las comparaciones correctamente, el $null
elemento debe estar en el lado izquierdo del operador.

Hay varias razones por las que esto ocurre:

$null es un valor escalar. Cuando el valor del lado izquierdo de un operador es


escalar, los operadores de comparación devuelven un valor booleano . Cuando el
valor es una colección, los operadores de comparación devuelven cualquier valor
coincidente o una matriz vacía si no hay coincidencias en la colección.
PowerShell realiza la conversión de tipos de izquierda a derecha, lo que da lugar a
comparaciones incorrectas cuando $null se convierte a otros tipos escalares.

La única manera de comprobar de forma confiable si un valor es $null colocar $null


en el lado izquierdo del operador para que se realice una comparación escalar.

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)
{
}
}

Pruébelo usted mismo


PowerShell

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

En el ejemplo siguiente se muestra el comportamiento diseñado del operador de


comparación cuando el lado izquierdo es una colección. Cada elemento de la colección
se compara con el valor del lado derecho. Cuando es true, se devuelve ese elemento de
la colección.

PowerShell

PS> 1,2,3,1,2 -eq $null


PS> 1,2,3,1,2 -eq 1
1
1
PS> (1,2,3,1,2 -eq $null).count
0
PS> (1,2,$null,3,$null,1,2 -eq $null).count
2
PossibleIncorrectUsageOfAssignmentOp
erator
Artículo • 13/12/2022

Nivel de gravedad: información

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

if ($a = Get-Something) # Only execute action if command returns something


and assign result to variable
{
Do-SomethingWith $a
}

Suplantación implícita mediante el estilo Clang


Hay algunos casos poco frecuentes en los que la asignación de variable dentro de una
if instrucción es por diseño. En lugar de suprimir la regla, también puede indicar que la

asignación fue intencionada ajustando la expresión entre paréntesis adicionales. Una


excepción para esto es cuando $null se usa en LHS porque no hay ningún caso de uso
para esto.

PowerShell

if (($shortVariableName = $SuperLongVariableName['SpecialItem']
['AnotherItem']))
{
...
}
PossibleIncorrectUsageOfRedirectionOp
erator
Artículo • 13/12/2022

Nivel de gravedad: información

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

if ($a > $b)


{
...
}

Correcto
PowerShell

if ($a -gt $b)


{
...
}
ProvideCommentHelp
Artículo • 15/05/2023

Nivel de gravedad: información

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:

Escribir ayuda basada en comentarios


Escritura de la ayuda de los cmdlets de PowerShell
Creación de ayuda basada en XML mediante PlatyPS

Configuración
PowerShell

Rules = @{
PSProvideCommentHelp = @{
Enable = $true
ExportedOnly = $false
BlockComment = $true
VSCodeSnippetCorrection = $false
Placement = 'before'
}
}

Parámetros

Habilitar: bool (el valor predeterminado es $true )


Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

ExportedOnly: bool (el valor predeterminado es $true )


Si está habilitada, inicie una infracción solo en funciones o cmdlets que se exportan
mediante el Export-ModuleMember cmdlet .

BlockComment: bool (el valor predeterminado es $true )

Si está habilitada, devuelve ayuda de comentario en el estilo de comentario de bloque,


es decir, <#...#> . De lo contrario, devuelve ayuda de comentario en el estilo de
comentario de línea, es decir, cada línea de comentario comienza por # .

VSCodeSnippetCorrection: bool (el valor predeterminado es


$false )

Si está habilitado, devuelve la ayuda de comentarios en formato de fragmento de


código de vscode.

Ubicación: cadena (el valor predeterminado es before )


Representa la posición de la ayuda de comentario con respecto a la definición de
función.

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 .

before significa que la ayuda se coloca antes de la definición de la función. begin

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

Nivel de gravedad: error

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.

Los caracteres reservados incluyen: #,(){}[]&/\\$^;:\"'<>|?@`*%+=~

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

Nivel de gravedad: error

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

Nivel de gravedad: advertencia

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,

# this parameter is never called in the function


$Parameter2
)

Get-Something $Parameter1
}

Correcto
PowerShell

function Test-Parameter
{
Param (
$Parameter1,

# now this parameter is being called in the same scope


$Parameter2
)

Get-Something $Parameter1 $Parameter2


}
ShouldProcess
Artículo • 15/05/2023

Nivel de gravedad: advertencia

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

SupportsShouldProcess atributo pero no realiza ninguna llamada a o llama

ShouldProcess a ShouldProcess , pero no declara SupportsShouldProcess .

Para más información, consulte los siguientes artículos.

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
)

if ($PSCmdlet.ShouldProcess($Path, ("Setting content to '{0}'" -f


$Content)))
{
$Content | Out-File -FilePath $Path
}
else
{
# Code that should be processed if doing a WhatIf operation
# Must NOT change anything outside of the function / script
}
}
UseApprovedVerbs
Artículo • 13/12/2022

Nivel de gravedad: advertencia

Descripción
Todos los cmdlets deben usar verbos aprobados.

Para encontrar verbos aprobados, ejecute el comando Get-Verb .

Puede encontrar documentación adicional sobre verbos aprobados en Verbos


aprobados para comandos de PowerShell. Algunos verbos no aprobados se
documentan en la página de verbos aprobados y apuntan a alternativas aprobadas.
Intente buscar el verbo que usó para encontrar su formulario aprobado. Por ejemplo, la
Read búsqueda de , Open o Search le lleva a Get .

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

Nivel de gravedad: advertencia

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

Nivel de gravedad: Advertencia

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

Nivel de gravedad: Advertencia

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')
}
}
}

El parámetro compatibility es una lista que contiene cualquiera de las siguientes


opciones:

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

Nivel de gravedad: advertencia

Descripción
Esta regla identifica los comandos que no están disponibles en una plataforma de PowerShell de destino.

Una plataforma de PowerShell se identifica con un nombre en el formato siguiente:

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

<ps-version> : la versión de PowerShell (de $PSVersionTable.PSVersion ).

<ps-arch> : la arquitectura de la máquina del proceso de PowerShell.


<dotnet-version> : la versión notificada de PowerShell en tiempo de ejecución de .NET se ejecuta en (desde

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:

win-4_x64_10.0.18312.0_5.1.18312.1000_x64_4.0.30319.42000_framework es PowerShell 5.1 que se ejecuta en Windows 10

Enterprise (compilación 18312) para x64.


win-4_x64_10.0.18312.0_6.1.2_x64_4.0.30319.42000_core es PowerShell 6.1.2 que se ejecuta en el mismo sistema

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.

Las plataformas agrupadas de forma predeterminada son:

Versión de PowerShell Sistema operativo ID

3.0 Windows Server 2012 win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework

4.0 Windows Server 2012 R2 win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework

5,1 Windows Server 2016 win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework

5,1 Windows Server 2019 win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework

5,1 Windows 10 1809 (RS5) win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework

6,2 Windows Server 2016 win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core

6,2 Windows Server 2019 win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core

6,2 Windows 10 1809 (RS5) win-4_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core

6,2 Ubuntu 18.04 LTS ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core


Versión de PowerShell Sistema operativo ID

7.0 Windows Server 2016 win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core

7.0 Windows Server 2019 win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core

7.0 Windows 10 1809 (RS5) win-4_x64_10.0.17763.0_6.2.4_x64_3.1.2_core

7.0 Ubuntu 18.04 LTS ubuntu_x64_18.04_6.2.4_x64_3.1.2_core

Otros perfiles se pueden encontrar en el repositorio de GitHub .

También puede generar su propio perfil de plataforma mediante el módulo PSCompatibilityCollector .

La configuración del perfil de compatibilidad toma una lista de plataformas de destino en TargetProfiles . Se puede especificar
una plataforma como:

Un nombre de plataforma (como ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core ), que se agregará .json al final y se


buscará en el directorio de perfil predeterminado.
Un nombre de archivo (como my_custom_platform.json ), que se buscará en el directorio de perfil predeterminado.
Ruta de acceso absoluta a un archivo (como D:\PowerShellProfiles\TargetMachine.json ).

El directorio de perfil predeterminado se encuentra en el módulo PSScriptAnalzyer en $PSScriptRoot/compatibility_profiles


(donde $PSScriptRoot aquí hace referencia al directorio que contiene PSScriptAnalyzer.psd1 ).

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

Enable Activa la regla bool No (valor $true


( $true / $false ) predeterminado:
$false )

TargetProfiles Lista de string[]: rutas No (valor @('ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core', 'win-


perfiles de de acceso predeterminado: @() ) 48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')
PowerShell de absolutas a
destino archivos de
perfil o
nombres de
perfiles en el
directorio de
perfiles

ProfileDirPath Ubicación para string: ruta de No (el valor C:\Users\me\Documents\pssaCompatProfiles


buscar perfiles acceso predeterminado es
por nombre y absoluta al compatibility_profiles
uso para la nuevo dir de directory en el módulo
generación de perfil PSScriptAnalyzer
perfiles de
unión

IgnoreCommands Comandos string[]: No (valor @('Get-ChildItem','Import-Module')


para omitir la nombres de predeterminado: @() )
compatibilidad comandos que
de en scripts se omitirán

Una configuración de ejemplo podría ser similar a la siguiente:

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', '')]

La regla también se puede suprimir solo para determinados comandos:

PowerShell

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Start-Service')]

Además, solo se suprime para los parámetros:

PowerShell

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Import-
Module/FullyQualifiedName')]
UseCompatibleSyntax
Artículo • 15/05/2023

Nivel de gravedad: Advertencia

Descripción
Esta regla identifica los elementos de sintaxis incompatibles con las versiones de
PowerShell de destino.

No puede identificar elementos de sintaxis incompatibles con PowerShell 3 o 4 cuando


se ejecutan desde esas versiones de PowerShell porque no pueden analizar las sintaxis
incompatibles.

PowerShell

@{
Rules = @{
PSUseCompatibleSyntax = @{
Enable = $true
TargetVersions = @(
'6.0',
'5.1',
'4.0'
)
}
}
}
UseCompatibleTypes
Artículo • 16/05/2023

Nivel de gravedad: Advertencia

Descripción
Esta regla identifica los tipos que no están disponibles (cargados de forma predeterminada) en las plataformas de PowerShell
de destino.

Una plataforma de PowerShell se identifica mediante un nombre con el siguiente formato:

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

<ps-version> : la versión de PowerShell (de $PSVersionTable.PSVersion ).


<ps-arch> : la arquitectura de la máquina del proceso de PowerShell.

<dotnet-version> : la versión notificada de PowerShell en tiempo de ejecución de .NET se ejecuta en (desde


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:

win-4_x64_10.0.18312.0_5.1.18312.1000_x64_4.0.30319.42000_framework es PowerShell 5.1 que se ejecuta en Windows 10


Enterprise (compilación 18312) para x64.
win-4_x64_10.0.18312.0_6.1.2_x64_4.0.30319.42000_core es PowerShell 6.1.2 que se ejecuta en el mismo sistema
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.

Las plataformas agrupadas de forma predeterminada son:

Versión de PowerShell Sistema operativo ID

3.0 Windows Server 2012 win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework

4.0 Windows Server 2012 R2 win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework

5,1 Windows Server 2016 win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework

5,1 Windows Server 2019 win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework

5,1 Windows 10 1809 (RS5) win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework

6,2 Windows Server 2016 win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core

6,2 Windows Server 2019 win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core

6,2 Windows 10 1809 (RS5) win-4_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core

6,2 Ubuntu 18.04 LTS ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core


Versión de PowerShell Sistema operativo ID

7.0 Windows Server 2016 win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core

7.0 Windows Server 2019 win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core

7.0 Windows 10 1809 (RS5) win-4_x64_10.0.17763.0_6.2.4_x64_3.1.2_core

7.0 Ubuntu 18.04 LTS ubuntu_x64_18.04_6.2.4_x64_3.1.2_core

Puede encontrar otros perfiles en el repositorio de GitHub .

También puede generar su propio perfil de plataforma mediante el módulo PSCompatibilityCollector .

La configuración del perfil de compatibilidad toma una lista de plataformas de destino en TargetProfiles . Se puede especificar
una plataforma como:

Nombre de plataforma (como ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core ), que se agregará .json al final y se


buscará en el directorio de perfil predeterminado.
Un nombre de archivo (como my_custom_platform.json ), que se buscará en el directorio de perfil predeterminado.
Ruta de acceso absoluta a un archivo (como D:\PowerShellProfiles\TargetMachine.json ).

El directorio de perfil predeterminado está en el módulo PSScriptAnalzyer en


$PSScriptRoot/PSCompatibilityCollector/profiles (donde $PSScriptRoot aquí hace referencia al directorio que contiene
PSScriptAnalyzer.psd1 ).

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

Enable Activa la regla. bool No (valor $true


( $true / $false ) predeterminado:
$false )

TargetProfiles Lista de string[]: rutas No (valor @('ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core', 'win-


perfiles de de acceso predeterminado: @() ) 48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')
PowerShell de absolutas a
destino archivos de
perfil o
nombres de
perfiles en el
directorio de
perfiles

ProfileDirPath Ubicación que string: ruta de No (el valor C:\Users\me\Documents\pssaCompatProfiles


se va a buscar acceso predeterminado es
perfiles por absoluta al compatibility_profiles
nombre y uso nuevo dir de directory en el módulo
para la perfil PSScriptAnalyzer
generación de
perfiles de
unión
Clave de Significado Valores Mandatory Ejemplo
configuración aceptados

IgnoreTypes Nombres string[]: No (valor @('System.Collections.ArrayList','string')


completos de nombres de predeterminado: @() )
tipos o tipos que se
aceleradores omitirán
de tipos para
omitir la
compatibilidad
de en scripts

Una configuración de ejemplo podría ser similar a la siguiente:

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'
)
}
}
}

Como alternativa, puede proporcionar un objeto de configuración de la siguiente manera:

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''

RuleName Severity ScriptName Line Message


-------- -------- ---------- ---- -------
PSUseCompatibleTypes Warning 1 The type 'System.Management.Automation.SemanticVersion'
is
not available by default in PowerShell version
'5.1.17763.316' on platform 'Microsoft Windows 10 Pro'

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', '')]

La regla también se puede suprimir solo para determinados tipos:


PowerShell

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes',
'System.Management.Automation.Security.SystemPolicy')]

Y también se suprime solo para los miembros de tipo:

PowerShell

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands',
'System.Management.Automation.LanguagePrimitives/ConvertTypeNameToPSTypeName')]
UseConsistentIndentation
Artículo • 13/12/2022

Nivel de gravedad: Advertencia

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

Habilitar: bool (el valor predeterminado es $false )


Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

IndentationSize: int (el valor predeterminado es 4 )


Tamaño de sangría en el número de caracteres de espacio.

PipelineIndentation: cadena (el valor predeterminado es


IncreaseIndentationForFirstPipeline )

Si se va a aumentar la sangría después de una canalización para instrucciones de varias


líneas. Los parámetros son:
IncreaseIndentationForFirstPipeline (valor predeterminado): sangría una vez
después de la primera canalización y mantenga esta sangría. Ejemplo:

PowerShell

foo |
bar |
baz

IncreaseIndentationAfterEveryPipeline: sangría más después de la primera


canalización y mantenga esta sangría. Ejemplo:

PowerShell

foo |
bar |
baz

NoIndentation: No aumentar la sangría. Ejemplo:

PowerShell

foo |
bar |
baz

Ninguno: no cambie ninguna sangría de canalización existente.

Tipo: cadena (el valor predeterminado es space )

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 .

space significa IndentationSize que se usa el número de space caracteres para

proporcionar un nivel de sangría. tab significa un carácter de tabulación, \t .


UseConsistentWhitespace
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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
}
}

Habilitar: bool (el valor predeterminado es $false )


Habilite o deshabilite la regla durante la invocación de ScriptAnalyzer.

CheckInnerBrace: bool (el valor predeterminado es $true )


Comprueba si hay un espacio después de la llave de apertura y un espacio antes de la
llave de cierre. Por ejemplo, if ($true) { foo } en lugar de if ($true) {bar} .

CheckOpenBrace: bool (el valor predeterminado es


$true )
Comprueba si hay un espacio entre una palabra clave y su llave abierta correspondiente.
Por ejemplo, foo { } en lugar de foo{ } . Si una llave abierta va precedida de un
paréntesis abierto, no se requiere espacio.

CheckOpenParen: bool (el valor predeterminado es


$true )

Comprueba si hay espacio entre una palabra clave y su paréntesis abierto


correspondiente. Por ejemplo, if (true) en lugar de if(true) .

CheckOperator: bool (el valor predeterminado es $true )


Comprueba si un operador binario o unario está rodeado en ambos lados por un
espacio. Por ejemplo, $x = 1 en lugar de $x=1 .

CheckSeparator: bool (el valor predeterminado es $true )


Comprueba si una coma o un punto y coma va seguido de un espacio. Por ejemplo,
@(1, 2, 3) o @{a = 1; b = 2} en lugar de @(1,2,3) o @{a = 1;b = 2} .

CheckPipe: bool (el valor predeterminado es $true )


Comprueba si una canalización está rodeada en ambos lados por un espacio, pero
omite el espacio en blanco redundante. Por ejemplo, foo | bar en lugar de foo|bar .

CheckPipeForRedundantWhitespace : bool (el valor


predeterminado es $false )
Comprueba si una canalización está rodeada por espacios en blanco redundantes (es
decir, más de 1 espacio en blanco). Por ejemplo, foo | bar en lugar de foo | bar .

CheckParameter: bool (el valor predeterminado está


$false en el momento debido a que la configuración es
nueva)
Comprueba si hay más de un espacio entre parámetros y valores. Por ejemplo, foo -bar
$baz -bat en lugar de foo -bar $baz -bat . Esto elimina el espacio en blanco

redundante que probablemente se agregó involuntariamente. La regla no comprueba si


hay espacios en blanco entre el parámetro y el valor cuando se usa la sintaxis -
ParameterName:$ParameterValue de dos puntos, ya que algunos usuarios prefieren 0 o 1
espacio en blanco en este caso.

IgnoreAssignmentOperatorInsideHashTable: bool (el valor


predeterminado es $false )
Cuando CheckOperator se establece, omita el espacio en blanco alrededor de los
operadores de asignación dentro de las tablas hash de varias líneas. Establezca esta
opción para usar la AlignAssignmentStatement regla y seguir comprobando los espacios
en blanco alrededor de los operadores en cualquier otro lugar.
UseCorrectCasing
Artículo • 13/12/2022

Nivel de gravedad: información

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

invoke-command { 'foo' } -runasadministrator

Correcto
PowerShell

Invoke-Command { 'foo' } -RunAsAdministrator


UseDeclaredVarsMoreThanAssignments
Artículo • 16/05/2023

Nivel de gravedad: advertencia

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

Nivel de gravedad: Advertencia

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

$hashtable = New-Object -TypeName hashtable

Correcto
PowerShell

$hashtable = @{}
UseOutputType Incorrectamente
Artículo • 13/12/2022

Nivel de gravedad: información

Descripción
Un comando debe devolver el mismo tipo que se declara en OutputType .

Para obtener más detalles, ejecute Get-Help about_Functions_OutputTypeAttribute el


comando en PowerShell.

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

Nivel de gravedad: Advertencia

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

PS C:\> 1..5 | Get-Number


5

Correcto
PowerShell
Function Get-Number
{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline)]
[int]
$Number
)

process
{
$Number
}
}

Resultado

PS C:\> 1..5 | Get-Number


1
2
3
4
5
UsePSCredentialType
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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

Nivel de gravedad: Advertencia

Descripción
Funciones cuyos verbos cambian el estado del sistema deben admitir ShouldProcess .

Verbos que 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

Nivel de gravedad: advertencia

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

Nivel de gravedad: advertencia

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

Nivel de gravedad: Advertencia

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

FunctionToExport = @(Get-Foo, Set-Foo)


UseUsingScopeModifierInNewRunspace
s
Artículo • 13/12/2022

Nivel de gravedad: Advertencia

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:

Invoke-Command - Solo con el parámetro ComputerName o Session .


Workflow { InlineScript {} }

Foreach-Object - Solo con el parámetro Parallel


Start-Job

Start-ThreadJob

Recurso Script en configuraciones de DSC, específicamente para las


GetScript propiedades , TestScript y SetScript .

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 }

Ejemplos más correctos


PowerShell

$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

# Remark: Workflow is supported on Windows PowerShell only


Workflow {
$foo = "foo"
InlineScript { $using:foo }
}

PowerShell

$foo = "foo"
Start-ThreadJob -ScriptBlock { $using:foo }
Start-Job -ScriptBlock {$using:foo }
UseUTF8EncodingForHelpFile
Artículo • 13/12/2022

Nivel de gravedad: advertencia

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

El módulo SecretManagement ayuda a los usuarios a administrar secretos


proporcionando un conjunto común de cmdlets que interactúan con almacenes de
secretos. SecretManagement proporciona un modelo extensible donde se pueden
registrar almacenes locales y remotos para su uso. Esto le permite separar los detalles
específicos para acceder y administrar el almacén de los scripts que necesitan secretos.

Dado que SecretManagement es una capa de abstracción de módulo en PowerShell,


resulta útil una vez registrados los almacenes de extensiones. Hay ventajas y desventajas
entre la seguridad, la facilidad de uso y la especificidad de cualquier almacén, por lo que
es necesario que el usuario configure SecretManagement para que se integre con los
almacenes que mejor se ajusten a sus requisitos, así como para evaluar la medida en
que confía en las extensiones de almacén no desarrolladas por Microsoft.

SecretManagement no impone requisitos de autenticación para almacenes de


extensiones. Esto permite que cada almacén individual proporcione su propio
mecanismo. Algunos pueden requerir una contraseña o un token, mientras que otros
pueden aprovechar las credenciales de la cuenta actual.

SecretManagement habilita los siguientes escenarios clave:

Uso compartido de un script en toda la organización sin conocer el almacén local


de todos los usuarios
Ejecución del script de implementación en entornos locales, de prueba y de
producción con el cambio de un solo parámetro, Vault
Cambio del back-end del método de autenticación para satisfacer necesidades
específicas de seguridad u organización sin necesidad de actualizar todos mis
scripts

Ecosistema del almacén de extensiones


SecretManagement resulta útil una vez que se instalan y se registran almacenes de
extensiones. Los almacenes de extensiones, que son módulos de PowerShell con una
estructura determinada, proporcionan la conexión entre el módulo SecretManagement
y cualquier almacén de secretos local o remoto.
SecretStore es un módulo de extensión multiplataforma que implementa un almacén
local. El almacén de SecretStore almacena los secretos, localmente en un archivo, para
el usuario actual. Usa las API criptográficas de .NET Core para cifrar el contenido del
archivo. Este almacén de extensiones funciona en todas las plataformas que admiten
PowerShell 7.

Detección e instalación de extensiones de almacén


Para buscar los módulos del almacén de extensiones, busque la etiqueta
SecretManagement en la Galería de PowerShell.

Algunas extensiones del almacén de la comunidad que están disponibles:

Azure KeyVault (propiedad de Microsoft)


KeePass
LastPass
Hashicorp Vault
Llavero
CredMan

Comentarios y soporte técnico de la


comunidad
Los comentarios de la comunidad han sido esenciales para el desarrollo iterativo de
estos módulos. Para presentar problemas u obtener soporte técnico para la experiencia
de desarrollo de la interfaz SecretManagement o el almacén, use el repositorio
SecretManagement . Para problemas con el módulo SecretStore, use el repositorio
SecretStore .
Descripción de las características de
seguridad de SecretManagement y
SecretStore
Artículo • 13/12/2022

La seguridad de SecretManagement depende de los almacenes de extensiones que


hospeda. Estos almacenes realizan las funciones reales de almacenar y recuperar los
secretos. SecretManagement no devuelve secretos como texto sin formato de forma
predeterminada. De forma predeterminada, los secretos de texto se devuelven como
objetos SecureString a menos que el usuario solicite explícitamente el secreto como
texto sin formato mediante el modificador AsPlaintext .

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.

Un hash criptográfico valida el archivo de almacenamiento secreto para detectar daños


en archivos o alteraciones. Toda esta información está protegida por una sola clave
criptográfica y una contraseña opcional.

La configuración predeterminada de SecretStore requiere una contraseña. Sin embargo,


una contraseña es más difícil de administrar, ya que debe proporcionarse al configurar
por primera vez el almacén de SecretStore y proporcionarla de nuevo al acceder al
almacén.

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.

La configuración de SecretStore incluye un passwordTimeout, que limita la cantidad de


tiempo que el almacén permanece desbloqueado durante una sesión.

Un valor de tiempo de espera de -1 significa que el almacén permanece desbloqueado


durante toda la vida de la sesión. Esto es potencialmente menos seguro, pero resulta útil
cuando se ejecuta un script desatendido en una sola sesión. El almacén está
desbloqueado, con Unlock-SecretStore y permanece desbloqueado para toda la sesión.
La sesión se cierra cuando se completa el script.
El requisito de autenticación de contraseña también se puede desactivar por completo.
En este caso, no se requiere ninguna contraseña para acceder a los secretos desde una
cuenta de inicio de sesión y es mucho más cómodo. Los secretos siguen cifrados, pero
la clave para descifrar los secretos se almacena en el sistema de archivos de la cuenta de
usuario actual. La clave solo está protegida por la seguridad del sistema de archivos del
sistema operativo. Otras cuentas que tienen privilegios de lectura en archivos propiedad
de esa cuenta de usuario podrían detectar la clave. Por lo tanto, no se recomienda la
configuración sin contraseña para ningún sistema que necesite protecciones de
seguridad sólidas de los secretos almacenados.
Introducción al módulo SecretStore
Artículo • 13/12/2022

Los módulos SecretManagement y SecretStore están disponibles en el Galería de


PowerShell y se pueden instalar mediante comandos de PowerShellGet.

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

Creación de un almacén y adición de un secreto


En primer lugar, debe registrar el almacén. El parámetro Name es un nombre descriptivo
y puede ser cualquier cadena válida.

PowerShell

Register-SecretVault -Name SecretStore -ModuleName


Microsoft.PowerShell.SecretStore -DefaultVault

El parámetro DefaultVault convierte este almacén predeterminado.

Ahora puede crear un secreto.

PowerShell

Set-Secret -Name TestSecret -Secret "TestSecretPassword"

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

Vault SecretStore requires a password.


Enter password:
********
Enter password again for verification:
********

Ejecute Get-Secret para recuperar el secreto. El uso del modificador AsPlainText


devuelve el secreto como una cadena sin cifrar.

PowerShell

PS> Get-Secret -Name TestSecret -AsPlainText


TestSecretPassword

Para obtener la lista de todos los secretos, puede ejecutar:

PowerShell

PS> Get-SecretInfo

Name Type VaultName


---- ---- ---------
TestSecret String SecretStore

Vínculos relacionados
Register-SecretVault
Get-Secret
Set-Secret
Descripción del módulo
SecretManagement
Artículo • 13/12/2022

El propósito del módulo SecretManagement es proporcionar almacenamiento seguro y


acceso a secretos a través de almacenes de extensiones registrados. Los almacenes de
extensiones registrados son módulos de PowerShell que cumplen los requisitos del
módulo SecretManagement . Los almacenes de extensiones realizan el trabajo real de
autenticación y almacenan y recuperan secretos de forma segura. Un almacén de
extensiones puede almacenar secretos de forma local o remota para un almacén basado
en la nube.

El módulo SecretManagement proporciona comandos para registrar extensiones de


almacén y acceder a secretos del almacén. Esto reduce considerablemente la tentación
de codificar los secretos directamente en el código fuente de producción. En su lugar, el
módulo SecretManagement permite recuperar dinámicamente secretos en tiempo de
ejecución.

Los almacenes de extensiones se registran para el contexto de usuario actual. El registro


del almacén se almacena por separado de los archivos de datos del almacén. La
ubicación del archivo depende del sistema operativo de la plataforma.

Para las plataformas Windows, la ubicación es:


$env:LOCALAPPDATA\Microsoft\PowerShell\secretmanagement\secretvaultregistry\

Para las plataformas que no son de Windows, la ubicación es:


$HOME/.secretmanagement/secretvaultregistry/

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.

El módulo SecretManagement ayuda a los usuarios a administrar secretos


proporcionando un conjunto común de cmdlets para interactuar con secretos entre
almacenes. Para obtener una lista completa de cmdlets, consulte la página del módulo
Microsoft.PowerShell.SecretManagement en la documentación.
Creación de un almacén de extensiones
El valor de la interfaz SecretManagement procede del almacén subyacente y resulta
más útil con cada módulo del almacén de extensiones. Para obtener más información
sobre el diseño de SecretManagement y cómo compilar almacenes de extensiones,
consulte el documento de diseño en el repositorio SecretManagement . En este
documento se describe un módulo TestVault de implementación de referencia. Además,
revisar el código fuente del módulo SecretStore puede servir como ejemplo para los
autores de almacenes de extensiones que buscan crear almacenes existentes.

Cuentas administradas de Windows


SecretManagement no funciona actualmente para las cuentas administradas de
Windows. El módulo depende de ambas $env:LOCALAPPDATA carpetas para almacenar la
información del Registro y las API de Protección de datos de Windows (DPAPI) para
controlar de forma segura los secretos con el tipo SecureString de .NET. Las cuentas
administradas de Windows no tienen perfiles ni $env:LOCALAPPDATA carpetas y DPAPI no
admite cuentas administradas.
Administración de un almacén de
SecretStore
Artículo • 02/03/2023

El módulo SecretStore es un almacén de extensiones para el módulo


SecretManagement de PowerShell. Almacena secretos, localmente, en archivos para el
contexto de la cuenta de usuario actual y usa las API criptográficas de .NET para cifrar el
contenido del archivo. El módulo SecretStore tiene varias opciones de configuración. En
la configuración predeterminada, se requiere una contraseña para almacenar y acceder
a secretos, y proporciona la protección más segura. SecretStore también admite el
almacenamiento de metadatos sobre secretos.

Registro de un nuevo almacén


Para poder crear un nuevo secreto, debe registrar un almacén. El parámetro Name es un
nombre descriptivo y puede ser cualquier cadena válida.

PowerShell

Register-SecretVault -Name SecretStore -ModuleName


Microsoft.PowerShell.SecretStore -DefaultVault

) Importante

El módulo SecretManagement permite registrar un almacén de extensiones varias


veces, ya que es posible que un almacén de extensiones admita contextos
diferentes a través de VaultParameters de registro. Sin embargo, el almacén de
SecretStore actualmente siempre funciona en el ámbito de usuario que ha iniciado
sesión. El registro de varios almacenes de SecretStore con nombres diferentes solo
da como resultado la duplicación del mismo almacén.

Use el siguiente comando para ver una lista de almacenes registrados:

PowerShell

Get-SecretVault

Name ModuleName IsDefaultVault


---- ---------- --------------
Edge SecretManagement.Chromium False
SecretStore Microsoft.PowerShell.SecretStore True
En este ejemplo hay dos almacenes registrados mediante módulos de extensión
diferentes.

Configuración de un almacén
Use el cmdlet para ver la Get-SecretStoreConfiguration configuración de un almacén.

PowerShell

Get-SecretStoreConfiguration

Scope Authentication PasswordTimeout Interaction


----- -------------- --------------- -----------
CurrentUser Password 900 Prompt

Los almacenes de SecretStore tienen las siguientes opciones de configuración:

Autenticación - Password (valor predeterminado) o None


PasswordTimeout - 900 seconds (valor predeterminado)
Interacción - Prompt (valor predeterminado) o None

La configuración predeterminada requiere una contraseña, establece el tiempo de


espera de la contraseña de sesión en 15 minutos y solicita al usuario una contraseña
para desbloquear el almacén.

En el caso de escenarios de automatización no interactivos, la interacción se puede


configurar para None suprimir la solicitud del usuario. Si se requiere una contraseña, los
comandos del almacén devuelven la excepción
Microsoft.PowerShell.SecretStore.PasswordRequiredException si no hay ninguna
contraseña de sesión válida. El Unlock-SecretStore cmdlet se puede usar para
proporcionar la contraseña de la sesión actual de PowerShell. El almacén permanece
desbloqueado hasta que expire el tiempo de espera.

La configuración y los datos del almacén se almacenan en archivos independientes. La


ubicación del archivo depende del sistema operativo de la plataforma.

Para las plataformas Windows, la ubicación es:


$env:LOCALAPPDATA\Microsoft\PowerShell\secretmanagement\localstore\
En el caso de las plataformas que no son de Windows, la ubicación es:
$HOME/.secretmanagement/localstore/
Cambio de la configuración
Puede cambiar la configuración de un almacén mediante el Set-
SecretStoreConfiguration cmdlet . El cmdlet proporciona los parámetros

Authentication, PasswordTimeout y Interaction que se usan para cambiar las


propiedades de configuración correspondientes. También hay un parámetro Default
para restablecer la configuración a los valores predeterminados.

Hay dos maneras de establecer la contraseña en el almacén.

1. El Set-SecretStoreConfiguration cmdlet tiene el parámetro Password que toma un


valor SecureString .
2. El Set-SecretStorePassword cmdlet cambia la contraseña del almacén. El cmdlet no
toma parámetros y solo se puede usar de forma interactiva. Se le pedirán las
contraseñas antiguas y nuevas.

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

Para crear un nuevo secreto con metadatos:

PowerShell

$metadata = @{
Purpose = 'Testing'
Expires = (Get-Date).AddDays(30)
Limit = 5
}
Set-Secret -Name TestSecret -Secret NewSecret -Metadata $metadata

Para ver los metadatos secretos, puede ejecutar el comando :


PowerShell

Get-SecretInfo -Name TestSecret | Format-List *

Name : TestSecret
Type : String
VaultName : SecretStore
Metadata : {[Limit, 5], [Expires, 6/23/2022 1:45:09 PM], [Purpose,
Testing]}

También puede establecer metadatos para un secreto existente mediante el Set-


SecretInfo cmdlet :

PowerShell

Set-SecretInfo TestSecret -Metadata @{Purpose = "showing the new cmdlet"}


Get-SecretInfo -Name TestSecret | Select-Object Metadata

Metadata
--------
{[Purpose, showing the new cmdlet]}

U Precaución

Esto sobrescribe los metadatos existentes con los nuevos valores.

Restablecimiento o eliminación de un almacén


El Reset-SecretStore cmdlet restablece el almacén de SecretStore eliminando todos los
datos secretos y configurando el almacén con opciones predeterminadas. Está pensado
para usarse solo cuando se pierde la contraseña necesaria o se dañan los archivos de
datos. Las opciones de configuración predeterminadas se pueden invalidar
especificando parámetros de opción de configuración de comandos individuales.

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

En este artículo se proporciona un ejemplo para usar un almacén


Microsoft.PowerShell.SecretStore en un escenario de automatización. Un almacén de
SecretStore proporciona una manera de almacenar y recuperar de forma segura las
contraseñas, los tokens y otros secretos que necesita usar en la canalización de
automatización en el equipo local.

La configuración del host ejecuta la


automatización.
Para este ejemplo, primero debe instalar y configurar los módulos SecretManagement.
En este ejemplo se supone que el host de automatización ejecuta Windows. Estos
comandos deben ejecutarse en el contexto de usuario de la cuenta de automation en el
host.

PowerShell

Install-Module -Name Microsoft.PowerShell.SecretStore -Repository PSGallery


-Force
Install-Module -Name Microsoft.PowerShell.SecretManagement -Repository
PSGallery -Force
Import-Module Microsoft.PowerShell.SecretStore
Import-Module Microsoft.PowerShell.SecretManagement

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

PS> $credential = Get-Credential -UserName 'SecureStore'

PowerShell credential request


Enter your credentials.
Password for user SecureStore: **************

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

A continuación, debe configurar el almacén de SecretStore . La configuración establece


la interacción None del usuario en , de modo que SecretStore nunca solicite al usuario.
La configuración requiere una contraseña y la contraseña se pasa como un objeto
SecureString . El -Confirm:false parámetro se usa para que PowerShell no solicite
confirmación.

PowerShell

Register-SecretVault -Name SecretStore -ModuleName


Microsoft.PowerShell.SecretStore -DefaultVault
$password = Import-CliXml -Path $securePasswordPath

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

Uso de secretos en la automatización


La contraseña de SecretStore debe proporcionarse de forma segura. Aquí se importa la
contraseña desde un archivo que se cifró mediante La protección de datos de Windows
(DPAPI).

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.

El script de automatización debe desbloquear el almacén para recuperar los secretos


necesarios en el script. El Unlock-SecretStore cmdlet se usa para desbloquear
SecretStore para esta sesión. El tiempo de espera de contraseña se configuró durante 1
hora. El almacén permanece desbloqueado en la sesión durante esa cantidad de tiempo.
Después del tiempo de espera, el almacén debe desbloquearse de nuevo antes de que
se pueda acceder a los secretos.

PowerShell

$password = Import-CliXml -Path $securePasswordPath


Unlock-SecretStore -Password $password
$automationPassword = Get-Secret -Name CIJobSecret
Uso de Azure Key Vault en la
automatización
Artículo • 13/12/2022

En este artículo se proporciona un ejemplo de uso de Azure Key Vault en un escenario


de automatización. Azure Key Vault proporciona una manera de almacenar y recuperar
de forma segura las contraseñas, los tokens y otros secretos, que se almacenan fuera del
equipo local y los usan en la canalización de automatización.

Configuración del host que ejecuta la


automatización
A partir de Az.KeyVault 3.3.0, el módulo incluye una extensión SecretManagement que
permite usar los cmdlets SecretManagement para interactuar con los secretos
almacenados en Azure Key Vault.

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 .

A continuación, registre el almacén mediante AZKVaultName y SubscriptionId. Estos


comandos se deben ejecutar en el contexto de usuario de la cuenta de automation en el
host de automatización.

PowerShell

Install-Module -Name Microsoft.PowerShell.SecretManagement -Repository


PSGallery -Force
Install-Module Az.KeyVault -Repository PSGallery -Force
Import-Module Microsoft.PowerShell.SecretManagement
Import-Module Az.KeyVault

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

También podría gustarte