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:
I don't know what syntax to use for the -ParameterFilter
argument to match all parameters with the prefix /MyApp/
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?
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?