如何在PowerShell中将长命令拆分为多行


227

如何在PowerShell中采用类似以下的命令并将其分成多行?

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


Answers:


321

尾部反引号字符,即

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

空格很重要。所需格式为Space`Enter


1
这似乎破坏了命令历史记录(向上箭头)的功能;因为每行显示为单独的命令。有没有解决的办法?
理查德·埃夫

2
如果您运行的是Powershell 3或更高版本,请参阅github.com/lzybkr/psreadline-多行语句的历史记录遍历是固定的。
2013年

43
#treaded-the-hard-way
乔什·格雷厄姆

29
@ josh-graham在反-之后不应有任何空格(或内联注释)。#learned-the-hard-way
RayLuo

1
反引号很脆(如上面的注释所述),并且在分析或查看文件时很难找到。如果您想更轻松地调试代码,@ StevenPenny的答案会更好。
mjd2 '19

67

传递更清晰的参数的另一种方法是splat

将您的参数和值定义为哈希表,如下所示:

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

然后像这样调用您的命令行开关:

Get-WmiObject @params

Microsoft Docs:关于Splatting

TechNet杂志2011:Windows PowerShell:喷射

看起来它可以与Powershell 2.0及更高版本一起使用


5
太好了!:您可以添加参数,这样 $params.add('name','Bob Newhart') ramblingcookiemonster.wordpress.com/2014/12/01/...
bgmCoder

1
分号可以,但是多余。仅当每行有多个值时才需要。
吉姆·

38

嗯,如果您要分解很长的字符串(例如HTML),则可以通过@在外部的每一侧都放一个来完成"-像这样:

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

您得到的完全是这样:

Bob
went
to town
to buy
a fat
pig.

而且,如果您使用的是Notepad ++,它甚至可以正确地突出显示为字符串块。

现在,如果您也希望该字符串也包含双引号,只需将其添加进去,如下所示:

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

您将得到以下确切信息:

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

但是,如果像这样在@字符串中使用双引号,则Notepad ++不会意识到这一点,并且会根据情况切换语法颜色,就像未加引号或加引号一样。

更好的是:在任何插入$ variable的地方,它都会得到解释!(如果您在文本中需要美元符号,则可以使用一个勾号将其转义,例如:``$ not-a-variable`。)

注意!如果您没有将决赛"@放在该行最开始,它将失败。我花了一个小时才弄清楚我无法在代码中缩进!

这是有关该主题的MSDN使用Windows PowerShell“此处字符串”


1
整洁的技巧,尽管如果我有一个变量$ ...似乎不起作用。我收到“此处的字符串标题后不允许使用该字符...”
tofutim 2013年

我认为您不能破坏变量名,只能是字符串。
bgmCoder

19

您可以使用反引号运算符:

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

这对于我的口味来说仍然太长了,因此我将使用一些命名良好的变量:

$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
我喜欢使用变量名而不是其他建议,因为对于非Powershell专家而言,它可能是最易读的选项。如果我看到了使用喷溅的教程/设置指南,那么如果没有关于喷溅的子教程,那么我将完全迷失正在发生的事情。同样,反引号似乎很脆弱,可能不像简单的经过尝试的真实PS变量那样广为人知。
乔什·戴斯蒙德

13

如果具有功能:

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

如果您有一个cmdlet

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

如果您有申请:

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

要么

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

3

在PowerShell 5和PowerShell 5 ISE中,也可以仅使用Shift+ Enter进行多行编辑(而不是`每行末尾的标准反引号):

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"

0

Splat方法与计算

如果选择splat方法,请注意使用其他参数进行的计算。在实践中,有时我必须先设置变量,然后创建哈希表。另外,格式不需要在键值或分号两边加上单引号(如上所述)。

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

注意:文件数组包含的信息将影响电子表格的填充方式。


-1

跨多行中断字符串的另一种方法是在字符串中间放置一个空表达式,然后跨行中断它:

样本字符串:

"stackoverflow stackoverflow stackoverflow stackoverflow stackoverflow"

断线:

"stackoverflow stackoverflow $(
)stackoverflow stack$(
)overflow stackoverflow"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.