Pendant des années, j'ai utilisé le cmd/DOS/Windows
Shell et arguments de ligne de commande passés aux fichiers de commandes. Par exemple, j'ai un fichier, zuzu.bat
et j'y accède %1
, %2
, etc. Maintenant, je veux faire la même chose quand j'appelle un PowerShell
script when I am in a Cmd.exe Shell
. J'ai un script, xuxu.ps1
(et j'ai ajouté PS1 à ma variable PATHEXT et aux fichiers PS1 associés avec PowerShell). Mais peu importe ce que je fais, il semble que je ne puisse rien obtenir du $args
variable. Il a toujours la longueur 0.
Si je suis dans un shell PowerShell
, au lieu de cmd.exe
, ça marche (bien sûr). Mais je ne suis pas encore assez à l'aise pour vivre dans l'environnement PowerShell à temps plein. Je ne veux pas taper powershell.exe -command xuxu.ps1 p1 p2 p3 p4
. Je veux taper xuxu p1 p2 p3 p4
.
Est-ce possible, et si oui comment?
L'exemple que je ne peux pas me mettre au travail est trivial, foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
}
Les résultats sont toujours comme ça:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
Cet article aide. En particulier, cette section:
-Fichier
Exécute le script spécifié dans l'étendue locale ("source source"), afin que les fonctions et les variables créées par le script soient disponibles dans la session en cours. Entrez le chemin du fichier de script et tous les paramètres. Fichier doit être le dernier paramètre de la commande, car tous les caractères tapés après le nom du paramètre File sont interprétés comme le chemin du fichier de script suivi des paramètres de script.
c'est à dire.
powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3
signifie que le fichier myfile.ps1 et arg1 arg2 & arg3 sont les paramètres du script PowerShell.
OK, cela commence par casser une fonctionnalité de sécurité de base dans PowerShell. Avec cette compréhension, voici comment vous pouvez le faire:
Vous voudrez peut-être mettre un -NoProfile
argument également selon ce que fait votre profil.
Après avoir parcouru la documentation PowerShell, j'ai découvert des informations utiles sur ce problème. Vous ne pouvez pas utiliser le $args
Si vous avez utilisé le param(...)
au début de votre fichier; à la place, vous devrez utiliser $PSBoundParameters
. J'ai copié/collé votre code dans un script PowerShell et il a fonctionné comme prévu dans la version 2 de PowerShell (je ne suis pas sûr de la version que vous utilisiez lorsque vous avez rencontré ce problème).
Si vous utilisez $PSBoundParameters
(Et cela ne fonctionne UNIQUEMENT si vous utilisez param(...)
au début de votre script), il ne s'agit pas d'un tableau, mais d'une table de hachage. besoin de faire référence à l'aide de la paire clé/valeur.
param($p1, $p2, $p3, $p4)
$Script:args=""
write-Host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
$Script:args+= "`$$key=" + $PSBoundParameters["$key"] + " "
}
write-Host $Script:args
Et quand appelé avec ...
PS> ./foo.ps1 a b c d
Le résultat est...
Num Args: 4
$p1=a $p2=b $p3=c $p4=d
Vous pouvez déclarer vos paramètres dans le fichier, comme par exemple:
[string]$para1
[string]$param2
Et appelez ensuite le fichier PowerShell comme suit .\temp.ps1 para1 para2....para10
, etc.
Peut-être que vous pouvez envelopper l'invocation de PowerShell dans un .bat
fichier comme ceci:
rem ps.bat
@echo off
powershell.exe -command "%*"
Si vous avez ensuite placé ce fichier dans un dossier de votre PATH
, vous pouvez appeler les scripts PowerShell de la manière suivante:
ps foo 1 2 3
Citant peut devenir un peu brouillon, cependant:
ps write-Host """hello from cmd!""" -foregroundcolor green
Vous ne pouvez pas obtenir "xuxu p1 p2 p3 p4" comme il semble. Mais lorsque vous êtes dans PowerShell et que vous définissez
PS > set-executionpolicy Unrestricted -scope currentuser
Vous pouvez exécuter ces scripts comme ceci:
./xuxu p1 p2 p3 p4
ou
.\xuxu p1 p2 p3 p4
ou
./xuxu.ps1 p1 p2 p3 p4
J'espère que cela vous rend un peu plus à l'aise avec PowerShell.
si vous souhaitez appeler des scripts ps1 à partir de cmd et transmettre des arguments sans invoquer le script tel que
powershell.exe script.ps1 -c test
script -c test ( wont work )
vous pouvez faire ce qui suit
setx PATHEXT "%PATHEXT%;.PS1" /m
assoc .ps1=Microsoft.PowerShellScript.1
ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*
En supposant que powershell.exe soit sur votre chemin
https://docs.Microsoft.com/en-us/windows-server/administration/windows-commands/ftype