aws / aws-tools-for-powershell

The AWS Tools for PowerShell lets developers and administrators manage their AWS services from the PowerShell scripting environment.
Apache License 2.0
235 stars 78 forks source link

Add support to transform Resource IDs into Resource Objects #173

Closed JustOneMoreDog closed 2 years ago

JustOneMoreDog commented 3 years ago

Describe the Feature

I have been working on a script that will link together a variety of EC2 resources via their properties. For example, a VPC object normally looks like this

CidrBlock                   : 10.200.0.0/16
CidrBlockAssociationSet     : {vpc-cidr-assoc-0465bbd81aab7f9ca}
DhcpOptionsId               : dopt-foobar123
InstanceTenancy             : default
Ipv6CidrBlockAssociationSet : {}
IsDefault                   : False
OwnerId                     : 645152623978
State                       : available
Tags                        : {Name}
VpcId                       : vpc-abc123456

And what I am doing in my script is taking that DhcpOptionsId String and turning it into a Amazon.EC2.Model.DhcpOptions object.

[DBG]: C:\Users\adam...\OneD...\Desktop\Proj...\AWS> $filledOutVpc[0] | select * | fl

DhcpOptionsId               : Amazon.EC2.Model.DhcpOptions      
ResourceID                  : vpc-087ba190c62907b7d
Exists                      : True
CidrBlock                   : 10.200.0.0/16
CidrBlockAssociationSet     : {vpc-cidr-assoc-0465bbd81aab7f9ca}
InstanceTenancy             : default
Ipv6CidrBlockAssociationSet : {}
IsDefault                   : False
OwnerId                     : 645152623978
State                       : available
Tags                        : {Name}
VpcId                       : vpc-087ba190c62907b7d

[DBG]: C:\Users\adam...\OneD...\Desktop\Proj...\AWS> $filledOutVpc[0] | select -expand dhcpoptionsid | select 
* | fl

ResourceID         : dopt-41474f23
Exists             : True
DhcpConfigurations : {domain-name, domain-name-servers}
DhcpOptionsId      : dopt-41474f23
OwnerId            : 645152623978
Tags               : {}

(Note that ResourceID and Exists are two custom properties that I add in to help reduce the amount of iterations I have to do in certain parts of the script) However, I have not been able to find a way to do this reliably and consistently without breaking the script. After digging deep into this I think the issue may be that there are no overloaded method definitions for get/set-ing these properties' values with anything except a String.

Is your Feature Request related to a problem?

As far as I am concerned, these cmdlets are working and working really well. Without them I would not have learned as much as I did and I am extremely thankful for them. I am just looking to finish out this fun project that has gotten completely out of hand (like all projects).

Proposed Solution

I have not done any work with C# so I cannot say what would be the best course of action if there even would be one taken. I wish I had a bunch of spare time to sit down, learn C#, and make a viable solution for this. I assume it has to do with there not being an overloaded function definition but that is a wild guess.

Describe alternatives you've considered

As I have more time to work on my script I plan on working around this by making custom objects whenever I have to. Creating EC2 objects with [Amazon.EC2.Model.InstanceBlockDeviceMapping]::new() and then trying to modify them beyond what is currently supported is my issue. It gets worse when I try and add them to a generic list like New-Object 'System.Collections.Generic.List[Amazon.EC2.Model.InstanceBlockDeviceMapping]' because it is expecting a specific type of object and I am feeding it a modified version. The current best solution I have found is to exclude the properties I will be modifying with I create the object; [Amazon.EC2.Model.EbsInstanceBlockDevice]::new() | Select-Object -Property * -ExcludeProperty "VolumeId". I then use ArrayLists instead of generic lists to hold the collections of these objects.

Additional Context

I would say what I am doing is mostly for fun and less so practical. However, it would make doing audits way easier. With just 10 API calls you are able to enumerate a large majority of your EC2 infrastructure. Then this script takes that information and ties it all together for you. I have used earlier versions of this script to locate Snapshots of instances that longer exist, determine all the instances that have a certain port open, audit security groups, and more. I personally found it way easier to get information when instead of being presented with a resource ID, I am instead presented with its actually object.

Map showing all the connections: https://i.imgur.com/bCWEhMM.png Reddit post I made about this while trying to figure out a solution: https://www.reddit.com/r/PowerShell/comments/imhkh2/addmember_not_overwriting_member_even_with_force/ The Get-AWSEC2 script in its current state should it help add context: https://github.com/picnicsecurity/Get-AWSEC2

Environment

→ C:\Users\adam...\OneD...\Desktop\Proj...\AWS> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

This is a :rocket: Feature Request

github-actions[bot] commented 2 years ago

We have noticed this issue has not recieved attention in 1 year. We will close this issue for now. If you think this is in error, please feel free to comment and reopen the issue.