Tag Archives: New-Object

Add Tags to Existing AWS Parameter Store Entries

While I work with AWS, it’s unfortunately not a regular, I’m-going-to-be-in-there-a-few-times-a-week kind of a thing. Perhaps that’ll change in time, but for now, I take myself in there occasionally when there’s something I want to try, use, fix, or experiment with. Today started when I ran up against a handful of Systems Manager Parameter Store entries I had created where I didn’t include any Tags. I didn’t want to be that guy, but I also didn’t want to be the guy that manually updated each of the 12 entries by hand. Yeah, that’s not me. There were two tags per entry. It’s not that many, but still.

The documentation to do this is available in the AWS PowerShell documentation. Even so, I’m going to share what I wrote and briefly discuss it. Perhaps someone will find it instead of, or in addition to, what’s already been written about it. Anyway, let’s get started. The below code is mostly one large, continuous code block, however, I’m breaking it up to discuss it.

The first code block creates and assigns a $CommonParams variable. This holds values that each of the AWS commands needs to have included. This is just an easier way to include these parameters and parameter values in each command. This variable, when included with an AWS command (as @CommonParams), will include the Region in which I’m working and the local AWS profile (on my computer) that I’m using to run these commands. Behind this profile is an Access Key Id and corresponding Secret Access Key.

$CommonParams = @{
	Region = 'us-west-2'
	ProfileName = 'tommymaynard_api@ecs-nonprod'
}

Using the below PowerShell we can isolate the Systems Manager Parameter Store entries that we want to modify. Each entry begins with a forward slash (/), but doesn’t begin with a forward-slash followed by fdn.

$Parameters = Get-SSMParameterList @CommonParams | Where-Object -FilterScript {
	$_.Name -like '/*' -and $_.Name -notlike '/fdn*'} | Select-Object -Property Name

This next section isn’t a part of the code. It’s being included, however, so that you’re able to view the values stored in the $Parameters variable. The entire code is included at the bottom of this evening’s post so that it’s easy to capture for those that are interested.

$Parameters

Name
----
/PowerShell/FunctionTemplate/Splunk/Logging/HEC_Token  
/PowerShell/FunctionTemplate/Splunk/Logging/HEC_URL    
/PowerShell/FunctionTemplate/Splunk/Telemetry/HEC_Token
/PowerShell/FunctionTemplate/Splunk/Telemetry/HEC_URL  
/ad_join/domain  
/ad_join/password
/ad_join/user    
/agents/duo/host 
/agents/duo/ikey 
/agents/duo/skey
/agents/omsagent/primarykey 
/agents/omsagent/workspaceid
/agents/sophos/linux_url        
/agents/tenable/nessus/host     
/agents/tenable/nessus/key      
/agents/tenable/nessus/linux_url

In order to apply Tags to each of the above Parameter Store entries, we need to first create them. In $Tag01 we’ll store the createdby key and its corresponding value. In $Tag02 we’ll store the contactid and its corresponding value.

$Tag01 = New-Object Amazon.SimpleSystemsManagement.Model.Tag
$Tag02 = New-Object Amazon.SimpleSystemsManagement.Model.Tag
$Tag01.Key = 'createdby'; $Tag01.Value = 'tommymaynard'
$Tag02.Key = 'contactid'; $Tag02.Value = $Tag01.Value

This section also isn’t a part of the code. It’s been included as verification that our Tags have been properly assigned, prior to being applied to each of the Parameter Store entries.

$Tag01; $Tag02

Key       Value
---       -----
createdby tommymaynard
contactid tommymaynard

This next code block returns the current Tags for each of the Parameter Store entries. Running this code here allows us to view the current Tags, if there are any, prior to adding the Tags we know we want on each of the entries.

$Parameters.Name | ForEach-Object {
	$_; Get-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_; '---'
} # End ForEach-Object.

This is the code block that adds our Tags to each of the Parameter Store entries. We ensured we were working with the correct entries, we created our Tags—both the keys and the corresponding values—and now we’re applying them to each entry.

$Parameters.Name | ForEach-Object {
	Add-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_ -Tag $Tag01,$Tag02
} # End ForEach-Object.

This is the same code block we saw two blocks earlier. All it does is return the Tags for each of the Parameter Store entries. It’s included again in order to review the changes since running the Add-SSMResourceTag command. While we might normally output this as PowerShell objects, I didn’t find that to be necessary since it was simple output that only I would see and then disregard.

$Parameters.Name | ForEach-Object {
	$_; Get-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_; '---'
} # End ForEach-Object.

As mentioned, and since I stuck some not to be included code within the code, here’s the full code for adding new Parameter Store Tags entries.

$CommonParams = @{
	Region = 'us-west-2'
	ProfileName = 'tommymaynard_api@ecs-nonprod'
}

$Parameters = Get-SSMParameterList @CommonParams | Where-Object -FilterScript {
	$_.Name -like '/*' -and $_.Name -notlike '/fdn*'} | Select-Object -Property Name

$Tag01 = New-Object Amazon.SimpleSystemsManagement.Model.Tag
$Tag02 = New-Object Amazon.SimpleSystemsManagement.Model.Tag
$Tag01.Key = 'createdby'; $Tag01.Value = 'tommymaynard'
$Tag02.Key = 'contactid'; $Tag02.Value = $Tag01.Value

$Parameters.Name | ForEach-Object {
	$_; Get-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_; '---'
} # End ForEach-Object.

$Parameters.Name | ForEach-Object {
	Add-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_ -Tag $Tag01,$Tag02
} # End ForEach-Object.

$Parameters.Name | ForEach-Object {
	$_; Get-SSMResourceTag @CommonParams -ResourceType 'Parameter' -ResourceId $_; '---'
} # End ForEach-Object.

I didn’t specifically test whether this overwrote Tags of the same name that existed on each entry. That said, I believe it did in fact appear to overwrite them without a care, concern, or prompt. If this is important, then it would probably be wise to test this and/or write the conditional code to do something different, if that’s what you want.