Blog ENI : Toute la veille numérique !
💥 Un livre PAPIER acheté
= La version EN LIGNE offerte pendant 1 an !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. PowerShell
  3. Workflows
Extrait - PowerShell Fonctionnalités avancées (2e édition)
Extraits du livre
PowerShell Fonctionnalités avancées (2e édition)
1 avis
Revenir à la page d'achat du livre

Workflows

Introduction

Les workflows sont apparus avec la version 3.0 de PowerShell. Pour rappel, c’est Windows Server 2012 et Windows 8 qui ont apporté cette version. À ce moment-là, la notion de cloud était bien présente et la virtualisation avait déjà quasiment conquis toutes les entreprises. Il était donc commun de se retrouver à administrer plusieurs centaines, voire milliers de serveurs Windows. Comment procéder alors ? L’équipe PowerShell a répondu à cette question par les workflows ou flux de travail.

Les workflows sont définis et gérés par la Windows Workflow Foundation (WWF). Il s’agit d’une technologie présente dans le framework .NET depuis sa version 3. PowerShell interagit avec cette technologie via un format de données nommé XAML. On retrouve ce format dans la conception d’interfaces graphiques WPF (voir le chapitre Création d’interfaces graphiques). Le moteur WWF interprète simplement les fichiers XAML sans se soucier de leur provenance. Ce qui fait que les workflows ne sont pas spécifiques à PowerShell. Ils peuvent être utilisés par d’autres applications.

L’objectif de ce chapitre est de vous initier à l’utilisation de cette technologie tout en vous mettant en garde sur les pièges que vous pourriez rencontrer. Il s’agit...

Création d’un workflow

1. Mot-clé workflow

Pour créer un workflow, il y a un mot-clé à connaître : workflow. La syntaxe affiliée à ce mot-clé est quasiment semblable à celle d’une fonction avancée. À la différence près que l’instruction [CmdletBinding()] n’autorise que certains attributs.

Syntaxe

workflow <Verbe-Nom> { 
    [CmdletBinding()] 
    param( 
        <bloc de paramètre> 
   ) 
    <Traitement du workflow..> 
} 

Le nom d’un workflow a la même forme que celui d’une fonction : Verbe-Nom. Pour plus de détails, référez-vous au chapitre Fonctions avancées.

Création du premier workflow :

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

L’utilisation de Write-Output est privilégiée à celle de Write-Host. En effet, cette dernière commande fait partie des restrictions qui seront vues plus loin.

Tout comme les fonctions, il est possible de lister les workflows grâce à la commande Get-Command, en lui spécifiant la valeur workflow sur le paramètre -CommandType.

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

Le workflow est bien présent.

La présence du workflow peut également être constatée dans le provider function:\.

2. Gestion des paramètres

Comme il a été dit, les workflows acceptent la mise en place de paramètres. Il existe plusieurs types de paramètres. On retrouve les paramètres communs, ceux contenus dans le bloc param(), et les paramètres propres aux workflows....

Restrictions

On ne peut pas faire ce que l’on veut avec les workflows. Ils ont des restrictions techniques provenant directement de leur mode de fonctionnement. Pour rappel, ils sont traduits en fichier XAML décrivant des activités, exécutés en tant que job, et transitent à travers le service WinRM. Cela fait beaucoup pour réussir à garder un mode de fonctionnement semblable à celui d’un script ou d’une fonction PowerShell standard.

Globalement, on garde ces éléments en tête quand on utilise un workflow :

  • restriction de langage

  • usage des variables limité

  • sérialisation et désérialisation des objets

  • impossible d’utiliser les alias de paramètres et l’appel des paramètres par leur position

1. Restrictions de commande

De ce fait, une partie des commandes de base de PowerShell n’ont pas leur équivalent en activité de workflow, et donc en XAML. En voici une liste non exhaustive :

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

On a également l’ensemble des commandes de formatage (Format-*) qui est exclu, ainsi que toute commande demandant une action de la part de l’utilisateur.

Des commandes ne sont exécutables qu’en 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. Restrictions sur les objets

Avec la sérialisation et la désérialisation des objets, on est confronté...

Exécution en parallèle

1. Bloc parallel

Les workflows offrent la possibilité de réaliser des actions de manière simultanée. Par défaut, les activités sont réalisées de manière séquentielle. La seconde activité attend que la première ait terminé son traitement pour démarrer. Pour qu’elle démarre en parallèle, on utilise le mot-clé parallel à l’intérieur du workflow. Ce mot-clé est d’ailleurs spécifique au workflow, comme InlineScript.

Syntaxe :

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

De manière générale, la parallélisation d’actions indépendantes les unes des autres est un véritable gain de temps. C’est bien sûr le cas dans le traitement d’un workflow.

Soit un traitement qui dure en moyenne 20 secondes, et un second 40 secondes. On obtient ainsi un traitement de 1 minute :

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 

On introduit l’instruction parallel :

PS > workflow Test-WfwPara { 
    parallel...

Points de synchronisation

Un workflow a la capacité de s’inscrire sur le disque pour sauvegarder son état d’avancement. De cette manière, si un problème inattendu survient, il est possible de reprendre là où le workflow a été sauvegardé pour la dernière fois. Parmi, les problèmes inattendus, on peut trouver un redémarrage, une coupure réseau ou une coupure électrique, plus impactante.

Ces sauvegardes sont nommées checkpoints. Pour les habitués de virtualisation sous Hyper-V, ce mot est familier. Il s’agit d’une capture du disque d’une machine virtuelle à un instant donné. Pour un workflow, c’est en quelque sorte la même chose. Le workflow est inscrit dans le dossier Appdata de l’utilisateur exécutant le workflow. L’arborescence complète est $env:LocalAppData\Microsoft\Windows\PowerShell\ WF\PS\. Les checkpoints sont sauvegardés dans des fichiers au format XML. Ils sont supprimés lorsque le workflow est terminé ou supprimé.

La gestion des checkpoints se fait via trois éléments. Le premier est la commande Checkpoint-Workflow à positionner à l’intérieur du workflow. Elle demande au workflow de réaliser un checkpoint et donc une inscription sur le disque. Dans l’exemple suivant, la fonctionnalité...

Suspension d’un workflow

Dans le chapitre Jobs et parallélisation, la notion de l’état suspendu d’un job a été abordée. Ce cas se présente seulement si le job est de type PSWorkflowJob. Pour qu’un workflow entre dans un état Suspended, il existe deux possibilités. La première est l’utilisation de la commande Suspend-Job directement sur le job du workflow en cours.

Exemple de syntaxe

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

L’utilisation de la commande Suspend-Job implique que le workflow soit lancé en tant que job grâce...

Relance d’un workflow (suite à une suspension ou à un crash)

Après qu’un workflow a été suspendu, on cherche généralement à relancer son traitement. Pour réaliser cela, on utilise la commande Resume-Job. Cette dernière, tout comme la commande Suspend-Job, n’est utilisable que sur des jobs de type PSWorkflowJob. Pour récupérer les différents jobs d’un workflow, il est possible d’appeler directement la commande 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-... 

On tente maintenant de relancer le second job :

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

Observation du contenu d’un workflow

Comme on le dit depuis le début de ce chapitre, les workflows sont représentés sous forme XAML. Il est possible de connaître cette forme, car elle est contenue dans une propriété de l’objet workflow. Pour récupérer cet objet, on utilise la commande Get-Command et on pointe ensuite sur la propriété qui nous intéresse. Ici, il s’agit de XamlDefinition. Reprenons notre premier exemple pour éviter un affichage trop complexe à appréhender :

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

On utilise ensuite la commande Get-Command :

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

Puis, on affine l’affichage pour montrer le code 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..." ...

Intégration dans un module

Les workflows se déclarent de la même manière que les fonctions. Il n’est donc pas surprenant de pouvoir les porter à travers un module. Le procédé est identique à celui mis en œuvre pour une fonction. Il suffit d’ajouter la déclaration du workflow au fichier PSM1 d’un module. Pour plus d’informations sur la création d’un module, référez-vous au chapitre Création de modules.

Exemple du contenu d’un fichier PSM1

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

Pour utiliser le workflow, il suffit d’importer le module et de lancer la commande :

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

Workflow : pour qui ? pour quoi ?

Les workflows sont un formidable outil malgré leur complexité de mise en œuvre et les limites qu’ils imposent. Toutefois, on peut sérieusement se poser la question de leur utilité aujourd’hui, surtout avec des outils comme DSC (voir le chapitre Desired State Configuration (DSC)) permettant la gestion de configuration de systèmes avec prise en charge de redémarrage. En outre, la version 6.0 Core de PowerShell ne dispose pas des workflows. Les développeurs ont dû faire un choix lors du portage de la solution vers le monde libre et ont choisi de les mettre de côté.

Pour l’ensemble de ces raisons, il est recommandé d’utiliser les workflows dans des cas précis, pour s’épargner quelques déboires :

  • Lorsque le traitement nécessite plus de 6 heures.

  • Lorsque le traitement pourrait être perturbé par des coupures réseau ou des redémarrages intempestifs.

  • Lorsque le traitement nécessite une forte parallélisation et un séquençage des actions. 

  • Lorsque aucune autre solution ne répond correctement à la problématique.

Gardez quand même à l’esprit qu’un workflow passe par une mécanique complexe avant de s’exécuter réellement. Par exemple, utiliser un workflow pour récupérer...