如何使用 splatting 将参数传递给双引号内的 PowerShell 命令

如何使用 splatting 将参数传递给双引号内的 PowerShell 命令

我正在尝试使用 msdeploy.exe 部署 Windows 服务。在这里我使用哈希表使其清晰易读。

对于此示例,我使用以下变量

$WIN_SERVICE_NAME="myService"
$SERVICE_APP_FILE="C:\Users\My User\Desktop\myService.exe"

# Windows 服务的哈希表

$params = @{
   Name = "$WIN_SERVICE_NAME"
   BinaryPathName = "$SERVICE_APP_FILE"
   StartupType = "Automatic"
   Description = "Release Management Service"
}

为了确保我可以使用 splatting 运算符获取正确的值,我使用了以下命令并返回预期的输出。

命令: Write-Host @params

输出: -DisplayName: myService -StartupType: Automatic -Description: Release Management Service -Name: myService -BinaryPathName: C:\Users\My User\Desktop\myService.exe

但是,当我尝试在双引号内使用 splatting 运算符时,如下所示:

Write-Host "@params"

@params作为输出返回而不进行扩展。

总之,这与我的函数内部发生的情况相同。我使用双引号,但 splatting 运算符无法展开。

# 使用 msdeploy.exe 部署 Windows 服务

& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
   -- AVOIDING UNNECESSARY LINES--
   -postSync:runCommand="`"powershell if (Get-Service $WIN_SERVICE_NAME -ErrorAction SilentlyContinue){ sc.exe delete $WIN_SERVICE_NAME; New-Service @params; Start-Service $WIN_SERVICE_NAME } else { New-Service @params; Start-Service $WIN_SERVICE_NAME }`""

你能帮我解决这个问题吗?我想扩展双引号内的 splatting 运算符,或者需要另一种解决方案,而无需在一行中添加所有参数。提前致谢!

答案1

您无法在字符串中预扩展 splat 变量。它由 PowerShell 命令解析器直接解释。

此外,您发送给 msdeploy 的命令最终会启动其自己的 PowerShell 会话。因此,如果您想使用变量(例如 splat 变量),则必须在您为该会话编写的代码中定义它。

因此,您必须$params = @{<blah>}在 runCommand 字符串中添加代码。如下所示:

& "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
   -- AVOIDING UNNECESSARY LINES--
   -postSync:runCommand="`"powershell $params = @{Name=`"$WIN_SERVICE_NAME`";StartupType=`"Automatic`"}; if (Get-Service $WIN_SERVICE_NAME -ErrorAction SilentlyContinue){ sc.exe delete $WIN_SERVICE_NAME; New-Service @params; Start-Service $WIN_SERVICE_NAME } else { New-Service @params; Start-Service $WIN_SERVICE_NAME }`""

注意哈希表声明中的转义引号。你需要这个,因为你的当前的PowerShell 会话将像您创建的字符串一样扩展变量$WIN_SERVICE_NAME。但您仍然需要用引号将值括起来未来实际上将运行命令中的代码的 PowerShell 会话。

答案2

在这种情况下,我建议不要使用 splat,而是将参数放在单个字符串变量中。如果您出于清晰度或其他原因确实想使用 slat,那么请创建一个由 splat 填充的字符串变量。

例如:

$params = @{
   Name = "service name"
   BinaryPathName = "C:\Program Files\Some Service\"
   StartupType = "Automatic"
   Description = "Release Management Service"
}
$newparams = ""
$newparams += foreach($k in $params.Keys) {
    Write-Output "-$k `"$($params.Item($k))`""
    }

相关内容