Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send variable number of key value pairs from CLI

Tags:

powershell

I'm needing to execute a PowerShell script as part of my TFS build pipeline. The PowerShell script is generic and executes a given AWS Cloud Formation template given to it. I need the developer to supply the template with a list of key/value pairs that represent the templates parameters. Since they can use this to execute any Cloud Formation template, the input parameters will vary.

How can I create an input parameter that is key/value based that I can pass as a parameter to another PowerShell object that accepts a Hashmap of parameters?

The following pseudo code is what I'm trying to achieve

param(
    [Parameter(Mandatory=$true)][string]$environment,
    [KeyValuePair[]]$templateParameters
)
New-CFNStack -StackName $stackName -TemplateURL $fullTemplateUrlPath -Parameters @( $templateParameters)

I can explicitly create the parameters and pass them in like this:

$bucketNameParameter = new-object Amazon.CloudFormation.Model.Parameter
$bucketNameParameter.ParameterKey = "bucketname"
$bucketNameParameter.ParameterValue = "FooBar"
$isVersionedParameter = new-object Amazon.CloudFormation.Model.Parameter
$isVersionedParameter.ParameterKey = "bucketname"
$isVersionedParameter.ParameterValue = "FooBar"
New-CFNStack -StackName $stackName -TemplateURL $fullTemplateUrlPath -Parameters @( $environmentParameter, @isVersionedParameter )

Since each template has completely different parameters they can take, I would like to make this script flexible to facilitate re-use. What is the most PowerShell way of approaching that?

like image 751
Johnathon Sullinger Avatar asked Sep 18 '25 13:09

Johnathon Sullinger


1 Answers

You can accept a [hashtable] instance and create your [Amazon.CloudFormation.Model.Parameter] instances based on its entries:

param(
  [Parameter(Mandatory=$true)] [string] $environment,
  [hashtable] $templateParameters
)

# Convert the hashtable's entries to an array of
# [Amazon.CloudFormation.Model.Parameter] instances.
$params = $templateParameters.GetEnumerator() | ForEach-Object { 
  $param = New-Object Amazon.CloudFormation.Model.Parameter
  $param.ParameterKey = $_.Key
  $param.ParameterValue = $_.Value
  $param # output
}

New-CFNStack -StackName $stackName -TemplateURL $fullTemplateUrlPath -Parameters $params

Note the use of .GetEnumerator(), which is necessary in order to enumerate the hashtable's entries and send them through the pipeline; by default, PowerShell sends hashtables as a whole through the pipeline.

Using your (modified-to-be-unique) example values, you'd invoke your script as:

./script.ps1 -environment foo `
             -templateParameters @{ bucketName1 = 'FooBar1'; bucketName2 = 'FooBar2' }
like image 74
mklement0 Avatar answered Sep 21 '25 18:09

mklement0