├── License ├── ReadMe.md ├── Register-VNAWSArgumentCompleter.ps1 ├── Register-VNActiveDirectoryArgumentCompleter.ps1 ├── Register-VNVMwarePowerCLIArgumentCompleter.ps1 ├── ScriptFileInfoConfig_Register-VNAWSArgumentCompleter.psd1 ├── ScriptFileInfoConfig_Register-VNActiveDirectoryArgumentCompleter.psd1 ├── ScriptFileInfoConfig_Register-VNVMwarePowerCLIArgumentCompleter.psd1 ├── Set-ScriptFileInfoForCompleter.ps1 ├── docs ├── ChangeLog.md ├── ReadMe.md └── resources │ └── ArgCompleterDemo_Keystrokes.gif └── snippetsAndExploration.ps1 /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) since 2019, vNugglets 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | ## Argument Completers for some PowerShell module cmdlets 2 | 3 | A collection of some PowerShell argument completers for various cmdlets from some PowerShell modules: 4 | 5 | | Argument Completer Script | Description | PSGallery Info | 6 | |---------------------------|-------------|----------------| 7 | | Register-VNActiveDirectoryArgumentCompleter.ps1 | Completers for Microsoft's `ActiveDirectory` PowerShell module | [![Latest Version](https://img.shields.io/powershellgallery/v/Register-VNActiveDirectoryArgumentCompleter.svg?style=flat&logo=powershell&label=Latest)](https://www.powershellgallery.com/packages/Register-VNActiveDirectoryArgumentCompleter) [![Downloads](https://img.shields.io/powershellgallery/dt/Register-VNActiveDirectoryArgumentCompleter.svg?style=flat&logo=powershell&label=Downloads)](https://www.powershellgallery.com/packages/Register-VNActiveDirectoryArgumentCompleter) | 8 | | Register-VNAWSArgumentCompleter.ps1 | Completers for some of the AWS PowerShell modules `AWS.Tools.*`, and the monolithic `AWSPowerShell*` | [![Latest Version](https://img.shields.io/powershellgallery/v/Register-VNAWSArgumentCompleter.svg?style=flat&logo=powershell&label=Latest)](https://www.powershellgallery.com/packages/Register-VNAWSArgumentCompleter) [![Downloads](https://img.shields.io/powershellgallery/dt/Register-VNAWSArgumentCompleter.svg?style=flat&logo=powershell&label=Downloads)](https://www.powershellgallery.com/packages/Register-VNAWSArgumentCompleter) | 9 | | Register-VNVMwarePowerCLIArgumentCompleter.ps1 | Completers for VMware PowerShell module `VMware.PowerCLI` | [![Latest Version](https://img.shields.io/powershellgallery/v/Register-VNVMwarePowerCLIArgumentCompleter.svg?style=flat&logo=powershell&label=Latest)](https://www.powershellgallery.com/packages/Register-VNVMwarePowerCLIArgumentCompleter) [![Downloads](https://img.shields.io/powershellgallery/dt/Register-VNVMwarePowerCLIArgumentCompleter.svg?style=flat&logo=powershell&label=Downloads)](https://www.powershellgallery.com/packages/Register-VNVMwarePowerCLIArgumentCompleter) | 10 | 11 | 12 | 13 | Contents: 14 | 15 | - [What is Argument Completing?](#whatIsArgCompleting) 16 | - [Getting Started](#gettingStarted) 17 | - [Deeper Info](#deeperInfo) 18 | 19 | 20 | 21 | ## What is Argument Completing? 22 | Background: PowerShell argument completers are a way to enable tab-completion of cmdlet parameter values. These can be from static sources, live sources -- whatever you can imagine. Here are some examples of argument completing for a few VMware PowerCLI cmdlets' parameters: 23 | 24 | ![Examples of Argument Completers for cmdlets from VMware.PowerCLI](docs/resources/ArgCompleterDemo_Keystrokes.gif) 25 | 26 | 27 | ## Getting Started 28 | The [docs](./docs) for this project have the information about getting started with using argument completers. Check them out. 29 | 30 | 31 | ## Deeper Info 32 | 33 | One can use a scriptblock of goodness in order to generate the completion results. So, for example: 34 | ``` PowerShell 35 | ## with a proper argument completer for the -Name parameter, the following cycles through VMs whose name match the given string, live, from the given virtual infrastructure 36 | Get-VM -Name matt 37 | ``` 38 | By registering an argument completer scriptblock for a particular cmdlet and parameter, at tab-completion time, that completer generates a list of completion results (assuming any matches), through which the user can subsequently cycle via further `Tab`-ing. The workflow: 39 | - register argument completer scriptblock for a cmdlet/parameter pair (say, by runnig a script that has argument completers in it, and that registers them for cmdlet/parameter pairs) 40 | - for a registered argument completer, the argument scriptblock is executed one time for the first press of the `Tab` key, creating a list of completion results (if any) 41 | - each subsequent press of `Tab` cycles through the list of completions results (assuming that there is more than one) 42 | - one can also see the whole list of completion results, assuming they are in an environment that supports such things, like in something with IntelliSense, or in a PowerShell session with the `PSReadline` module loaded 43 | 44 | A bit deeper explanation on the behavior resides at [https://github.com/mtboren/PowerCLIFeedback/blob/master/PowerCLISuggestions.md](https://github.com/mtboren/PowerCLIFeedback/blob/master/PowerCLISuggestions.md) in the "Support Natural PowerShell Interactive Behavior" section 45 | 46 | For a bit more information about PowerShell argument completers (though there is not extensive official documentation on argument completers themselves to be found, yet), see [Register-ArgumentCompleter 47 | ](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter) -------------------------------------------------------------------------------- /Register-VNAWSArgumentCompleter.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | 3 | .VERSION 1.3.2 4 | 5 | .GUID bc73fa4a-6436-4524-b722-e7b3a98fdfac 6 | 7 | .AUTHOR Matt Boren (@mtboren) 8 | 9 | .COMPANYNAME vNugglets 10 | 11 | .COPYRIGHT MIT License 12 | 13 | .TAGS vNugglets PowerShell ArgumentCompleter Parameter AWS Amazaon AmazonWebServices AdminOptimization NaturalExperience TabComplete TabCompletion Completion Awesome 14 | 15 | .LICENSEURI https://github.com/vNugglets/PowerShellArgumentCompleters/blob/main/License 16 | 17 | .PROJECTURI https://github.com/vNugglets/PowerShellArgumentCompleters 18 | 19 | .ICONURI https://avatars0.githubusercontent.com/u/22530966 20 | 21 | .EXTERNALMODULEDEPENDENCIES 22 | 23 | .REQUIREDSCRIPTS 24 | 25 | .EXTERNALSCRIPTDEPENDENCIES 26 | 27 | .RELEASENOTES 28 | See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters 29 | 30 | .PRIVATEDATA 31 | 32 | #> 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | <# 45 | 46 | .DESCRIPTION 47 | Script to register PowerShell argument completers for many parameters for many AWS.Tools.* (and AWSPowerShell*) cmdlets, making us even more productive on the command line. This enables the tab-completion of actual AWS inventory objects' names as values to parameters to AWS cmdlets -- neat! 48 | 49 | .Example 50 | Register-VNAWSArgumentCompleter.ps1 51 | Register argument completers for all of the AWS PowerShell cmdlets that are currently available in this PowerShell session, and for which there is an argument completer defined in this script 52 | 53 | .Link 54 | https://vNugglets.com 55 | https://github.com/vNugglets 56 | Register-ArgumentCompleter 57 | AWS PowerShell modules 58 | #> 59 | 60 | Param() 61 | 62 | process { 63 | ## Object name completer 64 | $sbObjectNameCompleter = { 65 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 66 | ## any parameters to pass on through to the Get-* cmdlet (like ProfileName, for example) 67 | $hshParamForGet = @{} 68 | if ($commandBoundParameter.ContainsKey("ProfileName")) {$hshParamForGet["ProfileName"] = $commandBoundParameter.ProfileName} 69 | 70 | ## the property of returned objects that is of interest 71 | $strPropertyNameOfInterest = $parameterName ## the property name that corrsponds to the 72 | $strPropertyNameOfInterest_CreationDate = "CreationDate" ## the property name that corresponds to when the object was created (not consistent across all objects) 73 | ## string to include in tooltip for creation / last modified text 74 | $strAddlInfoDescriptor = "created" 75 | $strCmdletForGet = Switch ($parameterName) { 76 | "AutoScalingGroupName" {"Get-ASAutoScalingGroup"; $strPropertyNameOfInterest_CreationDate = "CreatedTime"} 77 | "BucketName" {"Get-S3Bucket"} 78 | "FunctionName" {"Get-LMFunctionList"} 79 | "LaunchConfigurationName" {"Get-ASLaunchConfiguration"; $strPropertyNameOfInterest_CreationDate = "CreatedTime"} 80 | {"LogGroupName", "LogGroupNamePrefix" -contains $_} {"Get-CWLLogGroup"; $strPropertyNameOfInterest = "LogGroupName"; $strPropertyNameOfInterest_CreationDate = "CreationTime"} 81 | "Name" { 82 | $strPropertyNameOfInterest_CreationDate = "CreatedTime" 83 | ## return the name of the cmdlet to use for getting list of arg completers, and optionally set other things 84 | Switch ($commandName) { 85 | "Get-ELB2LoadBalancer" {$commandName; $strPropertyNameOfInterest = "LoadBalancerName"} 86 | "Get-ELB2TargetGroup" {$commandName; $strPropertyNameOfInterest = "TargetGroupName"} 87 | "Get-SSMDocument" {"Get-SSMDocumentList"; $strPropertyNameOfInterest_CreationDate = "CreatedDate"} 88 | {"Get-SSMParameter", "Get-SSMParameterHistory" -contains $_} {"Get-SSMParameterList"; $strPropertyNameOfInterest_CreationDate = "LastModifiedDate"; $strAddlInfoDescriptor = "last modified"} 89 | default {$commandName} 90 | } ## end inner switch 91 | } ## end case 92 | "RoleName" {"Get-IAMRoleList"; $strPropertyNameOfInterest_CreationDate = "CreateDate"} 93 | "StackName" {"Get-CFNStack"; $strPropertyNameOfInterest_CreationDate = "CreationTime"} 94 | } 95 | & $strCmdletForGet @hshParamForGet | Foreach-Object {if (-not [System.String]::IsNullOrEmpty($wordToComplete)) {if ($_.$strPropertyNameOfInterest -like "${wordToComplete}*") {$_}} else {$_}} | Sort-Object -Property $strPropertyNameOfInterest | Foreach-Object { 96 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 97 | $_.$strPropertyNameOfInterest, # CompletionText 98 | $_.$strPropertyNameOfInterest, # ListItemText 99 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 100 | ("{0}{1}" -f $_.$strPropertyNameOfInterest, $(if ($_ | Get-Member -Name $strPropertyNameOfInterest_CreationDate) {" ($strAddlInfoDescriptor $($_.$strPropertyNameOfInterest_CreationDate))"})) # ToolTip 101 | ) 102 | } ## end Foreach-Object 103 | } ## end scriptblock 104 | 105 | ## for all of the cmdlets with these params 106 | $arrAllCmdsOfInterest = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName ($arrParamNames = Write-Output AutoScalingGroupName, BucketName, FunctionName, LaunchConfigurationName, LogGroupName, LogGroupNamePrefix, RoleName, StackName) -ErrorAction:SilentlyContinue 107 | $arrParamNames | ForEach-Object { 108 | $strThisParamName = $_ 109 | ## commands with this parameter 110 | $arrCommandsWithThisParam = $arrAllCmdsOfInterest.Where({$_.Parameters.ContainsKey($strThisParamName) -or ($_.Parameters.Values.Aliases -contains $strThisParamName)}) 111 | ## if there are any commands with this param, register the arg completer for them for this param 112 | if (($arrCommandsWithThisParam | Measure-Object).Count -gt 0) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $strThisParamName -ScriptBlock $sbObjectNameCompleter} 113 | } ## end foreach-object 114 | 115 | ## specific cmdlets with -Name parameter 116 | Write-Output Get-ELB2LoadBalancer, Get-ELB2TargetGroup, Get-SSMDocument, Get-SSMParameter, Get-SSMParameterHistory | Foreach-Object { 117 | if (Get-Command -Name $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $_ -ParameterName Name -ScriptBlock $sbObjectNameCompleter} 118 | } ## end Foreach-Object 119 | 120 | 121 | 122 | ## Completer for things like VPCId, EC2 KeyName, lots more 123 | $sbMultipleObjCompleter = { 124 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 125 | ## any parameters to pass on through to the Get-* cmdlet (like ProfileName, for example) 126 | $hshParamForGet = @{} 127 | if ($commandBoundParameter.ContainsKey("ProfileName")) {$hshParamForGet["ProfileName"] = $commandBoundParameter.ProfileName} 128 | 129 | ## strPropertyNameOfInterest: property of returned objects that is of interest 130 | ## strCmdletForGet: name of cmdlet to use to _get_ the objects to use for completing argument 131 | ## or sbToGetDesiredObjects: script block for geting said objects (useful if the "getting" is more than just a cmdlet) 132 | ## arrPropertiesToSelect: the properties to select for the ToolTip output (can be calculated properties) 133 | switch ($parameterName) { 134 | "AssociationId" { 135 | $strPropertyNameOfInterest = "AssociationId" 136 | $strCmdletForGet = "Get-SSMAssociationList" 137 | $arrPropertiesToSelect = Write-Output AssociationName AssociationVersion LastExecutionDate @{n="DocumentName"; e={$_.Name}} ScheduleExpression 138 | break 139 | } 140 | "Cluster" { 141 | $strPropertyNameOfInterest = "ClusterName" 142 | $sbToGetDesiredObjects = {(Get-ECSClusterList @hshParamForGet | Get-ECSClusterDetail @hshParamForGet).Clusters} 143 | $arrPropertiesToSelect = Write-Output ActiveServicesCount Attachments CapacityProviders RegisteredContainerInstancesCount RunningTasksCount Status 144 | break 145 | } 146 | "DBInstanceIdentifier" { 147 | $strPropertyNameOfInterest = "DBInstanceIdentifier" 148 | $strCmdletForGet = "Get-RDSDBInstance" 149 | $arrPropertiesToSelect = Write-Output DBName @{n="AllocatedStorageGB"; e={$_.AllocatedStorage}} AvailabilityZone DBClusterIdentifier DBInstanceClass DBInstanceStatus Engine EngineVersion StorageEncrypted StorageType 150 | break 151 | } 152 | "EventBusName" { 153 | $strPropertyNameOfInterest = "Name" 154 | $strCmdletForGet = "Get-EVBEventBusList" 155 | $arrPropertiesToSelect = Write-Output Arn 156 | break 157 | } 158 | "FileSystemId" { 159 | ## the noun prefix for the invoking command, so as to know what Get- cmdlet to use 160 | $strNounPrefixFromInvokingCmdlet = (($commandName.Split("-")[1]).ToCharArray() | Select-Object -First 3) -join "" 161 | $strPropertyNameOfInterest = "FileSystemId" 162 | Switch ($strNounPrefixFromInvokingCmdlet) { 163 | "EFS" { 164 | $strCmdletForGet = "Get-EFSFileSystem" 165 | $arrPropertiesToSelect = Write-Output Name Encrypted LifeCycleState NumberOfMountTargets @{n="SizeGB"; e={$_.SizeInBytes.Value / 1GB}} 166 | break 167 | } 168 | "FSX" { 169 | $strCmdletForGet = "Get-FSXFileSystem" 170 | $arrPropertiesToSelect = Write-Output FileSystemType Lifecycle @{n="StorageCapacityGB"; e={$_.StorageCapacity}} StorageType 171 | break 172 | } 173 | } ## end switch 174 | } 175 | "Group" { 176 | $strPropertyNameOfInterest = "Name" 177 | $sbToGetDesiredObjects = {Get-RGGroupList | ForEach-Object {Get-RGGroup -Group $_.GroupName}} 178 | $arrPropertiesToSelect = Write-Output Description 179 | } 180 | "GroupName" { 181 | $strPropertyNameOfInterest = "GroupName" 182 | $strCmdletForGet = "Get-IAMGroupList" 183 | $arrPropertiesToSelect = Write-Output Arn CreateDate GroupId 184 | } 185 | "KeyName" { 186 | $strPropertyNameOfInterest = "KeyName" 187 | $strCmdletForGet = "Get-EC2KeyPair" 188 | $arrPropertiesToSelect = Write-Output KeyFingerprint KeyPairId KeyType 189 | break 190 | } 191 | "PolicyArn" { 192 | $strPropertyNameOfInterest = "Arn" 193 | $strCmdletForGet = "Get-IAMPolicyList" 194 | $arrPropertiesToSelect = Write-Output PolicyName DefaultVersionId UpdateDate AttachmentCount Description 195 | break 196 | } 197 | "RoleArn" { 198 | $strPropertyNameOfInterest = "Arn" 199 | $strCmdletForGet = "Get-IAMRoleList" 200 | $arrPropertiesToSelect = Write-Output CreateDate Description Path RoleLastUsed 201 | break 202 | } 203 | "RepositoryName" { 204 | $strPropertyNameOfInterest = "RepositoryName" 205 | $strCmdletForGet = "Get-ECRRepository" 206 | $arrPropertiesToSelect = Write-Output RepositoryUri CreatedAt 207 | break 208 | } 209 | {$_ -match "SubnetId"} { 210 | $strPropertyNameOfInterest = "SubnetId" 211 | $strCmdletForGet = "Get-EC2Subnet" 212 | $arrPropertiesToSelect = Write-Output AvailabilityZone CidrBlock Ipv6Native MapCustomerOwnedIpOnLaunch MapPublicIpOnLaunch State VpcId 213 | break 214 | } 215 | "VaultName" { 216 | $strPropertyNameOfInterest = "VaultName" 217 | $strCmdletForGet = "Get-GLCVaultList" 218 | $arrPropertiesToSelect = Write-Output CreationDate LastInventoryDate NumberOfArchives SizeInBytes 219 | break 220 | } 221 | {$_ -match "VpcId"} { 222 | $strPropertyNameOfInterest = "VpcId" 223 | $strCmdletForGet = "Get-EC2Vpc" 224 | $arrPropertiesToSelect = Write-Output State CidrBlock IsDefault OwnerId 225 | break 226 | } 227 | "UserName" { 228 | $strPropertyNameOfInterest = "UserName" 229 | $strCmdletForGet = "Get-IAMUserList" 230 | $arrPropertiesToSelect = Write-Output UserId CreateDate PasswordLastUsed Path PermissionsBoundary Arn 231 | break 232 | } 233 | } 234 | 235 | $(if ($null -ne $sbToGetDesiredObjects) {& $sbToGetDesiredObjects} else {& $strCmdletForGet @hshParamForGet}) | Foreach-Object {if (-not [System.String]::IsNullOrEmpty($wordToComplete)) {if ($_.$strPropertyNameOfInterest -like "${wordToComplete}*") {$_}} else {$_}} | Sort-Object -Property $strPropertyNameOfInterest | Foreach-Object { 236 | $strCompletionText = if ($_.$strPropertyNameOfInterest -match "\s") {'"{0}"' -f $_.$strPropertyNameOfInterest} else {$_.$strPropertyNameOfInterest} 237 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 238 | $strCompletionText, # CompletionText 239 | $_.$strPropertyNameOfInterest, # ListItemText 240 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 241 | ($_ | Select-Object -Property $arrPropertiesToSelect | Format-List | Out-String) # ToolTip 242 | ) 243 | } ## end Foreach-Object 244 | } ## end scriptblock 245 | 246 | ## for all of the cmdlets with parameter names like these param name wildcard strings 247 | $arrAllCmdsOfInterest = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName ($arrParamNames = Write-Output EndpointDetails_VpcId, VPC_VPCId, VpcConfig_VpcId, VpcConfiguration_VpcId, VpcId, VPCSettings_VpcId, Cluster, EventBusName, *SubnetId*, VaultName, FileSystemId, RoleArn) -ErrorAction:SilentlyContinue 248 | ## for each full parameter name from all the interesting cmdlets' params that are like the param wildcard from the param name array, register arg completer 249 | (($arrAllCmdsOfInterest.Parameters.Keys | Group-Object -NoElement).Name.Where({$strThisParamName = $_; $arrParamNames.Where({$strThisParamName -like $_})}) | Group-Object -NoElement).Name | ForEach-Object { 250 | $strThisParamName = $_ 251 | ## commands with this parameter 252 | $arrCommandsWithThisParam = $arrAllCmdsOfInterest.Where({$_.Parameters.ContainsKey($strThisParamName) -or ($_.Parameters.Values.Aliases -contains $strThisParamName)}) 253 | ## if there are any commands with this param, register the arg completer for them for this param 254 | if (($arrCommandsWithThisParam | Measure-Object).Count -gt 0) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $strThisParamName -ScriptBlock $sbMultipleObjCompleter} 255 | } ## end foreach-object 256 | 257 | ## specific cmdlets with -KeyName parameter 258 | Write-Output KeyName | Foreach-Object { 259 | ## if there are any commands with this parameter name, register an argument completer for them 260 | if ($arrCommandsWithThisParam = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName $_ -Name Get-EC2KeyPair, New-ASLaunchConfiguration, New-EC2Instance, Remove-EC2KeyPair -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbMultipleObjCompleter} 261 | } ## end Foreach-Object 262 | 263 | ## SSM cmdlets with -AssociationId parameter 264 | Write-Output AssociationId | Foreach-Object { 265 | ## if there are any commands with this parameter name, register an argument completer for them 266 | if ($arrCommandsWithThisParam = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName $_ -Noun SSM* -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbMultipleObjCompleter} 267 | } ## end Foreach-Object 268 | 269 | ## RDS cmdlets with -DBInstanceIdentifier parameter 270 | Write-Output DBInstanceIdentifier | Foreach-Object { 271 | ## if there are any commands with this parameter name, register an argument completer for them 272 | if ($arrCommandsWithThisParam = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName $_ -Noun RDS* -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbMultipleObjCompleter} 273 | } ## end Foreach-Object 274 | 275 | ## for all of the IAM cmdlets with parameter names like these param name wildcard strings 276 | $arrAllCmdsOfInterest = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName ($arrParamNames = Write-Output UserName, PolicyArn, GroupName) -ErrorAction:SilentlyContinue -Noun IAM* 277 | ## for each full parameter name from all the interesting cmdlets' params that are like the param wildcard from the param name array, register arg completer 278 | (($arrAllCmdsOfInterest.Parameters.Keys | Group-Object -NoElement).Name.Where({$strThisParamName = $_; $arrParamNames.Where({$strThisParamName -like $_})}) | Group-Object -NoElement).Name | ForEach-Object { 279 | $strThisParamName = $_ 280 | ## commands with this parameter 281 | $arrCommandsWithThisParam = $arrAllCmdsOfInterest.Where({$_.Parameters.ContainsKey($strThisParamName) -or ($_.Parameters.Values.Aliases -contains $strThisParamName)}) 282 | ## if there are any commands with this param, register the arg completer for them for this param 283 | if (($arrCommandsWithThisParam | Measure-Object).Count -gt 0) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $strThisParamName -ScriptBlock $sbMultipleObjCompleter} 284 | } ## end foreach-object 285 | 286 | ## for all of the ECR cmdlets with the given parameter name(s) 287 | Write-Output RepositoryName | Foreach-Object { 288 | ## if there are any commands with this parameter name, register an argument completer for them 289 | if ($arrCommandsWithThisParam = Get-Command -ParameterName $_ -Noun ECR* -Module AWSPowerShell*, AWS.Tools.* -ErrorAction:SilentlyContinue) { 290 | Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbMultipleObjCompleter 291 | } ## end if 292 | } ## end Foreach-Object 293 | 294 | ## for all of the RG cmdlets with the given parameter name(s) 295 | Write-Output Group | Foreach-Object { 296 | ## if there are any commands with this parameter name, register an argument completer for them 297 | if ($arrCommandsWithThisParam = Get-Command -ParameterName $_ -Module AWS.Tools.ResourceGroups -ErrorAction:SilentlyContinue) { 298 | Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbMultipleObjCompleter 299 | } ## end if 300 | } ## end Foreach-Object 301 | 302 | 303 | 304 | 305 | 306 | ## Completer for EC2 Security Group things 307 | $sbSecurityGroupCompleter = { 308 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 309 | ## any parameters to pass on through to the Get-* cmdlet (like ProfileName, for example) 310 | $hshParamForGet = @{} 311 | if ($commandBoundParameter.ContainsKey("ProfileName")) {$hshParamForGet["ProfileName"] = $commandBoundParameter.ProfileName} 312 | 313 | ## strPropertyNameOfInterest: property of returned objects that is of interest for giving as tab-completed value 314 | ## arrPropertyNamesToWhichToCompare: propert(ies) of returned objects that is of interest for determining which objects "match" the wordToCompleter 315 | ## strCmdletForGet: name of cmdlet to use to _get_ the objects to use for completing argument 316 | ## arrPropertiesToSelect: the properties to select for the ToolTip output (can be calculated properties) 317 | $strPropertyNameOfInterest = "GroupId" 318 | $arrPropertyNamesToWhichToCompare = Write-Output GroupId GroupName 319 | $strCmdletForGet = "Get-EC2SecurityGroup" 320 | $arrPropertiesToSelect = Write-Output GroupName Description IpPermissions Tags 321 | 322 | & $strCmdletForGet @hshParamForGet | Foreach-Object { 323 | $oThisRetrievedObj = $_ 324 | if (-not [System.String]::IsNullOrEmpty($wordToComplete)) { 325 | ## if this retrieved object has a property of interest whose value is liek this wordToComplete, return it 326 | if ($true -in ($arrPropertyNamesToWhichToCompare | Foreach-Object {$oThisRetrievedObj.$_ -like "${wordToComplete}*"})) {$oThisRetrievedObj} 327 | } 328 | ## else, no wordToComplete, so return it 329 | else {$oThisRetrievedObj} 330 | } | Sort-Object -Property $strPropertyNameOfInterest | Foreach-Object { 331 | $strCompletionText = if ($_.$strPropertyNameOfInterest -match "\s") {'"{0}"' -f $_.$strPropertyNameOfInterest} else {$_.$strPropertyNameOfInterest} 332 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 333 | $strCompletionText, # CompletionText 334 | $_.$strPropertyNameOfInterest, # ListItemText 335 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 336 | ($_ | Select-Object -Property $arrPropertiesToSelect | Format-List | Out-String) # ToolTip 337 | ) 338 | } ## end Foreach-Object 339 | } ## end scriptblock 340 | 341 | ## specific cmdlets with -GroupId parameter 342 | Write-Output GroupId | Foreach-Object { 343 | ## if there are any commands with this parameter name, register an argument completer for them 344 | if ($arrCommandsWithThisParam = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName $_ -Noun EC2* -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbSecurityGroupCompleter} 345 | } ## end Foreach-Object 346 | 347 | ## for all of the cmdlets with parameter names like these param name wildcard strings; adds ~150 completer registrations, but adds 10-20% "register args" time; worth having? Disabled for now 348 | # $arrAllCmdsOfInterest = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName ($arrParamNames = Write-Output AddSecurityGroupId, AmazonopensearchserviceDestinationConfiguration_VpcConfiguration_SecurityGroupIds, AwsvpcConfiguration_SecurityGroup, Ec2SecurityGroupId, EndpointDetails_SecurityGroupId, EngineSecurityGroupId, ExecutionEngine_MasterInstanceSecurityGroupId, InputSecurityGroup, InputSecurityGroupId, Instances_AdditionalMasterSecurityGroup, Instances_AdditionalSlaveSecurityGroup, Instances_EmrManagedMasterSecurityGroup, Instances_EmrManagedSlaveSecurityGroup, Instances_ServiceAccessSecurityGroup, LaunchSpecification_AllSecurityGroup, LaunchSpecification_SecurityGroupId, MetricSource_RDSSourceConfig_VpcConfiguration_SecurityGroupIdList, MetricSource_RedshiftSourceConfig_VpcConfiguration_SecurityGroupIdList, NetworkConfiguration_SecurityGroupId, NotebookInstanceSecurityGroupId, RemoveSecurityGroupId, SecurityGroup, SecurityGroupId, SecurityGroupRuleId, Vpc_SecurityGroupId, VpcConfig_SecurityGroupId, VpcConfiguration_SecurityGroup, VpcConfiguration_SecurityGroupId, VPCOptions_SecurityGroupId, VpcSecurityGroupId) -ErrorAction:SilentlyContinue 349 | # ## for each full parameter name from all the interesting cmdlets' params that are like the param wildcard from the param name array, register arg completer 350 | # (($arrAllCmdsOfInterest.Parameters.Keys | Group-Object -NoElement).Name.Where({$strThisParamName = $_; $arrParamNames.Where({$strThisParamName -like $_})}) | Group-Object -NoElement).Name.ForEach({ 351 | # $strThisParamName = $_ 352 | # ## commands with this parameter 353 | # $arrCommandsWithThisParam = $arrAllCmdsOfInterest.Where({$_.Parameters.ContainsKey($strThisParamName) -or ($_.Parameters.Values.Aliases -contains $strThisParamName)}) 354 | # ## if there are any commands with this param, register the arg completer for them for this param 355 | # if (($arrCommandsWithThisParam | Measure-Object).Count -gt 0) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $strThisParamName -ScriptBlock $sbSecurityGroupCompleter} 356 | # }) ## end foreach method 357 | 358 | 359 | 360 | 361 | ## Completer for things for which to have no toolTip (say, due to lack of interesting other properties to display) 362 | $sbObjCompleter_NoToolTip = { 363 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 364 | ## any parameters to pass on through to the Get-* cmdlet (like ProfileName, for example) 365 | $hshParamForGet = @{} 366 | if ($commandBoundParameter.ContainsKey("ProfileName")) {$hshParamForGet["ProfileName"] = $commandBoundParameter.ProfileName} 367 | 368 | ## strPropertyNameOfInterest: property of returned objects that is of interest 369 | $strPropertyNameOfInterest = $parameterName ## default here 370 | ## strCmdletForGet: name of cmdlet to use to _get_ the objects to use for completing argument 371 | switch ($parameterName) { 372 | {$_ -in "MetricName", "NameSpace"} { 373 | $strCmdletForGet = "Get-CWMetricList" 374 | if ($commandBoundParameter.ContainsKey("Namespace")) {$hshParamForGet["NameSpace"] = $commandBoundParameter["NameSpace"]} 375 | break 376 | } ## end case 377 | "RegistryId" { 378 | $strCmdletForGet = "Get-ECRRegistry" 379 | } 380 | } ## end switch 381 | 382 | & $strCmdletForGet @hshParamForGet | Foreach-Object {if (-not [System.String]::IsNullOrEmpty($wordToComplete)) {if ($_.$strPropertyNameOfInterest -like "${wordToComplete}*") {$_}} else {$_}} | Sort-Object -Property $strPropertyNameOfInterest | Foreach-Object { 383 | $strCompletionText = if ($_.$strPropertyNameOfInterest -match "\s") {'"{0}"' -f $_.$strPropertyNameOfInterest} else {$_.$strPropertyNameOfInterest} 384 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ($strCompletionText <# CompletionText #>) 385 | } ## end Foreach-Object 386 | } ## end scriptblock 387 | 388 | ## matching cmdlets with -MetricName, -NameSpace parameters 389 | Write-Output MetricName, NameSpace | Foreach-Object { 390 | ## if there are any commands with this parameter name, register an argument completer for them 391 | if ($arrCommandsWithThisParam = Get-Command -Module AWSPowerShell*, AWS.Tools.* -ParameterName $_ -Noun CW* -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbObjCompleter_NoToolTip} 392 | } ## end Foreach-Object 393 | ## for ECR RegistryId 394 | Write-Output RegistryId | Foreach-Object { 395 | ## if there are any commands with this parameter name, register an argument completer for them 396 | if ($arrCommandsWithThisParam = Get-Command -ParameterName $_ -Module AWSPowerShell*, AWS.Tools.* -ErrorAction:SilentlyContinue) { 397 | Register-ArgumentCompleter -CommandName $arrCommandsWithThisParam -ParameterName $_ -ScriptBlock $sbObjCompleter_NoToolTip 398 | } ## end if 399 | } ## end Foreach-Object 400 | 401 | 402 | 403 | 404 | ## completer scriptblock for -Service 405 | $sbServiceCompleter = { 406 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 407 | 408 | Get-AWSService | Foreach-Object { 409 | ## if no wordToComplete provided, or this item is like wordToComplete, use it 410 | if ( 411 | [System.String]::IsNullOrEmpty($wordToComplete) -or 412 | $_.Service -like "${wordToComplete}*" 413 | ) {$_} 414 | } | Sort-Object -Property Service | Foreach-Object { 415 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 416 | $_.Service, # CompletionText 417 | $_.Service, # ListItemText 418 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 419 | ("{0} ({1}{2})" -f $_.Service, $_.ServiceName, $(if ($_ | Get-Member -Name ModuleName) {", module '$($_.ModuleName)'"})) # ToolTip 420 | ) 421 | } ## end Foreach-Object 422 | } ## end scriptblock 423 | 424 | ## specific cmdlets with -Service parameter 425 | Write-Output Get-AWSCmdletName, Get-AWSService | Foreach-Object { 426 | if (Get-Command -Name $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $_ -ParameterName Service -ScriptBlock $sbServiceCompleter} 427 | } ## end Foreach-Object 428 | 429 | 430 | ## completer scriptblock for -ApiOperation 431 | $sbApiOperationCompleter = { 432 | param($commandName, $parameterName, $wordToComplete, $commandAst, $commandBoundParameter) 433 | 434 | $hshParamFOrGetAWSCmdletName = @{ApiOperation = $wordToComplete.Trim("*"); MatchWithRegex = $true} 435 | 436 | Get-AWSCmdletName @hshParamFOrGetAWSCmdletName | Sort-Object -Property ServiceName, CmdletName | Foreach-Object { 437 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 438 | $_.ServiceOperation, # CompletionText 439 | $_.ServiceOperation, # ListItemText 440 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 441 | ("{0} (for service '{1}')" -f $_.ServiceOperation, $_.ServiceName) # ToolTip 442 | ) 443 | } ## end Foreach-Object 444 | } ## end scriptblock 445 | 446 | ## specific cmdlets with -ApiOperation parameter 447 | Write-Output Get-AWSCmdletName | Foreach-Object { 448 | if (Get-Command -Name $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $_ -ParameterName ApiOperation -ScriptBlock $sbApiOperationCompleter} 449 | } ## end Foreach-Object 450 | } 451 | -------------------------------------------------------------------------------- /Register-VNActiveDirectoryArgumentCompleter.ps1: -------------------------------------------------------------------------------- 1 | 2 | <#PSScriptInfo 3 | 4 | .VERSION 1.0.1 5 | 6 | .GUID d7c13ce3-a513-4a05-8093-8e098a7e9557 7 | 8 | .AUTHOR Matt Boren (@mtboren) 9 | 10 | .COMPANYNAME vNugglets 11 | 12 | .COPYRIGHT MIT License 13 | 14 | .TAGS vNugglets PowerShell ArgumentCompleter Parameter ActiveDirectory AD AdminOptimization NaturalExperience TabComplete TabCompletion Completion Awesome 15 | 16 | .LICENSEURI https://github.com/vNugglets/PowerShellArgumentCompleters/blob/main/License 17 | 18 | .PROJECTURI https://github.com/vNugglets/PowerShellArgumentCompleters 19 | 20 | .ICONURI https://avatars0.githubusercontent.com/u/22530966 21 | 22 | .EXTERNALMODULEDEPENDENCIES ActiveDirectory 23 | 24 | .REQUIREDSCRIPTS 25 | 26 | .EXTERNALSCRIPTDEPENDENCIES 27 | 28 | .RELEASENOTES 29 | See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters 30 | 31 | .PRIVATEDATA 32 | 33 | #> 34 | 35 | #Requires -Module ActiveDirectory 36 | 37 | 38 | 39 | <# 40 | 41 | .DESCRIPTION 42 | Script to register PowerShell argument completers for many parameters of ActiveDirectory module cmdlets, making us even more productive on the command line. This enables the tab-completion of actual ActiveDirectory objects' and properties' names as values to parameters to ActiveDirectory cmdlets -- neat! 43 | 44 | #> 45 | 46 | Param() 47 | 48 | 49 | 50 | process { 51 | ## AD object property name completer 52 | $sbPropertyNameCompleter = { 53 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 54 | 55 | ## get the AD schema for the default AD forest; used to get given object class and its properties 56 | $oADSchema = [DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetSchema([System.DirectoryServices.ActiveDirectory.DirectoryContext]::new([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Forest, (Get-ADForest))) 57 | $strADClassName = Switch ($commandName) { 58 | "Get-ADComputer" {"computer"} 59 | "Get-ADGroup" {"group"} 60 | "Get-ADOrganizationalUnit" {"organizationalUnit"} 61 | "Get-ADUser" {"user"} 62 | } 63 | 64 | $oADSchema.FindClass($strADClassName).GetAllProperties().Where({$_.Name -like "${wordToComplete}*"}) | Sort-Object -Property Name |Foreach-Object { 65 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 66 | $_.Name, # CompletionText 67 | $_.Name, # ListItemText 68 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 69 | ("[{0}] {1} (description of '{2}')" -f $_.Syntax, $_.Name, $_.Description) # ToolTip 70 | ) 71 | } ## end Foreach-Object 72 | } ## end scriptblock 73 | 74 | ## specific cmdlets with given parameter 75 | Write-Output Get-ADComputer, Get-ADGroup, Get-ADOrganizationalUnit, Get-ADUser | Foreach-Object { 76 | Register-ArgumentCompleter -CommandName $_ -ParameterName Properties -ScriptBlock $sbPropertyNameCompleter 77 | } ## end Foreach-Object 78 | 79 | 80 | ## AD OU DN completer, searching by OU DN 81 | $sbOUDNCompleter = { 82 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 83 | 84 | ## get OUs, supporting filtering _just_ on the OU name 85 | # Get-ADOrganizationalUnit -Filter {Name -like "${wordToCompleter}*"} | Foreach-Object { 86 | ## get OUs, supporting filtering on the OU DN itself; must be done by getting all OUs and then filtering client-side, as server-side DN filter only supports exact match, not wildcarding, seemingly 87 | # and, sorting by the parent OUs, essentially, so matches are presented in "grouped-by-OU" order, for easiest recognition by consumer 88 | $hshParmForGetADOU = @{Filter = "*"; Properties = "Name", "DistinguishedName", "whenCreated", "Description"} 89 | ## if these other params are specified to the command, pass them through 90 | Write-Output Credential Server | Foreach-Object { 91 | if ($fakeBoundParameter.ContainsKey($_)) {$hshParmForGetADOU[$_] = $fakeBoundParameter.$_} 92 | } 93 | (Get-ADOrganizationalUnit @hshParmForGetADOU).Where({$_.DistinguishedName -like "*${wordToComplete}*"}) | Sort-Object -Property {($arrlTmp = [System.Collections.ArrayList]($_.DistinguishedName).Split(",")).Reverse(); $arrlTmp -join ","} | Foreach-Object { 94 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 95 | $(if ($_.DistinguishedName -match "[, ']") {'"{0}"' -f $_.DistinguishedName} else {$_.DistinguishedName}), # CompletionText 96 | $_.DistinguishedName, # ListItemText 97 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 98 | ("{0} (created '{1}', description of '{2}')" -f $_.DistinguishedName, $_.whenCreated, $_.Description) # ToolTip 99 | ) 100 | } ## end Foreach-Object 101 | } ## end scriptblock 102 | 103 | ## cmdlets with given parameter 104 | Write-Output SearchBase, TargetPath | Foreach-Object { 105 | $strThisParamName = $_ 106 | Get-Command -Module ActiveDirectory -ParameterName $strThisParamName | ForEach-Object {Register-ArgumentCompleter -CommandName $_ -ParameterName $strThisParamName -ScriptBlock $sbOUDNCompleter} 107 | } ## end Foreach-Object 108 | ## specific Cmdlets 109 | ## param Path 110 | Register-ArgumentCompleter -CommandName (Write-Output New-ADComputer, New-ADGroup, New-ADObject, New-ADOrganizationalUnit, New-ADServiceAccount, New-ADUser) -ParameterName Path -ScriptBlock $sbOUDNCompleter 111 | ## param Identity 112 | Register-ArgumentCompleter -CommandName (Get-Command -Module ActiveDirectory -ParameterName Identity -Noun ADOrganizationalUnit).Name -ParameterName Identity -ScriptBlock $sbOUDNCompleter 113 | 114 | 115 | ## AD Group name completer 116 | $sbGroupIdentityCompleter = { 117 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 118 | 119 | $hshParmForGetADGroup = @{Filter = "Name -like '${wordToComplete}*'"; Properties = "Name", "Description"} 120 | ## if these other params are specified to the command, pass them through 121 | Write-Output Credential Server | Foreach-Object { 122 | if ($fakeBoundParameter.ContainsKey($_)) {$hshParmForGetADGroup[$_] = $fakeBoundParameter.$_} 123 | } 124 | Get-ADGroup @hshParmForGetADGroup | Sort-Object -Property Name | Foreach-Object { 125 | $strCompletionText = if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name} 126 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 127 | $strCompletionText, # CompletionText 128 | $_.Name, # ListItemText 129 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 130 | ("{0} ({1} {2} group, description of '{3}')" -f $_.DistinguishedName, $_.GroupScope, $_.GroupCategory, $_.Description) # ToolTip 131 | ) 132 | } ## end Foreach-Object 133 | } ## end scriptblock 134 | 135 | ## for these cmdlets 136 | Register-ArgumentCompleter -CommandName (Write-Output Get-ADGroup Remove-ADGroup Set-ADGroup Add-ADGroupMember Get-ADGroupMember Remove-ADGroupMember) -ParameterName Identity -ScriptBlock $sbGroupIdentityCompleter 137 | ## for MemberOf param 138 | Register-ArgumentCompleter -CommandName (Write-Output Add-ADPrincipalGroupMembership) -ParameterName MemberOf -ScriptBlock $sbGroupIdentityCompleter 139 | 140 | 141 | 142 | ## AD Group membership completer (say, for a principal, or for members of a group) 143 | $sbGroupMembershipCompleter = { 144 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 145 | 146 | ## if the -Idenity param is in the command line, get the corresponding AD object and return info on its members 147 | if ($fakeBoundParameter.ContainsKey("Identity")) { 148 | ## if these other params are specified to the command, pass them through 149 | Write-Output Credential | Foreach-Object -Begin {$hshParmForGet = @{}} { 150 | if ($fakeBoundParameter.ContainsKey($_)) {$hshParmForGet[$_] = $fakeBoundParameter.$_} 151 | } 152 | ## if -Server specified, use it for Get-ADObject call; else, use the domain root / global catalog port for server, to account for getting AD objects from cross-domain in the same forest 153 | $hshParmForGet["Server"] = if ($fakeBoundParameter.ContainsKey("Server")) {$fakeBoundParameter["Server"]} else {"{0}:3268" -f (Get-ADForest).RootDomain} 154 | 155 | $strThisIdentity = $fakeBoundParameter["Identity"] 156 | $strCmdletToGetThisIdentity, $strMembershipPropertyOfInterest = Switch ($commandName) { 157 | "Remove-ADGroupMember" {"Get-ADGroup", "members"; break} ## "members" property name seems case sensitive in at least some AD envs 158 | "Remove-ADPrincipalGroupMembership" {"Get-ADObject", "MemberOf"; break} 159 | } 160 | $oThisADObject = & $strCmdletToGetThisIdentity -Properties $strMembershipPropertyOfInterest -Filter "(Name -eq '$strThisIdentity') -or (SamAccountName -eq '$strThisIdentity')" @hshParmForGet 161 | ## if this AD object has members (for group) or is a member of things (for principal), get them 162 | if (($oThisADObject.$strMembershipPropertyOfInterest | Measure-Object).Count -gt 0) { 163 | $oThisADObject.$strMembershipPropertyOfInterest | Where-Object {$_.Split(",")[0].Split("=")[1] -like "${wordToComplete}*"} | Foreach-Object {Get-ADObject @hshParmForGet -Identity $_ -Properties Description, samaccountname, DisplayName} | Sort-Object -Property Name | Foreach-Object { 164 | $strCompletionText = if ($_.samaccountname -match "\s") {'"{0}"' -f $_.samaccountname} else {$_.samaccountname} 165 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 166 | $strCompletionText, # CompletionText 167 | $_.samaccountname, # ListItemText 168 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 169 | ("[{0}] {1} (DisplayName of '{2}', description of '{3}')" -f $_.ObjectClass, $_.DistinguishedName, $_.DisplayName, $_.Description) # ToolTip 170 | ) 171 | } ## end Foreach-Object 172 | } 173 | } 174 | } ## end scriptblock 175 | 176 | ## for these cmdlets 177 | Register-ArgumentCompleter -CommandName (Write-Output Remove-ADPrincipalGroupMembership) -ParameterName MemberOf -ScriptBlock $sbGroupMembershipCompleter 178 | Register-ArgumentCompleter -CommandName (Write-Output Remove-ADGroupMember) -ParameterName Members -ScriptBlock $sbGroupMembershipCompleter 179 | } 180 | -------------------------------------------------------------------------------- /Register-VNVMwarePowerCLIArgumentCompleter.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | 3 | .VERSION 1.3.0 4 | 5 | .GUID 3290ce71-109f-486d-8f58-49eb21d6c334 6 | 7 | .AUTHOR Matt Boren (@mtboren) 8 | 9 | .COMPANYNAME vNugglets 10 | 11 | .COPYRIGHT MIT License 12 | 13 | .TAGS vNugglets PowerShell ArgumentCompleter Parameter VMware PowerCLI AdminOptimization NaturalExperience TabComplete TabCompletion Completion Awesome 14 | 15 | .LICENSEURI https://github.com/vNugglets/PowerShellArgumentCompleters/blob/master/License 16 | 17 | .PROJECTURI https://github.com/vNugglets/PowerShellArgumentCompleters 18 | 19 | .ICONURI https://avatars0.githubusercontent.com/u/22530966 20 | 21 | .EXTERNALMODULEDEPENDENCIES 22 | 23 | .REQUIREDSCRIPTS 24 | 25 | .EXTERNALSCRIPTDEPENDENCIES 26 | 27 | .RELEASENOTES 28 | See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters 29 | 30 | .PRIVATEDATA 31 | 32 | #> 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <# 43 | 44 | .DESCRIPTION 45 | Script to register PowerShell argument completers for many parameters for many VMware.PowerCLI cmdlets, making us even more productive on the command line. This enables the tab-completion of actual vSphere inventory objects' names as values to parameters to VMware.PowerCLI cmdlets -- neat! 46 | 47 | .Example 48 | Register-VNVMwarePowerCLIArgumentCompleter.ps1 49 | Register argument completers for all of the VMware.PowerCLI cmdlets that are currently available in this PowerShell session, and for which there is an argument completer defined in this script 50 | 51 | .Link 52 | https://vNugglets.com 53 | https://github.com/vNugglets 54 | Register-ArgumentCompleter 55 | VMware.PowerCLI module 56 | #> 57 | 58 | Param() 59 | 60 | process { 61 | ## all of the modules that are a part of the VMware.PowerCLI module; grouping by name and the selecting just the most recent version of each module (so as to avoid issue w/ using params that may have not existed in older module versions) 62 | $arrModulesOfVMwarePowerCLIModule = (Get-Module VMware.PowerCLI -ListAvailable).RequiredModules | Group-Object -Property Name | ForEach-Object {$_.Group | Sort-Object -Property Version | Select-Object -Last 1} 63 | 64 | ## VM or template name completer 65 | $sbGetVmOrTemplateNameCompleter = { 66 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 67 | ## make the regex pattern to use for Name filtering for given View object (convert from globbing wildcard to regex pattern, to support globbing wildcard as input) 68 | $strNameRegex = if ($wordToComplete -match "\*") {$wordToComplete.Replace("*", ".*")} else {$wordToComplete} 69 | ## is this command getting Template objects? (vs. VM objects) 70 | $bGettingTemplate = $commandName -ne "Get-VM" -and $parameterName -ne "VM" 71 | Get-View -ViewType VirtualMachine -Property Name, Runtime.Powerstate -Filter @{Name = "^${strNameRegex}"; "Config.Template" = $bGettingTemplate.ToString()} | Where-Object {$fakeBoundParameter.$parameterName -notcontains $_.Name} | Sort-Object -Property Name -Unique | Foreach-Object { 72 | $strCompletionText = $strListItemText = if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name} 73 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 74 | $strCompletionText, # CompletionText 75 | $strListItemText, # ListItemText 76 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 77 | ## for tooltip, give Name and either PowerState (for VM) or GuestFullName (for Template) 78 | ("{0} ({1})" -f $_.Name, $(if (-not $bGettingTemplate) {$_.Runtime.PowerState} else {$_.UpdateViewData("Config.GuestFullName"); $_.Config.GuestFullName})) # ToolTip 79 | ) 80 | } ## end foreach-object 81 | } ## end scriptblock 82 | 83 | Register-ArgumentCompleter -CommandName Get-VM, Get-Template -ParameterName Name -ScriptBlock $sbGetVmOrTemplateNameCompleter 84 | Write-Output VM, Template | Foreach-Object { 85 | ## if there are any cmdlets from any loaded modules with the given parametername, register an arg completer 86 | if ($arrCommandsOfInterest = Get-Command -Module ($arrModulesOfVMwarePowerCLIModule | Where-Object {$_.Name -ne "VMware.VimAutomation.Cloud"}) -ParameterName $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName $_ -ScriptBlock $sbGetVmOrTemplateNameCompleter} 87 | } ## end ForEach-Object 88 | 89 | 90 | ## multiple "core" item name completer, like cluster, datacenter, hostsystem, datastore, etc. 91 | $sbGetCoreItemNameCompleter = { 92 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 93 | ## non-exhaustive list of View items to easily grab for -Name param value completion on corresponding cmdlet 94 | $hshCmdletToViewType = @{ 95 | "Get-Cluster" = "ClusterComputeResource" 96 | "Get-Datacenter" = "Datacenter" 97 | "Get-Datastore" = "Datastore" 98 | "Get-DatastoreCluster" = "StoragePod" 99 | "Get-Folder" = "Folder" 100 | "Get-ResourcePool" = "ResourcePool" 101 | "Get-VDPortGroup" = "DistributedVirtualPortgroup" 102 | "Get-VDSwitch" = "DistributedVirtualSwitch" 103 | "Get-VApp" = "VirtualApp" 104 | "Get-VMHost" = "HostSystem" 105 | } ## end hshtable 106 | ## make the regex pattern to use for Name filtering for given View object (convert from globbing wildcard to regex pattern, to support globbing wildcard as input) 107 | $strNameRegex = if ($wordToComplete -match "\*") {$wordToComplete.Replace("*", ".*")} else {$wordToComplete} 108 | ## get the possible matches, create a new CompletionResult object for each 109 | Get-View -ViewType $hshCmdletToViewType[$commandName] -Property Name -Filter @{Name = "^${strNameRegex}"} | Sort-Object -Property Name -Unique | Foreach-Object { 110 | $viewThisItem = $_ 111 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 112 | $strCompletionText = $strListItemText = if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name} 113 | ## the Tool Tip extra info 114 | $strToolTipExtraInfo = Switch ($commandName) { 115 | ## Datastores/DatastoreClusters 116 | {$_ -in "Get-Datastore", "Get-DatastoreCluster"} { 117 | $viewThisItem.UpdateViewData("Summary.Capacity", "Summary.FreeSpace") 118 | "{0}GB, {1}GB free" -f [Math]::Round($viewThisItem.Summary.Capacity / 1GB, 1).ToString("N1"), [Math]::Round($viewThisItem.Summary.FreeSpace / 1GB, 1).ToString("N1") 119 | } 120 | ## VMHosts 121 | "Get-VMHost" { 122 | $viewThisItem.UpdateViewData("Runtime.ConnectionState", "Runtime.PowerState", "Runtime.InMaintenanceMode") 123 | "{0}, {1}" -f $viewThisItem.Runtime.PowerState, $(if ($viewThisItem.Runtime.InMaintenanceMode) {"maintenance"} else {$viewThisItem.Runtime.ConnectionState}) 124 | } 125 | default {"'$($viewThisItem.MoRef)'"} 126 | } ## end switch 127 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 128 | $strCompletionText, # CompletionText 129 | $strListItemText, # ListItemText 130 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 131 | ("{0} ({1})" -f $viewThisItem.Name, $strToolTipExtraInfo) # ToolTip 132 | ) 133 | } ## end foreach-object 134 | } ## end scriptblock 135 | 136 | Register-ArgumentCompleter -CommandName Get-Cluster, Get-Datacenter, Get-Datastore, Get-DatastoreCluster, Get-Folder, Get-ResourcePool, Get-VDPortGroup, Get-VDSwitch, Get-VApp, Get-VMHost -ParameterName Name -ScriptBlock $sbGetCoreItemNameCompleter 137 | 138 | 139 | 140 | ## multiple inventory item name completer for parameters other than "-Name", like -VMHost, -Datastore, etc. 141 | $sbGetVIItemNameCompleter = { 142 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 143 | ## the View object type name that corresponds to the given parameter name, to be used in a Get-View call, later; defaults to the parameter name used (so as to not have to have a switch case for when a param name is the same as the View object type name; like, for example, "datastore" -- the View object type is "datastore") 144 | $strViewTypePerParamName = Switch ($parameterName) { 145 | {"VMHost", "AddVMHost", "RemoveVMHost" -contains $_} {"HostSystem"} 146 | "VApp" {"VirtualApp"} 147 | "Cluster" {"ClusterComputeResource"} 148 | "DatastoreCluster" {"StoragePod"} 149 | default {$parameterName} ## gets things like Datacenter, ResourcePool 150 | } ## end switch 151 | ## make the regex pattern to use for Name filtering for given View object (convert from globbing wildcard to regex pattern, to support globbing wildcard as input) 152 | $strNameRegex = if ($wordToComplete -match "\*") {$wordToComplete.Replace("*", ".*")} else {$wordToComplete} 153 | ## get the possible matches, create a new CompletionResult object for each 154 | Get-View -ViewType $strViewTypePerParamName -Property Name -Filter @{Name = "^${strNameRegex}"} | Sort-Object -Property Name -Unique | Foreach-Object { 155 | $viewThisItem = $_ 156 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 157 | $strCompletionText = $strListItemText = if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name} 158 | ## the Tool Tip extra info 159 | $strToolTipExtraInfo = Switch ($strViewTypePerParamName) { 160 | ## Datastores/DatastoreClusters 161 | {$_ -in "Datastore", "StoragePod"} { 162 | $viewThisItem.UpdateViewData("Summary.Capacity", "Summary.FreeSpace") 163 | "{0}GB, {1}GB free" -f [Math]::Round($viewThisItem.Summary.Capacity / 1GB, 1).ToString("N1"), [Math]::Round($viewThisItem.Summary.FreeSpace / 1GB, 1).ToString("N1") 164 | } 165 | ## VMHosts 166 | "HostSystem" { 167 | $viewThisItem.UpdateViewData("Runtime.ConnectionState", "Runtime.PowerState", "Runtime.InMaintenanceMode") 168 | "{0}, {1}" -f $viewThisItem.Runtime.PowerState, $(if ($viewThisItem.Runtime.InMaintenanceMode) {"maintenance"} else {$viewThisItem.Runtime.ConnectionState}) 169 | } 170 | default {"'$($viewThisItem.MoRef)'"} 171 | } ## end switch 172 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 173 | $strCompletionText, # CompletionText 174 | $strListItemText, # ListItemText 175 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 176 | ("{0} ({1})" -f $viewThisItem.Name, $strToolTipExtraInfo) # ToolTip 177 | ) 178 | } ## end foreach-object 179 | } ## end scriptblock 180 | 181 | Write-Output AddVMHost, Cluster, Datacenter, Datastore, DatastoreCluster, RemoveVMHost, ResourcePool, VMHost | Foreach-Object { 182 | ## if there are any cmdlets from any loaded modules with the given parametername, register an arg completer 183 | if ($arrCommandsOfInterest = Get-Command -Module $arrModulesOfVMwarePowerCLIModule -ParameterName $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName $_ -ScriptBlock $sbGetVIItemNameCompleter} 184 | } ## end ForEach-Object 185 | if ($arrCommandsOfInterest = Get-Command -Module ($arrModulesOfVMwarePowerCLIModule | Where-Object {$_.Name -ne "VMware.VimAutomation.Cloud"}) -ParameterName VApp -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName VApp -ScriptBlock $sbGetVIItemNameCompleter} 186 | 187 | 188 | 189 | ## Name completer for multiple things; Get-VIRole, Get-VMHostProfile 190 | $sbGeneralVIItemNameCompleter = { 191 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 192 | $hshParamForGetVIItem = @{} 193 | if (-not [System.String]::isNullOrEmpty($wordToComplete)) {$hshParamForGetVIItem['Name'] = "${wordToComplete}*"} 194 | ## the PowerCLI cmdlet name to use to get the completer values for this parameter 195 | $strCommandNameToGetCompleters = Switch ($parameterName) { 196 | Baseline {"Get-Baseline"} 197 | {"HostProfile", "Profile" -contains $_} {"Get-VMHostProfile"} 198 | Name {$commandName} ## if it's -Name param, use the $commandName that is for this invocation 199 | OSCustomizationSpec {"Get-OSCustomizationSpec"} 200 | Role {"Get-VIRole"} 201 | StoragePolicy {"Get-SpbmStoragePolicy"} 202 | } ## end switch 203 | & $strCommandNameToGetCompleters @hshParamForGetVIItem | Sort-Object -Property Name | Foreach-Object { 204 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 205 | $strCompletionText = $strListItemText = if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name} 206 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 207 | $strCompletionText, # CompletionText 208 | $strListItemText, # ListItemText 209 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 210 | ## if getting OSCustSpec, include the OSCS OSType info, too; else, just the description 211 | ("{0} ({1}{2})" -f $_.Name, $(if ($strCommandNameToGetCompleters -eq "Get-OSCustomizationSpec") {"[$($_.OSType)] "}), $(if (-not [System.String]::isNullOrEmpty($_.Description)) {$_.Description} else {""})) # ToolTip 212 | ) 213 | } ## end foreach-object 214 | } ## end scriptblock 215 | 216 | Write-Output Baseline, HostProfile, OSCustomizationSpec, Profile, Role, StoragePolicy | ForEach-Object { 217 | ## if there are any cmdlets from any loaded modules with the given parametername, register an arg completer 218 | if ($arrCommandsOfInterest = Get-Command -Module $arrModulesOfVMwarePowerCLIModule -ParameterName $_ -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName $_ -ScriptBlock $sbGeneralVIItemNameCompleter} 219 | } ## end ForEach-Object 220 | Register-ArgumentCompleter -CommandName Get-OSCustomizationSpec, Get-PatchBaseline, Get-SpbmStoragePolicy, Get-VIRole, Get-VMHostProfile -ParameterName Name -ScriptBlock $sbGeneralVIItemNameCompleter 221 | 222 | 223 | 224 | ## Enum completer for enumeration values, like for -GuestID (type [VMware.Vim.VirtualMachineGuestOsIdentifier]) 225 | $sbGuestIDEnumNameCompleter = { 226 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 227 | ## the Enumeration type to use to get the completer values for this parameter 228 | $oEnumType = Switch ($parameterName) { 229 | GuestID {[VMware.Vim.VirtualMachineGuestOsIdentifier]} 230 | } ## end switch 231 | [System.Enum]::GetValues($oEnumType) | Select-Object -Property @{n="Name"; e = {$_.ToString()}}, value__ | Where-Object {if (-not ([System.String]::isNullOrEmpty($wordToComplete))) {$_.Name -like "${wordToComplete}*"} else {$true}} | Sort-Object -Property Name | Foreach-Object { 232 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 233 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 234 | $_.Name, # CompletionText 235 | $_.Name, # ListItemText 236 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 237 | ("{0} ({1})" -f $_.Name, $_.value__) # ToolTip 238 | ) 239 | } ## end foreach-object 240 | } ## end scriptblock 241 | 242 | Register-ArgumentCompleter -CommandName New-VM, Set-VM -ParameterName GuestID -ScriptBlock $sbGuestIDEnumNameCompleter 243 | 244 | 245 | 246 | ## Name completer for -Server param for cmdlets that are dealing with vCenter/VIServer (not for cmdlets where -Server is something else, like cmdlets for vROps, NSXT, HorizonView, VMC, etc.) 247 | $sbVIServerNameCompleter = { 248 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 249 | $global:DefaultVIServers | Where-Object {$_.Name -like "${wordToComplete}*"} | Where-Object {$fakeBoundParameter.$parameterName -notcontains $_.Name} | Sort-Object -Property Name | Foreach-Object { 250 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 251 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 252 | $_.Name, # CompletionText 253 | $_.Name, # ListItemText 254 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 255 | ("{0} ({1})" -f $_.Name, $_.User) # ToolTip 256 | ) 257 | } ## end foreach-object 258 | } ## end scriptblock 259 | 260 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -ParameterName Server -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Server -ScriptBlock $sbVIServerNameCompleter} 261 | 262 | 263 | 264 | $sbTagNameCompleter = { 265 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 266 | 267 | $hshParamForGetCmdlet = @{Name = "${wordToComplete}*"} 268 | if ($fakeBoundParameter.ContainsKey("Server")) {$hshParamForGetCmdlet["Server"] = $fakeBoundParameter.Server} 269 | Get-Tag @hshParamForGetCmdlet | Sort-Object -Property Name | Foreach-Object { 270 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 271 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 272 | $(if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name}), # CompletionText 273 | $_.Name, # ListItemText 274 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 275 | ("{0} (category '{1}', description '{2}')" -f $_.Name, $_.Category, $_.Description) # ToolTip 276 | ) 277 | } ## end foreach-object 278 | } ## end scriptblock 279 | 280 | ## for this cmdlet 281 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name Get-Tag -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Name -ScriptBlock $sbTagNameCompleter} 282 | ## for all cmdlets w Param named Tag 283 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -ParameterName Tag -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Tag -ScriptBlock $sbTagNameCompleter} 284 | 285 | 286 | 287 | $sbTagCategoryNameCompleter = { 288 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 289 | 290 | $hshParamForGetCmdlet = @{Name = "${wordToComplete}*"} 291 | if ($fakeBoundParameter.ContainsKey("Server")) {$hshParamForGetCmdlet["Server"] = $fakeBoundParameter.Server} 292 | Get-TagCategory @hshParamForGetCmdlet | Sort-Object -Property Name | Foreach-Object { 293 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 294 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 295 | $(if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name}), # CompletionText 296 | $_.Name, # ListItemText 297 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 298 | ("{0} (description '{1}', cardinality '{2}')" -f $_.Name, $_.Description, $_.Cardinality) # ToolTip 299 | ) 300 | } ## end foreach-object 301 | } ## end scriptblock 302 | 303 | ## for this cmdlet 304 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name Get-TagCategory -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Name -ScriptBlock $sbTagCategoryNameCompleter} 305 | ## for all cmdlets w Param named Tag 306 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -ParameterName Category -Noun Tag* -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Category -ScriptBlock $sbTagCategoryNameCompleter} 307 | 308 | 309 | 310 | ## completer for the Name or ID of VIPrivileges 311 | $sbVIPrivilegeCompleter = { 312 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 313 | 314 | ## if the param is ID, use that for the Get; else, use Name for the get 315 | $hshParamForGetCmdlet = @{$(if ($parameterName -eq "Id") {$parameterName} else {"Name"}) = "${wordToComplete}*"} 316 | ## if this is trying to get Privilege _Groups_, add the PrivilegeGroup switch parameter 317 | if ($parameterName -eq "Group" -or ($true -eq $fakeBoundParameter["PrivilegeGroup"])) {$hshParamForGetCmdlet["PrivilegeGroup"] = $true} 318 | if ($fakeBoundParameter.ContainsKey("Server")) {$hshParamForGetCmdlet["Server"] = $fakeBoundParameter.Server} 319 | 320 | ## the scriptblock to get the VIPrivilege objects of interest 321 | # if the command is Set-VIRole 322 | $sbGetVIPrivilegeThings = if ($commandName -eq "Set-VIRole" -and $fakeBoundParameter.ContainsKey("Role")) { 323 | ## if Adding privs to this VIRole, then get only the VIPrivs _not_ already a part of the role 324 | if ($parameterName -eq "AddPrivilege") { 325 | { 326 | $arrPrivilegesInThisRole = Get-VIPrivilege @hshParamForGetCmdlet -Role $fakeBoundParameter["Role"] 327 | (Get-VIPrivilege @hshParamForGetCmdlet).Where({$_.Id -notin $arrPrivilegesInThisRole.Id}) 328 | } 329 | } 330 | ## else, removing VIPrivs from the VIRole, so get only the VIPrivs that are a part of this role 331 | else { 332 | $hshParamForGetCmdlet["Role"] = $fakeBoundParameter["Role"] 333 | {Get-VIPrivilege @hshParamForGetCmdlet} 334 | } 335 | } 336 | else { 337 | ## else, just get the VIPrivs with params and no additional filtering 338 | {Get-VIPrivilege @hshParamForGetCmdlet} 339 | } 340 | ## the property of interest, based on the parameterName 341 | $strPropertyOfInterest = if ($parameterName -eq "Id") {$parameterName} else {"Name"} 342 | & $sbGetVIPrivilegeThings | Sort-Object -Property $strPropertyOfInterest | Foreach-Object { 343 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 344 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 345 | $(if ($_.$strPropertyOfInterest -match "\s") {'"{0}"' -f $_.$strPropertyOfInterest} else {$_.$strPropertyOfInterest}), # CompletionText 346 | $_.$strPropertyOfInterest, # ListItemText 347 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 348 | ("[{0}] {1} (description '{2}'{3})" -f $(if ($_ -is [VMware.VimAutomation.Types.PermissionManagement.PrivilegeGroup]) {"PrivilegeGroup"} else {"PrivilegeItem"}), $_.$strPropertyOfInterest, $_.Description, $(if ($_ -is [VMware.VimAutomation.Types.PermissionManagement.PrivilegeItem]) {", in group ID '$($_.ParentGroupId)'"})) # ToolTip 349 | ) 350 | } ## end foreach-object 351 | } ## end scriptblock 352 | 353 | ## for this cmdlet 354 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name Get-VIPrivilege -ErrorAction:SilentlyContinue) {Write-Output Name ID Group | Foreach-Object {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName $_ -ScriptBlock $sbVIPrivilegeCompleter}} 355 | ## for this cmdlet 356 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name New-VIRole -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Privilege -ScriptBlock $sbVIPrivilegeCompleter} 357 | ## for Set-VIRole cmdlet 358 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name Set-VIRole -ErrorAction:SilentlyContinue) {Write-Output AddPrivilege RemovePrivilege | Foreach-Object {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName $_ -ScriptBlock $sbVIPrivilegeCompleter}} 359 | 360 | 361 | 362 | $sbVirtualNetworkCompleter = { 363 | param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 364 | 365 | $hshParamForGetCmdlet = @{Name = "${wordToComplete}*"} 366 | Write-Output Server Location NetworkType | Foreach-Object { 367 | if ($fakeBoundParameter.ContainsKey($_)) {$hshParamForGetCmdlet[$_] = $fakeBoundParameter.$_} 368 | } 369 | Get-VirtualNetwork @hshParamForGetCmdlet | Sort-Object -Property Name | Foreach-Object { 370 | ## make the Completion and ListItem text values; happen to be the same for now, but could be 371 | New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList ( 372 | $(if ($_.Name -match "\s") {'"{0}"' -f $_.Name} else {$_.Name}), # CompletionText 373 | $_.Name, # ListItemText 374 | [System.Management.Automation.CompletionResultType]::ParameterValue, # ResultType 375 | ("[{0}] {1} (id '{2}')" -f $_.NetworkType, $_.Name, $_.Id) # ToolTip 376 | ) 377 | } ## end foreach-object 378 | } ## end scriptblock 379 | 380 | ## for this cmdlet 381 | if ($arrCommandsOfInterest = Get-Command -Module VMware.* -Name Get-VirtualNetwork -ErrorAction:SilentlyContinue) {Register-ArgumentCompleter -CommandName $arrCommandsOfInterest -ParameterName Name -ScriptBlock $sbVirtualNetworkCompleter} 382 | 383 | 384 | ## will need more research (are specific to a particular instance of an object, for example, or current retrieval method is sllloowww) 385 | ## Snapshot, PortGroup, NetworkAdapter, HardDisk, VirtualSwitch, VDPortGroup, Tag 386 | } ## end process 387 | -------------------------------------------------------------------------------- /ScriptFileInfoConfig_Register-VNAWSArgumentCompleter.psd1: -------------------------------------------------------------------------------- 1 | ## config file for creating/update PowerShell ScriptInfo for given script file (via the New-ScriptFileInfo, Update-ScriptFileInfo cmdlets) 2 | ## for script Register-VNVMwarePowerCLIArgumentCompleter.ps1 3 | @{ 4 | Version = "1.3.2" 5 | Author = "Matt Boren (@mtboren)" 6 | CompanyName = 'vNugglets' 7 | Copyright = "MIT License" 8 | Description = "Script to register PowerShell argument completers for many parameters for many AWS.Tools.* (and AWSPowerShell*) cmdlets, making us even more productive on the command line. This enables the tab-completion of actual AWS inventory objects' names as values to parameters to AWS cmdlets -- neat!" 9 | IconUri = "https://avatars0.githubusercontent.com/u/22530966" 10 | LicenseUri = "https://github.com/vNugglets/PowerShellArgumentCompleters/blob/main/License" 11 | ProjectUri = "https://github.com/vNugglets/PowerShellArgumentCompleters" 12 | ReleaseNotes = "See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters" 13 | Tags = "vNugglets", "PowerShell", "ArgumentCompleter", "Parameter", "AWS", "Amazaon", "AmazonWebServices", "AdminOptimization", "NaturalExperience", "TabComplete", "TabCompletion", "Completion", "Awesome" 14 | # RequiredModules 15 | # ExternalModuleDependencies 16 | # RequiredScripts 17 | # ExternalScriptDependencies 18 | # PrivateData 19 | Verbose = $true 20 | } ## end hashtable -------------------------------------------------------------------------------- /ScriptFileInfoConfig_Register-VNActiveDirectoryArgumentCompleter.psd1: -------------------------------------------------------------------------------- 1 | ## config file for creating/update PowerShell ScriptInfo for given script file (via the New-ScriptFileInfo, Update-ScriptFileInfo cmdlets) 2 | ## for script Register-VNVMwarePowerCLIArgumentCompleter.ps1 3 | @{ 4 | Version = "1.0.1" 5 | Author = "Matt Boren (@mtboren)" 6 | CompanyName = 'vNugglets' 7 | Copyright = "MIT License" 8 | Description = "Script to register PowerShell argument completers for many parameters of ActiveDirectory module cmdlets, making us even more productive on the command line. This enables the tab-completion of actual ActiveDirectory objects' and properties' names as values to parameters to ActiveDirectory cmdlets -- neat!" 9 | IconUri = "https://avatars0.githubusercontent.com/u/22530966" 10 | LicenseUri = "https://github.com/vNugglets/PowerShellArgumentCompleters/blob/main/License" 11 | ProjectUri = "https://github.com/vNugglets/PowerShellArgumentCompleters" 12 | ReleaseNotes = "See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters" 13 | Tags = "vNugglets", "PowerShell", "ArgumentCompleter", "Parameter", "ActiveDirectory", "AD", "AdminOptimization", "NaturalExperience", "TabComplete", "TabCompletion", "Completion", "Awesome" 14 | # RequiredModules 15 | ExternalModuleDependencies = "ActiveDirectory" 16 | # RequiredScripts 17 | # ExternalScriptDependencies 18 | # PrivateData 19 | Verbose = $true 20 | } ## end hashtable -------------------------------------------------------------------------------- /ScriptFileInfoConfig_Register-VNVMwarePowerCLIArgumentCompleter.psd1: -------------------------------------------------------------------------------- 1 | ## config file for creating/update PowerShell ScriptInfo for given script file (via the New-ScriptFileInfo, Update-ScriptFileInfo cmdlets) 2 | ## for script Register-VNVMwarePowerCLIArgumentCompleter.ps1 3 | @{ 4 | Version = "1.3.0" 5 | Author = "Matt Boren (@mtboren)" 6 | CompanyName = 'vNugglets' 7 | Copyright = "MIT License" 8 | Description = "Script to register PowerShell argument completers for many parameters for many VMware.PowerCLI cmdlets, making us even more productive on the command line. This enables the tab-completion of actual vSphere inventory objects' names as values to parameters to VMware.PowerCLI cmdlets -- neat!" 9 | IconUri = "https://avatars0.githubusercontent.com/u/22530966" 10 | LicenseUri = "https://github.com/vNugglets/PowerShellArgumentCompleters/blob/main/License" 11 | ProjectUri = "https://github.com/vNugglets/PowerShellArgumentCompleters" 12 | ReleaseNotes = "See ReadMe and other docs at https://github.com/vNugglets/PowerShellArgumentCompleters" 13 | Tags = "vNugglets", "PowerShell", "ArgumentCompleter", "Parameter", "VMware", "PowerCLI", "AdminOptimization", "NaturalExperience", "TabComplete", "TabCompletion", "Completion", "Awesome" 14 | # RequiredModules 15 | # ExternalModuleDependencies 16 | # RequiredScripts 17 | # ExternalScriptDependencies 18 | # PrivateData 19 | Verbose = $true 20 | } ## end hashtable -------------------------------------------------------------------------------- /Set-ScriptFileInfoForCompleter.ps1: -------------------------------------------------------------------------------- 1 | <# .Description 2 | Create/Update the ScriptInfo of a script file (will create it if it does not yet exist) 3 | #> 4 | [CmdletBinding(SupportsShouldProcess = $true)] 5 | param ( 6 | ## The completer script whose Script Info to update/create 7 | [Parameter(Mandatory = $true)][ValidateSet("ActiveDirectory", "AWS", "VMwarePowerCLI")][String[]]$CompleterType, 8 | 9 | ## Force the update of Script File Info in the given script file? Useful for an existing script that has no Script File Info, yet 10 | [Switch]$Force 11 | ) 12 | 13 | process { 14 | $CompleterType | ForEach-Object { 15 | $oCfg = @{ 16 | strPathToScriptFile = "$PSScriptRoot\Register-VN${_}ArgumentCompleter.ps1" 17 | strPathToScriptFileInfoDatafile = "$PSScriptRoot\ScriptFileInfoConfig_Register-VN${_}ArgumentCompleter.psd1" 18 | } 19 | ## parameters for use by both New-ScriptFileInfo and Update-ScriptFileInfo 20 | $hshScriptInfoParams = Import-PowerShellDataFile $oCfg.strPathToScriptFileInfoDatafile 21 | $hshScriptInfoParams["Path"] = $oCfg.strPathToScriptFile 22 | 23 | $strCmdletNameForScriptFileInfoAction, $strVerbForShouldProcessMessage = if (Test-Path $oCfg.strPathToScriptFile) { 24 | ## script file already exists, so update it 25 | "Update-ScriptFileInfo", "Update" 26 | ## if -Force was specified, use it 27 | if ($Force.IsPresent) {$hshScriptInfoParams["Force"] = $true} 28 | } else { 29 | ## else, will create anew 30 | "New-ScriptFileInfo", "Create" 31 | } 32 | 33 | ## do the actual module manifest creation/update 34 | if ($PSCmdlet.ShouldProcess($hshScriptInfoParams["Path"], "$strVerbForShouldProcessMessage Script Information")) { 35 | ## update the existing ScriptInfo in a script file, or create anew (so, would create a new file with just the ScriptInfo info in it, and we would add the actual script contents thereafter) 36 | & $strCmdletNameForScriptFileInfoAction @hshScriptInfoParams 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # Change Log for Argument Completer Scripts 2 | 3 | ## Register-VNActiveDirectoryArgumentCompleter 4 | ### v1.0.1, Jan 2022 5 | - update to handle getting AD objects from other domains in same forest (for completing things like groups and group members) 6 | - add `DisplayName` info to the ToolTip for some member/membership completers 7 | 8 | ### v1.0.0, Jan 2022 9 | - initial release of argument completers -- yay! 10 | - added completers for several parameters like `-Identity` and AD paths (`-Path`, `-SearchBase`, `-TagetPath`, etc.), and for group membership management (`-Members`, `-MemberOf`) 11 | - added completer for arguments for parameter `-Properties` for the cmdlets `Get-ADComputer`, `Get-ADGroup`, `Get-ADOrganizationalUnit`, `Get-ADUser`, for easy discovery/specifying of choice properties to return; based on [Matt McNabb](https://mattmcnabb.github.io/)'s example from a while ago 12 | - included helpful information in the completions' Tool Tip text, like object descriptions, types, creation information where suitable 13 | - see [Issue #11, Add completers for ActiveDirectory module cmdlets](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/11) and the [ReadMe.md](./ReadMe.md) here for other details 14 | 15 | ## Register-VNAWSArgumentCompleter 16 | ### v1.3.2, Feb 2022 17 | - Add completers for AWS ResourceGroup items (feature request in [Issue #21](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/21)) 18 | ### v1.3.1, Jan 2022 19 | - Internal optimization/simplification of completers (feature request in [Issue #18](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/18)) 20 | ### v1.3.0, Jan 2022 21 | - Sped up registering of AWS completers (feature request in [Issue #16](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/16)) 22 | - Added argument completers for the following cmdlets/parameters (feature request in [Issue #13](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/13)): 23 | 24 | | Parameter | NumNewCompletions | Notes | 25 | |-----------|-------------------|-------| 26 | `-RoleArn` | 147 | for cmdlets across several AWS services 27 | `-RepositoryName` | 42 | for cmdlets `Get-Command -ParameterName RepositoryName -Noun ECR*` 28 | `-RegistryId` | 46 | for cmdlets `Get-Command -ParameterName RegistryId` 29 | `-VpcId` | 72 | and for variations of param named `EndpointDetails_VpcId`, `VPC_VPCId`, `VpcConfig_VpcId`, `VpcConfiguration_VpcId`, `VpcId`, `VPCSettings_VpcId` 30 | `-KeyName` | 4 | for `Get-EC2KeyPair`, `New-ASLaunchConfiguration`, `New-EC2Instance`, `Remove-EC2KeyPair` 31 | `-GroupName` | 15 | for aguments of type IAMGroup, for cmdlets in `AWS.Tools.IdentityManagement` 32 | `-PolicyArn` | 18 | for cmdlets in `AWS.Tools.IdentityManagement` 33 | `-GroupId` | 14 | for noun `EC2*`; and, as a bonus feature, can type group _name_ for value of word to complete, the completer will get matching SecurityGroups, and present list of SG IDs (with tooltips that include group name) 34 | `-UserName` | 47 | for cmdlets in `AWS.Tools.IdentityManagement` 35 | `-MetricName` | 12 | for cmdlets in `AWS.Tools.CloudWatchLogs`, `AWS.Tools.CloudWatch` 36 | `-NameSpace` | 10 | for cmdlets in `AWS.Tools.CloudWatchLogs`, `AWS.Tools.CloudWatch` 37 | `-Cluster` | 32 | for cmdlets in `AWS.Tools.ECS` 38 | `-AssociationId` | 8 | for cmdlets in `AWS.Tools.SimpleSystemsManagement` 39 | `-VaultName` | 25 | for cmdlets in `AWS.Tools.Glacier` 40 | `-FileSystemId` | 28 | for cmdlets in `AWS.Tools.ElasticFileSystem`, `AWS.Tools.FSx` (yes, different completion types) 41 | `-EventBusName` | 24 | all such cmdlets are for CloudWatch Events (CWE) / EventBridge (EVB) things 42 | `-SubnetId` | 110 | for cmdlets with variations of param named `*SubnetId*` 43 | `DBInstanceIdentifier` | 22 | for cmdlets in at least `AWS.Tools.RDS` 44 | 45 | ### v1.2.0, Dec 2021 46 | - added completer for arguments for parameter `-Service` for cmdlets `Get-AWSCmdletName`, `Get-AWSService` (feature request in [Issue #9](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/9)) 47 | - added completer for arguments for parameter `-ApiOperation` for cmdlet `Get-AWSCmdletName` (feature request in [Issue #9](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/9)) 48 | - added Tool Tip info for SSM Document and SSM Parameter completions (creation and last modified date, respectively) 49 | 50 | 51 | ## Register-VNVMwarePowerCLIArgumentCompleter 52 | ### v1.2.0 53 | Updated Intellisense ToolTip value for various types to be more useful (feature request in [Issue #3](https://github.com/vNugglets/PowerShellArgumentCompleters/issues/3)): Added more useful ToolTip values to the values in the list of possible tab completions. The list of possible completions is available when pressing `Ctrl+Space` with the cursor at the argument position, like: 54 | ```PowerShell 55 | Get-DatastoreCluster my 56 | ``` 57 | Some examples of the enhanced ToolTips: 58 | - Storage things show free/total space 59 | - VMHost objects show the power- and connection state of the VMHost 60 | - Templates show the configured Guest OS full name 61 | - OSCustomization Specs show the OS type 62 | -------------------------------------------------------------------------------- /docs/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## Docs for PowerShell Arguments Completers 2 | Some info about using argument completers. For other info, the [ReadMe.md](../ReadMe.md) in the root of the project tells a bit of background/overview about PowerShell argument completers, and has links to further reading about how argument completers make better our daily experience in a PowerShell session. 3 | 4 | Contents: 5 | 6 | - [Getting Started](#gettingStarted) 7 | - [ActiveDirectory Argument Completer quick info](#ActiveDirectory-Argument-Completer-quick-info) 8 | - [AWS Argument Completer quick info](#AWS-Argument-Completer-quick-info) 9 | - [VMware-PowerCLI Argument Completer quick info](#VMware-PowerCLI-Argument-Completer-quick-info) 10 | - [Info about Argument Completers in a PowerShell Session](#infoAboutArgCompleterInPSSession) 11 | - [Other Examples](#otherExamples) 12 | 13 | 14 | 15 | ### Getting Started 16 | To register the argument completers provided by this project, you need just a couple of things: 17 | - the script file in which the argument completer definitions and registration statements reside (save or install it from the PowerShell Gallery) 18 | - a PowerShell session with the given module(s) (`ActiveDirectory`, `AWS.Tools.*`, `VMware.PowerCLI`) available to it (in the `$env:PSModulePath` path, at least -- for the VMware completers, the modules don't necessarily have to be imported, yet, but for the AWS completers, only cmdlets for imported modules will be considered for arugment completers, for the sake of speed (since there are 12,000+ cmdlets in all of the AWS modules)). Note: the AWS completers will also work for the monolithic AWS modules (`AWSPowerShell` and `AWSPowerShell.NetCore`), but the way forward is to use the per-service AWS modules (provided by AWS as the `AWS.Tools.*` individual modules). 19 | 20 | The Argument completer scripts available as a part of this project: 21 | - `Register-VNActiveDirectoryArgumentCompleter` 22 | - `Register-VNAWSArgumentCompleter` 23 | - `Register-VNVMwarePowerCLIArgumentCompleter` 24 | 25 | So, for getting/invoking any of these argument-completer scripts from the PowerShell Gallery (use the corresponding script name from above), it goes like: 26 | ``` PowerShell 27 | ## Install and invoke (if you already trust the contents) 28 | ## Install a completer script (again, specify the desired name of completer script) 29 | Find-Script Register-VNActiveDirectoryArgumentCompleter | Install-Script 30 | Find-Script Register-VNAWSArgumentCompleter | Install-Script 31 | Find-Script Register-VNVMwarePowerCLIArgumentCompleter | Install-Script 32 | ## or, collect 'em all! (install them all) 33 | Find-Script Register-VN*ArgumentCompleter | Install-Script 34 | 35 | ## once installed (which should then be in the Path), run the script to register argument completers 36 | Register-VNVMwarePowerCLIArgumentCompleter.ps1 37 | 38 | 39 | ## or, Save, inspect, install, invoke 40 | ## find the script, and save it somewhere 41 | Find-Script Register-VNVMwarePowerCLIArgumentCompleter | Save-Script -Path C:\temp\ScriptsToInspect\ 42 | 43 | ## take a minute to open up the script and make sure that all is well. 44 | # While vNuggs is trustworthy, trust no one, right? Safety first! 45 | 46 | ## then, just run the saved script -- this registers the argument completers in the current PowerShell session 47 | # of course, if you Installed the script, you should just be able to call the script by name, without an explicit path 48 | C:\temp\ScriptsToInspect\Register-VNVMwarePowerCLIArgumentCompleter.ps1 49 | ``` 50 | 51 | And, ¡voila! Now when you use the `VMware.PowerCLI` cmdlets (after connecting to a vCenter server or ESXi host), you can use \ to tab-complete names of inventory objects for parameters. 52 | 53 | ### ActiveDirectory Argument Completer quick info 54 | The argument completers for the `ActiveDirectory` module are currently centered around object types of `Computer`, `Group`, `OrganizationalUnit`, and `User`. At least one handy thing for getting these objects is a completer for the `-Properties` parameter, since none of us remember the names of all ~401 `User` properties, or all ~189 `Group` properties, etc. 55 | 56 | Some of the ActiveDirectory module commands for which this argument completer adds completion support: 57 | 58 | | Name | Parameter | 59 | | ---- | --------- | 60 | Add-ADGroupMember | Identity 61 | Add-ADPrincipalGroupMembership | MemberOf 62 | Get-ADComputer | {Properties, SearchBase} 63 | Get-ADFineGrainedPasswordPolicy | SearchBase 64 | Get-ADGroup | {Identity, Properties, SearchBase} 65 | Get-ADGroupMember | Identity 66 | Get-ADObject | SearchBase 67 | Get-ADOptionalFeature | SearchBase 68 | Get-ADOrganizationalUnit | {Identity, Properties, SearchBase} 69 | Get-ADServiceAccount | SearchBase 70 | Get-ADUser | {Properties, SearchBase} 71 | Move-ADObject | TargetPath 72 | New-ADComputer | Path 73 | New-ADGroup | Path 74 | New-ADObject | Path 75 | New-ADOrganizationalUnit | Path 76 | New-ADServiceAccount | Path 77 | New-ADUser | Path 78 | Remove-ADGroup | Identity 79 | Remove-ADGroupMember | {Identity, Members} 80 | Remove-ADOrganizationalUnit | Identity 81 | Remove-ADPrincipalGroupMembership | MemberOf 82 | Restore-ADObject | TargetPath 83 | Search-ADAccount | SearchBase 84 | Set-ADGroup | Identity 85 | Set-ADOrganizationalUnit | Identity 86 | 87 | Quick examples of some argument tab completions for cmdlets in the ActiveDirectory module: 88 | ```PowerShell 89 | ## tab complete the names of the AD groups that start with 'serverOwner_' in the given AD domain, using specified creds 90 | Get-ADGroup -Server myotherdom -Credential $myCred serverOwner_ 91 | 92 | ## display an interactive list of matching AD OUs through which to navigate (arrow keys) to select the desired OU 93 | Get-ADOrganizationalUnit groups 94 | 95 | ``` 96 | 97 | ### AWS Argument Completer quick info 98 | As of v1.2.0 of the AWS completers, the script registers about 310 additional cmdlet/param completion combinations. A quick list of the `AWS.Tools.*` cmdlet parameters whose values can be tab-completed after registering argument completers with the given script: 99 | 100 | - `-ApiOperation` 101 | - `-AutoScalingGroupName` 102 | - `-BucketName` 103 | - `-FunctionName` 104 | - `-LaunchConfigurationName` 105 | - `-LogGroupName` 106 | - `-LogGroupNamePrefix` 107 | - `-RoleName` 108 | - `-Service` 109 | - `-StackName` 110 | - ..and a few more (`Name` on some cmdlets, for example) 111 | 112 | ### VMware PowerCLI Argument Completer quick info 113 | See the next section for how to inspect what argument completers are added by this script to what parameters/cmdlets. 114 | 115 | 116 | ### Info about Argument Completers in a PowerShell Session 117 | Here is a sample transcript in which the user investigated some about the Argument Completers in their PowerShell session, both before and after registering completers with the given script. 118 | 119 | We see that there were none registered for starters, and eventually there were oodles. 120 | 121 | ``` PowerShell 122 | PS C:\> ## have already imported VMware.PowerCLI module, say, via $Profile 123 | PS C:\> ## let's see what argument completers are already registered (none, yet) 124 | PS C:\> ## note: Get-ArgumentCompleter.ps1 is available from Chris Dent's Gist at 125 | ## https://gist.github.com/indented-automation/26c637fb530c4b168e62c72582534f5b 126 | PS C:\> Get-ArgumentCompleter.ps1 127 | PS C:\> 128 | PS C:\> ## register some PowerCLI argument completers 129 | PS C:\> Register-VNVMwarePowerCLIArgumentCompleter.ps1 130 | PS C:\> 131 | PS C:\> ## see what Parameters' values we will now be able to tab-complete! 132 | PS C:\> ## (get argument completers are now registered, grouped by the Parameter name) 133 | PS C:\> Get-ArgumentCompleter.ps1 | Select-Object -Property CommandName, ParameterName | Group-Object ParameterName | Sort-Object -Property Name 134 | 135 | Count Name Group 136 | ----- ---- ----- 137 | 1 AddPrivilege {@{CommandName=Set-VIRole; ParameterName=AddPrivilege}} 138 | 1 AddVMHost {@{CommandName=Set-VsanFaultDomain; ParameterName=AddVMHost}} 139 | 5 Category {@{CommandName=Get-Tag; ParameterName=Category}, @{CommandName=Get-TagAssignment; Para… 140 | 52 Cluster {@{CommandName=Repair-VsanObject; ParameterName=Cluster}, @{CommandName=Add-VmcSddcHos… 141 | 8 Datacenter {@{CommandName=Get-Datastore; ParameterName=Datacenter}, @{CommandName=Get-VDSwitch; P… 142 | 29 Datastore {@{CommandName=New-DatastoreDrive; ParameterName=Datastore}, @{CommandName=Add-CIDatas… 143 | 2 DatastoreCluster {@{CommandName=Remove-DatastoreCluster; ParameterName=DatastoreCluster}, @{CommandName… 144 | 1 Group {@{CommandName=Get-VIPrivilege; ParameterName=Group}} 145 | 2 GuestID {@{CommandName=New-VM; ParameterName=GuestID}, @{CommandName=Set-VM; ParameterName=Gue… 146 | 5 HostProfile {@{CommandName=Get-VMHostProfileImageCacheConfiguration; ParameterName=HostProfile}, @… 147 | 1 ID {@{CommandName=Get-VIPrivilege; ParameterName=ID}} 148 | 21 Name {@{CommandName=Get-VM; ParameterName=Name}, @{CommandName=Get-Template; ParameterName=… 149 | 7 OSCustomizationSpec {@{CommandName=Get-OSCustomizationNicMapping; ParameterName=OSCustomizationSpec}, @{Co… 150 | 1 PolicyType {@{CommandName=Set-VmcClusterEdrsPolicy; ParameterName=PolicyType}} 151 | 1 Privilege {@{CommandName=New-VIRole; ParameterName=Privilege}} 152 | 9 Profile {@{CommandName=Apply-VMHostProfile; ParameterName=Profile}, @{CommandName=Export-VMHos… 153 | 1 RemovePrivilege {@{CommandName=Set-VIRole; ParameterName=RemovePrivilege}} 154 | 1 RemoveVMHost {@{CommandName=Set-VsanFaultDomain; ParameterName=RemoveVMHost}} 155 | 5 ResourcePool {@{CommandName=Get-VMHost; ParameterName=ResourcePool}, @{CommandName=Move-ResourcePoo… 156 | 7 Role {@{CommandName=Get-PIUser; ParameterName=Role}, @{CommandName=Get-CIUser; ParameterNam… 157 | 565 Server {@{CommandName=Apply-VMHostProfile; ParameterName=Server}, @{CommandName=Connect-PICom… 158 | 23 StoragePolicy {@{CommandName=Export-SpbmStoragePolicy; ParameterName=StoragePolicy}, @{CommandName=G… 159 | 18 Tag {@{CommandName=Get-Cluster; ParameterName=Tag}, @{CommandName=Get-Datacenter; Paramete… 160 | 15 Template {@{CommandName=Get-CDDrive; ParameterName=Template}, @{CommandName=Get-DatastoreCluste… 161 | 11 VApp {@{CommandName=Export-VM; ParameterName=VApp}, @{CommandName=Export-VApp; ParameterNam… 162 | 63 VM {@{CommandName=Export-VM; ParameterName=VM}, @{CommandName=Shutdown-VMGuest; Parameter… 163 | 77 VMHost {@{CommandName=Add-VDSwitchVMHost; ParameterName=VMHost}, @{CommandName=Add-VMHostNtpS… 164 | 165 | PS C:\> 166 | PS C:\> ## see how many scenarios now have argument completers available, if we want to use them 167 | PS C:\> Get-ArgumentCompleter.ps1 | Measure-Object 168 | 169 | Count : 931 170 | Average : 171 | Sum : 172 | Maximum : 173 | Minimum : 174 | Property : 175 | 176 | PS C:\> 177 | PS C:\> ## yay! 178 | ``` 179 | 180 | 181 | ### Examples 182 | There is a [short .gif](resources/ArgCompleterDemo_Keystrokes.gif) (displayed on top-level ReadMe for this repo, too) that depicts some use cases (pictures are worth lots of words). Some examples typed out in words, though: 183 | 184 | In the following line, each "\" is meant to show where pressing the \ key will cycle through the possible completion values for the corresponding parameters: 185 | ``` PowerShell 186 | ## create a new VM 187 | New-VM -VMHost myho -ResourcePool re -Datastore ssd33 -GuestId windows -OSCustomizationSpec win -StoragePolicy VVol -Server vcent -Name mynewvm0 ... 188 | 189 | ## move some VM 190 | Move-VM dd -Datastore nas -Destination (Get-VMHost esxi0) 191 | 192 | ## get some template 193 | Get-Template win201 194 | ``` 195 | -------------------------------------------------------------------------------- /docs/resources/ArgCompleterDemo_Keystrokes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vNugglets/PowerShellArgumentCompleters/c836093ffe2624051f5bbb2d47416fd64b9f980f/docs/resources/ArgCompleterDemo_Keystrokes.gif -------------------------------------------------------------------------------- /snippetsAndExploration.ps1: -------------------------------------------------------------------------------- 1 | ## some snippets from exploring things 2 | 3 | ## get the parameter names for the given cmdlets 4 | (Get-Command -Module (Get-Module VMware.PowerCLI -ListAvailable).RequiredModules).Parameters | Foreach-Object {$_.Getenumerator()} | Group-Object -Proper key -OutVariable arrParamNameGroups 5 | ## see how cmdlets use each param; useful to know on which param names to focus 6 | $arrParamNameGroups | Sort-Object -Property Count, name 7 | --------------------------------------------------------------------------------