1. Libros y videos
  2. PowerShell
  3. Workflows
Extrait - PowerShell Funcionalidades avanzadas
Extractos del libro
PowerShell Funcionalidades avanzadas Volver a la página de compra del libro

Workflows

Introducción

Los workflows (flujos de trabajo) se introdujeron con la versión 3.0 de PowerShell. Como recordatorio, fueron Windows Server 2012 y Windows 8 los que trajeron esta versión. En aquella época, la noción de nube estaba bien asentada y la virtualización ya había conquistado prácticamente todas las empresas. Por lo tanto, era habitual gestionar varios cientos o incluso miles de servidores Windows. Entonces, ¿cómo hacerlo? El equipo de PowerShell respondió a esta pregunta con flujos de trabajo.

Los flujos de trabajo son definidos y gestionados por la Windows Workflow Foundation (WWF). Esta tecnología está presente en la plataforma .NET desde la versión 3. PowerShell interactúa con esta tecnología a través de un formato de datos llamado XAML. Este formato se utiliza en el diseño de interfaces gráficas WPF (véase el capítulo Creación de interfaces gráficas). El motor WWF simplemente interpreta los archivos XAML sin preocuparse de su procedencia. Esto significa que los workflows no son exclusivos de PowerShell y pueden ser utilizados por otras aplicaciones.

El objetivo de este capítulo es introducirte en el uso de esta tecnología, advirtiéndote al mismo tiempo de los obstáculos que puede encontrar. Se trata de una herramienta formidable, con posibilidades y casos de uso que van más...

Creación de un workflow

1. Palabra clave workflow

Para crear un workflow, es necesario conocer una palabra clave: workflow. La sintaxis asociada a esta palabra clave es casi idéntica a la de una función avanzada. La única diferencia es que la instrucción [CmdletBinding()] solo autoriza determinados atributos.

Sintaxis

workflow <Verbe-Nom> {  
    [CmdletBinding()]  
    param(  
        <bloque de parámetros>  
   )  
    <procesamiento del workflow ...>  
} 

El nombre de un workflow tiene la misma forma que el de una función: Verbo-nombre. Para más detalles, consulte el capítulo Funciones avanzadas.

Creación del primer workflow:

workflow Demo-Workflow {  
    Write-Output "I am a flow"  
} 

Se recomienda usar Write-Output en lugar de Write-Host. Esta última es una de las restricciones que se explicarán más adelante.

Al igual que las funciones, los flujos de trabajo pueden listarse mediante el comando Get-Command, especificando el valor del workflow en el parámetro -CommandType.

PS > Get-Command -CommandType workflow  
  
CommandType     Name                       Version    Source  
-----------     ----                       -------    ------  
workflow        Demo-Workflow 

El workflow está presente.

La presencia del workflow también puede verificarse en el proveedor function:\.

2. Gestión de parámetros

Como ya se ha mencionado, los workflows permiten la configuración de parámetros. Existen varios tipos de parámetros. Hay parámetros comunes, los contenidos en el bloque param(), y parámetros específicos de los workflows.

a. Parámetros comunes

Los flujos de trabajo aceptan parámetros comunes, como -Verbose o -ErrorAction. Por lo tanto, puede...

Restricciones

No se puede hacer cualquier cosa con los workflows. Tienen limitaciones técnicas que derivan directamente de su modo de funcionamiento. Como recordatorio, se traducen en archivos XAML que describen actividades, se ejecutan como jobs y dependen del servicio WinRM. Eso implica gestionar muchos elementos para mantener un funcionamiento similar al de un script o función estándar de PowerShell.

En general, hay que tener en cuenta los siguientes aspectos al utilizar un workflow: 

  • restricción de lenguaje

  • uso limitado de variables

  • serialización y deserialización de objetos

  • no es posible utilizar alias de parámetros ni pasar parámetros por posición.

1. Restricciones en los comandos

En consecuencia, algunos de los comandos básicos de PowerShell no tienen equivalente como actividad de workflow, y por lo tanto no son compatibles con XAML. He aquí una lista no exhaustiva:

Add-History

Add-PSSnapin

Clear-History

Clear-Variable

Complete-Transaction

Connect-Wsman

Debug-Process

Disable-PSBreakpoint

Disconnect-Wsman

Enable-PSBreakpoint

Enter-PSSession

Exit-PSSession

Export-Alias

Export-Console

Get-Alias

Get-History

Get-PSBreakpoint

Get-PSCallStack

Get-PSSnapin

Get-Transaction

Get-Variable

Import-Alias

Invoke-History

New-Alias

New-Variable

Out-GridView

Remove-PSSnapin

Remove-Variable

Set-Alias

Set-PSBrealkpoint

Set-PSDebug

Set-StrictMode

Set-Variable

Start-Transaction

Start-Transcript

Stop-Transcript

Trace-Command

Undo-Transaction

Use-Transaction

Write-Host

También se excluye el conjunto de comandos de formato (Format-*), así como cualquier comando que requiera la acción del usuario.

Algunos comandos solo pueden ejecutarse en el sistema local:

Add-Member

Compare-Object

ConvertFrom-Csv

ConvertFrom-Json

Convert-From-StringData

Convert-Path

ConvertTo-Csv

ConvertTo-Html

ConvertTo-Json

ConvertTo-Xml

Foreach-Object

Get-Host

Get-Member

Get-Random

Get-Unique

Group-Object

Measure-Command

Measure-Object

New-PSSessionOption

New-PSTransportOption

New-TimeSpan

Out-Default

Out-Host

Out-Null

Out-String

Select-Object

Sort-object

Update-List

Where-Object

Write-Debug

Write-Error

Write-Host

Write-OutPut

Write-Progress

Write-Verbose

 

2. Restricciones sobre los objetos

La serialización y deserialización de objetos presenta el mismo problema que en una sesión remota de PowerShell. Es posible acceder a las propiedades, pero no invocar métodos...

Ejecución en paralelo

1. Bloque parallel

Los workflows permiten realizar acciones simultáneamente. Por defecto, las actividades se realizan secuencialmente. La segunda actividad espera hasta que la primera haya terminado de procesarse antes de comenzar. Para iniciarlas en paralelo, utilice la palabra clave parallel dentro del flujo de trabajo. Esta palabra clave también es específica del workflow, como InlineScript.

Sintaxis:

workflow <verb-noun> {  
    parallel {  
           #Actividad 1  
           #Actividad 2  
    }  
} 

En general, el paralelismo en acciones independientes entre sí permite ahorrar mucho tiempo. Este es obviamente el caso cuando se procesa un workflow.

Así, un primer proceso dura una media de 20 segundos, y un segundo, de 40 segundos. Esto da como resultado un tiempo de procesamiento de 1 minuto:

PS > workflow Test-WfwPara {  
    Start-Sleep -Second 20  
    Start-Sleep -Second 40  
}  
PS > Measure-Command { Test-WfwPara }  
  
Days              : 0  
Hours             : 0  
Minutes           : 1  
Seconds           : 0  
Milliseconds      : 750  
Ticks             : 607502613  
TotalDays         : 0,000703128024305556  
TotalHours        : 0,0168750725833333  
TotalMinutes      : 1,012504355  
TotalSeconds      : 60,7502613  
TotalMilliseconds : 60750,2613 

Se introduce ahora la instrucción parallel:

PS > workflow Test-WfwPara {  
    parallel {  
           Start-Sleep...

Puntos de sincronización

Un workflow puede guardarse en disco para conservar su progreso. De este modo, si se produce un problema inesperado, es posible reanudar el workflows donde se guardó por última vez. Los imprevistos pueden incluir reinicios, interrupciones de red o incluso cortes eléctricos importantes.

Estas copias de seguridad se denominan puntos de control (checkpoints). Para quienes están familiarizados con la virtualización Hyper-V, este término resulta familiar. Es una instantánea del disco de una máquina virtual en un momento dado. Para un workflow, es prácticamente lo mismo. El workflow se escribe en la carpeta Appdata del usuario que ejecuta el workflow. El árbol completo es $env:LocalAppData\Microsoft\Windows\PowerShell\ WF\PS\. Los checkpoints se guardan en archivos con formato XML. Estos se eliminan cuando el workflow se completa o se elimina.

Los checkpoints se gestionan mediante tres elementos. El primero es el comando Checkpoint-Workflow, que se sitúa dentro del workflow. Solicita al flujo de trabajo que cree un punto de control y lo escriba en disco. En el siguiente ejemplo, la funcionalidad Hyper-V se activa en un cliente Windows, al igual que la funcionalidad HostGuardian. Entre estas dos acciones, se genera un punto de control.

Ejemplo de sintaxis

PS > workflow EnableHyperV {  
    Enable-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V  ...

Suspensión de un workflow

En el capítulo Jobs y paralelismo, se explicó el concepto de estado suspendido de un job. Esto solo es aplicable cuando el trabajo es de tipo PSWorkflowJob. Para que un workflow entre en estado Suspended, existen dos posibilidades. La primera consiste en utilizar el comando Suspend-Job directamente en el job del flujo de trabajo actual.

Ejemplo de sintaxis

PS > workflow Test-WfwSuspend {  
    Foreach ($num in 1..10) {  
        $num  
        CheckPoint-Workflow  
        Start-Sleep -Seconds $num  
    }  
}   
  
PS > $WorkflowJob = Test-WfwSuspend -AsJob  
  
PS > Suspend-Job -Job $WorkflowJob  
  
Id Name  PSJobTypeName State      HasMoreData  Location   Command   
-- ----  ------------- -----      -----------  --------   -------   
3  Job3  PSWorkflowJob Suspending True         localhost  Test-... 

El uso del comando Suspend-Job requiere que el workflow se inicie como un job utilizando el parámetro...

Reiniciar un workflow (tras una suspensión o un crash)

Después de suspender un workflow, generalmente se desea reanudar su ejecución. Esto se hace utilizando el comando Resume-Job. Este comando, al igual que Suspend-Job, solo se puede utilizar con trabajos de tipo PSWorkflowJob. Para recuperar los diferentes Jobs de un workflow, se puede llamar directamente al comando Get-Job:

PS > Get-Job  
  
Id Name  PSJobTypeName State      HasMoreData  Location  Command   
-- ----  ------------- -----      -----------  --------  -------   
3  Job3  PSWorkflowJob Suspending True         localhost Test-...   
5  Job5  PSWorkflowJob Suspending True         localhost Test-... 

Ahora estamos intentando relanzar el segundo trabajo:

PS > Get-Job -ID 5 | Resume-Job  
  
Id Name  PSJobTypeName State      HasMoreData  Location  Command   
-- ----  ------------- -----      -----------  --------  -------   
5  Job5  PSWorkflowJob Running    True         localhost Test-......

Observación del contenido de un workflow

Como se mencionó al principio de este capítulo, los workflows se representan en forma XAML. Es posible conocer dicha estructura, ya que está contenida en una propiedad del objeto del flujo de trabajo. Para recuperar este objeto, se utiliza el comando Get-Command y luego apunte a la propiedad de interés. En este caso, es XamlDefinition. Volvamos a nuestro primer ejemplo para evitar una visualización demasiado compleja de entender:

workflow Demo-Workflow {  
   Write-Output "I am a flow"  
} 

A continuación, utilice el comando Get-Command:

PS > Get-Command Demo-Workflow   
  
CommandType     Name                  Version    Source   
-----------     ----                  -------    ------   
workflow        Demo-Workflow     

A continuación, se refina la visualización para mostrar el código XAML:

PS > Get-Command Demo-Workflow | Foreach-Object XamlDefinition  
<Activity  
    x:Class="Microsoft.PowerShell.DynamicActivities.Activity_..."  
    xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activ..."  
    xmlns:sad="clr-namespace:System.Activities.Debugger;assem..."  ...

Integración en un módulo

Los workflows se declaran del mismo modo que las funciones. Por lo tanto, no es de extrañar que también puedan definirse dentro de un módulo. El proceso es idéntico al utilizado para una función. Basta con añadir la declaración del workflow en el archivo PSM1 del módulo. Para más información sobre cómo crear un módulo, consulte el capítulo Creación de módulos.

Ejemplo de contenido de un archivo PSM1

PS > Get-Content ./MyModule.psm1  
  
workflow Demo-Workflow {  
    Write-Output "I am a flow"  
} 

Para utilizar el workflow, basta con importar el módulo y ejecutar el comando:

PS > Import-Module ./MyModule.psm1  
PS > Demo-Workflow  
I am a flow 

Workflow: ¿para quién? ¿por qué?

Los workflows son una herramienta maravillosa, a pesar de la complejidad de su implementación y de las limitaciones que conllevan. Sin embargo, hoy en día podemos cuestionar seriamente su utilidad, especialmente con herramientas como DSC (véase el capítulo Desired State Configuration (DSC)) que permiten gestionar la configuración de sistemas con soporte de reinicio. Además, la versión 6.0 Core de PowerShell no incluye workflows. Los desarrolladores tuvieron que tomar una decisión al trasladar la solución al mundo libre y optaron por dejarlos fuera.

Por todo ello, es aconsejable utilizar workflows solo en casos concretos, para evitar contratiempos:

  • Cuando la ejecución del proceso supere las 6 horas.

  • Cuando exista riesgo de interrupciones por fallos de red o reinicios inesperados. 

  • Cuando se requiere un alto grado de paralelismo y secuenciación de acciones.

  • Cuando no existe una alternativa más simple o moderna que resuelva el mismo problema.

Tenga en cuenta, sin embargo, que un workflow pasa por un proceso complejo antes de ejecutarse realmente. Por ejemplo, utilizar un workflow para recuperar la lista de servicios de varias máquinas no es eficiente. Preferimos utilizar PSRemoteJob para esto. Su activación es mucho más rápida, porque no se necesita la compilación en XAML. En resumen, evite...