我想使用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:\用户\管理\ Dropbox的\项目\德勤\芯光伏\开发\脚本\ AZ-d eploy.ps1:36 char:13 + -ResourceGroupName $ ResourceGroup
+ ~~~~~~~~~~~~~~~~~~ Unexpected token '-ResourceGroupName' in expression or statement. At C:\Users\Administrator\Dropbox\projects\deloitte\Suncore\Dev\scripts\az-d eploy.ps1:36 char:32 + -ResourceGroupName $ResourceGroup
+ ~~~~~~~~~~~~~~
答案 0 :(得分:6)
要完全按照您的描述进行操作,您需要将整个命令包装为字符串,然后使用Invoke-Expression
调用它。例如:
$MyCommand = "$myVerb-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroup -TemplateFile $TemplateUri"
Invoke-Expression $MyCommand
但我认为这不是编写脚本的非常明确的方法。更好的选择是使用Splatting,您可以在其中创建参数的哈希表,然后可以通过带有变量名称的特殊@
字符发送cmdlet。例如:
$AzureParams = @{
ResourceGroupName = $ResourceGroup
TemplateFile = $TemplateUri
TemplateParameterFile = $TemplateParamFile
}
If ($booleanTest) {
Test-AzureRmResourceGroupDeployment @AzureParams
} Else {
New-AzureRmResourceGroupDeployment @AzurParams
}
这也有利于避免使用反引号字符,这通常是鼓励的,因为它很难发现并且容易破坏。
答案 1 :(得分:3)
我建议不要在其他答案上使用它,但要直接回答您的问题,请添加调用运算符&
$command = if ($booleanTest) {
"Test-AzureRmResourceGroupDeployment"
} else {
"New-AzureRmResourceGroupDeployment"
}
& $command `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
答案 2 :(得分:2)
补充现有的有用答案:
Invoke-Expression
应该始终是 last 度假胜地,此处不需要。使用Invoke-Expression
,获得正确的引用是很棘手的,并且它的使用可能是一种安全风险(执行任意命令作为字符串传递,类似于类似POSIX的shell中的eval
)。
Splatting (Get-Help about_Splatting
)总值得考虑:
但是,在目前的情况下,由于只有命令名称是可变的,Patrick's answer基于 &
},调用运算符最简单(参见Get-Help about_Operators
)。
通常,只要命令名称不 未加引号的文字 ,就需要&
(例如notepad foo.txt
虽然有效,但'notepad' foo.txt
没有。
换句话说:您需要&
,如果您的命令名称是:
'...'
还是"..."
);例如,'notepad'
$cmdName
('get' + '-item')
&
,以告诉PowerShell您的意图是调用命令,而不是评估表达式;如果没有&
,则此类令牌将被解释为启动表达式;请参阅Get-Help about_Parsing
,了解 PowerShell的两种基本解析模式,参数模式和表达模式 。
虽然它可能不是最易读的解决方案,但您甚至可以将可扩展字符串与嵌入式子表达式($(...)
- 再次组合,请参阅Get-Help about_Operators
)组合起来,无需辅助。变量:
& "$( if ($booleanTest) {'Test'} else {'New'} )-AzureRmResourceGroupDeployment" `
-ResourceGroupName $ResourceGroup `
-TemplateFile $TemplateUri `
-TemplateParameterFile $TemplateParamFile
答案 3 :(得分:0)
Splatting建议使用Mathias R. Jessen:
Function Do-AzureRmResourceGroupDeployment ([ValidateSet("Test", "New")]$Verb, $ResourceGroupName, $TemplateFile, $TemplateParameterFile) {
$PSBoundParameters.Remove("Verb")
& "$Verb-AzureRmResourceGroupDeployment" @PSBoundParameters
}