This post was triggered by a question in the PowerCLI Community around the ConfirmImpact attribute for PowerCLI cmdlets.
In PowerShell you can access the metadata of each cmdlet and extract quite a bit of useful information.
So I decided to have a look how I could use this cmdlet metadata to produce an alternative cmdlet reference for the PowerCLI cmdlets.
The list my script produces is NOT intended as a replacement for the excellent PowerCLI Reference. It is intended for those who already know what a PowerCLI cmdlet does but want to access parameter information quickly. It condences a lot of information in a spreadsheet.
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Get-Command -Module VMware.VimAutomation.Core | %{ $meta = New-Object System.Management.Automation.CommandMetadata (Get-Command $_.Name) $paramNr = 0 $meta.Parameters.GetEnumerator() | %{ $attribute = $_.Value.Attributes | where {$_.GetType().Name -eq "ParameterAttribute"} Select -InputObject $_ ` -Property @{N="Cmdlet";E={if($paramNr -eq 0){$meta.Name}}}, @{N="Parameter Name";E={$_.Key}}, @{N="Parameter Aliases";E={[string]::Join(',',($_.Value.Aliases.GetEnumerator() | %{$_}))}}, @{N="ParameterSets";E={[string]::Join(',',($_.Value.ParameterSets.GetEnumerator() | where {$_.Key -ne "__AllParameterSets"} | %{$_.Key}))}}, @{N="ConfirmImpact";E={if($paramNr -eq 0){$meta.ConfirmImpact}}}, @{N="OBN";E={if(($_.Value.Attributes | where {$_.GetType().Name -eq "ObnArgumentTransformationAttribute"})){$true}else{$false}}}, @{N="Mandatory";E={$attribute.Mandatory}}, @{N="Pipeline";E={$attribute.ValueFromPipeline}}, @{N="Position";E={if($attribute.Position -ne 0x80000000){$attribute.Position}}} $paramNr++ } } | Export-Csv "C:\PowerCLI-Xref.csv" -NoTypeInformation -UseCulture |
Annotations
Line 2: With the System.Management.Automation.CommandMetadata object we gain access to the cmdlet metadata.
Line 4: The Parameters property gives access to a hash table that holds all the information we are after.
Line 12: The OBN attribute indicates if for that specific parameter the value can be provided as an Object By Name.
Line 15: A parameter that is not a positional parameter will have the value 0x80000000
The file
The CSV file that the script produces looks like this
You can see all the PowerCLI cmdlets, the parameter sets that exist for a cmdlet, the eventual aliases that exist, the confirmimpact setting, if you can pass a specific parameter as an Object By Name, if the parameter is mandatory, if a parameter accepts pipeline input and finally the position number if it concerns a positional parameter.
Oddities
When you look closer at the CSV file you will notice that there are some oddities present. Most probably, the majority of these slipped it between successive PowerCLI builds. A short overview of what I noticed. Feel free to mention others in a comment.
Alias names
To say the least, they are not really consistent.
You would assume that the VMHost parameter has alias called Host. With most of the cmdlets that is the case, but there are exceptions.
Parameter sets
This handy feature seems to have some quirks as well.
Why would the RunAsync parameter have a dedicated parameter set for the Move-Datacenter cmdlet ?
Why does the DistributedSwitch parameter belong to a seperate parameter set on the New-NetworkAdapter cmdlet but not on the Set-NetworkAdapter ?
Confirm impact
Some of these settings do not look consistent and logical to me. What are the criteria to decide if the impact is Low, Medium or High ?
Postional parameters
The Position of a parameter is indicated with an integer, which starts at 0.
When you display the parameters with the Get-Help cmdlet, the position index is incremented by 1. This leads to the funny situation that you have no positional parameter in position 1.
I’m probably not seeing the bigger picture and I don’t know why some decissions were taken during the development of some of the cmdlets.
But perhaps the Dev Team could enlighten us and produce “The making of” blog post or video 😉
Hal Rottenberg
Any sufficiently advanced PowerShell scripter will eventually write this script, especially those who write books. 😀
Here’s my version: https://halr9000.com/article/507
And here’s one that was initially based on mine, but later improved by Joel Bennett, Oisin Grehan, and Jason Archer: https://poshcode.org/2404
LucD
Indeed 😉
But also someone who starts with a new snapin can profit from a handy XRef of the cmdlets and their parameters. You even mentioned my first attempt at such a parameter XRef in http://halr9000.com/article/482.
But the main goal of this post was in fact to show the oddities in the current PowerCLI snapin and perhaps trigger a global review of all the oddities.
Rusty
Ah, ’tis all good. Ran the script again today and this time there is output.
Cheers
Rusty
Hi, Ran the script and the csv was empty?
LucD
@Rusty, did you get any error messages ?
Are you using PowerShell v2 ?
Alan van Wyk
Thanks Luc- that’s genius – and very handy.
LucD
Thanks Alan, glad you like it.
Andrey Anastasov
Luc, thanks for taking the time to investigate and report the oddities. You are correct to assume that they accumulated over multiple releases and can benefit from cleanup.
In the case of ConfirmImpact, the rules we follow are not straightforward and indeed deserve a dedicated blog post. To use your example as illustration:
– Set-* cmdlets usually end up as medium priority
– Set-Snapshot can only modify name and description which have no impact on virtual machines’ end users. This amounts to ‘Low’ impact.
– With Set-StatInterval, it is possible to irreversibly delete existing statistics by setting a small StorageTimeSecs. This makes for ‘High’ impact.
Cheers,
Andrey Anastasov
PowerCLI Dev Team
LucD
Thanks for the feedback Andrey.
I’m looking forward to that blog post.