2011-03-03 3 views
7

J'ai un script PowerShell (2.0) en appelant un autre. Je veux recevoir non seulement la sortie principale, mais un objet supplémentaire que je peux utiliser séparément, par ex. pour afficher une ligne récapitulative dans un message.Retourne un objet de PowerShell en utilisant un paramètre (paramètre "Par référence")?

Ayons Test2.ps1 que le script appelé:

param([String]$SummaryLine) 
$Issues = "Potentially long list of issues" 
$SummaryLine = "37 issues found" 
$Issues 

Et Test1.ps1 comme le script qu'il appelle:

$MainOutput = & ".\Test2.ps1" -SummaryLine $SummaryOutput 
$MainOutput 
$SummaryOutput 

La sortie est tout simplement:

Potentially long list of issues 

Bien que le paramètre $ SummaryLine soit rempli par Test2, $ SummaryOutput reste indéfini dans Test1. La définition de $ SummaryOutput avant l'appel de Test2 n'aide pas;

il conserve juste la valeur assignée avant d'appeler Test2.

J'ai essayé de configurer $ SummaryOutput et $ SummaryLine en tant que variables [ref] (comme on peut apparemment le faire avec des fonctions), mais la propriété $ SummaryOutput.Value est $ null après avoir appelé Test2.

Est-il possible dans PowerShell de renvoyer une valeur dans un paramètre? Si non, quelles sont les solutions de contournement? Affectation directe d'une variable de portée parent dans Test2?

Répondre

9

Ref devrait fonctionner, vous ne dites pas ce qui s'est passé quand vous l'avez essayé. Voici un exemple:

Test.ps1:

Param ([ref]$OptionalOutput) 

"Standard output" 
$OptionalOutput.Value = "Optional Output" 

Lancez-:

$x = "" 
.\Test.ps1 ([ref]$x) 
$x 

Voici une alternative que vous pourriez aimer mieux.

Test.ps1:

Param ($OptionalOutput) 

"Standard output" 
if ($OptionalOutput) { 
    $OptionalOutput | Add-Member NoteProperty Summary "Optional Output" 
} 

Lancez-:

$x = New-Object PSObject 
.\Test.ps1 $x 
$x.Summary 
+0

Vache sacrée, [ref] fonctionne! Quand j'ai essayé cela, j'ai assigné $ OptionalOutput plutôt que $ OptionalOutput.Value à l'intérieur du script appelé, donc $ x n'a pas été mis à jour dans le script appelant. Alors, que se passe-t-il dans votre deuxième approche? Si $ x est un PSObject, il est automatiquement passé comme [ref]? –

+2

Je suggère d'utiliser [ref] et non la deuxième option. Dans PowerShell (en tant que .NET), les objets sont transmis par référence, mais les variables sont définies. Cela peut être difficile à comprendre au début, mais c'est vrai. – JasonMArcher

+0

@JasonMArcher: Oui, j'aime [ref] pour être plus explicite. Ré. passer des objets, si tous les objets sont passés par référence, pourquoi cela ne fonctionne-t-il pas pour une chaîne (qui est un objet .NET Reference Type)? –

1

Est-ce plus proche de ce que vous voulez faire?

Test2.ps1

$Issues = "Potentially long list of issues" 
$SummaryLine = "37 issues found" 
$Issues 
$SummaryLine 

Test1.ps1

$MainOutput,$SummaryOutput = & ".\Test2.ps1" 
$MainOutput 
$SummaryOutput 

Ce:

param([String]$SummaryLine) 
$Issues = "Potentially long list of issues" 
$SummaryLine = "37 issues found" 
$Issues 

est irrationnel. Vous passez un paramètre pour $ SummaryLine, puis le remplacez immédiatement par "37 problèmes trouvés". Cette variable n'existe que dans la portée du script appelé. Dès que ce script se termine, il est parti. Si vous voulez l'utiliser plus tard, vous devez le sortir et l'enregistrer dans une variable de votre script d'appel.

+0

Oui, je tentais de traiter essentiellement Test2 en fonction avec un paramètre "ByRef" (sortie). Votre syntaxe est assez proche.Plusieurs variables à gauche du = est nouveau pour moi mais je pense que je l'ai: [Multi Variable Assignment] (http://get-powershell.com/2008/02/05/multi-variable-assignment-in-powershell /). La seule "fonctionnalité" supplémentaire que je voudrais est de pouvoir appeler Test2 _without_ en voyant le $ SummaryLine. En d'autres termes, la valeur par défaut serait de renvoyer uniquement le détail $ Issues. Je suppose que pour cela je pourrais passer un paramètre booléen $ ShowSummary et ne sortir que $ SummaryLine si $ ShowSummary = True. –

+0

J'utiliserais un paramètre [switch] plutôt qu'un booléen. – mjolinor

Questions connexes