IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Enchainement de scripts powershell


Sujet :

Scripts/Batch

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut Enchainement de scripts powershell
    Bonjour,

    Débutant en powershell, je souhaiterai savoir si quelqu'un peut me donner un exemple de la structure d'un script powershell qui bouclerai sur un fichier texte comprenant une liste de script et qui les executerai en série avec récupération du $lastexitcode et en fonction du retour soit lancer le script suivant de la liste soit stopper le script..
    Une espèce de script chapeau qui pilote d'autres scripts.
    voila merci d'avance.

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lavocatb Voir le message
    Bonjour,
    ... qui les executerai en série avec récupération du $lastexitcode
    Utilise les exceptions et les blocs try/catch, le $lastexitcode est dédié au process externe.
    Une solution :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    $File='c:\temp\test.txt'
    @'
    c:\temp\un.ps1
    c:\temp\deux.ps1
    c:\temp\trois.ps1
    '@ > $File
     
    "Write-host 'Call script un'" > c:\temp\un.ps1
    "Write-host 'Call script deux'" > c:\temp\deux.ps1
    "Write-host 'Call script trois'" > c:\temp\trois.ps1
     
    Foreach( $Script in (Get-Content $File))
    {
     & $Script
    }
     
    @'
    Write-host 'Call script deux'
    throw 'ça marche pas'
    '@  > c:\temp\deux.ps1
    Foreach( $Script in (Get-Content $File))
    {
     try {
      & $Script
     } catch {
       Write-Warning "Erreur pour le script $file.On stoppe" 
       Break #stoppe la boucle
     }
    }

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut
    Merci pour la réponse mais je ne comprends pas trop le code que tu as écris, peux tu le commenter stp?
    @' = ?
    & $Script = ?
    Sinon j'ai écris un code de mon côté mais quelques subtilités m'échappent?

    Faire une boucle sur un fichier txt contenant la liste des scripts à lancer = OK
    Executer chaque script en série = OK
    En fonction du code retour du script continuer le lancement des scripts ou stopper le script = NOK

    J'aimerai récupérer un code qui m'indiquerai si le script a réussi ou non, je me suis inspiré de ce que tu m'avais indiqué avec la commande write-output mais ça ne marche pas.
    Je lance les scripts via la commande start-process avec laquelle je pensais pouvoir récupérer un code retour mais le code retour est tjrs le même quoi qu'il se passe.
    j'espère avoir été le plus clair possible.
    Merci d'avance.

    Code PowerShell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    $DossierScript			= Split-Path $MyInvocation.MyCommand.Path
    $Dossier_de_Base		= Split-Path -Parent $DossierScript
    $Nom_du_Script		= Split-Path -Leaf $MyInvocation.MyCommand.Definition
    $Extension_Script		= $Nom_du_Script.SubString( ( $Nom_du_Script.Length )-3,3 )
    Log_Cour			        = $Dossier_de_Base + "\Logs\" + ( $Nom_du_Script).Replace( $Extension_Script,"txt" )
    $List_Script                       = $Dossier_de_Base + "\Inputs\testcoucou.txt"
     
    $List = ( Get-Content $List_Script )
        ForEach ( $Line In $List )
            {
            [int]$Script               = 0
            $Line1                     =  Split-Path -Leaf $Line
            $Msg0                    = "Erreur - L'execution du script $Line1 est en Erreur - Arrêt du script"
            $Msg1                    = "OK     - L'execution du script $Line1  est OK - Lancement du prochain script"
            $script                    = Start-Process -FilePath powershell.exe -ArgumentList $Line  -Wait 
            Write-Output "* Code de retour : $($script.ExitCode)
            Write-Host "Process finished with return code:  $script.ExitCode
            $LASTEXITCODE
     
                switch ( $script )
                        {
                            0    { Write-Host $Msg0 -ForegroundColor Red
                                   $Msg0 | Add-Content $Log_Cour 
                                   Exit }
     
                            1    { write-host $Msg1 -ForegroundColor Green 
                                   $Msg1 | Add-Content $Log_Cour }
                        }
            }

    dans les scripts qui s'enchainent j'ai mis un code simple juste pour tester comme ci-dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    write-host "coucou1"
    Write-output 1

  4. #4
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut
    Finalement j'ai réussi à me débrouiller avec invoke-command
    ci-dessous le code que j'ai utilisé.
    Code PowerShell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    $DossierScript			= Split-Path $MyInvocation.MyCommand.Path
    $Dossier_de_Base		= Split-Path -Parent $DossierScript
    $Nom_du_Script		= Split-Path -Leaf $MyInvocation.MyCommand.Definition
    $Extension_Script		= $Nom_du_Script.SubString( ( $Nom_du_Script.Length )-3,3 )
    $Log_Cour			= $Dossier_de_Base + "\Logs\" + ( $Nom_du_Script).Replace( $Extension_Script,"txt" )
     
    $List_Script                       = $Dossier_de_Base + "\Inputs\testcoucou.txt"
     
    $AD_Login                       = "DOMAINE\USER"
    $AD_Pwd                         = "MotDepasse"
     
     #Création du credential
            $SecurePassword = ConvertTo-SecureString $AD_Pwd -AsPlainText -force
            $Credential     = New-Object System.Management.Automation.PsCredential( $AD_Login, $SecurePassword )
            $RemoteSession   = New-PSSession -ComputerName "$($Env:COMPUTERNAME).DOMAINE.COM" -Credential $Credential
     
     
    <#Liste des scripts
    ------------------#>
    Write-host " Lancement du script Général qui ordonnance les différents scripts dédiés à la migration du serveur "
    $List = ( Get-Content $List_Script )
        ForEach ( $Line In $List )
            { $Line1                  =  Split-Path -Leaf $Line
              Write-host $Line1 -ForegroundColor Yellow
                If ( !( Test-Path $Line ) )
                    { Write-host "Le script $Line1 est introuvable" -ForegroundColor Red
                      "Le script $Line1 est introuvable" | Add-Content $Log_Cour
                      Write-host "Arrêt du script Général" -ForegroundColor Red
                      "Arrêt du script Général" | Add-Content $Log_Cour
                      Exit }
                Else
                    {
                    [int]$Script            = 0
                    write-host "Le script $Line1 est en cours d'execution" -ForegroundColor Green
                    $Msg1                   = "Erreur - L'execution du script $Line1 est en Erreur - Arrêt du script"
                    $Msg0                   = "OK     - L'execution du script $Line1  est OK - Lancement du prochain script"
                    $script                   =  Invoke-Command -session $RemoteSession -filepath $Line 
                    write-host "Le code retour est $script"
                    }
     
                switch ( $script )
                        {
                            1    { Write-Host $Msg1 -ForegroundColor Red
                                   $Msg1 | Add-Content $Log_Cour 
                                   Exit }
     
                            0    { write-host $Msg0 -ForegroundColor Green 
                                   $Msg0 | Add-Content $Log_Cour }
                        }
            } 
     
     
    "fini" | Add-Content $Log_Cour

  5. #5
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut
    mon script avance et semble presque au point.
    Néanmoins j'ai un message d'erreur sur la console lorsque le script relance un invoke-command
    Invoke-command s'execute bien mais j'ai le message d'erreur ci-dessous je ne sais pas si c'est bloquant, je n'ai pas l'impression.
    On dirait qu'il s'agit d'un pb de time out, j'ai donc placé un start-sleep après la fermeture de la session mais ça n'a rien donné.

    Code PowerShell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Remove-pSSession -session $RemoteSession
    Start-Sleep -s 10
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Cannot invoke pipeline because runspace is not in the Opened state. Current state of runspace is 'Closed'.
        + CategoryInfo          : OperationStopped: (Microsoft.Power...tHelperRunspace:ExecutionCmdletHelperRunspace) [], I 
       nvalidRunspaceStateException

    quelqu'un peut il m'aider svp?
    Merci d'avance

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lavocatb Voir le message
    Merci pour la réponse mais je ne comprends pas trop le code que tu as écris, peux tu le commenter stp?
    @' = ?
    & $Script = ?
    Ceci:
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    @'
    c:\temp\un.ps1
    c:\temp\deux.ps1
    c:\temp\trois.ps1
    '@ > $File
    Crée un fichier à partir d'une here-string, construction qui permet de saisir + lignes et de garder le formatage.

    L'opérateur & est un opérateur d'invocation(run/start), il exécute le script indiqué, son nom est contenu dans une variable.
    Si tu fais juste $Script il affiche le contenu.
    Citation Envoyé par lavocatb Voir le message
    quelqu'un peut il m'aider svp?
    J'ai un peu de mal à relire ...
    Si tu as un pb de timeout le runtime Powershell te le dira, fais lui confiance :-)
    Quelle version de Powershell as-tu et quelles sont les versions de l'OS local & distant ?

    Tu as la variable $Error et $Stacktrace pour débugger.

  7. #7
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut
    Merci pour les explications
    Concernant mon problème après différents tests il ne s'agit pas d'un pb de time out.
    Petite explication du contexte de mon travail.

    La finalité de mon travail en ce moment, est de créer un ensemble de script qui permettront
    de migrer de façon automatique des serveurs 2003 vers des serveurs en 2012 R2,
    ou de créer de façon automatique des serveurs en 2012 R2

    Un serveur local lanceur de script. [OS LOCAL W2008 R2/ Powershell v4]
    Beaucoup de serveurs distants. [OS DISTANTS W2012 R2/ Powershell v5]
    En résumé les étapes sont:
    -Création d'un VM 2012 R2
    -Paramétrage system (Share, Local Account, Contrôle de service, etc...)
    -Installation d'applications
    -Copie Data, migration et bascule de l'ancien serveur vers le nouveau serveur

    Depuis un script principale je lance en série des script via invoke-command.
    Chaque script lancé me renvoi une valeur 0 ou 1 via la commande write-output.
    Cette valeur que le script principal reçoit sert à faire le choix de lancer le script suivant ou de stopper l'enchainement si une erreur survient par exemple.

    Le 1er script lancé depuis le principal me renvoi une valeur que le script principal peux interpréter mais lorsque le second script renvoie lui aussi une valeur via write-output, cette valeur ne peut être pris en compte par mon script je ne sais pas pourquoi mais j'ai le message ci-dessous.
    As tu une idée stp?

    Cannot invoke pipeline because runspace is not in the Opened state. Current state of runspace is 'Closed'.
    + CategoryInfo : OperationStopped: (Microsoft.Power...tHelperRunspace:ExecutionCmdletHelperRunspace) [], I
    nvalidRunspaceStateException

  8. #8
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lavocatb Voir le message
    As tu une idée stp?
    J'en ai Plein
    Mais te seront-elles utiles...
    J'ai recherché rapido dans le code source, mais je n'ai pas le temps pour analyser la centaine d’occurrences renvoyées.

    Vérifie déjà tes assertions : $remotesession est-il dans l'état attendu ?
    Code PowerShell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    $RemoteSession|select *
    # State                  : Opened
    # IdleTimeout            : 7200000
    # OutputBufferingMode    : Block
    # DisconnectedOn         :
    # ExpiresOn              :
    # ComputerName           : localhost
    # ConfigurationName      : Microsoft.PowerShell
    # InstanceId             : 7e940d3b-dc24-4bdd-846e-3e8f697a6ef7
    # Id                     : 1
    # Name                   : Session1
    # Availability           : Available
    # ApplicationPrivateData : {DebugMode, DebugStop, UnhandledBreakpointMode, PSVersionTable, BreakAll,
    #                          DebugBreakpointCount}
    # Runspace               : System.Management.Automation.RemoteRunspace
     
    $RemoteSession.Runspace.RunspaceStateInfo|select *
     
    #  State Reason
    #  ----- ------
    # Opened
    Si le runspace est clos, reste à savoir si c'est ton code le responsable ou si le remoting PS pose pb entre 2 versions différentes.
    Tu peux aussi tester avec un poste local PS V5 ET adresser UN serveur PS v5 ou le même scénario avec la V4.

    ps
    Pour terminer ton script principal en cas d'erreur, je te conseille d'utiliser l'instruction break, pour quitter la boucle, au lieu d'Exit.

  9. #9
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2016
    Messages : 14
    Par défaut
    Merci pour les réponses ça me donne des idées.
    Par contre le break ne stoppe pas le script mais cela fonctionne avec exit.

    Sinon j'ai solutionné mon pb autrement. Je me rends compte que je suis vraiement nul.
    tous les scripts sont locaux
    le script principal execute les petits scripts qui utilisent invoke-command pour faire leurs affaires.
    mon pb était de récupérer le resultat des petits scripts dans mon script principal.
    comme je l'ai dit je suis débutant et je ne connaissais pas d'autres moyen de lancer un script que de le lancer via invoke-command.
    Mais j'ai trouvé comment faire autrement
    je lance les scripts comme ci-dessous
    . script;ps1
    j'utilise ensuite exit 1 ou exit 0 puis je récupère le résultat et fait un switch sur $lastexitcode
    ET CA MARCHE.
    Merci pour ton aide;
    Je pense que tu risque de me revoir bientôt
    encore merci.

  10. #10
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lavocatb Voir le message
    Je me rends compte que je suis vraiment nul.
    M'es avis que tu dois avoir le temps de livrer mais pas celui d'apprendre
    Citation Envoyé par lavocatb Voir le message
    Je lance les scripts comme ci-dessous :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    . script.ps1
    Oui c'est la solution que je t'ai proposé, la différence est que l'opérateur d'invocation '.' utilise la portée de l'appelant, là où '&' crée une nouvelle portée.
    Tu te prépares de belles séances de debug

Discussions similaires

  1. Essayer d'activer un script powershell sous IIS
    Par machpro dans le forum IIS
    Réponses: 1
    Dernier message: 06/12/2008, 00h08
  2. Attendre la fin d'un son pour enchainer le script
    Par cahierlabo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/02/2008, 09h55
  3. [AJAX] enchainement de script ajax sur <select>
    Par lodan dans le forum Général JavaScript
    Réponses: 62
    Dernier message: 16/09/2006, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo