我想使用 if else
语句确定要运行的cmdlet,同时保留两个命令的相同参数:
例如,我有这个电话:
New-AzureRmResourceGroupDeployment `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
,但我想使用一个变量来确定动词:
$myVerb = if ($booleanTest) {"Test"} else {"New"}
[$myVerb]-AzureRmResourceGroupDeployment `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
或类似的东西:
$command = if ($booleanTest) {"Test-AzureRmResourceGroupDeployment"} else {"New-AzureRmResourceGroupDeployment"}
$command `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
我尝试了$command
版本,但由于以下方式失败了:
在 C: users indercancer dropbox projects deloitte suncore suncore dev scripts az-d eploy.ps1:36 char:13 -ResourceGroupName $ ResourceGroup
+ ~~~~~~~~~~~~~~~~~~ Unexpected token '-ResourceGroupName' in expression or statement. At C:UsersAdministratorDropboxprojectsdeloitteSuncoreDevscriptsaz-d eploy.ps1:36 char:32 + -ResourceGroupName $ResourceGroup
~~~~~~~~~~~~~~~
准确地做您所描述的操作,需要将整个命令包裹为字符串,然后用Invoke-Expression
调用它。例如:
$MyCommand = "$myVerb-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroup -TemplateFile $TemplateUri"
Invoke-Expression $MyCommand
,但我认为这不是编写脚本的非常清晰的方法。一个更好的选择是使用剥离,这是您创建参数的标签,然后可以通过具有变量名称的特殊@
字符发送CMDLET。例如:
$AzureParams = @{
ResourceGroupName = $ResourceGroup
TemplateFile = $TemplateUri
TemplateParameterFile = $TemplateParamFile
}
If ($booleanTest) {
Test-AzureRmResourceGroupDeployment @AzureParams
} Else {
New-AzureRmResourceGroupDeployment @AzurParams
}
这也具有避免使用反向特征的好处,这通常会受到鼓励,因为很难发现并且易于破裂。
我不建议通过其他答案使用它,而是要直接回答您的问题,请添加调用操作员&
$command = if ($booleanTest) {
"Test-AzureRmResourceGroupDeployment"
} else {
"New-AzureRmResourceGroupDeployment"
}
& $command `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
to 补充现有有用的答案:
-
Invoke-Expression
始终是 last Resort ,在这里不需要。使用Invoke-Expression
,正确的报价很棘手,并且其使用可能是安全风险(执行任意命令作为字符串执行,类似于Posix的Shell中的eval
)。 -
splatting (
Get-Help about_Splatting
)总是值得考虑的:- 这是与Mark的答案解释的多行参数通行更强大的替代方案。
- it 允许逐步构造参数值集及其在多个调用中使用。
-
在手头的情况下,由于仅命令名称是变量,帕特里克的答案基于
&
,呼叫操作员最简单(请参阅Get-Help about_Operators
)。
通常,您需要&
,每当命令名称 and 无引用的文字(例如,notepad foo.txt
工作,'notepad' foo.txt
都没有)。
以不同的方式提出:您需要&
,如果您的命令名称是:
- 在 quotes 中(无论是
'...'
还是"..."
);例如,'notepad'
- 或IS 变量参考;例如,
$cmdName
- 或 expression 的结果(例如,
('get' + '-item')
&
,以便告诉PowerShell您的意图是调用A 命令,而不是评估 expression ;没有&
,这种令牌将被解释为启动 expression ;请参阅Get-Help about_Parsing
了解 PowerShell的两种基本解析模式,参数模式和表达模式。
虽然它可能不是最可读的解决方案,因此您甚至可以将可扩展的字符串与嵌入式子表达($(...)
-再次,请参见Get-Help about_Operators
)结合起来,而无需AUX。变量:
& "$( if ($booleanTest) {'Test'} else {'New'} )-AzureRmResourceGroupDeployment" `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
使用Mathias R. Jessen建议的分裂:
Function Do-AzureRmResourceGroupDeployment ([ValidateSet("Test", "New")]$Verb, $ResourceGroupName, $TemplateFile, $TemplateParameterFile) {
$PSBoundParameters.Remove("Verb")
& "$Verb-AzureRmResourceGroupDeployment" @PSBoundParameters
}