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
239 stars 79 forks source link

Proper use of the pipeline with cmdlets #214

Open jrich523 opened 3 years ago

jrich523 commented 3 years ago

If you attempt to do this

Get-EC2Address | ? { -not $_.associationid } | Remove-EC2Address

You'll get the error: Remove-EC2Address: You may specify a public IP or allocation id, but not both in the same call.

Typically with powershell to solve this you'd give the cmdlet an inputobject param which it typed to the object, and allows pipeline input, which would end up binding the object to the param, and not to the params that are by property name

ashishdhingra commented 2 years ago

Refer about_Pipelines. Needs review with the team.

jrich523 commented 2 years ago

@ashishdhingra thank you for looking at this. As time has gone on i've noticed that this seems to happen with other aws cmdlets. I think it should be a safe assumption that if there is a Get-<something> i should always be able to pipe that directly to the related Remove-<something> it would certainly help with usability :)

jrich523 commented 2 years ago

I'll also add that its very common to use a param of InputObject as the typed object, for example look at Stop-Process

-InputObject <System.Diagnostics.Process[]>
        Specifies the process objects to stop. Enter a variable that contains the objects, or type a command or expression that gets the objects.

        Required?                    true
        Position?                    0
        Default value                None
        Accept pipeline input?       True (ByValue)
        Accept wildcard characters?  false

You could add this support without having to do anything too crazy or break backwards compatibility. Also maybe as a side note, but related, if an object is region bound, region should be included in the object (been a bit since i've used these, but i recall some objects not having that), so when its passed like this, you dont have to specify a region.

You can use the cmdlet info to poke around at it

$sp = get-command stop-process
$sp.ParameterSets | group name
$sp.ParameterSets | where name -eq InputObject

you'd create the InputObject parameter and parameter set and hopefully a some what light refactoring of the code it and shouldnt break any backwards compatibility and will allow the cmdlets to act in a more powershellish way

ojintoad commented 2 years ago

Thanks to the original submitter for adding this item. I brought this up in this discussion QA essentially: https://github.com/aws/aws-tools-for-powershell/discussions/285

Having to map 66 distinct properties just to have high confidence I'm updating my cloudfront distribution to be consistent with its existing state is just wild.

dbaileyut commented 1 year ago

Yes, much of the "power" of PowerShell comes from the pipeline. VMware.PowerCLI is a good example of a set of modules that treats the pipeline properly most of the time. AWS.Tools needs a lot of work in this area. Almost every cmdlet should accept pipeline input. Get verb cmdlets should accept strings of ARNs, for example. Set/Remove/Update/etc. should accept the output of the corresponding Get.