Fundamentos de Scripting en PowerShell

PowerShell Logo

Variables y Ámbitos de PowerShell

Variables

Una variable es una ubicación de almacenamiento con nombre en la memoria de una computadora que contiene un valor que puede cambiar.

El signo $ al principio indica una variable.

$i = 1
$string = "Hola Mundo!"
$this_is_a_variable = "prueba"

Las variables se utilizan para almacenar valores simples, cadenas y también la salida de comandos.

$date = Get-Date
Write-Host "Hoy es" $date

Tipos de Datos

PowerShell asigna automáticamente un tipo de datos a una variable según el tipo que mejor se adapte a su contenido.

Usando el comando Get-Type para averiguar el tipo de datos de una variable:

$x = 4
$string = "Hola Mundo!"
$date = Get-Date

$x.GetType().Name
$string.GetType().Name
$date.GetType().Name

Resumen de Tipos de Datos

Tipo Descripción
[string] System.String. Una cadena simple
[char] Carácter Unicode de 16 bits
[byte] Carácter sin signo de 8 bits
[int], [int32] Entero con signo de 32 bits
[long] Entero con signo de 64 bits
[bool] Booleano: Puede ser Verdadero o Falso
[decimal] Decimal de 128 bits
[single], [float] Número de punto flotante de precisión simple de 32 bits
[double] Número de punto flotante de precisión doble de 64 bits
[datetime] Fecha y hora
[array] Matriz de valores
[hashtable] Objeto de tabla hash
[guid] Identificador Único Global (GUID)
[psobject], [PSCustomobject] Objeto de PowerShell
[scriptblock] Bloque de script de PowerShell
[regex] Expresión Regular
[timespan] Objeto de intervalo de tiempo

Conversión de Variables (Casting)

Convierte el tipo de datos de una variable casteándolo a otro tipo.

$number = "4"
$number.GetType().Name    # Tipo de dato String

# Convertir cadena a enteros
$int_number = [int]$number
$int_number.GetType().Name   # Int32

# Convertir una cadena hexadecimal Unicode en un carácter
[char]0x263a

Variables Automáticas

Variables integradas que son creadas y mantenidas por PowerShell.

Get-ChildItem -Path C:\ -Directory -Force -ErrorAction SilentlyContinue | ForEach-Object {
    Write-Host $_.FullName
}

Variables de Entorno

Almacenan información sobre el sistema operativo y las rutas que el sistema utiliza con frecuencia.

Para mostrar todas las variables de entorno dentro de una sesión, use dir env:

Accediendo y reutilizando variables anteponiendo $env:

# Accediendo al valor de PSModulePath.
$env:PSModulePath

Palabras Reservadas y Palabras Clave del Lenguaje

Palabras que están reservadas por el sistema y no deben usarse como nombres de variables o funciones.

# Más información sobre palabras reservadas
Get-Help about_reserved_words

# Obtener una descripción general detallada y explicación de todas las palabras clave del lenguaje:
Get-Help about_Language_Keywords

Resumen de Todas las Palabras Clave del Lenguaje

Begin Enum Param
Break Exit Process
Catch Filter Return
Class Finally Static
Continue For Switch
Data ForEach Throw
Define From Trap
Do Function Try
DynamicParam Hidden Until
Else If Using
Elseif In Var
End InlineScript While
# Aprender más sobre una palabra clave específica del lenguaje
Get-Help break

# Encontrar páginas de ayuda que hablen sobre la palabra que estamos buscando
Get-Help filter -Category:HelpFile

Ámbito de Variables

El ámbito de variable determina dónde se puede acceder a una variable dentro de un script, función o sesión.

En general, las variables solo están disponibles en el contexto en el que se establecen.

# Establecer el ámbito de la variable $ModuleRoot a script
$script:ModuleRoot = $PSScriptRoot

Modificador de Ámbito

Las variables con ámbito global definidas en un módulo están disponibles en la sesión una vez que se carga el módulo.

function Set-Variables {
    $local_variable = "Hola, soy una variable local."
    $script:script_variable = "Hola, soy una variable de script."
    $global:global_variable = "Hola, soy una variable global."

    Write-Host "################################################################"
    Write-Host "Así se ven nuestras variables en la función, donde definimos las variables - en un ÁMBITO LOCAL:"
    Write-Host " Local: " $local_variable
    Write-Host " Script: " $script_variable
    Write-Host " Global: " $global_variable
}

Set-Variables

Write-Host "########################################################"
Write-Host "Así se ven nuestras variables en el mismo script - en un ÁMBITO DE SCRIPT:"
Write-Host " Local: " $local_variable
Write-Host " Script: " $script_variable
Write-Host " Global: " $global_variable

Primero se declara la función Set-Variable, una vez que se llama a la función, establece variables de tres ámbitos.

############################################################
Así se ven nuestras variables en la función, donde definimos las variables - en un ÁMBITO LOCAL:
Local: Hola, soy una variable local.
Script: Hola, soy una variable de script.
Global: Hola, soy una variable global.
############################################################
Así se ven nuestras variables en el mismo script - en un ÁMBITO DE SCRIPT:
Local:
Script: Hola, soy una variable de script.
Global: Hola, soy una variable global.

Llamando a variables con ámbito local, de script y global.

Al trabajar con variables de ámbito script y global, es una buena práctica usar siempre la variable con el modificador: $script:script_variable/$global:global_variable

Operadores

Operadores Aritméticos

# Suma
$a = 3; $b = 5; $result = $a + $b

# Resta
$a = 3; $b = 5; $result = $b - $a

# Multiplicación
$a = 3; $b = 5; $result = $a * $b

# División
$a = 3; $b = 5; $result = $a / $b

# Módulo
$a = 12; $b = 4; $result = $a % $b

Operadores de Comparación

$a = 1; $b = 1; $a -eq $b
$a = 1; $b = 2; $a -ne $b
$a = 1; $b = 2; $a -le $b
$a = 1; $b = 2; $a -ge $b
$a = 1; $b = 2; $a -lt $b
$a = 1; $b = 2; $b -gt $a
"PowerShell" -like "*owers*"
True

Usado en un contexto de matriz, el operador -like devuelve solo los elementos que coinciden con la expresión comodín especificada.

"PowerShell", "Perro", "Gato", "Cobaya" -like "*owers*"
PowerShell
"PowerShell" -notlike "*owers*"
False

Usado en un contexto de matriz, el operador -notlike devuelve solo los elementos que no coinciden con la expresión comodín especificada.

"PowerShell", "Perro", "Gato", "Cobaya" -notlike "*owers*"
Perro
Gato
Cobaya
"Cybersecurity scripting in PowerShell 7.3" -match "shell\s*(\d)"
True

# shell: Coincide con la palabra literal "shell".
# \s*: Coincide con cero o más caracteres de espacio en blanco.
# (\d): Captura un solo dígito (0-9) en un grupo de captura.

"PowerShell Scripting and Automation" -notmatch "^Cyb"

Operadores de Asignación

= : Asigna un valor

$a = 1; $a

+= : Aumenta el valor por la cantidad definida después del operador y almacena el resultado en la variable inicial.

$a += 1; $a += 2; $a

-= : Disminuye el valor por la cantidad definida después del operador y almacena el resultado en la variable inicial.

$a -= 1; $a

*= : Multiplica el valor por la cantidad definida después del operador y almacena el resultado en la variable inicial.

$a *= 5; $a

/= : Divide el valor por la cantidad definida después del operador y almacena el resultado en la variable inicial.

$a /= 2; $a

%= : Realiza una operación de módulo en la variable usando la cantidad después del operador y almacena el resultado en la variable inicial.

$a %= 2; $a

++ : Aumenta la variable en 1

$a = 1; $a++; $a

-- : Disminuye la variable en 1

$a = 10; $a--; $a

Operadores Lógicos

-and : Combina condiciones, la acción se activa solo si se cumplen ambas condiciones.

$a = 1; $b = 2
if (($a -eq 1) -and ($b -eq 2)) {Write-Host "¡La condición es verdadera!"}

-or : Si se cumple una de las condiciones definidas, se activa la acción.

$a = 2; $b = 2
if (($a -eq 1) -or ($b -eq 2)) {Write-Host "¡La condición es verdadera!"}

not o ! : Se utilizan para negar una condición.

$path = $env:TEMP + "\TestDirectory"
if (-not (Test-Path -Path $path)) {
    New-Item -ItemType directory -Path $path
}

if (!(Test-Path -Path $path)){
    New-Item -ItemType directory -Path $path
}

-xor : O exclusivo lógico. Es True si solo una declaración es True (pero devuelve False si ambas son True).

$a = 1; $b = 2; ($a -eq 1) -xor ($b -eq 1)

Estructuras de Control

Una estructura de control es una lógica que evalúa condiciones y variables y decide qué acción definida tomar si se cumple cierta condición.

Condiciones

if / elseif / else :

Sintaxis:

if (<condición>)
{
    <acción>
}
elseif (<condición>)
{
    <acción 2>
}
...
else
{
    <acción 3>
}

Código:

$color = "verde"
if ($color -eq "azul") {
    Write-Host "¡El color es azul!"
}
elseif ($color -eq "verde") {
    Write-Host "¡El color es verde!"
}
else {
    Write-Host "¡Ese también es un color muy bonito!"
}
# devuelve: ¡El color es verde!

Switch

Comprueba una variable con una larga lista de valores.

Sintaxis:

switch (<valor a probar>) {
    <condición 1> {<acción 1>}
    <condición 2> {<acción 2>}
    <condición 3> {<acción 3>}
    ...
    default {}
}

Código:

$color = Read-Host "¿Cuál es tu color favorito?"
switch ($color){
    "azul" { Write-Host "Soy AZUL, Da ba dee da ba di..." }
    "amarillo" { Write-Host "El AMARILLO es el color de mi equipo de IPL favorito." }
    "rojo" { Write-Host "¡Esté alerta!" }
    "púrpura" { Write-Host "¡Lluvia PÚRPURA, lluvia púrpura!" }
    "negro" { Write-Host "Hombres de negro..." }
    default { Write-Host "El color no está en esta lista" }
}

• Usando expresión regular:
- El parámetro Regex permite el uso de expresiones regulares para coincidir con la entrada.

switch -Regex ($userInput){
    "^[A-Z]" { "La entrada del usuario comienza con una letra." }
    "^[0-9]" { "La entrada del usuario comienza con un número." }
    default { "La entrada del usuario no comienza con una letra o número" }
}

• Procesando el contenido de un archivo:
El parámetro -wildcard permite el uso de lógica comodín en el código.

$path = $env:TEMP + "\ejemplo.txt"
switch -wildcard -File $path {
    "*Error*" { Write-Host "¡Se encontró un error!: $_" }
}

Bucles e Iteraciones

Ejecuta una acción una y otra vez hasta que se cumple una determinada condición.

ForEach-Object:

Acepta una lista o una matriz de elementos y permite realizar una acción contra cada uno de ellos.

❌ Mejor caso de uso cuando se canalizan objetos de tubería a ForEach-Object.

• Procesando todos los archivos que están en una carpeta:

$path = $env:TEMP + "\baselines"
Get-ChildItem -Path $path | ForEach-Object {Write-Host $_}

○ Para realizar acciones específicas antes de procesar cada elemento, use los parámetros Begin y End.
○ Use el parámetro -process para especificar el bloque de script que se ejecuta para cada elemento en la canalización.

Foreach:

Funciona de manera similar a foreach-Object, pero no acepta objetos de canalización.

La declaración Foreach carga todos los elementos en una colección antes de que se procesen, lo que la hace más rápida pero consume más memoria que foreach-Object.

Código:

declaración foreach:

$path = $env:TEMP + "\baselines"
$items = Get-ChildItem -Path $path

foreach ($file in $items){
    Write-Host $file
}

método foreach:

$path = $env:TEMP + "\baselines"
$items = Get-ChildItem -Path $path

$items.foreach({ 
    Write-Host "Elemento actual: $_"
})

La variable $_ se utiliza para hacer referencia al elemento actual que se está iterando.

while:

Hace algo () siempre que la condición definida sea True.
Sintaxis:

while (<condición>) { <acción> }

Código:

while (($input = Read-Host -Prompt "Elige un comando (escribe 'help' para ver una descripción general)") -ne "quit") {
    switch($input) {
        "hola" {Write-Host "¡Hola Mundo!"}
        "color" {Write-Host "¿Cuál es tu deporte favorito?"}
        "help" {Write-Host "Opciones: 'hola', 'color', 'help', 'quit'"}
    }
}

for:

Define la declaración de inicialización, una condición y recorre hasta que la condición definida no se cumple.
Sintaxis:

for (<declaración de inicialización>; <condición>; <repetir>)
{
    <acciones>
}

Código:

for ($i=1; $i -le 5; $i++) {Write-Host "i: $i"}

do-until / do-while:

Comienza ejecutando los comandos definidos y luego verifica si la condición aún se cumple o no.

Sintaxis:

do{
    <acción>
}
<while/until> <condición>

do-while se ejecuta mientras la condición sea True, do-until se ejecuta mientras la condición no se cumpla.

break:

Se utiliza para salir del bucle.

Código:

for ($i=1; $i -le 10; $i++) {
    Write-Host "i: $i"
    if ($i -eq 3) {break}
}

continue:

Se utiliza para omitir la iteración actual de un bucle y pasar a la siguiente.

Código:

for ($i=1; $i -le 10; $i++) {
    if (($i % 2) -ne 0) {continue}
    Write-Host "i: $i"
}

Convenciones de Nomenclatura

Tanto los cmdlets como las funciones siguen el esquema verbo-sustantivo, como Get-Help o Stop-Process.

Microsoft ha publicado una lista de verbos aprobados.

Encontrar los verbos aprobados

Comando Get-Verb para obtener la lista de verbos aprobados.

# Por el nombre "Verbo"
Get-Verb | Sort-Object Verb

# Usando comodines para prefiltrar la lista:
Get-Verb re*

# Listar verbos de cierto grupo (en este caso el grupo Security):
Get-Verb | Where-Object Group -eq Security

Perfiles de PowerShell

Los perfiles de PowerShell son archivos de configuración que permiten personalizar el entorno de PowerShell.

Los perfiles son scripts que se ejecutan cuando se inicia una sesión de PowerShell, permiten establecer variables, definir funciones, crear alias y más.

Tipos de perfiles de PowerShell

Un host de PowerShell es una aplicación que aloja el motor de PowerShell.

Los hosts de PowerShell incluyen la consola de Windows PowerShell, el Entorno de Scripting Integrado (ISE) de PowerShell y la terminal de PowerShell en Visual Studio Code.

Encontrar la ubicación de los perfiles locales de PowerShell:

$PROFILE | Format-List * -force

• Se aplica a shells locales y todos los usuarios: windows\system32\WindowsPowerShell\v1.0\profile.ps1
• Se aplica a todos los shells y todos los usuarios: windows\system32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
• Se aplica a todos los shells ISE locales y todos los usuarios: windows\system32\WindowsPowerShell\v1.0\Microsoft.PowerShellISE_profile.ps1

Este perfil se carga cuando se usa PowerShell ISE y se puede ver ejecutando el comando $profile | fl -force dentro de ISE.

• Se aplica a los shells ISE del usuario actual en el host local: %userProfile%\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

Acceder a la ruta del archivo de un perfil particular:

# Sintaxis:
# $profile.<nombre del perfil>

# Acceder a la ruta del perfil CurrentUserCurrentHost
$profile.CurrentUserCurrentHost

Crear un perfil de usuario:

• Comprobar si el archivo de perfil ya existe, si no, crear uno.

if (!(Test-Path $profile.CurrentUserCurrentHost)) {
    New-Item -ItemType File -Path $profile.CurrentUserCurrentHost
}

• Agregar los comandos, funciones o alias al perfil de usuario:

Add-Content -Path $profile -Value "New-Alias -Name Get-Ip -Value ipconfig.exe"

Comprender las PSDrives

Las unidades de PowerShell (PSDrives) en PowerShell son similares a las unidades del sistema de archivos en Windows, pero en lugar de acceder a archivos o carpetas, use PSDrives para acceder a una variedad de almacenes de datos.

Los almacenes de datos incluyen directorios, claves del registro y otras fuentes de datos.

Las PSDrives son impulsadas por PSProviders, que son componentes subyacentes que proporcionan acceso a los almacenes de datos.

Env: es una unidad de PowerShell integrada que proporciona acceso a las variables de entorno.

Para acceder a una PSDrive, use un prefijo especial en la ruta, como hacemos con C: para acceder a la unidad del sistema de archivos.

Recuperando todas las variables de entorno con la cadena path en su nombre:

Get-ChildItem Env:\*path*

PSDrives integradas en PowerShell incluyen:

Hacer que tu código sea reutilizable

La reutilización es un aspecto importante de la codificación que permite crear una función, cmdlet o módulo una vez y usarlo múltiples veces sin tener que reescribir el mismo código una y otra vez.

Cmdlets

Comando de PowerShell que realiza una tarea específica y puede escribirse en C# o en otro lenguaje .NET.

- Para encontrar todos los cmdlets que están actualmente instalados en la máquina:

Get-Command -CommandType Cmdlet

Funciones

Las funciones son una colección de comandos de PowerShell que deben ejecutarse siguiendo una cierta lógica.

Estructura Básica de una Función:

function Verbo-Sustantivo {
<#
<Texto de ayuda opcional>
#>
param(
    [tipo de datos] $Parámetro
)
<...Código: Lógica de la Función...>
}

Llamar a una Función:

Verbo-Sustantivo -Parámetro "prueba"

Parámetros:

Permiten pasar valores a las funciones, mejorando su flexibilidad y reutilización.

Definir parámetros:

function Invoke-Greeting {
    param (
        [string] $Nombre
    )
    Write-Output "¡Hola $Nombre!"
}

CmdletBinding:

CmdletBinding es una característica en PowerShell que permite agregar parámetros comunes como (-Verbose, -Debug, -ErrorAction) a funciones y cmdlets sin definirlos.

- [CmdletBinding()] hace que las funciones de PowerShell se comporten como cmdlets avanzados.

Hacer un parámetro obligatorio en una función:

function Invoke-Greeting {
    [cmdletbinding()]
    param (
        [Parameter(Mandatory)]
        [string] $Nombre
    )
    Write-Output "¡Hola $Nombre!"
}

SupportsShouldProcess:

Agregando [CmdletBinding(SupportsShouldProcess)], habilita los parámetros -WhatIf y -Confirm en la función.

Para usar SupportsshouldProcess efectivamente, necesitará llamar a ShouldProcess() para cada elemento que se esté procesando.

Código de Ejemplo:

function Invoke-Greeting {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        $Nombre
    )
    foreach ($item in $Nombre) {
        if ($PSCmdlet.ShouldProcess($item)) {
            Write-Output "¡Hola $item!"
        }
    }
}

Aceptar entrada a través de la canalización:

Aceptar entrada a través de la canalización se puede hacer de dos maneras, por valor o por nombre de propiedad.

1. Por Valor (Parámetros Posicionales):
Acepta la entrada pasando valores directamente a los parámetros de la función al llamarla, y PowerShell coincide automáticamente con los parámetros posicionales.

2. Por Nombre de Propiedad (Parámetros con Nombre):
Especifique los nombres de los parámetros al llamar a la función. Esto permite pasar argumentos en cualquier orden.

Código de Ejemplo:

function Invoke-Greeting {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String] $Nombre
    )
    process {
        Write-Output "¡Hola $Nombre!"
    }
}

Llamar a la Función:

1. Por Valor:

"Alicia", "Roberto" | Invoke-Greeting

2. Por nombre de propiedad:

[pscustomobject]@{Nombre = "Prash"} | Invoke-Greeting

Ayuda basada en comentarios:

Los comentarios simplifican el ajuste o la reutilización del código de la función.

<#
.SYNOPSIS
<Describe la función brevemente.>

.DESCRIPTION
<Descripción más detallada de la función.>

.PARAMETER Nombre
<Agrega una sección para describir cada parámetro, si la función tiene uno o más parámetros.>

.EXAMPLE
<Ejemplo de cómo llamar a la función>

<Describe qué sucede si se ejecuta la llamada de ejemplo.>
#>

Manejo de Errores:

try{
    New-PSSession -ComputerName $Computadora -ErrorAction Stop
}
catch {
    Write-Warning -Message "No se pudo conectar a la Computadora: $Computadora"
}

• Establecer ErrorAction en Stop tratará el error como un error terminante.

• Como se detectan errores terminantes, se activa la acción definida en el bloque catch.

Demo: Script de PowerShell Integral

function Write-Helloword(){
    <#
    .SYNOPSIS
    Esta función escribe "¡Hola Mundo!" en la línea de comandos.
    .DESCRIPTION
    Esto es solo para fines de aprendizaje
    .PARAMETER Identidad
    Si se especifica el parámetro, se agrega un saludo individual.
    .EXAMPLE
    Write-Helloword -Identidad "prash"

    Escribe la salida "¡Hola Mundo! ¡Hola prash!"
#>

    [cmdletbinding()]
    param(
        [string]$Identidad
    )
    if (![string]::IsNullOrEmpty($Identidad)) {
        $appendStr = " ¡Hola $Identidad!"
    }
    else{
        $appendstr = ""
    }

    Write-Host "¡Hola Mundo!$appendStr"
}

# Llamar a la función sin parámetro
Write-Helloword

# Llamar a la función con el parámetro de identidad agregado
Write-Helloword -Identidad "prash"

Diferencia entre cmdlets y script cmdlets (funciones avanzadas):

Aspecto Cmdlets Script Cmdlets (Funciones Avanzadas)
Implementación Escritos en un lenguaje compilado como C# Escritos en lenguaje de scripting de PowerShell
Rendimiento Más rápidos y eficientes debido a la compilación Ligeramente más lentos debido a la interpretación
Complejidad Más complejos de desarrollar y requieren compilación Más fáciles de escribir, modificar y depurar
Implementación Empaquetados como un DLL y cargados a través de módulos Incluidos en scripts o módulos como archivos .ps1
Extensibilidad Puede acceder a todo el poder del framework .NET Limitado a lo que el scripting de PowerShell puede lograr
Ejemplo Get-Process (cmdlet integrado) function Get-Helloworld { [CmdletBinding()] ... }
Caso de Uso Cuando el rendimiento y las operaciones de bajo nivel son importantes Para tareas de automatización más simples y desarrollo rápido

Alias

Los alias son nombres abreviados o alternativos para cmdlets, funciones, scripts o comandos.

• Para ver todos los cmdlets disponibles que tienen la palabra Alias en el nombre:

Get-Command -Name "*Alias*"

Trabajar con Alias:

Get-Alias:
Para ver todos los alias que están actualmente configurados en la computadora.

CommandType Name Version Source
--- --- --- ---
Alias 2 -> Where-Object
Alias 3 -> ForEach-Object
Alias ac -> Add-Content
Alias cat -> Get-Content
Alias cd -> Set-Location
Alias chdir -> Set-Location
Alias clc -> Clear-Content
Alias clear -> Clear-Host
Alias clhy -> Clear-History
Alias cli -> Clear-Item
Alias clp -> Clear-ItemProperty
Alias cls -> Clear-Host
Alias clv -> Clear-Variable
Alias cnsn -> Connect-PSSession
Alias compare -> Compare-Object
Alias copy -> Copy-Item
Alias cp -> Copy-Item
Alias cpi -> Copy-Item
Alias cpp -> Copy-ItemProperty
Alias cvpa -> Convert-Path
Alias db -> Disable-PSBreakpoint
Alias del -> Remove-Item
Alias diff -> Compare-Object
Alias dir -> Get-ChildItem
Alias dnsn -> Disconnect-PSSession

Salida del comando Get-Alias

Get-Alias también se puede usar para comprobar si existe un alias específico usando el parámetro -Name.

New-Alias:
Use New-Alias para crear un nuevo alias dentro de la sesión actual de PowerShell.

New-Alias -Name Get-IP -Value ipconfig

💡 Estos alias no se establecen permanentemente, por lo que una vez que salga de la sesión, el alias no funcionará más.
Para hacer estos alias permanentes, configúrelos en el perfil de PowerShell.

Export-Alias:
Exporta uno o más alias con Export-Alias.

Exportar todos los alias a un archivo .csv:

Export-Alias -Path "alias.csv"

Exportar todos los alias como script que se puede ejecutar:

Export-Alias -Path "alias.ps1" -As Script

Exportar un solo alias usando el parámetro -Name:

Export-Alias -Path "alias.ps1" -Name Get-Ip -As Script

Import-Alias:
Se utiliza para importar alias desde un archivo a la sesión actual de PowerShell.

Importando los alias exportados anteriormente a través de un archivo:

Import-Alias -Path .\alias.csv

Salida del alias GetIp

Módulos

Los módulos son una colección de comandos y funciones de PowerShell que se pueden enviar e instalar fácilmente en otros sistemas.

💡 Todos los módulos instalados en el sistema se pueden encontrar en las carpetas PSModulePath, parte de la PSDrive Env:\

Get-Item -Path Env:\PSModulePath

Trabajar con módulos:

1. Encontrar e instalar módulos
Busque módulos usando Find-Module -Name <nombredelmódulo>, que consulta los repositorios que están configurados en el sistema operativo.

Instale el módulo en el sistema local usando Install-Module <nombredelmódulo>:

- Actualizar módulo con Update-Module <nombredelmódulo> -Force:

[Administrator PowerShell 7 (64)]
PS C:\Users\Administrator\Desktop\awesome-powerShell> Install-Module EventList
Installing package 'PowerList' [Installing Commanding package 'PSFramework'
Installing package 'PSFramework' [Copying unsigned package to "C:\Users\Administrator\AppData\Local\Temp\X86Hosts4.|

- Para ver qué repositorios están disponibles en el sistema usando Get-PSRepository:

[Administrator PowerShell 7 (64)]
PS C:\Users\Administrator\Desktop\awesome-powerShell> Get-PSRepository

Name InstallationPolicy SourceLocation
--- --- ---
PSGallery Untrusted https://www.powershellgallery.com/api/v2

La Galería de PowerShell (PowerShell Gallery) es el repositorio central para contenido de PowerShell, que contiene miles de módulos útiles, scripts y recursos de Configuración de Estado Deseado (DSC).

Usar la Galería de PowerShell para instalar módulos directamente requiere que NuGet y PowerShellGet estén instalados.

Configurar PSGallery como repositorio confiable:

Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
[Administrator PowerShell 7 (64)]
PS C:\Users\Administrator\Desktop\awesome-powerShell> Get-PSRepository

Name InstallationPolicy SourceLocation
--- --- ---
PSGallery Trusted https://www.powershellgallery.com/api/v2

- Para encontrar módulos ya disponibles en la sesión actual usando Get-Module:

Lista de todos los módulos disponibles en la sesión actual

- Para ver qué módulos están disponibles para importar, incluidos los que vienen preinstalados con Windows, usando Get-Module -ListAvailable:

Lista de todos los módulos disponibles

- Para encontrar qué comandos están disponibles en un módulo usando Get-Command -Module <nombredelmódulo>:

Listando todos los comandos disponibles de un módulo

- Para conocer el uso de un comando específico, use Get-Help -Full <comando>:

PS C:\> Get-Help -Full Open-EventListGUI

NAME
Open-EventListGUI

SYNOPSIS
Opens the EventList GUI.

SYNTAX
Open-EventListGUI [<CommonParameters>]

DESCRIPTION
Opens the EventList GUI.

PARAMETERS
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).

Obteniendo la página de ayuda de un comando

• Descarga el módulo de la sesión actual usando Remove-Module <nombredelmódulo>:

Administrator PowerShell 7 (64)
PS C:\Users\Administrator> Get-Module

ModuleType Version PreRelease Name ExportedCommands
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-It…}
Script 2.3.5 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, …}
PS C:\Users\Administrator> Remove-Module PSReadLine
PS C:\Users\Administrator> Get-Module

ModuleType Version PreRelease Name ExportedCommands
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-It…}

Eliminando el módulo PSReadLine de la sesión actual

2. Crear tus propios módulos:
Para hacer que las funciones sean más fáciles de enviar a otros sistemas, crear un módulo es una gran manera.

Archivos más necesarios comúnmente vistos en módulos: archivo .psm1 y archivo .psd1.

• El archivo .psm1 contiene la lógica de scripting que debe proporcionar el módulo, y también puede usarlo para importar otras funciones dentro de un módulo.

• El archivo .psd1 es el manifiesto del módulo, que incluye información sobre el módulo.

Desarrollar un módulo básico:

El archivo de módulo termina con la extensión de archivo .psm1

1. Defina la ruta donde se debe guardar el módulo en la variable $path.

2. Use el cmdlet New-ModuleManifest para crear un nuevo archivo de manifiesto de módulo.

3. El parámetro -RootModule especifica el nombre del archivo de módulo de PowerShell.

4. Usando el cmdlet Set-Content, cree el archivo Module.psm1 que contiene la lógica del código.

$path = $env::TEMP + "\MyModule\"
if (!(Test-Path -Path $path)) {
    New-Item -ItemType directory -Path $path
}
New-ModuleManifest -Path $path\MyModule.psd1 -RootModule MyModule.psm1
Set-Content -Path $path/MyModule.psm1 -Value {
    function Invoke-Greeting{
        [Cmdletbinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string] $Name
        )
        "Hello $Name!"
    }
}
Administrator: PowerShell 7 (x64) --- □

PowerShell 7.4.6
PS C:\Users\Administrator> notepad
PS C:\Users\Administrator> notepad .\createModule.ps1
PS C:\Users\Administrator> .\createModule.ps1

Directory: C:\Users\ADMINI~1\AppData\Local\Temp

Mode LastWriteTime Length Name
--- --- --- ---
d---- 12/15/2024 2:17 AM MyModule

Ejecutando el código anterior

Para usar el módulo en una sesión de PowerShell, impórtelo directamente en la sesión o cópielo en una de las rutas de PSModule.

Las rutas de PSModule son directorios que se buscan para módulos cuando se usa el cmdlet Import-Module.

• Para ver la ruta de PSModule usando $env:PSModulePath:

5. Copie el directorio del módulo a la ubicación de la ruta de PSModule

6. Importe el módulo a la sesión actual usando Import-Module MyModule:

Import-Module MyModule

O
• Importando el módulo directamente desde la ruta de PSModule:

Import-Module $env::TEMP\MyModule\MyModule.psd1

6. Llamando a la función que se definió en el módulo MyModule:

Invoke-Greeting -Name "Prashant"

Las Opciones del Manifiesto del Módulo permiten especificar el autor, la descripción o los módulos que se requieren para instalar el módulo, usando la tabla hash RequiredModules.

Herramientas como PSModuleDevelopment vale la pena explorarlas.

Lecturas Adicionales

  1. Espacio de Nombres System: https://learn.microsoft.com/en-us/dotnet/api/system
  2. Espacio de Nombres System.Management.Automation: https://learn.microsoft.com/en-us/dotnet/api/system.management.automation
  3. about_Automatic_Variables: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables
  4. about_Environment_Variables: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables
  5. about_Scopes: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes
  6. about_Comparison_Operators: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators
  7. about_Assignment_Operators: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_assignment_operators
  8. about_Operators: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators
  9. ForEach-Object: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object
  10. about_Break: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_break
  11. Verbos Aprobados para Comandos de PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands
  12. Pautas de Desarrollo Fuertemente Alentadas: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/strongly-encouraged-development-guidelines
  13. Resumen de Cmdlet: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/cmdlet-overview
  14. Conceptos de Cmdlet de Windows PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/windows-powershell-cmdlet-concepts
  15. about_Functions_CmdletBindingAttribute: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_cmdletbindingattribute
  16. Conceptos Básicos de PowerShell para Profesionales de Seguridad Parte 6 – Pipeline por Carlos Perez: https://youtube.com/watch?v=P3ST3lat9bs
  17. About Pipelines: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipelines
  18. about_Aliases: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_aliases
  19. Galería de PowerShell: https://www.powershellgallery.com/
  20. Escribir un Módulo de Windows PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/developer/module/writing-a-windows-powershell-module
  21. PowerShell Framework: https://psframework.org/documentation/documents/psmoduledevelopment.html
  22. Todo lo que quieres saber sobre matrices: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays
  23. Todo lo que quieres saber sobre tablas hash: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-hashtable
  24. Todo lo que quieres saber sobre $null: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-null
  25. Todo lo que quieres saber sobre PSCustomObject: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-pscustomobject
  26. Acerca de las funciones: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions
  27. Funciones 101: https://docs.microsoft.com/en-us/powershell/scripting/learn/ps101/09-functions
  28. Acerca de los parámetros avanzados de las funciones: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters
  29. Cmdlets versus funciones: https://www.leeholmes.com/blog/2007/07/24/cmdlets-vs-functions/
  30. Páginas de ayuda de módulos: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_modules