Comment diviser des commandes longues sur plusieurs lignes dans PowerShell

227

Comment prendre une commande comme la suivante dans PowerShell et la diviser 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"
asgerhallas
la source
Copie possible de Comment saisir une commande multiligne?
Michael Freidgeim

Réponses:

323

Caractère de point arrière arrière, c.-à-d.

&"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"

L'espace blanc est important. Le format requis est Space`Enter.

Colin Pickard
la source
1
Cela semble rompre la fonctionnalité de l'historique des commandes (flèche vers le haut); car chaque ligne apparaît comme une commande distincte. Y a-t-il un moyen de contourner ceci?
Richard Ev
2
Si vous utilisez PowerShell 3 ou supérieur, consultez github.com/lzybkr/psreadline - la traversée de l'historique est corrigée pour les instructions multilignes.
2013
43
L'espace devant la tique arrière est requis # appris à la dure
Josh Graham
29
@ josh-graham Et il ne devrait PAS y avoir d'espace (ou de commentaire en ligne) APRÈS le retour. # appris à la dure
RayLuo
1
Les backticks sont fragiles (comme l'indiquent les commentaires ci-dessus) et difficiles à trouver lors de l'analyse ou de la révision d'un fichier. La réponse de @StevenPenny est meilleure si vous voulez plus facile à déboguer du code.
mjd2
67

Une autre méthode pour passer des arguments plus propres serait l' éclaboussure .

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

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

Et puis appelez votre commande comme ceci:

Get-WmiObject @params

Microsoft Docs: à propos de l'éclaboussure

TechNet Magazine 2011: Windows PowerShell: Splatting

Il semble que cela fonctionne avec Powershell 2.0 et versions ultérieures

BJHop
la source
5
C'est magnifique! ET vous pouvez ajouter des paramètres comme celui-ci: $params.add('name','Bob Newhart') ramblingcookiemonster.wordpress.com/2014/12/01/…
bgmCoder
1
Les points-virgules sont corrects mais superflus. Requis uniquement s'il existe plusieurs valeurs par ligne.
Jim
38

Ah, et si vous avez une très longue chaîne que vous voulez casser, disons du HTML, vous pouvez le faire en mettant un @de chaque côté de l'extérieur "- comme ceci:

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

Vous obtenez exactement ceci:

Bob
went
to town
to buy
a fat
pig.

Et si vous utilisez Notepad ++ , il sera même correctement mis en surbrillance en tant que bloc de chaîne.

Maintenant, si vous vouliez que cette chaîne contienne également des guillemets, ajoutez-les simplement, comme ceci:

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

Vous obtiendriez exactement ceci:

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

Cependant, si vous utilisez des guillemets doubles dans cette chaîne @ comme ça, Notepad ++ ne s'en rend pas compte et changera la coloration de la syntaxe comme si elle n'était pas citée ou citée, selon le cas.

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

REMARQUER! Si vous ne placez pas la finale "@au tout début de la ligne , elle échouera. Il m'a fallu une heure pour comprendre que je ne pouvais pas mettre cela en retrait dans mon code!

Voici MSDN sur le sujet: Utilisation de Windows PowerShell «Here-Strings»

bgmCoder
la source
1
Une astuce intéressante, mais si j'ai une variable $ ... cela semble ne pas fonctionner.
J'obtiens
Je ne pense pas que vous puissiez casser un nom de variable, juste une chaîne.
bgmCoder
19

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, donc 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
Aaron Jensen
la source
1
J'aime les noms de variables par rapport aux autres suggestions, car c'est probablement l'option la plus lisible pour les experts non PowerShell. Si je voyais un tutoriel / guide d'installation qui utilisait l'éclaboussure, je serais totalement perdu dans ce qui se passe sans un sous-tutoriel sur l'éclaboussure. De même, les backticks semblent fragiles et probablement moins bien connus que les simples variables PS éprouvées.
Josh Desmond
13

Si vous avez une fonction:

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

Si vous avez une applet de commande :

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

Si vous avez une application:

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

Ou

icm {foo.exe @Args} -Args @(
  'bar'
  'directory'
  $true
)
Steven Penny
la source
3

Dans PowerShell 5 et PowerShell 5 ISE, il est également possible d'utiliser juste Shift+ Enterpour l'édition multiligne (au lieu des raccourcis standard `à la fin de chaque ligne):

PS> &"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" # Shift+Enter
>>> -verb:sync # Shift+Enter
>>> -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" # Shift+Enter
>>> -dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"
Mauvais
la source
0

Méthode Splat avec calculs

Si vous choisissez la méthode splat, méfiez-vous des calculs effectués à l'aide d'autres paramètres. Dans la pratique, je dois parfois d'abord définir des variables, puis créer la table de hachage. En outre, le format ne nécessite pas de guillemets simples autour de la valeur de clé ou du point-virgule (comme mentionné ci-dessus).

Example of a call to a function that creates an Excel spreadsheet

$title = "Cut-off File Processing on $start_date_long_str"
$title_row = 1
$header_row = 2
$data_row_start = 3
$data_row_end = $($data_row_start + $($file_info_array.Count) - 1)

# use parameter hash table to make code more readable
$params = @{
    title = $title
    title_row = $title_row
    header_row = $header_row
    data_row_start = $data_row_start
    data_row_end = $data_row_end
}
$xl_wksht = Create-Excel-Spreadsheet @params

Remarque: Le tableau de fichiers contient des informations qui affecteront la façon dont la feuille de calcul est remplie.

marque
la source
-1

Une autre façon de séparer une chaîne sur plusieurs lignes consiste à placer une expression vide au milieu de la chaîne et à la répartir sur plusieurs lignes:

exemple de chaîne:

"stackoverflow stackoverflow stackoverflow stackoverflow stackoverflow"

en travers des lignes:

"stackoverflow stackoverflow $(
)stackoverflow stack$(
)overflow stackoverflow"
Kirill Yunussov
la source