Si j'ai une fonction qui accepte plusieurs paramètres de chaîne, le premier paramètre semble obtenir toutes les données qui lui sont affectées et les paramètres restants sont passés comme vides.
Un script de test rapide:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
La sortie générée est
$arg1 value: ABC DEF
$arg2 value:
La sortie correcte doit être:
$arg1 value: ABC
$arg2 value: DEF
Cela semble être cohérent entre v1 et v2 sur plusieurs machines, donc évidemment, je fais quelque chose de mal. Quelqu'un peut-il indiquer exactement quoi?
powershell
Nasir
la source
la source
Test "ABC" "DEF"
Réponses:
Les paramètres des appels aux fonctions dans PowerShell (toutes les versions) sont séparés par des espaces et non par des virgules . En outre, les parenthèses sont entièrement inutiles et provoqueront une erreur d'analyse dans PowerShell 2.0 (ou version ultérieure) si
Set-StrictMode
est actif. Les arguments entre parenthèses sont utilisés dans les méthodes .NET uniquement.la source
(1,2,3)
à une fonction est effectivement traité comme un tableau; un seul argument. Si vous souhaitez utiliser des arguments de style de méthode OO, utilisez les modules:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
Powershell
est un langage shell et il est courant que les langages shell utilisent des espaces comme séparateur de jetons. Je ne dirais pasPowershell
est d' être différent ici, il est juste en ligne avec d' autres coquilles par défaut du système commecmd
,sh
,bash
, etc.La bonne réponse a déjà été fournie, mais ce problème semble suffisamment répandu pour justifier certains détails supplémentaires pour ceux qui souhaitent comprendre les subtilités.
J'aurais ajouté cela juste en tant que commentaire, mais je voulais inclure une illustration - je l'ai arraché de mon tableau de référence rapide sur les fonctions PowerShell. Cela suppose que la signature de la fonction f est
f($a, $b, $c)
:Ainsi, on peut appeler une fonction avec des paramètres positionnels séparés par des espaces ou des paramètres nommés indépendants de l'ordre . Les autres pièges révèlent que vous devez être conscient des virgules, des parenthèses et des espaces blancs.
Pour en savoir plus, consultez mon article Down the Rabbit Hole: A Study in PowerShell Pipelines, Functions, and Parameters . L'article contient également un lien vers la référence rapide / graphique mural.
la source
Il y a de bonnes réponses ici, mais je voulais souligner quelques autres choses. Les paramètres de fonction sont en fait un endroit où PowerShell brille. Par exemple, vous pouvez avoir des paramètres nommés ou positionnels dans des fonctions avancées comme ceci:
Ensuite, vous pouvez soit l'appeler en spécifiant le nom du paramètre, soit utiliser des paramètres positionnels, car vous les avez définis explicitement. Donc, l'un ou l'autre fonctionnerait:
Le premier exemple fonctionne même s'il
Name
est fourni en second, car nous avons explicitement utilisé le nom du paramètre. Le deuxième exemple fonctionne cependant en fonction de la position, doncName
devrait donc être le premier. Lorsque cela est possible, j'essaie toujours de définir des positions afin que les deux options soient disponibles.PowerShell a également la possibilité de définir des ensembles de paramètres. Il utilise cela à la place de la surcharge de méthode, et est encore très utile:
Maintenant, la fonction prendra un nom ou un identifiant, mais pas les deux. Vous pouvez les utiliser de manière positionnelle ou par nom. Puisqu'ils sont d'un type différent, PowerShell le découvrira. Donc, tout cela fonctionnerait:
Vous pouvez également affecter des paramètres supplémentaires aux différents jeux de paramètres. (C'était évidemment un exemple assez basique.) À l'intérieur de la fonction, vous pouvez déterminer quel ensemble de paramètres a été utilisé avec la propriété $ PsCmdlet.ParameterSetName. Par exemple:
Ensuite, sur une note connexe, il y a également la validation des paramètres dans PowerShell. C'est l'une de mes fonctionnalités PowerShell préférées, et cela rend le code à l'intérieur de vos fonctions très propre. Il existe de nombreuses validations que vous pouvez utiliser. Quelques exemples sont:
Dans le premier exemple, ValidatePattern accepte une expression régulière qui garantit que le paramètre fourni correspond à ce que vous attendez. Si ce n'est pas le cas, une exception intuitive est levée, vous indiquant exactement ce qui ne va pas. Donc, dans cet exemple, «Quelque chose» fonctionnerait bien, mais «Summer» ne passerait pas la validation.
ValidateRange garantit que la valeur du paramètre se situe entre la plage attendue pour un entier. Donc 10 ou 99 fonctionneraient, mais 101 lèverait une exception.
Un autre utile est ValidateSet, qui vous permet de définir explicitement un tableau de valeurs acceptables. Si quelque chose d'autre est entré, une exception sera levée. Il y en a d'autres aussi, mais le plus utile est probablement ValidateScript. Cela prend un bloc de script qui doit être évalué à $ true, donc le ciel est la limite. Par exemple:
Dans cet exemple, nous sommes assurés non seulement que $ Path existe, mais qu'il s'agit d'un fichier (par opposition à un répertoire) et possède une extension .csv. ($ _ fait référence au paramètre, à l'intérieur de votre bloc de script.) Vous pouvez également passer des blocs de script à plusieurs lignes beaucoup plus grands si ce niveau est requis, ou utiliser plusieurs blocs de script comme je l'ai fait ici. Il est extrêmement utile et offre de belles fonctions propres et des exceptions intuitives.
la source
My_Function -NamedParamater "ParamValue"
le style d'appel de fonction. Il s'agit d'un modèle que davantage de code de script PS devrait suivre pour plus de lisibilité.Vous appelez des fonctions PowerShell sans les parenthèses et sans utiliser la virgule comme séparateur. Essayez d'utiliser:
Dans PowerShell, la virgule (,) est un opérateur de tableau, par exemple
Il définit
$a
un tableau avec trois valeurs.la source
la source
Si vous êtes un développeur C # / Java / C ++ / Ruby / Python / Pick-A-Language-From-This-Century et que vous souhaitez appeler votre fonction avec des virgules, car c'est ce que vous avez toujours fait, alors vous avez besoin de quelque chose comme ça:
Appelez maintenant:
et vous verrez
la source
Si vous ne savez pas (ou ne vous souciez pas) du nombre d'arguments que vous passerez à la fonction, vous pouvez également utiliser une approche très simple comme;
Code :
Cela imprimerait tous les arguments. Par exemple:
Production
Je trouve cela particulièrement utile lors de la création de fonctions qui utilisent des commandes externes qui pourraient avoir de nombreux paramètres différents (et facultatifs), mais s'appuie sur cette commande pour fournir des commentaires sur les erreurs de syntaxe, etc.
Voici un autre exemple du monde réel (création d'une fonction pour la commande tracert, que je déteste devoir me souvenir du nom tronqué);
Code :
la source
Si tu essayes:
vous obtenez:
Vous voyez donc que les parenthèses séparent les paramètres
Si tu essayes:
vous obtenez:
Vous pouvez maintenant trouver une utilité immédiate des parenthèses - un espace ne deviendra pas un séparateur pour le paramètre suivant - à la place, vous avez une fonction eval.
la source
@
) avant les premiers paren, comme ce tableau vide:@()
; ou ce tableau avec deux numéros:@(1, 2)
.Comme il s'agit d'une question fréquemment consultée, je tiens à mentionner qu'une fonction PowerShell doit utiliser des verbes approuvés ( Verb-Noun comme nom de fonction). La partie verbale du nom identifie l'action que l'applet de commande effectue. La partie nominale du nom identifie l'entité sur laquelle l'action est effectuée. Cette règle simplifie l'utilisation de vos applets de commande pour les utilisateurs avancés de PowerShell.
De plus, vous pouvez spécifier des choses comme si le paramètre est obligatoire et la position du paramètre:
Pour passer le paramètre à la fonction, vous pouvez soit utiliser la position :
Ou toi spécifiez le nom du paramètre :
Vous n'utilisez pas de parenthèses comme vous le faites lorsque vous appelez une fonction dans C #.
Je recommanderais de toujours passer les noms de paramètres lorsque vous utilisez plusieurs paramètres, car cela est plus lisible .
la source
Get-Node
applet de commande. Il serait clair pour nous que nous devons invoquerGet-Node
, nonRetrieve-Node
, niReceive-Node
, ni .....Je ne sais pas ce que vous faites avec la fonction, mais jetez un œil à l'utilisation du mot-clé 'param'. Il est un peu plus puissant pour passer des paramètres dans une fonction et la rend plus conviviale. Vous trouverez ci-dessous un lien vers un article trop complexe de Microsoft à ce sujet. Ce n'est pas aussi compliqué que l'article le donne.
Utilisation des paramètres
Aussi, voici un exemple d' une question sur ce site:
Vérifiez-le.
la source
la source
J'ai déclaré ce qui suit plus tôt:
Le problème courant est l'utilisation de la forme singulière
$arg
, qui est incorrecte. Il doit toujours être pluriel comme$args
.Le problème n'est pas ça. En réalité,
$arg
peut être autre chose. Le problème était l'utilisation de la virgule et des parenthèses.J'exécute le code suivant qui a fonctionné et la sortie suit:
Code:
Test "ABC" "DEF"
Production:
la source
Ceci est un bon
params
déclaration .Voir about_Functions_Advanced_Parameters .
Et cela fonctionne en effet.
la source
Vous pouvez également transmettre des paramètres dans une fonction comme celle-ci:
la source
Je ne le vois pas mentionné ici, mais répartir vos arguments est une alternative utile et devient particulièrement utile si vous construisez les arguments d'une commande dynamiquement (par opposition à l'utilisation
Invoke-Expression
). Vous pouvez répartir des tableaux pour les arguments positionnels et des tables de hachage pour les arguments nommés. Voici quelques exemples:Splat avec des tableaux (arguments positionnels)
Test de connexion avec des arguments positionnels
Avec éclaboussure de tableau
Splat With Hashtable (arguments nommés)
Test de connexion avec des arguments nommés
Avec éclaboussures de table de hachage
Splat arguments positionnels et nommés simultanément
Test-Connection avec les arguments positionnels et nommés
Splatting Array and Hashtables Together
la source