DCSIMG
Parsing PowerShell scripts - Shay Levy

Shay Levy

If you repeat it, PowerShell it!

News


btn_donate_LG

View Shay Levy's profile on LinkedIn Follow Shay Levy at Twitter Shay Levy's Facebook profile Subscribe to my FriendFeed


site statistics




Parsing PowerShell scripts

The PsParser class, introduced in Windows PowerShell 2.0, provides a mechanism to parse a script into a collection of tokens. There are some neat applications written using the Tokenize method such as Syntax Highlighting, Alias resolving and discovering functions in scripts . One other great benefit of the method is the ability to find if a script contains syntax errors without actually running the script.

The Tokenize method has two overloads, both accept a script as a string or as an array of lines (Script parameter) and both update a referenced variable with a collection of the errors that occurred when parsing the script (Errors parameter).

Test-PSScript is a v2 advanced function. Its FilePath parameter accepts input from the pipeline or through the command parameter. The output of the function is an extended Token object (see sample usage and result below) which includes the path of the script, Error Message, the line where the error occurred and some other information.

 

#Requires -Version 2

function
Test-PSScript
{

  
param(
      [Parameter(Mandatory
=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 
      [ValidateNotNullOrEmpty()] 
      [Alias(
'PSPath','FullName')] 
      [
System.String[]] $FilePath,

      [Switch]$IncludeSummaryReport
   )

   begin
   {
     
$total=$fails=0
   }

   process
   {
      
$FilePath | Foreach-Object {

         if(Test-Path -Path $_ -PathType Leaf)
         {
           
$Path = Convert-Path -Path $_ 

           
$Errors = $null
           
$Content = Get-Content -Path $path 
           
$Tokens = [System.Management.Automation.PsParser]::Tokenize($Content,[ref]$Errors)

            if($Errors)
            {
              
$fails+=1
              
$Errors | Foreach-Object 
                  $_.Token | Add-Member -MemberType NoteProperty -Name Path -Value $Path -PassThru | `
                 
Add-Member -MemberType NoteProperty -Name ErrorMessage -Value $_.Message -PassThru
               }
            }

           $total+=1 
         }  
      }
   } 

  
end 
   {
      if($IncludeSummaryReport
      {
        
Write-Host "`n$total script(s) processed, $fails script(s) contain syntax errors."
      }
   }
}

Sample usage:

PS > Get-ChildItem –Filter *.ps1 | Test-PSScript -IncludeSummaryReport

Path         : D:\scripts\Recycle-IIsAppPool.ps1
ErrorMessage : Missing closing ')' in expression.
Content      : <position>
Type         : Position
Start        : 3928
Length       : 0
StartLine    : 113
StartColumn  : 1
EndLine      : 113
EndColumn    : 1


Path         : D:\scripts\Play-Sound.ps1
ErrorMessage : Missing expression after unary operator '--'.
Content      : --
Type         : Operator
Start        : 975
Length       : 2
StartLine    : 35
StartColumn  : 32
EndLine      : 35
EndColumn    : 34


35 script(s) processed, 2 script(s) contain syntax errors.

 

For Powershell 1.0 parsing technique see Keith Hill’s Preparsing Scripts to Check for Syntax Errors blog post.

Comments

Twitter Trackbacks for Parsing PowerShell scripts - Shay Levy [microsoft.co.il] on Topsy.com said:

Pingback from  Twitter Trackbacks for                 Parsing PowerShell scripts - Shay Levy         [microsoft.co.il]        on Topsy.com

# September 8, 2009 1:29 PM

Andy said:

Thanx ! Excellent

# September 16, 2009 11:07 PM

Parsing PowerShell scripts – Shay Levy « work4real.net said:

Pingback from  Parsing PowerShell scripts &#8211; Shay Levy &laquo; work4real.net

# September 17, 2009 3:10 PM

HA said:

Little cosmetic suggestion:

begin

  {

     $total,$fails=0

  }

should read

begin

  {

     $total,$fails=0,0

  }

Otherwise if no script failed the summary says ", script(s) contain syntax errors" instead of ", 0 script(s) contain syntax errors".

# September 17, 2009 4:13 PM

ScriptFanatic said:

Thanks HA!

When I wrote the script I was thinking about assigning a single value to multiple variables:

$total=$fails=0

Your example is valid as well.

# September 17, 2009 4:34 PM

New Articles, Tools, Tips and Tricks: Bugs, Annoyances, PowerShell and some other Stuff at Helge Klein said:

Pingback from  New Articles, Tools, Tips and Tricks: Bugs, Annoyances, PowerShell and some other Stuff at Helge Klein

# September 22, 2009 12:27 AM

New Articles, Tools, Tips and Tricks: Bugs, Annoyances, PowerShell and some other Stuff | sepago said:

Pingback from  New Articles, Tools, Tips and Tricks: Bugs, Annoyances, PowerShell and some other Stuff | sepago

# April 12, 2012 5:01 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: