PoshCode Logo PowerShell Code Repository

TabExpansion (modification of post by view diff)
View followups from foobar | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/781"></script>download | new post

Ported TabExpansion from V2CTP2 to v1.0 and extended.
Update:

Parameter expansion for function, filter and scripts
man -f<tab>
‘param([System.StringSplitOptions]$foo,[System.Management.Automation.ActionPreference]$bar,[System.Management.Automation.CommandTypes]$baz) {}’ > foobar.ps1
.\foobar.ps1 -<tab> -b<tab>

Enum expansion for function, filter and scripts parameter (this doesn’t work latest V2 CTP)
.\foobar.ps1 -foo rem<tab> -bar <tab><comma>c<tab><comma>sc<tab> -ea silent<tab> -wa con<tab>

Enum expansion for assignment expression
$ErrorActionPreference =<space><tab>
$cmdtypes = New-Object System.Management.Automation.CommandTypes[] 3
$cmdtypes =<space><tab><comma><space>func<tab><comma><space>cmd<tab> -as<space><tab>

Better ‘$_.’ expansion for Get-Item and Get-Command and a expression of only a variable
$data = Get-Process; $data[2,4,5] | % { $_.<tab>
gi hkcu:\ | % { $_.subkey<tab>
gcm powershell.exe | % { $_.file<tab> *this requires latest Get-PipeLineObject.ps1 in a same directory

  1. ## Tab-Completion
  2. #################
  3. ## Please dot souce this script file.
  4. ## In first loading, it may take a several minutes, in order to generate ProgIDs and TypeNames list.
  5. ## What this can do is:
  6. ##
  7. ## [datetime]::n<tab>
  8. ## [datetime]::now.d<tab>
  9. ## $a = New-Object "Int32[,]" 2,3; $b = "PowerShell","PowerShell"
  10. ## $c = [ref]$a; $d = [ref]$b,$c
  11. ## $d[0].V<tab>[0][0].Get<tab>
  12. ## $d[1].V<tab>[0,0].tos<tab>
  13. ## $function:a<tab>
  14. ## $env:a<tab>
  15. ## [System.Type].a<tab>
  16. ## [datetime].Assembly.a<tab>
  17. ## ).a<tab> # shows System.Type properties and methods...
  18.  
  19. ## #native command name expansion
  20. ## fsu<tab>
  21.  
  22. ## #command option name expansion (for fsutil ipconfig net powershell only)
  23. ## fsutil <tab>
  24. ## ipconfig <tab>
  25. ## net <tab>
  26. ## powershell <tab>
  27.  
  28. ## #TypeNames expansion
  29. ## [Dec<tab>
  30. ## [Microsoft.PowerShell.Com<tab>
  31. ## New-Object -TypeName IO.Dir<tab>
  32. ## New-Object System.Management.Auto<tab>
  33.  
  34. ## #ProgIDs expansion
  35. ## New-Object -Com shel<tab>
  36.  
  37. ## #Enum option expansion
  38. ## Set-ExecutionPolicy <tab>
  39. ## Set-ExecutionPolicy All<tab>
  40. ## Set-ExcusionPolisy -ex <tab>
  41. ## Get-TraceSource@Inte<tab>
  42. ## iex -Err <tab> -wa Sil<tab>
  43.  
  44. ## #WmiClasses expansion
  45. ## Get-WmiObject -class Win32_<tab>
  46. ## gwmi __Instance<tab>
  47.  
  48. ## #Encoding expansion
  49. ## [Out-File | Export-CSV | Select-String | Export-Clixml] -enc <tab>
  50. ## [Add-Content | Get-Content | Set-Content} -Encoding Big<tab>
  51.  
  52. ## #PSProvider name expansion
  53. ## [Get-Location | Get-PSDrive | Get-PSProvider | New-PSDrive | Remove-PSDrive] [-PSProvider] <tab>
  54. ## Get-PSProvider <tab>
  55. ## pwd -psp al<tab>
  56.  
  57. ## #PSDrive name expansion
  58. ## [Get-PSDrive | New-PSDrive | Remove-PSDrive] [-Name] <tab>
  59. ## Get-PSDrive <tab>
  60. ## pwd -psd <tab>
  61.  
  62. ## #PSSnapin name expansion
  63. ## [Add-PSSnapin | Get-PSSnapin | Remove-PSSnapin ] [-Name] <tab>
  64. ## Get-Command -PSSnapin <tab>
  65. ## Remove-PSSnapin <tab>
  66. ## Get-PSSnapin M<tab>
  67.  
  68. ## #Eventlog name and expansion
  69. ## Get-Eventlog -Log <tab>
  70. ## Get-Eventlog w<tab>
  71.  
  72. ## #Eventlog's entrytype expansion
  73. ## Get-EventLog -EntryType <tab>
  74. ## Get-EventLog -EntryType Er<tab>
  75. ## Get-EventLog -Ent <tab>
  76.  
  77. ## #Service name expansion
  78. ## [Get-Service | Restart-Service | Resume-Service | Start-Service | Stop-Service | Suspend-Service] [-Name] <tab>
  79. ## New-Service -DependsOn <tab>
  80. ## New-Service -Dep e<tab>
  81. ## Get-Service -n <tab>
  82. ## Get-Service <tab>,a<tab>,p<tab>
  83. ## gsv <tab>
  84.  
  85. ## #Service display name expansion
  86. ## [Get-Service | Restart-Service | Resume-Service | Start-Service | Stop-Service | Suspend-Service] [-DisplayName] <tab>
  87. ## Get-Service -Dis <tab>
  88. ## gsv -Dis <tab>,w<tab>,b<tab>
  89.  
  90. ## #Cmdlet and Topic name expansion
  91. ## Get-Help [-Name] about_<tab>
  92. ## Get-Help <tab>
  93.  
  94. ## #Category name expansion
  95. ## Get-Help -Category c<tab>,<tab>
  96.  
  97. ## #Command name expansion
  98. ## Get-Command [-Name] <tab>
  99. ## Get-Command -Name <tab>
  100. ## gcm a<tab>,<tab>
  101.  
  102. ## #Scope expansion
  103. ## [Clear-Variable | Export-Alias | Get-Alias | Get-PSDrive | Get-Variable | Import-Alias
  104. ## New-Alias | New-PSDrive | New-Variable | Remove-Variable | Set-Alias | Set-Variable] -Scope <tab>
  105. ## Clear-Variable -Scope G<tab>
  106. ## Set-Alias  -s <tab>
  107.  
  108. ## #Process name expansion
  109. ## [Get-Process | Stop-Process] [-Name] <tab>
  110. ## Stop-Process -Name <tab>
  111. ## Stop-Process -N pow<tab>
  112. ## Get-Process <tab>
  113. ## ps power<tab>
  114.  
  115. ## #Trace sources expansion
  116. ## [Trace-Command | Get-TraceSource | Set-TraceSource] [-Name] <tab>,a<tab>,p<tab>
  117.  
  118. ## #Trace -ListenerOption expansion
  119. ## [Set-TraceSource | Trace-Command] -ListenerOption <tab>
  120. ## Set-TraceSource -Lis <tab>,n<tab>
  121.  
  122. ## #Trace -Option expansion
  123. ## [Set-TraceSource | Trace-Command] -Option <tab>
  124. ## Set-TraceSource -op <tab>,con<tab>
  125.  
  126. ## #ItemType expansion
  127. ## New-Item -Item <tab>
  128. ## ni -ItemType d<tab>
  129.  
  130. ## #ErrorAction and WarningAction option expansion
  131. ## CMDLET [-ErrorAction | -WarningAction] <tab>
  132. ## CMDLET -Error s<tab>
  133. ## CMDLET -ea con<tab>
  134. ## CMDLET -wa <tab>
  135.  
  136. ## #Continuous expansion with comma when parameter can treat multiple option
  137. ## # if there are spaces, occur display bug in the line
  138. ## # if strings contains '$' or '-', not work
  139. ## Get-Command -CommandType <tab>,<tab><tab>,cm<tab>
  140. ## pwd -psp <tab>,f<tab>,va<tab>
  141. ## Get-EventLog -EntryType <tab>,i<tab>,s<tab>
  142.  
  143. ## #Enum expansion in method call expression
  144. ## # this needs one or more spaces after left parenthesis or comma
  145. ## $str = "day   night"
  146. ## $str.Split( " ",<space>rem<tab>
  147. ## >>> $str.Split( " ", "RemoveEmptyEntries" ) <Enter> ERROR
  148. ## $str.Split( " ", "RemoveEmptyEntries" -as<space><tab>
  149. ## >>> $str.Split( " ", "RemoveEmptyEntries" -as [System.StringSplitOptions] ) <Enter> Success
  150. ## $type = [System.Type]
  151. ## $type.GetMembers(<space>Def<tab>
  152. ## [IO.Directory]::GetFiles( "C:\", "*",<space>All<tab>
  153. ## # this can do continuous enum expansion with comma and no spaces
  154. ## $type.GetMembers( "IgnoreCase<comma>Dec<tab><comma>In<tab>"
  155. ## [IO.Directory]::GetAccessControl( "C:\",<space>au<tab><comma>ac<tab><comma>G<tab>
  156.  
  157. ## #Better '$_.' expansion when cmdlet output objects or method return objects
  158. ## ls |group { $_.Cr<tab>.Tost<tab>"y")} | tee -var foo| ? { $_.G<tab>.c<tab> -gt 5 } | % { md $_.N<tab> ; copy $_.G<tab> $_.N<tab>  }
  159. ## [IO.DriveInfo]::GetDrives() | ? { $_.A<tab> -gt 1GB }
  160. ## $Host.UI.RawUI.GetBufferContents($rect) | % { $str += $_.c<tab> }
  161. ## gcm Add-Content |select -exp Par<tab>|select -exp <tab> |
  162. ## select -ExpandProperty Par<tab>| | ? { $_.Par<tab>.N<tab> -eq "string" }
  163. ## $data = Get-Process
  164. ## $data[2,4,5]  | % { $_.<tab>
  165. ## #when Get-PipeLineObject failed, '$_.' shows methods and properties name of FileInfo and String and Type
  166.  
  167. ## #Property name expansion
  168. ## [ Format-List | Format-Custom | Format-Table | Format-Wide | Compare-Object |
  169. ##  ConvertTo-Html | Measure-Object | Select-Object | Group-Object | Sort-Object ] [-Property] <tab>
  170. ## Select-Object -ExcludeProperty <tab>
  171. ## Select-Object -ExpandProperty <tab>
  172. ## gcm Get-Acl|select -exp Par<tab>
  173. ## ps |group na<tab>
  174. ## ls | ft A<tab>,M<tab>,L<tab>
  175.  
  176. ## #Hashtable key expansion in the variable name and '.<tab>'
  177. ## Get-Process | Get-Unique | % { $hash += @{$_.ProcessName=$_} }
  178. ## $hash.pow<tab>.pro<tab>
  179.  
  180. ## #Parameter expansion for function, filter and script
  181. ## man -f<tab>
  182. ## 'param([System.StringSplitOptions]$foo,[System.Management.Automation.ActionPreference]$bar,[System.Management.Automation.CommandTypes]$baz) {}' > foobar.ps1
  183. ## .\foobar.ps1 -<tab> -b<tab>
  184.  
  185. ## #Enum expansion for function, filter and scripts
  186. ## # this can do continuous enum expansion with comma and no spaces
  187. ## .\foobar.ps1 -foo rem<tab> -bar <tab><comma>c<tab><comma>sc<tab> -ea silent<tab> -wa con<tab>
  188.  
  189. ## #Enum expansion for assignment expression
  190. ## #needs space(s) after '=' and comma
  191. ## #strongly-typed with -as operator and space(s)
  192. ## $ErrorActionPreference =<space><tab>
  193. ## $cmdtypes = New-Object System.Management.Automation.CommandTypes[] 3
  194. ## $cmdtypes =<space><tab><comma><space>func<tab><comma><space>cmd<tab> -as<space><tab>
  195.  
  196.  
  197. ### Generate ProgIDs list...
  198. if ($_ProgID -eq $null) {
  199.     $_HKCR = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey("CLSID\")
  200.     [Object[]] $_ProgID = $null
  201.     foreach ( $_subkey in $_HKCR.GetSubKeyNames() )
  202.     {
  203.         foreach ( $_i in [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey("CLSID\$_subkey\ProgID") )
  204.         {
  205.             if ($_i -ne $null)
  206.             {
  207.                 $_ProgID += $_i.GetValue("")
  208.             }
  209.         }
  210.     }
  211.     '$_ProgID was updated...' | Out-Host
  212.     $_ProgID = $_ProgID|sort -Unique
  213.  
  214.     Set-Content -Value $_ProgID -Path $PSHOME\ProgIDs.txt
  215.     Add-Content -Path $PSHOME\profile.ps1 -Value ';$_ProgID = Get-Content -Path C:\WINDOWS\system32\windowspowershell\v1.0\ProgIDs.txt;'
  216. }
  217.  
  218. ### Generate TypeNames list...
  219.  
  220. if ( $_TypeNames -eq $null ) {
  221.     [Object[]] $_TypeNames = $null
  222.     foreach ( $_asm in [AppDomain]::CurrentDomain.GetAssemblies() )
  223.     {
  224.         foreach ( $_type in $_asm.GetTypes() )
  225.         {
  226.             $_TypeNames += $_type.FullName
  227.         }
  228.     }
  229.     '$_TypeNames was updated...' | Out-Host
  230.     $_TypeNames = $_TypeNames | sort -Unique
  231.  
  232.     Set-Content -Value $_TypeNames -Path $PSHOME\TypeNames.txt
  233.     Add-Content -Path $PSHOME\profile.ps1 -Value ';$_TypeNames = Get-Content -Path $PSHOME\TypeNames.txt;'
  234. }
  235.  
  236. if ( $_TypeNames_System -eq $null ) {
  237.     [Object[]] $_TypeNames_System = $null
  238.     foreach ( $_type in $_TypeNames -like "System.*" )
  239.     {
  240.         $_TypeNames_System += $_type.Substring(7)
  241.     }
  242.     '$_TypeNames_System was updated...' | Out-Host
  243.     Set-Content -Value $_TypeNames_System -Path $PSHOME\TypeNames_System.txt
  244.     Add-Content -Path $PSHOME\profile.ps1 -Value ';$_TypeNames_System = Get-Content -Path $PSHOME\TypeNames_System.txt;'
  245. }
  246.  
  247. ### Generate WMIClasses list...
  248. if ( $_WMIClasses -eq $null ) {
  249.     [Object[]] $_WMIClasses = $null
  250.     foreach ( $_class in gwmi -List )
  251.     {
  252.         $_WMIClasses += $_class.Name
  253.     }
  254.     $_WMIClasses = $_WMIClasses | sort -Unique
  255.     '$_WMIClasses was updated...' | Out-Host
  256.     Set-Content -Value $_WMIClasses -Path $PSHOME\WMIClasses.txt
  257.     Add-Content -Path $PSHOME\profile.ps1 -Value ';$_WMIClasses = Get-Content -Path $PSHOME\WMIClasses.txt;'
  258. }
  259. $global:_snapin = $null
  260.  
  261. # Load Get-PipeLineObject function for $_ and property name expansion.
  262. $_scriptpath = gi $MyInvocation.MyCommand.Path
  263. iex (". " + (Join-Path $_scriptpath.DirectoryName "Get-PipeLineObject.ps1"))
  264.  
  265. function TabExpansion {
  266.             # This is the default function to use for tab expansion. It handles simple
  267.             # member expansion on variables, variable name expansion and parameter completion
  268.             # on commands. It doesn't understand strings so strings containing ; | ( or { may
  269.             # cause expansion to fail.
  270.  
  271.             param($line, $lastWord)
  272.  
  273.             & {
  274.                 # Helper function to write out the matching set of members. It depends
  275.                 # on dynamic scoping to get $_base, _$expression and $_pat
  276.                 function Write-Members ($sep='.')
  277.                 {
  278.  
  279.                     # evaluate the expression to get the object to examine...
  280.                     Invoke-Expression ('$_val=' + $_expression)
  281.  
  282.                     if ( $_expression -match '^\$global:_dummy' )
  283.                     {
  284.                         $temp = $_expression -replace '^\$global:_dummy(.*)','$1'
  285.                         $_expression = '$_' + $temp
  286.                     }
  287.  
  288.  
  289.                     $_method = [Management.Automation.PSMemberTypes] `
  290.                         'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
  291.  
  292.                     if ($sep -eq '.')
  293.                     {
  294.                         $members =
  295.                             (
  296.                                 [Object[]](Get-Member -InputObject $_val.PSextended $_pat) +
  297.                                 [Object[]](Get-Member -InputObject $_val.PSadapted $_pat) +
  298.                                 [Object[]](Get-Member -InputObject $_val.PSbase $_pat)
  299.                             )
  300.                         if ( $_val -is [Hashtable] )
  301.                         {
  302.                             [Microsoft.PowerShell.Commands.MemberDefinition[]]$_keys = $null
  303.                             foreach ( $_name in $_val.Keys )
  304.                             {
  305.                                 $_keys += `
  306.                                 New-Object Microsoft.PowerShell.Commands.MemberDefinition `
  307.                                 [int],$_name,"Property",0
  308.                             }
  309.  
  310.                             $members += [Object[]]$_keys | ? { $_.Name -like $_pat }
  311.                         }
  312.  
  313.                         foreach ($_m in $members | sort membertype,name -Unique)
  314.                             {
  315.                                 if ($_m.MemberType -band $_method)
  316.                                 {
  317.                                     # Return a method...
  318.                                     $_base + $_expression + $sep + $_m.name + '('
  319.                                 }
  320.                                 else {
  321.                                     # Return a property...
  322.                                     $_base + $_expression + $sep + $_m.name
  323.                                 }
  324.                             }
  325.                         }
  326.  
  327.                     else
  328.                     {
  329.                     foreach ($_m in Get-Member -Static -InputObject $_val $_pat |
  330.                         Sort-Object membertype,name)
  331.                        {
  332.                            if ($_m.MemberType -band $_method)
  333.                            {
  334.                                # Return a method...
  335.                                $_base + $_expression + $sep + $_m.name + '('
  336.                            }
  337.                            else {
  338.                                # Return a property...
  339.                                $_base + $_expression + $sep + $_m.name
  340.                            }
  341.                         }
  342.                     }
  343.                 }
  344.  
  345.                 switch -regex ($lastWord)
  346.                 {
  347.  
  348.                     # Handle property and method expansion at '$_'
  349.                     '(^.*)(\$_\.)(\w*)$' {
  350.                         $_base = $matches[1]
  351.                         $_expression = '$global:_dummy'
  352.                         $_pat = $matches[3] + '*'
  353.                         $global:_dummy = $null
  354.                         Get-PipeLineObject
  355.                         if ( $global:_dummy -eq $null )
  356.                         {
  357.  
  358.                             if ( $global:_exp -match '^\$.*\(.*$' )
  359.                             {
  360.                                 $type = ( iex $_exp.Split("(")[0] ).OverloadDefinitions[0].Split(" ")[0] -replace '\[[^\[\]]*\]$' -as [type]
  361.  
  362.                                 if ( $_expression -match '^\$global:_dummy' )
  363.                                 {
  364.                                     $temp = $_expression -replace '^\$global:_dummy(.*)','$1'
  365.                                     $_expression = '$_' + $temp
  366.                                 }
  367.  
  368.                                 foreach ( $_m in $type.GetMembers() | sort membertype,name | group name | ? { $_.Name -like $_pat } | % { $_.Group[0] } )
  369.                                 {
  370.                                    if ($_m.MemberType -eq "Method")
  371.                                    {
  372.                                        $_base + $_expression + '.' + $_m.name + '('
  373.                                    }
  374.                                    else {
  375.                                        $_base + $_expression + '.' + $_m.name
  376.                                    }
  377.                                 }
  378.                                 break;
  379.                             }
  380.                             elseif ( $global:_exp -match '^\[.*\:\:.*\(.*$' )
  381.                             {
  382.                                 $tname, $mname = $_exp.Split(":(", "RemoveEmptyEntries"-as [System.StringSplitOptions])[0,1]
  383.                                 $type = @(iex ($tname + '.GetMember("' + $mname + '")'))[0].ReturnType.FullName -replace '\[[^\[\]]*\]$' -as [type]
  384.  
  385.                                 if ( $_expression -match '^\$global:_dummy' )
  386.                                 {
  387.                                     $temp = $_expression -replace '^\$global:_dummy(.*)','$1'
  388.                                     $_expression = '$_' + $temp
  389.                                 }
  390.  
  391.                                 foreach ( $_m in $type.GetMembers() | sort membertype,name | group name | ? { $_.Name -like $_pat } | % { $_.Group[0] } )
  392.                                 {
  393.                                    if ($_m.MemberType -eq "Method")
  394.                                    {
  395.                                        $_base + $_expression + '.' + $_m.name + '('
  396.                                    }
  397.                                    else {
  398.                                        $_base + $_expression + '.' + $_m.name
  399.                                    }
  400.                                 }
  401.                                 break;
  402.                             }
  403.                             elseif ( $global:_exp -match '^(\$\w+(\[[0-9,\.]+\])*(\.\w+(\[[0-9,\.]+\])*)*)$' )
  404.                             {
  405.                                 $global:_dummy = @(iex $Matches[1])[0]
  406.                             }
  407.                             else
  408.                             {
  409.                                 $global:_dummy =  $global:_mix
  410.                             }
  411.                         }
  412.  
  413.                         Write-Members
  414.                         break;
  415.                     }
  416.  
  417.                     # Handle property and method expansion rooted at variables...
  418.                     # e.g. $a.b.<tab>
  419.                     '(^.*)(\$(\w|\.)+)\.(\w*)$' {
  420.                         $_base = $matches[1]
  421.                         $_expression = $matches[2]
  422.                         [void] ( iex "$_expression.IsDataLanguageOnly" ) # for [ScriptBlock]
  423.                         $_pat = $matches[4] + '*'
  424.                         if ( $_expression -match '^\$_\.' )
  425.                         {
  426.                             $_expression = $_expression -replace '^\$_(.*)',('$global:_dummy' + '$1')
  427.                         }
  428.                         Write-Members
  429.                         break;
  430.                     }
  431.  
  432.                     # Handle simple property and method expansion on static members...
  433.                     # e.g. [datetime]::n<tab>
  434.                     '(^.*)(\[(\w|\.)+\])\:\:(\w*)$' {
  435.                         $_base = $matches[1]
  436.                         $_expression = $matches[2]
  437.                         $_pat = $matches[4] + '*'
  438.                         Write-Members '::'
  439.                         break;
  440.                     }
  441.  
  442.                     # Handle complex property and method expansion on static members
  443.                     # where there are intermediate properties...
  444.                     # e.g. [datetime]::now.d<tab>
  445.                     '(^.*)(\[(\w|\.)+\]\:\:(\w+\.)+)(\w*)$' {
  446.                         $_base = $matches[1]  # everything before the expression
  447.                         $_expression = $matches[2].TrimEnd('.') # expression less trailing '.'
  448.                         $_pat = $matches[5] + '*'  # the member to look for...
  449.                         Write-Members
  450.                         break;
  451.                     }
  452.  
  453.                     # Handle variable name expansion...
  454.                     '(^.*\$)(\w+)$' {
  455.                         $_prefix = $matches[1]
  456.                         $_varName = $matches[2]
  457.                         foreach ($_v in Get-ChildItem ('variable:' + $_varName + '*'))
  458.                         {
  459.                             $_prefix + $_v.name
  460.                         }
  461.                         break;
  462.                     }
  463.  
  464.                     # Handle env&function drives variable name expansion...
  465.                     '(^.*\$)(.*\:)(\w+)$' {
  466.                         $_prefix = $matches[1]
  467.                         $_drive = $matches[2]
  468.                         $_varName = $matches[3]
  469.                         if ($_drive -eq "env:" -or $_drive -eq "function:")
  470.                         {
  471.                             foreach ($_v in Get-ChildItem ($_drive + $_varName + '*'))
  472.                             {
  473.                                 $_prefix + $_drive + $_v.name
  474.                             }
  475.                         }
  476.                         break;
  477.                     }
  478.  
  479.                     # Handle array's element property and method expansion
  480.                     # where there are intermediate properties...
  481.                     # e.g. foo[0].n.b<tab>
  482.                     '(^.*)(\$((\w+\.)|(\w+(\[(\w|,)+\])+\.))+)(\w*)$'
  483.                     {
  484.                         $_base = $matches[1]
  485.                         $_expression = $matches[2].TrimEnd('.')
  486.                         $_pat = $Matches[8] + '*'
  487.                         [void] ( iex "$_expression.IsDataLanguageOnly" ) # for [ScriptBlock]
  488.                         if ( $_expression -match '^\$_\.' )
  489.                         {
  490.                             $_expression = $_expression -replace '^\$_(.*)',('$global:_dummy' + '$1')
  491.                         }
  492.                         Write-Members
  493.                         break;
  494.                     }
  495.  
  496.                     # Handle property and method expansion rooted at type object...
  497.                     # e.g. [System.Type].a<tab>
  498.                     '(^\[(\w|\.)+\])\.(\w*)$'
  499.                     {
  500.                         if ( $(iex $Matches[1]) -isnot [System.Type] ) { break; }
  501.                         $_expression = $Matches[1]
  502.                         $_pat = $Matches[$matches.Count-1] + '*'
  503.                         Write-Members
  504.                         break;
  505.                     }
  506.  
  507.                     # Handle complex property and method expansion on type object members
  508.                     # where there are intermediate properties...
  509.                     # e.g. [datetime].Assembly.a<tab>
  510.                     '^(\[(\w|\.)+\]\.(\w+\.)+)(\w*)$' {
  511.                         $_expression = $matches[1].TrimEnd('.') # expression less trailing '.'
  512.                         $_pat = $matches[4] + '*'  # the member to look for...
  513.                         if ( $(iex $_expression) -eq $null ) { break; }
  514.                         Write-Members
  515.                         break;
  516.                     }
  517.  
  518.                     # Handle property and method expansion rooted at close parenthes...
  519.                     # e.g. (123).a<tab>
  520.                     '^(.*)\)((\w|\.)*)\.(\w*)$' {
  521.                         $_base = $Matches[1] + ")"
  522.                         if ( $matches[3] -eq $null) { $_expression = '[System.Type]' }
  523.                         else { $_expression = '[System.Type]' + $Matches[2] }
  524.                         $_pat = $matches[4] + '*'
  525.                         iex "$_expression | Get-Member $_pat | sort MemberType,Name" |
  526.                         % {
  527.                             if ( $_.MemberType -like "*Method*" -or $_.MemberType -like "*Parameterized*" ) { $parenthes = "(" }
  528.                             if ( $Matches[2] -eq "" ) { $_base + "." + $_.Name + $parenthes }
  529.                             else { $_base + $Matches[2] + "." + $_.Name + $parenthes }
  530.                           }
  531.                         break;
  532.                     }
  533.  
  534.                     # Handle .NET type name expansion ...
  535.                     # e.g. [Microsoft.PowerShell.Com<tab>
  536.                     '^\[((\w+\.?)+)$' {
  537.                         $_opt = $matches[1] + '*'
  538.                         foreach ( $_exp in $_TypeNames_System -like $_opt )
  539.                         {
  540.                             '[' + $_exp
  541.                         }
  542.                         foreach ( $_exp in $_TypeNames -like $_opt )
  543.                         {
  544.                             '[' + $_exp
  545.                         }
  546.                         break;
  547.                     }
  548.  
  549.                     # Do completion on parameters...
  550.                     '^-([\w0-9]*)' {
  551.                         $_pat = $matches[1] + '*'
  552.  
  553.                         # extract the command name from the string
  554.                         # first split the string into statements and pipeline elements
  555.                         # This doesn't handle strings however.
  556.                         $_cmdlet = [regex]::Split($line, '[|;=]')[-1]
  557.  
  558.                         #  Extract the trailing unclosed block e.g. ls | foreach { cp
  559.                         if ($_cmdlet -match '\{([^\{\}]*)$')
  560.                         {
  561.                             $_cmdlet = $matches[1]
  562.                         }
  563.  
  564.                         # Extract the longest unclosed parenthetical expression...
  565.                         if ($_cmdlet -match '\(([^()]*)$')
  566.                         {
  567.                             $_cmdlet = $matches[1]
  568.                         }
  569.  
  570.                         # take the first space separated token of the remaining string
  571.                         # as the command to look up. Trim any leading or trailing spaces
  572.                         # so you don't get leading empty elements.
  573.                         $_cmdlet = $_cmdlet.Trim().Split()[0]
  574.  
  575.                         # now get the info object for it...
  576.                         $_cmdlet = @(Get-Command -type 'cmdlet,alias,function,filter,ExternalScript' $_cmdlet)[0]
  577.  
  578.                         # loop resolving aliases...
  579.                         while ($_cmdlet.CommandType -eq 'alias')
  580.                         {
  581.                             $_cmdlet = @(Get-Command -type 'cmdlet,alias,function,filter,ExternalScript' $_cmdlet.Definition)[0]
  582.                         }
  583.  
  584.                         if ( $_cmdlet.CommandType -eq "Cmdlet" )
  585.                         {
  586.                             # expand the parameter sets and emit the matching elements
  587.                             foreach ($_n in $_cmdlet.ParameterSets |
  588.                                 Select-Object -expand parameters | Sort-Object -Unique name)
  589.                             {
  590.                                 $_n = $_n.name
  591.                                 if ($_n -like $_pat) { '-' + $_n }
  592.                             }
  593.                             break;
  594.                         }
  595.  
  596.                         if ( "ExternalScript", "Function", "Filter" -contains $_cmdlet.CommandType )
  597.                         {
  598.                             if ( $_cmdlet.CommandType -eq "ExternalScript" )
  599.                             {
  600.                                 $_fsr = New-Object IO.StreamReader $_cmdlet.Definition
  601.                                 $_def = "Function _Dummy { $($_fsr.ReadToEnd()) }"
  602.                                 $_fsr.Close()
  603.                                 iex $_def
  604.                                 $_cmdlet = "_Dummy"
  605.                             }
  606.  
  607.                             if ( ((gi "Function:$_cmdlet").Definition -replace '\n').Split("{")[0] -match 'param\((.*\))\s*[;\.&a-zA-Z]*\s*$' )
  608.                             {
  609.                                 ( ( ( $Matches[1].Split('$', "RemoveEmptyEntries" -as [System.StringSplitOptions]) -replace `
  610.                                 '^(\w+)(.*)','$1' ) -notmatch '^\s+$' ) -notmatch '^\s*\[.*\]\s*$' ) -like $_pat | sort | % { '-' + $_ }
  611.                             }
  612.                             break;
  613.                         }
  614.  
  615.                     }
  616.  
  617.  
  618.                     # try to find a matching command...
  619.                     default {
  620.  
  621.                         $lastex =  [regex]::Split($line, '[|;]')[-1]
  622.                         if ( $lastex -match '^\s*(\$\w+(\[[0-9,]+\])*(\.\w+(\[[0-9,]+\])*)*)\s*=\s+(("\w+"\s*,\s+)*)"\w+"\s*-as\s+$' )
  623.                         {
  624.                             if ( $Matches[6] -ne $nul )
  625.                             {
  626.                             $brackets = "[]"
  627.                             }
  628.                             '['+ $global:_enum + $brackets + ']'
  629.                             break;
  630.                         }
  631.  
  632.  
  633.                         if ( $lastex -match '^\s*(\$\w+(\[[0-9,]+\])*(\.\w+(\[[0-9,]+\])*)*)\s*=\s+(("\w+"\s*,\s+)*)\s*(\w*)$' )
  634.                         {
  635.                             $_pat = $Matches[7] + '*'
  636.  
  637.                             $_type = @(iex $Matches[1])[0].GetType()
  638.                             if ( $_type.IsEnum )
  639.                             {
  640.                                 $global:_enum = $_type.FullName
  641.                                 [Enum]::GetValues($_type) -like $_pat -replace '^(.*)$','"$1"'
  642.                                 break;
  643.                             }
  644.                         }
  645.  
  646.                         $lastex =  [regex]::Split($line, '[|;=]')[-1]
  647.                         if ($lastex  -match '[[$].*\w+\(.*-as\s*$')
  648.                         {
  649.                             '['+ $global:_enum + ']'
  650.                         }
  651.                         elseif ( $lastex -match '([[$].*(\w+))\((.*)$' )
  652.                         #elseif ( $lastex -match '([[$].*(\w+))\(([^)]*)$' )
  653.                         {
  654.                             $_method = $Matches[1]
  655.  
  656.                             if ( $Matches[3] -match "(.*)((`"|')(\w+,)+(\w*))$" )
  657.                             {
  658.                                 $continuous = $true
  659.                                 $_opt =  $Matches[5] + '*'
  660.                                 $_base =  $Matches[2].TrimStart('"') -replace '(.*,)\w+$','$1'
  661.                                 $position = $Matches[1].Split(",").Length
  662.                             }
  663.                             else
  664.                             {
  665.                                 $continuous = $false
  666.                                 $_opt = ($Matches[3].Split(',')[-1] -replace '^\s*','') + "*"
  667.                                 $position = $Matches[3].Split(",").Length
  668.                             }
  669.  
  670.                             if ( ($_mdefs = iex ($_method + ".OverloadDefinitions")) -eq $null )
  671.                             {
  672.                                 $tname, $mname = $_method.Split(":", "RemoveEmptyEntries" -as [System.StringSplitOptions])
  673.                                 $_mdefs = iex ($tname + '.GetMember("' + $mname + '") | % { $_.ToString() }')
  674.                             }
  675.  
  676.                             foreach ( $def in $_mdefs )
  677.                             {
  678.                                 [void] ($def -match '\((.*)\)')
  679.                                 foreach ( $param in [regex]::Split($Matches[1], ', ')[$position-1] )
  680.                                 {
  681.                                     if ($param -eq $null -or $param -eq "")
  682.                                     {
  683.                                         continue;
  684.                                     }
  685.                                     $type = $param.split()[0]
  686.  
  687.                                     if ( $type -like '*`[*' -or $type -eq "Params" -or $type -eq "" )
  688.                                     {
  689.                                         continue;
  690.                                     }
  691.                                     $fullname  = @($_typenames -like "*$type*")
  692.                                     foreach ( $name in $fullname )
  693.                                     {
  694.                                         if ( $continuous -eq $true -and ( $name  -as [System.Type] ).IsEnum )
  695.                                         {
  696.                                             $output = [Enum]::GetValues($name) -like $_opt -replace '^(.*)$',($_base + '$1')
  697.                                             $output | sort
  698.                                         }
  699.                                         elseif ( ( $name  -as [System.Type] ).IsEnum )
  700.                                         {
  701.                                             $global:_enum = $name
  702.                                             $output = [Enum]::GetValues($name) -like $_opt -replace '^(.*)$','"$1"'
  703.                                             $output | sort
  704.                                         }
  705.                                     }
  706.                                 }
  707.                             }
  708.                             if ( $output -ne $null )
  709.                             {
  710.                                 break;
  711.                             }
  712.                         }
  713.  
  714.  
  715.                         if ( $line[-1] -eq " " )
  716.                         {
  717.                             $_cmdlet = $line.TrimEnd(" ").Split(" |(;={")[-1]
  718.  
  719.                             # now get the info object for it...
  720.                             $_cmdlet = @(Get-Command -type 'cmdlet,alias' $_cmdlet)[0]
  721.  
  722.                             # loop resolving aliases...
  723.                             while ($_cmdlet.CommandType -eq 'alias')
  724.                             {
  725.                                 $_cmdlet = @(Get-Command -type 'cmdlet,alias' $_cmdlet.Definition)[0]
  726.                             }
  727.  
  728.                             if ( "Set-ExecutionPolicy" -eq $_cmdlet.Name )
  729.                             {
  730.                                 "Unrestricted", "RemoteSigned", "AllSigned", "Restricted", "Default" | sort
  731.                                 break;
  732.                             }
  733.  
  734.                             if ( "Trace-Command","Get-TraceSource","Set-TraceSource" -contains $_cmdlet.Name )
  735.                             {
  736.                                Get-TraceSource | % { $_.Name } | sort -Unique
  737.                                break;
  738.                             }
  739.  
  740.                             if ( "New-Object" -eq $_cmdlet.Name )
  741.                             {
  742.                                  $_TypeNames_System
  743.                                  $_TypeNames
  744.                                  break;
  745.                             }
  746.  
  747.                             if ( $_cmdlet.Noun -like "*WMI*" )
  748.                             {
  749.                                 $_WMIClasses
  750.                                 break;
  751.                             }
  752.  
  753.                             if ( "Get-Process" -eq $_cmdlet.Name )
  754.                             {
  755.                                  Get-Process | % { $_.Name } | sort
  756.                                  break;
  757.                             }
  758.  
  759.                             if ( "Add-PSSnapin", "Get-PSSnapin", "Remove-PSSnapin" -contains $_cmdlet.Name )
  760.                             {
  761.                                 if ( $global:_snapin -ne $null )
  762.                                 {
  763.                                     $global:_snapin
  764.                                     break;
  765.                                 }
  766.                                 else
  767.                                 {
  768.                                     $global:_snapin = $(Get-PSSnapIn -Registered;Get-PSSnapIn)| sort Name -Unique;
  769.                                     $global:_snapin
  770.                                     break;
  771.                                 }
  772.                             }
  773.  
  774.                             if ( "Get-PSDrive", "New-PSDrive", "Remove-PSDrive" `
  775.                                  -contains $_cmdlet.Name -and "Name" )
  776.                             {
  777.                                 Get-PSDrive | sort
  778.                                 break;
  779.                             }
  780.  
  781.                             if ( "Get-Eventlog" -eq $_cmdlet.Name )
  782.                             {
  783.                                  Get-EventLog -List | % { $_base + ($_.Log -replace '\s','` ') }
  784.                                  break;
  785.                             }
  786.  
  787.                             if ( "Get-Help" -eq $_cmdlet.Name )
  788.                             {
  789.                                 Get-Help -Category all | % { $_.Name } | sort -Unique
  790.                                      break;
  791.                             }
  792.  
  793.                             if ( "Get-Service", "Restart-Service", "Resume-Service",
  794.                                  "Start-Service", "Stop-Service", "Suspend-Service" `
  795.                                  -contains $_cmdlet.Name )
  796.                             {
  797.                                 Get-Service | sort Name  | % { $_base + ($_.Name -replace '\s','` ') }
  798.                                 break;
  799.                             }
  800.  
  801.                             if ( "Get-Command" -eq $_cmdlet.Name )
  802.                             {
  803.                                  Get-Command -CommandType All | % { $_base + ($_.Name -replace '\s','` ') }
  804.                                  break;
  805.                             }
  806.  
  807.                             if ( "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Compare-Object",
  808.                                  "ConvertTo-Html", "Measure-Object", "Select-Object", "Group-Object", "Sort-Object" `
  809.                                   -contains $_cmdlet.Name )
  810.                             {
  811.                                  Get-PipeLineObject
  812.                                  $_dummy | Get-Member -MemberType Properties,ParameterizedProperty | sort membertype | % { $_base + ($_.Name -replace '\s','` ') }
  813.                                  break;
  814.                             }
  815.  
  816.                         }
  817.  
  818.                         if ( $line[-1] -eq " " )
  819.                         {
  820.                             # extract the command name from the string
  821.                             # first split the string into statements and pipeline elements
  822.                             # This doesn't handle strings however.
  823.                             $_cmdlet = [regex]::Split($line, '[|;=]')[-1]
  824.  
  825.                             #  Extract the trailing unclosed block e.g. ls | foreach { cp
  826.                             if ($_cmdlet -match '\{([^\{\}]*)$')
  827.                             {
  828.                                 $_cmdlet = $matches[1]
  829.                             }
  830.  
  831.                             # Extract the longest unclosed parenthetical expression...
  832.                             if ($_cmdlet -match '\(([^()]*)$')
  833.                             {
  834.                                 $_cmdlet = $matches[1]
  835.                             }
  836.  
  837.                             # take the first space separated token of the remaining string
  838.                             # as the command to look up. Trim any leading or trailing spaces
  839.                             # so you don't get leading empty elements.
  840.                             $_cmdlet = $_cmdlet.Trim().Split()[0]
  841.  
  842.                             # now get the info object for it...
  843.                             $_cmdlet = @(Get-Command -type 'Application' $_cmdlet)[0]
  844.  
  845.                             if ( $_cmdlet.Name -eq "powershell.exe" )
  846.                             {
  847.                                 "-PSConsoleFile", "-Version", "-NoLogo", "-NoExit", "-Sta", "-NoProfile", "-NonInteractive",
  848.                                 "-InputFormat", "-OutputFormat", "-EncodedCommand", "-File", "-Command" | sort
  849.                                 break;
  850.                             }
  851.                             if ( $_cmdlet.Name -eq "fsutil.exe" )
  852.                             {
  853.                                 "behavior query", "behavior set", "dirty query", "dirty set",
  854.                                 "file findbysid", "file queryallocranges", "file setshortname", "file setvaliddata", "file setzerodata", "file createnew",
  855.                                 "fsinfo drives", "fsinfo drivetype", "fsinfo volumeinfo", "fsinfo ntfsinfo", "fsinfo statistics",
  856.                                 "hardlink create", "objectid query", "objectid set", "objectid delete", "objectid create",
  857.                                 "quota disable", "quota track", "quota enforce", "quota violations", "quota modify", "quota query",
  858.                                 "reparsepoint query", "reparsepoint delete", "sparse setflag", "sparse queryflag", "sparse queryrange", "sparse setrange",
  859.                                 "usn createjournal", "usn deletejournal", "usn enumdata", "usn queryjournal", "usn readdata", "volume dismount", "volume diskfree" | sort
  860.                                 break;
  861.                             }
  862.                             if ( $_cmdlet.Name -eq "net.exe" )
  863.                             {
  864.                                 "ACCOUNTS ", " COMPUTER ", " CONFIG ", " CONTINUE ", " FILE ", " GROUP ", " HELP ",
  865.                                 "HELPMSG ", " LOCALGROUP ", " NAME ", " PAUSE ", " PRINT ", " SEND ", " SESSION ",
  866.                                 "SHARE ", " START ", " STATISTICS ", " STOP ", " TIME ", " USE ", " USER ", " VIEW" | sort
  867.                                 break;
  868.                             }
  869.                             if ( $_cmdlet.Name -eq "ipconfig.exe" )
  870.                             {
  871.                                 "/?", "/all", "/renew", "/release", "/flushdns", "/displaydns",
  872.                                 "/registerdns", "/showclassid", "/setclassid"
  873.                                 break;
  874.                             }
  875.                         }
  876.  
  877.                         if ( $line -match '\w+\s+(\w+(\.|[^\s\.])*)$' )
  878.                         {
  879.                             #$_opt = $Matches[1] + '*'
  880.                             $_cmdlet = $line.TrimEnd(" ").Split(" |(;={")[-2]
  881.  
  882.                             $_opt = $Matches[1].Split(" ,")[-1] + '*'
  883.                             $_base = $Matches[1].Substring(0,$Matches[1].Length-$Matches[1].Split(" ,")[-1].length)
  884.  
  885.  
  886.                             # now get the info object for it...
  887.                             $_cmdlet = @(Get-Command -type 'cmdlet,alias' $_cmdlet)[0]
  888.  
  889.                             # loop resolving aliases...
  890.                             while ($_cmdlet.CommandType -eq 'alias')
  891.                             {
  892.                                 $_cmdlet = @(Get-Command -type 'cmdlet,alias' $_cmdlet.Definition)[0]
  893.                             }
  894.  
  895.                             if ( "Set-ExecutionPolicy" -eq $_cmdlet.Name )
  896.                             {
  897.                                 "Unrestricted", "RemoteSigned", "AllSigned", "Restricted", "Default" -like $_opt | sort
  898.                                 break;
  899.                             }
  900.  
  901.                             if ( "Trace-Command","Get-TraceSource","Set-TraceSource" -contains $_cmdlet.Name )
  902.                             {
  903.                                Get-TraceSource -Name $_opt | % { $_.Name } | sort -Unique | % { $_base + ($_ -replace '\s','` ') }
  904.                                break;
  905.                             }
  906.  
  907.                             if ( "New-Object" -eq $_cmdlet.Name )
  908.                             {
  909.                                  $_TypeNames_System -like $_opt
  910.                                  $_TypeNames -like $_opt
  911.                                  break;
  912.                             }
  913.  
  914.                             if ( $_cmdlet.Name -like "*WMI*" )
  915.                             {
  916.                                 $_WMIClasses -like $_opt
  917.                                 break;
  918.                             }
  919.  
  920.                             if ( "Get-Process" -eq $_cmdlet.Name )
  921.                             {
  922.                                  Get-Process $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') }
  923.                                  break;
  924.                             }
  925.  
  926.                             if ( "Add-PSSnapin", "Get-PSSnapin", "Remove-PSSnapin" -contains $_cmdlet.Name )
  927.                             {
  928.                                 if ( $global:_snapin -ne $null )
  929.                                 {
  930.                                     $global:_snapin -like $_opt | % { $_base + ($_ -replace '\s','` ') }
  931.                                     break;
  932.                                 }
  933.                                 else
  934.                                 {
  935.                                     $global:_snapin = $(Get-PSSnapIn -Registered;Get-PSSnapIn)| sort Name -Unique;
  936.                                     $global:_snapin -like $_opt | % { $_base + ($_ -replace '\s','` ') }
  937.                                     break;
  938.                                 }
  939.                             }
  940.  
  941.                             if ( "Get-PSDrive", "New-PSDrive", "Remove-PSDrive" `
  942.                                  -contains $_cmdlet.Name -and "Name" )
  943.                             {
  944.                                 Get-PSDrive -Name $_opt | sort | % { $_base + ($_ -replace '\s','` ') }
  945.                                 break;
  946.                             }
  947.  
  948.                             if ( "Get-PSProvider" -eq $_cmdlet.Name )
  949.                             {
  950.                                 Get-PSProvider -PSProvider $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') }
  951.                                 break;
  952.                             }
  953.  
  954.  
  955.                             if ( "Get-Eventlog" -eq $_cmdlet.Name )
  956.                             {
  957.                                  Get-EventLog -List | ? { $_.Log -like $_opt } | % { $_base + ($_.Log -replace '\s','` ') }
  958.                                  break;
  959.                             }
  960.  
  961.                             if ( "Get-Help" -eq $_cmdlet.Name )
  962.                             {
  963.                                 Get-Help -Category all -Name $_opt | % { $_.Name } | sort -Unique
  964.                                      break;
  965.                             }
  966.  
  967.                             if ( "Get-Service", "Restart-Service", "Resume-Service",
  968.                                  "Start-Service", "Stop-Service", "Suspend-Service" `
  969.                                  -contains $_cmdlet.Name )
  970.                             {
  971.                                 Get-Service -Name $_opt | sort Name  | % { $_base + ($_.Name -replace '\s','` ') }
  972.                                 break;
  973.                             }
  974.  
  975.                             if ( "Get-Command" -eq $_cmdlet.Name )
  976.                             {
  977.                                  Get-Command -CommandType All -Name $_opt | % { $_base + ($_.Name -replace '\s','` ') }
  978.                                  break;
  979.                             }
  980.  
  981.                             if ( "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Compare-Object",
  982.                                  "ConvertTo-Html", "Measure-Object", "Select-Object", "Group-Object", "Sort-Object" `
  983.                                   -contains $_cmdlet.Name )
  984.                             {
  985.                                  Get-PipeLineObject
  986.                                  $_dummy | Get-Member -Name $_opt -MemberType Properties,ParameterizedProperty | sort membertype | % { $_base + ($_.Name -replace '\s','` ') }
  987.                                  break;
  988.                             }
  989.                         }
  990.  
  991.                         if ( $line -match '(-(\w+))\s+([^-]*$)' )
  992.                         {
  993.  
  994.                             $_param = $matches[2] + '*'
  995.                             $_opt = $Matches[3].Split(" ,")[-1] + '*'
  996.                             $_base = $Matches[3].Substring(0,$Matches[3].Length-$Matches[3].Split(" ,")[-1].length)
  997.  
  998.                             # extract the command name from the string
  999.                             # first split the string into statements and pipeline elements
  1000.                             # This doesn't handle strings however.
  1001.                             $_cmdlet = [regex]::Split($line, '[|;=]')[-1]
  1002.  
  1003.                             #  Extract the trailing unclosed block e.g. ls | foreach { cp
  1004.                             if ($_cmdlet -match '\{([^\{\}]*)$')
  1005.                             {
  1006.                                 $_cmdlet = $matches[1]
  1007.                             }
  1008.  
  1009.                             # Extract the longest unclosed parenthetical expression...
  1010.                             if ($_cmdlet -match '\(([^()]*)$')
  1011.                             {
  1012.                                 $_cmdlet = $matches[1]
  1013.                             }
  1014.  
  1015.                             # take the first space separated token of the remaining string
  1016.                             # as the command to look up. Trim any leading or trailing spaces
  1017.                             # so you don't get leading empty elements.
  1018.                             $_cmdlet = $_cmdlet.Trim().Split()[0]
  1019.  
  1020.                             # now get the info object for it...
  1021.                             $_cmdlet = @(Get-Command -type 'cmdlet,alias,ExternalScript,Filter,Function' $_cmdlet)[0]
  1022.  
  1023.                             # loop resolving aliases...
  1024.                             while ($_cmdlet.CommandType -eq 'alias')
  1025.                             {
  1026.                                 $_cmdlet = @(Get-Command -type 'cmdlet,alias,ExternalScript,Filter,Function' $_cmdlet.Definition)[0]
  1027.                             }
  1028.  
  1029.                             if ( $_param.TrimEnd("*") -eq "ea" -or $_param.TrimEnd("*") -eq "wa" )
  1030.                             {
  1031.                                "SilentlyContinue", "Stop", "Continue", "Inquire" |
  1032.                                ? { $_ -like $_opt } | sort -Unique
  1033.                                break;
  1034.                             }
  1035.  
  1036.                             if ( "Out-File","Export-CSV","Select-String","Export-Clixml" -contains $_cmdlet.Name `
  1037.                                  -and "Encoding" -like $_param)
  1038.                             {
  1039.                                 "Unicode",  "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM" |
  1040.                                 ? { $_ -like $_opt } | sort -Unique
  1041.                                 break;
  1042.                             }
  1043.  
  1044.                             if ( "Trace-Command","Get-TraceSource","Set-TraceSource" -contains $_cmdlet.Name `
  1045.                                 -and "Name" -like $_param)
  1046.                             {
  1047.                                Get-TraceSource -Name $_opt | % { $_.Name } | sort -Unique | % { $_base + ($_ -replace '\s','` ') }
  1048.                                break;
  1049.                             }
  1050.  
  1051.                             if ( "New-Object" -like $_cmdlet.Name )
  1052.                             {
  1053.                                 if ( "ComObject" -like $_param )
  1054.                                 {
  1055.                                     $_ProgID -like $_opt  | % { $_ -replace '\s','` ' }
  1056.                                     break;
  1057.                                 }
  1058.  
  1059.                                 if ( "TypeName" -like $_param )
  1060.                                 {
  1061.                                     $_TypeNames_System -like $_opt
  1062.                                     $_TypeNames -like $_opt
  1063.                                     break;
  1064.                                 }
  1065.                             }
  1066.  
  1067.                             if ( "New-Item" -eq $_cmdlet.Name )
  1068.                             {
  1069.                                 if ( "ItemType" -like $_param )
  1070.                                 {
  1071.                                     "directory", "file" -like $_opt
  1072.                                     break;
  1073.                                 }
  1074.                             }
  1075.  
  1076.                             if ( "Get-Location", "Get-PSDrive", "Get-PSProvider", "New-PSDrive", "Remove-PSDrive" `
  1077.                                  -contains $_cmdlet.Name `
  1078.                                  -and "PSProvider" -like $_param )
  1079.                             {
  1080.                                 Get-PSProvider -PSProvider $_opt | % { $_.Name } | sort  | % { $_base + ($_ -replace '\s','` ') }
  1081.                                 break;
  1082.                             }
  1083.  
  1084.                             if ( "Get-Location" -eq $_cmdlet.Name -and "PSDrive" -like $_param )
  1085.                             {
  1086.                                 Get-PSDrive -Name $_opt | sort | % { $_base + ($_ -replace '\s','` ') }
  1087.                                 break;
  1088.                             }
  1089.  
  1090.                             if ( "Get-PSDrive", "New-PSDrive", "Remove-PSDrive" `
  1091.                                  -contains $_cmdlet.Name -and "Name" -like $_param )
  1092.                             {
  1093.                                 Get-PSDrive -Name $_opt | sort | % { $_base + ($_ -replace '\s','` ') }
  1094.                                 break;
  1095.                             }
  1096.  
  1097.                             if ( "Get-Command" -eq $_cmdlet.Name -and  "PSSnapin" -like $_param)
  1098.                             {
  1099.                                 if ( $global:_snapin -ne $null )
  1100.                                 {
  1101.                                     $global:_snapin -like $_opt  | % { $_base + $_ }
  1102.                                     break;
  1103.                                 }
  1104.                                 else
  1105.                                 {
  1106.                                     $global:_snapin = $(Get-PSSnapIn -Registered;Get-PSSnapIn)| sort Name -Unique;
  1107.                                     $global:_snapin -like $_opt  | % { $_base + ($_ -replace '\s','` ') }
  1108.                                     break;
  1109.                                 }
  1110.                             }
  1111.  
  1112.                             if ( "Add-PSSnapin", "Get-PSSnapin", "Remove-PSSnapin" `
  1113.                                  -contains $_cmdlet.Name -and "Name" -like $_param )
  1114.                             {
  1115.                                 if ( $global:_snapin -ne $null )
  1116.                                 {
  1117.                                     $global:_snapin -like $_opt | % { $_base + ($_ -replace '\s','` ') }
  1118.                                     break;
  1119.                                 }
  1120.                                 else
  1121.                                 {
  1122.                                     $global:_snapin = $(Get-PSSnapIn -Registered;Get-PSSnapIn)| sort Name -Unique;
  1123.                                     $global:_snapin -like $_opt | % { $_base + $_ }
  1124.                                     break;
  1125.                                 }
  1126.                             }
  1127.  
  1128.                             if ( "Clear-Variable", "Export-Alias", "Get-Alias", "Get-PSDrive", "Get-Variable", "Import-Alias",
  1129.                                  " New-Alias", "New-PSDrive", "New-Variable", "Remove-Variable", "Set-Alias", "Set-Variable" `
  1130.                                  -contains $_cmdlet.Name -and "Scope" -like $_param )
  1131.                             {
  1132.                                 "Global", "Local", "Script" -like $_opt
  1133.                                 break;
  1134.                             }
  1135.  
  1136.                             if ( "Get-Process", "Stop-Process", "Wait-Process" -contains $_cmdlet.Name -and "Name" -like $_param )
  1137.                             {
  1138.                                  Get-Process $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') }
  1139.                                  break;
  1140.                             }
  1141.  
  1142.                             if ( "Get-Eventlog" -eq $_cmdlet.Name -and "LogName" -like $_param )
  1143.                             {
  1144.                                  Get-EventLog -List | ? { $_.Log -like $_opt } | % { $_base + ($_.Log -replace '\s','` ') }
  1145.                                  break;
  1146.                             }
  1147.  
  1148.                             if ( "Get-Help" -eq $_cmdlet.Name )
  1149.                             {
  1150.                                  if ( "Name" -like $_param )
  1151.                                  {
  1152.                                      Get-Help -Category all -Name $_opt | % { $_.Name } | sort -Unique
  1153.                                      break;
  1154.                                  }
  1155.                                  if ( "Category" -like $_param )
  1156.                                  {
  1157.                                      "Alias", "Cmdlet", "Provider", "General", "FAQ",
  1158.                                      "Glossary", "HelpFile", "All" -like $_opt | sort | % { $_base + $_ }
  1159.                                      break;
  1160.                                  }
  1161.                             }
  1162.  
  1163.                             if ( "Get-Service", "Restart-Service", "Resume-Service",
  1164.                                  "Start-Service", "Stop-Service", "Suspend-Service" `
  1165.                                  -contains $_cmdlet.Name )
  1166.                             {
  1167.                                  if ( "Name" -like $_param )
  1168.                                  {
  1169.                                      Get-Service -Name $_opt | sort Name  | % { $_base + ($_.Name -replace '\s','` ') }
  1170.                                      break;
  1171.                                  }
  1172.                                  if ( "DisplayName" -like $_param )
  1173.                                  {
  1174.                                      Get-Service -Name $_opt | sort DisplayName | % { $_base + ($_.DisplayName -replace '\s','` ') }
  1175.                                      break;
  1176.                                  }
  1177.                             }
  1178.  
  1179.                             if ( "New-Service" -eq $_cmdlet.Name -and "dependsOn" -like $_param )
  1180.                             {
  1181.                                  Get-Service -Name $_opt | sort Name | % { $_base + ($_.Name -replace '\s','` ') }
  1182.                                  break;
  1183.                             }
  1184.  
  1185.                             if ( "Get-EventLog" -eq $_cmdlet.Name -and "EntryType" -like $_param )
  1186.                             {
  1187.                                  "Error", "Information", "FailureAudit", "SuccessAudit", "Warning" -like $_opt | sort | % { $_base + $_ }
  1188.                                  break;
  1189.                             }
  1190.  
  1191.                             if ( "Get-Command" -eq $_cmdlet.Name -and "Name" -like $_param )
  1192.                             {
  1193.                                  Get-Command -CommandType All -Name $_opt | % { $_base + ($_.Name -replace '\s','` ') }
  1194.                                  break;
  1195.                             }
  1196.  
  1197.                             if ( $_cmdlet.Noun -like "*WMI*" )
  1198.                             {
  1199.                                 if ( "Class" -like $_param )
  1200.                                 {
  1201.                                     $_WMIClasses -like $_opt
  1202.                                     break;
  1203.                                 }
  1204.                             }
  1205.  
  1206.                             if ( "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Compare-Object",
  1207.                                  "ConvertTo-Html", "Measure-Object", "Select-Object", "Group-Object", "Sort-Object" `
  1208.                                   -contains $_cmdlet.Name -and "Property" -like $_param )
  1209.                             {
  1210.                                  Get-PipeLineObject
  1211.                                  $_dummy | Get-Member -Name $_opt -MemberType Properties,ParameterizedProperty | sort membertype | % { $_base + ($_.Name -replace '\s','` ') }
  1212.                                  break;
  1213.                             }
  1214.  
  1215.                             if ( "Select-Object" -eq $_cmdlet.Name )
  1216.                             {
  1217.                                 if ( "ExcludeProperty" -like $_param )
  1218.                                 {
  1219.                                  Get-PipeLineObject
  1220.                                  $_dummy | Get-Member -Name $_opt -MemberType Properties,ParameterizedProperty | sort membertype | % { $_base + ($_.Name -replace '\s','` ') }
  1221.                                  break;
  1222.                                 }
  1223.  
  1224.                                 if ( "ExpandProperty" -like $_param )
  1225.                                 {
  1226.                                  Get-PipeLineObject
  1227.                                  $_dummy | Get-Member -Name $_opt -MemberType Properties,ParameterizedProperty | sort membertype | % { $_.Name }
  1228.                                  break;
  1229.                                 }
  1230.                             }
  1231.  
  1232.                         if ( "ExternalScript", "Function", "Filter" -contains $_cmdlet.CommandType )
  1233.                         {
  1234.                             if ( $_cmdlet.CommandType -eq "ExternalScript" )
  1235.                             {
  1236.                                 $_fsr = New-Object IO.StreamReader $_cmdlet.Definition
  1237.                                 $_def = "Function _Dummy { $($_fsr.ReadToEnd()) }"
  1238.                                 $_fsr.Close()
  1239.                                 iex $_def
  1240.                                 $_cmdlet = "_Dummy"
  1241.                             }
  1242.  
  1243.                             if ( ((gi "Function:$_cmdlet").Definition -replace '\n').Split("{")[0] -match 'param\((.*\))\s*[;\.&a-zA-Z]*\s*$' )
  1244.                             {
  1245.                                 $Matches[1].Split(',', "RemoveEmptyEntries" -as [System.StringSplitOptions]) -like "*$_param" |
  1246.                                 % { $_.Split("$ )`r`n", "RemoveEmptyEntries" -as [System.StringSplitOptions])[0] -replace '^\[(.*)\]$','$1' -as "System.Type" } |
  1247.                                 ? { $_.IsEnum } | % { [Enum]::GetNames($_) -like $_opt | sort } | % { $_base + $_ }
  1248.                             }
  1249.                             break;
  1250.                         }
  1251.  
  1252.                             select -InputObject $_cmdlet -ExpandProperty ParameterSets | select -ExpandProperty Parameters |
  1253.                             ? { $_.Name -like $_param } | ? { $_.ParameterType.IsEnum } |
  1254.                             % { [Enum]::GetNames($_.ParameterType) } | ? { $_ -like $_opt } | sort -Unique | % { $_base + $_ }
  1255.  
  1256.                         }
  1257.  
  1258.  
  1259.                                if ( $line[-1] -match "\s" ) { break; }
  1260.        
  1261.                                if ( $lastWord -ne $null -and $lastWord.IndexOfAny('/\') -eq -1 ) {
  1262.                                   $command = $lastWord.Substring( ($lastWord -replace '([^\|\(;={]*)$').Length )
  1263.                                   $_base = $lastWord.Substring( 0, ($lastWord -replace '([^\|\(;={]*)$').Length )
  1264.                                   $pattern = $command + "*"
  1265.                                   gcm -Name $pattern -CommandType All | % { $_base + $_.Name } | sort -Unique
  1266.                                }
  1267.                     }
  1268.                 }
  1269.             }
  1270.        
  1271. }

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