268 votes

Comment répartir les longues commandes sur plusieurs lignes dans PowerShell

Comment prendre une commande comme celle-ci dans PowerShell et la répartir sur plusieurs lignes ?

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"

0 votes

0 votes

395voto

Colin Pickard Points 23922

Caractère de backtick arrière, c'est-à-dire,

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
-verb:sync `
-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
-dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"

Les espaces blancs sont importants. Le format requis est le suivant Space`Enter .

2 votes

Cela semble rompre la fonctionnalité d'historique des commandes (flèche vers le haut), car chaque ligne s'affiche comme une commande distincte. Existe-t-il un moyen de contourner ce problème ?

2 votes

Si vous utilisez powershell 3 ou une version ultérieure, consultez github.com/lzybkr/psreadline - la traversée de l'historique est corrigée pour les instructions multilignes.

52 votes

L'espace devant le back-tick est requis #learned-the-hard-way

78voto

BJHop Points 51

Une autre méthode pour un passage d'argument plus propre serait éclaboussures .

Définissez vos paramètres et vos valeurs comme une table de hachage comme ceci :

$params = @{ 'class' = 'Win32_BIOS';
             'computername'='SERVER-R2';
             'filter'='drivetype=3';
             'credential'='Administrator' }

Et ensuite appelez votre commandlet comme ceci :

Get-WmiObject @params

Microsoft Docs : À propos de Splatting

TechNet Magazine 2011 : Windows PowerShell : Splatting

Il semble que cela fonctionne avec Powershell 2.0 et plus.

8 votes

C'est merveilleux ! ET vous pouvez ajouter des paramètres comme ceci : $params.add('name','Bob Newhart') ramblingcookiemonster.wordpress.com/2014/12/01/

2 votes

Les points-virgules sont corrects mais superflus. Il n'est nécessaire que s'il y a plusieurs valeurs par ligne.

1 votes

Cela ne fonctionne pas pour les commandes shell normales, mais principalement pour les commandlets PowerShell.

43voto

BGM Points 2427

Ah, et si vous avez une très longue chaîne de caractères que vous voulez séparer, disons en HTML, vous pouvez le faire en mettant une balise @ de chaque côté de l'extérieur " - comme ça :

$mystring = @"
Bob
went
to town
to buy
a fat
pig.
"@

Vous obtenez exactement cela :

Bob
went
to town
to buy
a fat
pig.

Et si vous utilisez Notepad++ il sera même mis en évidence correctement en tant que bloc de chaînes.

Maintenant, si vous voulez que cette chaîne contienne aussi des guillemets, il suffit de les ajouter, comme ceci :

$myvar = "Site"
$mystring = @"
<a href="http://somewhere.com/somelocation">
Bob's $myvar
</a>
"@

Vous obtiendriez exactement cela :

<a href="http://somewhere.com/somelocation">
Bob's Site
</a>

Toutefois, si vous utilisez des guillemets doubles dans cette chaîne @, Notepad++ ne s'en rend pas compte et modifiera la coloration syntaxique comme s'il s'agissait d'une chaîne non citée ou citée, selon le cas.

Et ce qui est encore mieux, c'est que partout où vous insérez une $variable, elle est interprétée ! (Si vous avez besoin du signe dollar dans le texte, vous l'échappez avec un point de suspension comme ceci : ``$not-a-variable``).

AVIS ! Si vous ne mettez pas la finale "@ au tout début de la ligne il échouera. Il m'a fallu une heure pour comprendre que je ne pouvais pas indenter cela dans mon code !

Voici MSDN sur le sujet : Utilisation de Windows PowerShell " Here-Strings " (chaînes de caractères)

1 votes

Astuce intéressante, mais si j'ai une variable $... cela ne semble pas fonctionner. J'obtiens "le caractère n'est pas autorisé après un en-tête de chaîne ici...".

0 votes

Je ne pense pas que vous puissiez casser un nom de variable, juste une chaîne.

21voto

Aaron Jensen Points 5170

Vous pouvez utiliser l'opérateur backtick :

& "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
    -verb:sync `
    -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
    -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"

C'est encore un peu trop long à mon goût, alors j'utiliserais des variables bien nommées :

$msdeployPath = "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
$verbArg = '-verb:sync'
$sourceArg = '-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web"'
$destArg = '-dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"'

& $msdeployPath $verbArg $sourceArg $destArg

1 votes

Je préfère les noms de variables aux autres suggestions parce que c'est probablement l'option la plus lisible pour les non experts de powershell. Si je voyais un tutoriel/guide de configuration qui utilise le splatting, je serais totalement perdu sans un sous-tutoriel sur le splatting. De même, les backticks semblent fragiles et probablement moins connus que les simples variables PS qui ont fait leurs preuves.

17voto

Steven Penny Points 18523

Si vous avez une fonction :

$function:foo | % Invoke @(
  'bar'
  'directory'
  $true
)

Si vous avez un cmdlet :

[PSCustomObject] @{
  Path  = 'bar'
  Type  = 'directory'
  Force = $true
} | New-Item

Si vous avez une demande :

{foo.exe @Args} | % Invoke @(
  'bar'
  'directory'
  $true
)

Ou

icm {foo.exe @Args} -Args @(
  'bar'
  'directory'
  $true
)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X