Use the Abstract Syntax Tree (AST) to inspect PowerShell command syntax in scripts

I recently needed to determine the PowerShell commands and parameters used in multiple scripts. What better way to accomplish this task than to use the Abstract Syntax Tree (AST)?

The Get-MrSyntax function begins by requiring at least PowerShell version 3.0. This is the oldest version that exposes the AST.

The Path parameter uses ValidateScript for parameter validation to only accept files with a PS1 or PSM1 extension. The path(s) to the script files can be specified via pipeline or parameter input.

The function iterates through each file and each command within the file to return the results. For a more concise list of results, I decided not to unroll the parameters used by the commands.

 1#Requires -Version 3.0
 2function Get-MrSyntax {
 3
 4<#
 5.SYNOPSIS
 6    List PowerShell commands and parameters in the specified PowerShell script.
 7
 8.DESCRIPTION
 9    Get-MrSyntax is a PowerShell function that uses the Abstract Syntax Tree (AST) to determine the
10    commands and parameters within a PowerShell script.
11
12.PARAMETER Path
13    Path to one of more PowerShell PS1 or PSM1 script files.
14
15.EXAMPLE
16    Get-MrSyntax -Path C:\Scripts\MyScript.ps1
17
18.EXAMPLE
19    Get-ChildItem -Path C:\Scripts\*.ps1 | Get-MrSyntax
20
21.EXAMPLE
22    Get-MrSyntax -Path (Get-ChildItem -Path C:\Scripts\*.ps1)
23
24.NOTES
25    Author:  Mike F Robbins
26    Website: https://mikefrobbins.com
27    Twitter: @mikefrobbins
28#>
29
30    [CmdletBinding()]
31    param (
32        [Parameter(ValueFromPipeline)]
33        [ValidateScript({
34            If (Test-Path -Path $_ -PathType Leaf -Include *.ps1, *.psm1) {
35                $True
36            } else {
37                Throw "'$_' is not a valid PowerShell PS1 or PSM1 script file."
38            }
39        })]
40        [string[]]$Path
41    )
42
43    PROCESS {
44
45        foreach ($file in $Path) {
46            $AST = [System.Management.Automation.Language.Parser]::ParseFile($File, [ref]$null, [ref]$null)
47
48            $AST.FindAll({$args[0].GetType().Name -like 'CommandAst'}, $true) |
49            ForEach-Object {
50                [pscustomobject]@{
51                    Cmdlet = $_.CommandElements[0].Value
52                    Parameters = $_.CommandElements.ParameterName
53                    File = $file
54                }
55            }
56        }
57    }
58}

script-functions-and-parameters1a.jpg

The Get-MrSyntax function shown in this blog article is part of my MrInspector PowerShell module. You can install it from the PowerShell Gallery using the following command.

1Install-Module -Name MrInspector

The video shown below demonstrates how to use this module.

You can download the source code from my Inspector GitHub repo. Feel free to submit a GitHub issue if you have suggestions or find problems. I accept pull requests if you would like to contribute.

µ