PoshCode Logo PowerShell Code Repository

Get-Parameter 2.0 (modification of post by Joel Bennett view diff)
View followups from Joel Bennett | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/2005"></script>download | new post

This is the only Get-Parameter you need ;)

  1. #Requires -version 2.0
  2. #.Synopsys
  3. #  Enumerates the parameters of one or more commands
  4. #.Notes
  5. #  With many thanks to Hal Rottenberg, Oisin Grehan and Shay Levy
  6. #  Version 0.* - By Hal Rottenberg http://poshcode.org/549
  7. #  Version 0.* - By Oisín Grehan http://poshcode.org/446
  8. #              - Added resolving aliases and avoided empty output
  9. #  Version 1.* - By Joel Bennett http://poshcode.org/1592
  10. #              - Merged Oisín and Hal's code with my own implementation
  11. #              - Added calculation of dynamic paramters
  12. #  Version 2.0 - By Joel Bennett (this version):
  13. #              - Now uses FormatData so the output is objects
  14. #              - Added calculation of shortest names to the aliases (idea from Shay Levy http://poshcode.org/1982, but with a correct implementation)
  15. #.Description
  16. # Lists all the parameters of a command, by ParameterSet, including their aliases, type, etc.
  17. #
  18. # By default, formats the output to tables grouped by command and parameter set
  19. #.Example
  20. #  Get-Command Select-Xml | Get-Parameter
  21. #.Example
  22. #  Get-Parameter Select-Xml
  23. #.Parameter Name
  24. #  The name of the command to get parameters for
  25. #.Parameter ModuleName
  26. #  The name of the module which contains the command (this is for scoping)
  27. #.Parameter Force
  28. #  Forces including the CommonParameters in the output
  29. [CmdletBinding()]
  30. ##This is just script-file nesting stuff, so that you can call the SCRIPT, and after it defines the global function, it will call it.
  31. param (
  32.    [Parameter(Position=1,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
  33.    [string[]]$Name
  34. ,
  35.    [Parameter(Position=2,ValueFromPipelineByPropertyName=$true,Mandatory=$false)]
  36.    $ModuleName
  37. ,
  38.    [switch]$Force
  39. )
  40.  
  41. Function global:Get-Parameter {
  42. #.Synopsis
  43. #  Enumerates the parameters of one or more commands
  44. #.Description
  45. # Lists all the parameters of a command, by ParameterSet, including their aliases, type, etc.
  46. #
  47. # By default, formats the output to tables grouped by command and parameter set
  48. #.Example
  49. #  Get-Command Select-Xml | Get-Parameter
  50. #.Example
  51. #  Get-Parameter Select-Xml
  52. #.Parameter Name
  53. #  The name of the command to get parameters for
  54. #.Parameter ModuleName
  55. #  The name of the module which contains the command (this is for scoping)
  56. #.Parameter Force
  57. #  Forces including the CommonParameters in the output
  58. [CmdletBinding()]
  59. param (
  60.    [Parameter(Position=1,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
  61.    [string[]]$Name
  62. ,
  63.    [Parameter(Position=2,ValueFromPipelineByPropertyName=$true,Mandatory=$false)]
  64.    $ModuleName
  65. ,
  66.    [switch]$Force
  67. )
  68. begin {
  69.    $PropertySet = @( "Name",
  70.                      @{n="Position";e={if($_.Position -lt 0){"Named"}else{$_.Position}}},
  71.                      "Aliases",
  72.                      @{n="Short";e={$_.Name}},
  73.                      @{n="Type";e={$_.ParameterType.Name}},
  74.                      @{n="ParameterSet";e={$paramset}},
  75.                      @{n="Command";e={$command}},
  76.                      @{n="Mandatory";e={$_.IsMandatory}},
  77.                      @{n="Provider";e={$_.DynamicProvider}},
  78.                      @{n="ValueFromPipeline";e={$_.ValueFromPipeline}},
  79.                      @{n="ValueFromPipelineByPropertyName";e={$_.ValueFromPipelineByPropertyName}}
  80.                   )
  81.    function Join-Object {
  82.    Param(
  83.       [Parameter(Position=0)]
  84.       $First
  85.    ,
  86.       [Parameter(ValueFromPipeline=$true,Position=1)]
  87.       $Second
  88.    )
  89.       begin {
  90.          [string[]] $p1 = $First | gm -type Properties | select -expand Name
  91.       }
  92.       process {
  93.          $Output = $First | Select $p1
  94.          foreach($p in $Second | gm -type Properties | Where { $p1 -notcontains $_.Name } | select -expand Name) {
  95.             Add-Member -in $Output -type NoteProperty -name $p -value $Second."$p"
  96.          }
  97.          $Output
  98.       }
  99.    }
  100. }
  101. process{
  102.    foreach($cmd in $Name) {
  103.       if($ModuleName)   { $cmd = "$ModuleName\$cmd" }
  104.       $commands = @(Get-Command $cmd)
  105.  
  106.       foreach($command in $commands) {
  107.          # resolve aliases (an alias can point to another alias)
  108.          while ($command.CommandType -eq "Alias") {
  109.             $command = @(Get-Command ($command.definition))[0]
  110.          }
  111.          if (-not $command) { continue }
  112.  
  113.          $Parameters = @{}
  114.  
  115.          foreach($provider in Get-PSProvider) {
  116.             $drive = "{0}\{1}::\" -f $provider.ModuleName, $provider.Name
  117.             Write-Verbose ("Get-Command $command -Args $drive | Select -Expand Parameters")
  118.            
  119.             $MoreParameters = Get-Command $command -Args $drive | Select -Expand Parameters
  120.             $Dynamic = $MoreParameters | Select -Expand Values | Where { $_.IsDynamic }
  121.             foreach($k in $Parameters.Keys | Where { $Dynamic.Keys -notcontains $_ } ){ $null = $MoreParameters.Remove($k) }
  122.             $Parameters += $MoreParameters
  123.            
  124.             # Write-Verbose "Drive: $Drive | Parameters: $($Parameters.Count)"
  125.             if($dynamic) {
  126.                foreach($d in $dynamic) {
  127.                   if(Get-Member -input $Parameters.($d.Name) -Name DynamicProvider) {
  128.                      Write-Debug ("ADD:" + $d.Name + " " + $provider.Name)
  129.                      $Parameters.($d.Name).DynamicProvider += $provider.Name
  130.                   } else {
  131.                      Write-Debug ("CREATE:" + $d.Name + " " + $provider.Name)
  132.                      $Parameters.($d.Name) = $Parameters.($d.Name) | Add-Member NoteProperty DynamicProvider @($provider.Name) -Passthru
  133.                   }
  134.                }
  135.             }
  136.          }
  137.          
  138.          ## Calculate the shortest distinct parameter name -- do this BEFORE removing the common parameters or else.
  139.          foreach($p in $($Parameters.Keys))
  140.          {
  141.             $shortest="^"
  142.             foreach($char in [char[]]$p)
  143.             {            
  144.                $shortest += $char
  145.                $Matches = ($Parameters.Keys -match $Shortest).Count
  146.                Write-Debug "$($shortest.SubString(1)) $Matches"
  147.                if($Matches -eq 1)
  148.                {
  149.                   $Parameters.$p = $Parameters.$p | Add-Member NoteProperty Aliases ($Parameters.$p.Aliases + @($shortest.SubString(1).ToLower($PSUICulture))) -Force -Passthru
  150.                   break
  151.                }
  152.             }
  153.          }
  154.    
  155.          Write-Verbose "Parameters: $($Parameters.Count)`n $($Parameters | ft | out-string)"
  156.        
  157.          foreach ($paramset in @($command.ParameterSets | Select -Expand "Name")){
  158.             foreach($parameter in $Parameters.Keys | Sort) {
  159.                Write-Verbose "Parameter: $Parameter"
  160.                if(!$Force -and ($Parameters.$Parameter.aliases -match "vb|db|ea|wa|ev|wv|ov|ob|wi|cf")) { continue }
  161.                if($Parameters.$Parameter.ParameterSets.ContainsKey($paramset) -or $Parameters.$Parameter.ParameterSets.ContainsKey("__AllParameterSets")) {                  
  162.                   if($Parameters.$Parameter.ParameterSets.ContainsKey($paramset)) {
  163.                      $output = Join-Object $Parameters.$Parameter $Parameters.$Parameter.ParameterSets.$paramSet
  164.                   } else {
  165.                      $output = Join-Object $Parameters.$Parameter $Parameters.$Parameter.ParameterSets.__AllParameterSets
  166.                   }
  167.                   Write-Output $Output | Select-Object $PropertySet | ForEach {
  168.                      $null = $_.PSTypeNames.Insert(0,"System.Management.Automation.ParameterMetadata")
  169.                      $null = $_.PSTypeNames.Insert(0,"System.Management.Automation.ParameterMetadataEx")
  170.                      Write-Verbose "$(($_.PSTypeNames.GetEnumerator()) -join ", ")"
  171.                      $_
  172.                   }
  173.                }
  174.             }
  175.          }
  176.       }
  177.    }
  178. }
  179. }
  180.  
  181.  
  182. # Since you can't update format data without a file that has a ps1xml ending, let's make one up...
  183. $tempFile = "$([IO.Path]::GetTempFileName()).ps1xml"
  184. Set-Content $tempFile @'
  185. <?xml version="1.0" encoding="utf-8" ?>
  186. <Configuration>
  187.    <Controls>
  188.        <Control>
  189.            <Name>ParameterGroupingFormat</Name>
  190.              <CustomControl>
  191.                  <CustomEntries>
  192.                      <CustomEntry>
  193.                          <CustomItem>
  194.                              <Frame>
  195.                                  <LeftIndent>4</LeftIndent>
  196.                                  <CustomItem>
  197.                                      <Text>Command: </Text>
  198.                                      <ExpressionBinding>
  199.                                          <ScriptBlock>"{0}/{1}" -f $(if($_.command.ModuleName){$_.command.ModuleName}else{$_.Command.CommandType.ToString()+":"}),$_.command.Name</ScriptBlock>
  200.                                      </ExpressionBinding>
  201.                                      <NewLine/>
  202.                                      <Text>Set:     </Text>
  203.                                      <ExpressionBinding>
  204.                                          <ScriptBlock>if($_.ParameterSet -eq "__AllParameterSets"){"Default"}else{$_.ParameterSet}</ScriptBlock>
  205.                                      </ExpressionBinding>
  206.                                      <NewLine/>
  207.                                  </CustomItem>
  208.                              </Frame>
  209.                          </CustomItem>
  210.                      </CustomEntry>
  211.                  </CustomEntries>
  212.            </CustomControl>
  213.        </Control>
  214.    </Controls>
  215.    <ViewDefinitions>
  216.        <View>
  217.            <Name>ParameterMetadataEx</Name>
  218.            <ViewSelectedBy>
  219.                <TypeName>System.Management.Automation.ParameterMetadataEx</TypeName>
  220.            </ViewSelectedBy>
  221.            <GroupBy>
  222.                <PropertyName>ParameterSet</PropertyName>
  223.                <CustomControlName>ParameterGroupingFormat</CustomControlName>  
  224.            </GroupBy>
  225.            <TableControl>
  226.                <TableHeaders>
  227.                    <TableColumnHeader>
  228.                        <Label>Name</Label>
  229.                        <Width>22</Width>
  230.                    </TableColumnHeader>
  231.                    <TableColumnHeader>
  232.                        <Label>Aliases</Label>
  233.                        <Width>12</Width>
  234.                    </TableColumnHeader>
  235.                    <TableColumnHeader>
  236.                        <Label>Position</Label>
  237.                        <Width>8</Width>
  238.                    </TableColumnHeader>
  239.                    <TableColumnHeader>
  240.                        <Label>Mandatory</Label>
  241.                        <Width>9</Width>
  242.                    </TableColumnHeader>
  243.                    <TableColumnHeader>
  244.                        <Label>Pipeline</Label>
  245.                        <Width>8</Width>
  246.                    </TableColumnHeader>
  247.                    <TableColumnHeader>
  248.                        <Label>ByName</Label>
  249.                        <Width>6</Width>
  250.                    </TableColumnHeader>
  251.                    <TableColumnHeader>
  252.                        <Label>Provider</Label>
  253.                        <Width>15</Width>
  254.                    </TableColumnHeader>
  255.                    <TableColumnHeader>
  256.                        <Label>Type</Label>
  257.                    </TableColumnHeader>
  258.                </TableHeaders>
  259.                <TableRowEntries>
  260.                    <TableRowEntry>
  261.                        <TableColumnItems>
  262.                            <TableColumnItem>
  263.                                <PropertyName>Name</PropertyName>
  264.                            </TableColumnItem>
  265.                            <TableColumnItem>
  266.                                <PropertyName>Aliases</PropertyName>
  267.                            </TableColumnItem>
  268.                            <TableColumnItem>
  269.                                <!--PropertyName>Position</PropertyName-->
  270.                                <ScriptBlock>if($_.Position -lt 0){"Named"}else{$_.Position}</ScriptBlock>
  271.                            </TableColumnItem>
  272.                            <TableColumnItem>
  273.                                <PropertyName>Mandatory</PropertyName>
  274.                            </TableColumnItem>
  275.                            <TableColumnItem>
  276.                                <PropertyName>ValueFromPipeline</PropertyName>
  277.                            </TableColumnItem>
  278.                            <TableColumnItem>
  279.                                <PropertyName>ValueFromPipelineByPropertyName</PropertyName>
  280.                            </TableColumnItem>
  281.                            <TableColumnItem>
  282.                                <!--PropertyName>Provider</PropertyName-->
  283.                                <ScriptBlock>if($_.Provider){$_.Provider}else{"All"}</ScriptBlock>
  284.                            </TableColumnItem>
  285.                            <TableColumnItem>
  286.                                <PropertyName>Type</PropertyName>
  287.                            </TableColumnItem>
  288.                        </TableColumnItems>
  289.                    </TableRowEntry>
  290.                 </TableRowEntries>
  291.            </TableControl>
  292.        </View>
  293.    </ViewDefinitions>
  294. </Configuration>
  295. '@
  296.  
  297. Update-FormatData -Append $tempFile
  298.  
  299.  
  300. # This is nested stuff, so that you can call the SCRIPT, and after it defines the global function, we will call that.
  301. Get-Parameter @PSBoundParameters

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me