Flash info

Une frénésie incontrollée poussent certains individus à convertir tous les scripts d'admin en PowerShell. L'un d'eux aurait été apperçu récemment près du campus universitaire de Talence.

 
Accueil arrow Forum

Bienvenue sur le forum PowerShell-Scripting.com

 
Neandril
Utilisateur

PowerShelleur Débutant
Messages: 16
graphgraph
Karma: 0  
[Résolu] Accès à une variable dans un workflow - 3/04/18 10:42 Bonjour

Je souhaite accéder à une variable initialisée hors d'un workflow, dans un workflow.

Ce workflow fait un foreach parallel pour pinger une liste de machine, et pour chaque poste qui répond, copie un dossier.

Cependant, le dossier pouvant changer, l'utilisateur sélectionnera sa cible via une dialog box pour choisir son répertoire.

Mon Workflow ressemble a ceci :

Code:

 $ip_list Get-Content -LiteralPath ".\pclist.txt" workflow parallelPingCOmputer {     Param($computers,         $location)     foreach -parallel($computer in $computers)     {         $ping $null         If (Test-Connection -ComputerName $computer -Count 1 -quiet) {                          $ping "Le poste répond"             Copy-Item -Path $location -Destination "\\$computer\c$\destination\" -Force -Recurse -ErrorAction stop         } else {             $ping "Le poste ne répond pas"         }         $arrayResults = New-Object -Type PSObject -Property @{         Hostname $computer         Ping $ping         }         return($arrayResults)     } } parallelPingComputer -computers $ip_list Select-Object Hostnameping Out-GridView



Seulement, la variable $location renvoi la valeur null apparemment (message d'erreur powershell). Ca fonctionne si je l'inclue dans le workflow, mais avec le "folder-picker" que je vais utiliser, il faut impérativement que cette variable soit créée en dehors du workflow, et accédée à l'intérieur de celui-ci. A moins qu'il est possible d'inclure le "folder-picker" dans le workflow, mais je n'ai pas réussi.

Auriez-vous une idée svp ?

Merci beaucoup d'avance.

Message édité par: Arnaud, à: 11/04/18 13:48
  | | L'administrateur a désactivé l'accés public en écriture.
Arnaud
Admin

Administrateur
Messages: 1232
graphgraph
Karma: 43  
Re:Accès à une variable dans un workflow. - 3/04/18 16:33 Hello,

A tout hasard essaie d'accèder à ta variable externe à ton workflow avec la syntaxe $using:MaVariable

Mais personnellement j'éviterai d'utiliser les workflows...

Arnaud
MVP PowerShell (depuis 2007)
Suivez moi sur Twitter !
  | | L'administrateur a désactivé l'accés public en écriture.
Neandril
Utilisateur

PowerShelleur Débutant
Messages: 16
graphgraph
Karma: 0  
Re:Accès à une variable dans un workflow. - 3/04/18 17:10 Merci Arnaud.

J'ai déjà essayé avec $using, mais sans succès. Le $using ne peut être utilisé qu'avec invoke command, ou inlinescript... Mais même en essayant ça, j'ai pas réussi.

Par contre, pourquoi me conseille tu d'éviter les workflows ?

Message édité par: Neandril, à: 3/04/18 18:12
  | | L'administrateur a désactivé l'accés public en écriture.
Laurent Dardenne
Utilisateur

PowerShelleur Platinum
Messages: 5497
graph
Karma: 204  
Re:Accès à une variable dans un workflow. - 4/04/18 08:48 Salut,
je ne rencontre pas de pb avec ton code (PS v5.1 Seven) :
Code:

  workflow parallelPingCOmputer {     Param($computers,         $location)          Write-Warning "Location WF : $location"     foreach -parallel($computer in $computers)     {         Write-Warning "Location // : $location"         $ping $null         If (Test-Connection -ComputerName $computer -Count 1 -quiet) {                          $ping "Le poste répond"             Copy-Item -Path $location -Destination "\\$computer\c$\destination\" -Force -Recurse -ErrorAction stop         } else {             $ping "Le poste ne répond pas"         }         Write-output (New-Object -Type PSObject -Property @{          Hostname $computer          Ping $ping         })     }     Write-Warning "Fin " } parallelPingCOmputer -computers 'localhost' -Location c:\temp\Test # WARNING: [localhost]:Location WF : c:\temp\Test # WARNING: [localhost]:Location // : c:\temp\Test #  #  # Ping                  : Le poste répond # Hostname              : localhost # PSComputerName        : localhost # PSSourceJobInstanceId : d17dbfe0-756a-47df-b8f0-7e58672980b5 #  # WARNING: [localhost]:F


Il y a juste le return à retirer et à émettre l'objet résultat directement.
Personnellement je lui ajouterais une propriété de type booléen pour connaitre les machines en erreur.
Tutoriels PowerShell
  | | L'administrateur a désactivé l'accés public en écriture.
Neandril
Utilisateur

PowerShelleur Débutant
Messages: 16
graphgraph
Karma: 0  
Re:Accès à une variable dans un workflow. - 4/04/18 10:05 Merci beaucoup.

Le premier test que je viens de réaliser par rapport à ton retour à l'air concluant.

Je n'avais effectivement pas renvoyer le résultat directement dans l'appel du Workflow.

Les machines en erreur je les capte par un bloc try / catch (que j'ai pas inclu dans ce post), et la sortie est redirigée vers un out-gridview + un csv.

Si d'après toi c'est mieux de renvoyer un objet de type booléen, je veux bien un exemple si ça te dérange pas.
  | | L'administrateur a désactivé l'accés public en écriture.
Laurent Dardenne
Utilisateur

PowerShelleur Platinum
Messages: 5497
graph
Karma: 204  
Re:Accès à une variable dans un workflow. - 4/04/18 11:16 Neandril écrit:

Si d'après toi c'est mieux de renvoyer un objet de type booléen

Ton objet renseigne des donnés pour l'affichage et pas pour les possible traitements.
Code:

          $IsConnected=Test-Connection -ComputerName $computer -Count 1 -quiet     if ($IsConnected)        $Message "Le poste répond."        Copy-Item -Path $location -Destination "\\$computer\c$\destination\" -Force -Recurse -ErrorAction stop     } else {        $Message "Le poste ne répond pas."     }       Write-output (New-Object -Type PSObject -Property @{      Hostname $computer      IsConnected  $IsConnected      Message=$Message     })


La propriété IsConnected permet de filtrer le résultat et Message de renseigner le texte à afficher.
Mais pour moi la propriété IsConnected porte déjà l'information, ceci peut être suffisant :
Code:

      $IsConnected=Test-Connection -ComputerName $computer -Count 1 -quiet     if ($Connected)     {  Copy-Item -Path $location -Destination "\\$computer\c$\destination\" -Force -Recurse -ErrorAction stop }       Write-output (New-Object -Type PSObject -Property @{      Hostname $computer      IsConnected  $IsConnected     })


Filtrer le résultat :
Code:

  $result=@( New-Object -Type PSObject -Property @{      Hostname 'computer1'      IsConnected  $true     } New-Object -Type PSObject -Property @{      Hostname 'computer2'      IsConnected  $false     } ) $result|where-object {$_.isconnected} # IsConnected Hostname # ----------- -------- #        True computer1 $result|where-object {-not $_.isconnected} # IsConnected Hostname # ----------- -------- #       False computer2


La présence de la propriété Message n'est nécessaire qu'une fois que tu construis un rapport
Code:

  $Messages=@( "Le poste répond." "Le poste ne répond pas." )  #Propriété calculée $NewResult=$Result|  Select-object -Property HostName,@{Name='Message';e={$Messages[($_.IsConnected)]}} $NewResult # Hostname  Message # --------  ------- # computer1 Le poste ne répond pas. # computer2 Le poste répond.



Message édité par: Laurent Dardenne, à: 4/04/18 12:16
Tutoriels PowerShell
  | | L'administrateur a désactivé l'accés public en écriture.
Neandril
Utilisateur

PowerShelleur Débutant
Messages: 16
graphgraph
Karma: 0  
Re:Accès à une variable dans un workflow. - 5/04/18 09:19 Merci beaucoup pour ces informations, ça m'a été très utile.

J'aimerai te poser une dernière question.

Après la copie, je dois executé un script (cmd), ainsi copié donc. seulement, dans l'activité workflow, impossible de le faire fonctionner :

Code:

  inlinescript {     $session = New-PSSession -ComputerName $computer     Invoke-Command -Session $using:session -ScriptBlock set-location $location }     Enter-PSSession -Session $using:session     Invoke-Command -Session $using:session -ScriptBlock cmd /"$location\commandpkg.cmd" }     Exit-PSSession }



Cela fonctionne bien en dehors du Workflow, mais pour l'inclure j'ai quelques difficultés.

Merci d'avance pour ton aide.
  | | L'administrateur a désactivé l'accés public en écriture.
Laurent Dardenne
Utilisateur

PowerShelleur Platinum
Messages: 5497
graph
Karma: 204  
Re:Accès à une variable dans un workflow. - 5/04/18 10:42 Quel erreur as-tu ?
Et je suis tenté de simplifier ainsi (je n'ai pas testé) :
Code:

 inlinescript {     Invoke-Command -ComputerName $computer -ScriptBlock{        set-location $location        cmd /"$location\commandpkg.cmd"       } }


Sous réserve que le nb d'exécution simultanée de la boucle corresponde à celui des jobs distants.

Et à priori c'est ton fichier batch qui devrait se charger de modifier le path courant.
Tutoriels PowerShell
  | | L'administrateur a désactivé l'accés public en écriture.
Neandril
Utilisateur

PowerShelleur Débutant
Messages: 16
graphgraph
Karma: 0  
Re:Accès à une variable dans un workflow. - 11/04/18 10:27 Salut.

Désolé pour ma réponse tardive (pris par le boulot).

J'ai finalement trouvé une solution :

Code:

              InlineScript {                 Copy-Item -path $using:location -Destination (New-item -type directory -force ("\\$using:computer\c$\_sources\")) -Force -Recurse -ErrorAction Stop                 $pkg Split-Path $using:location -leaf                 $s = New-PSSession -ComputerName $using:computer                 Invoke-Command -Session $s -ScriptBlock {                     param($pkg)                     set-location "c:\$pkg\" } -ArgumentList $pkg                 Enter-PSSession -Session $s -ErrorAction SilentlyContinue                 Invoke-Command -session $s -ScriptBlock {                      param($pkg)                     cmd /"c:\$pkg\command.cmd" } -ArgumentList $pkg                 Exit-PSSession -ErrorAction SilentlyContinue                 } -ErrorAction Stop



Alors il y a peut-être effectivement plus simple, mais ça fait exactement ce dont j'ai besoin

Pour info, la version simplifiée que tu m'a communiqué n'a pas fonctionné, certainement dû à l'infrastructure dans laquelle j'étais.

J'ai été obligé de séparé le set-location et le cmd dans 2 invoke-command distinct. J'avais déjà fait des tests en ce sens au préalables, sans succès.

En tout les cas, merci beaucoup pour tes conseils.
  | | L'administrateur a désactivé l'accés public en écriture.
© 2018 PowerShell-Scripting.com