How to use Get-SSMParameterList CmdLet to process parameters with a specific prefix

4.1k views Asked by At

I want to write a Powershell script that will get all parameters from the AWS SSM Parameter store that belong to my application, then iterate over the parameters and perform an action on each one. The parameters for my application are identified by having a specific prefix, e.g. they are named:

/MyApp/Component1/Param1
/MyApp/Component1/Param2
/MyApp/Component2/Param1
...

I'm a Powershell beginner, but my starting point is to use the AWS Get-SSMParameterList CmdLet, and filter the results by the prefix /MyApp/.

I see from the linked documentation, that a single call to Get-SSMParameterList returns results on a best-effort basis, i.e. I may need to call it repeatedly passing the -NextToken parameter received from a previous call in order to guarantee that I get all results. This answer to a related question states that "the vast majority" of AWS CmdLets handle paging automatically if -NextToken and -MaxResult are not specified but it's not clear to me from the documentation if this CmdLet is included in this majority.

I'm stuck on the following:

  1. I don't know what syntax to use for the -ParameterFilter argument to match all parameters with the prefix /MyApp/

  2. I'd like confirmation that I don't need to use -NextToken to get all results, or, if I do need it, to know how to capture the NextToken value returned by the API, so I can loop and get the next page of results.

Can anyone help with this?

UPDATE

For point 2, my experience suggests I don't need to use -NextToken and to date have always got all results in one call. But I guess this may depend on the number of parameters in the result set.

For point 1, I've found a way of doing this, which is:

[System.Reflection.Assembly]::LoadFile(
    "...\AWSSDK.SimpleSystemsManagement.dll")

...
$p = New-Object Amazon.SimpleSystemsManagement.Model.ParameterStringFilter
$p.Key = "Name"
$p.Option = "BeginsWith"
$p.Values = "/...my prefix..."

Get-SSMParameterList -ParameterFilter $p ...

but this seems ugly, as it requires me to know where the AWSSDK.SimpleSystemsManagement.dll assembly is installed in order to use the Get-SSMParameterList CmdLet. I would have expected as a minimum to be able to use:

$p = New-SSMParameterFilter -Key "Name" -Option "BeginsWith" -Values "..."
Get-SSMParameterList -ParameterFilter $p

Another SSM CmdLet that appears to require me to load the AWSSDK.SimpleSystemsManagement.dll assembly is Add-SSMResourceTag, whose -Tags parameter requires an array of Amazon.SimpleSystemsManagement.Model.Tag objects:

$tag = New-Object Amazon.SimpleSystemsManagement.Model.Tag
$tag.Key = ...
$tag.Value = ...
Add-SSMResourceTag -Tags ($tag)

Why doesn't the -Tags parameter take a Hashtable like Add-SQSResourceTag?

$tags = @{}
$tags.add(key, value)
Add-SQSResourceTag -Tags $tags

Have I understood this right or is there a way of doing this without loading an assembly?

3

There are 3 answers

0
Joe On BEST ANSWER

As pointed out in the answer from Nick Cox:

the DLL is loaded with the AWSPowerShell module for me

In the example Nick posted, it was loaded by a previous call to Get-AWSPowerShellVersion: in fact it is auto-loaded the first time any AWS cmdlet is called (and, btw, it takes up to 30 seconds to load!!!). I understand Amazon is working on the load time but I haven't seen this so far (in particular it's not in the AMIs I'm currently using, which means the UserData script is very slow).

So the inconsistent behavior I was seeing was because the availability or not of the Amazon.SimpleSystemsManagement.Model.ParameterStringFilter Type was dependent on whether or not the AWSPowerShell module had been previously loaded. If I happen to have used an AWS cmdlet previously, it works; otherwise, it doesn't.

The solution, of course, is to explicitly ensure it's loaded before referencing any of its types:

Import-Module "AWSPowerShell" 
$p = New-Object Amazon.SimpleSystemsManagement.Model.ParameterStringFilter
$p.Key = "Name"
$p.Option = "BeginsWith"
$p.Values = "/...my prefix..."

Get-SSMParameterList -ParameterFilter $p ...

This still begs the question: why does a cmdlet take a parameter that is a custom type that may not be available before the cmdlet is called?

1
Greg Faulk On

Regarding your question about the explicit loading of the DLL, I find that with the following code that is not necessary for me:

$p = new-object -typename Amazon.SimpleSystemsManagement.Model.ParameterStringFilter -property @{key="Name";Option="BeginsWith";Values="sandbox"}
Get-SSMParameterList -ParameterFilter @($p)

This produces the correct filtered results for me.

Please note that -ParameterFilter takes an array of ParameterStringFilter.

I am using powershell version 5.1.17134.228 (as shown by $PSVERSIONTABLE) and Get-AWSPowerShellVersion returns "Version 3.3.215.0"

0
Nick Cox On

Late to the party here but, like Greg, the DLL is loaded with the AWSPowerShell module for me.

PS C:\Users\ncox> Get-AWSPowerShellVersion

AWS Tools for Windows PowerShell
Version 3.3.390.0
Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Amazon Web Services SDK for .NET
Core Runtime Version 3.3.28.0
Copyright 2009-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

...

PS C:\Users\ncox> [appdomain]::currentdomain.getassemblies() |? FullName -Like "AWSSDK.SimpleSystems*" | select fullname

FullName
--------
AWSSDK.SimpleSystemsManagement, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604

PS C:\Users\ncox> 

As as alternative, perhaps you could use Get-SSMParametersByPath?

Get-SSMParametersByPath -Path '/...myPrefix...'