Using PowerShell’s PsParser::Tokenize, Discover Functions in PowerShell Scripts

by Doug Finke on November 14, 2008

in PowerShell

Another CTP drop for PowerShell is expected in December. One of the new features, Modules, allows PowerShell code to be organized in self-contained, reusable units.

In anticipation of this feature, I am experimenting with building PowerShell solutions by organizing several related functions into a single script that is sourced. Think; Clear-Item, Copy-Item, Get-Item, Invoke-Item,  but tailored to a custom system.

The Challenge

As the PowerShell code grows, remembering the functions is harder. Here is script that discovers them.

Get-Functions

Get-Functions takes a single file, a list of files or the –Recurse switch. The recurse switch finds all the functions in all the files in the subdirectories.

param(
 $files,
 [switch] $recurse
)
 
$parser = [System.Management.Automation.PsParser]
 
if($recurse) {
 $files=(dir . -Recurse *.ps1)
} else {
 if(!$files) {throw "Please enter a file for scanning."}
 if($files -is [String]) {$files=(dir $files)}
}
 
ForEach($file in $files) {
 $parser::Tokenize((Get-Content $file.FullName), [ref] $null) |
 ForEach {
  $PSToken = $_
  if($PSToken.Type -eq  'Keyword' -and
     $PSToken.Content -eq 'Function' ) {     
     $functionKeyWordFound = $true
  }
  
  if($functionKeyWordFound -and
     $PSToken.Type -eq  'CommandArgument') {
     
     '' | Select `
      @{
       Name="FunctionName"
       Expression={$PSToken.Content}
      },
      @{
       Name="Line"
       Expression={$PSToken.StartLine}
      },
      @{
       Name="File"
       Expression={$file.FullName}
      }
      
      $functionKeyWordFound = $false
  }
 }
}

Example

I downloaded PowerShell code for two books, Windows PowerShell in Action and Windows PowerShell Cookbook. Then ran the command:

Get-Functions -r | Out-GridView

image

The Out-GridView lets you sort columns and filter. Typing in the search box scans each column, showing matches.

Get-Functions provides the file name and line number where to find function.

Thanks to James Brundage. He blogged the approach in WPF & PowerShell – Part 2 (Exploring WPF (and the rest of .NET) with Scripts). Also, he pointed out timings comparing PSObject creation using Add-Member v. the above Select @{name;expression} approach. Super helpful.

Download Get-Functions

{ 1 comment… read it below or add one }

delvinj 11.15.08 at 12:17 pm

Nice. I think I need to have another go at some PowerShell hacking. Thanks for posting!

Daniel

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>