Learn about the PowerShell Abstract Syntax Tree (AST) – Part 2
In my previous blog article a few weeks ago on
Learning about the PowerShell Abstract Syntax Tree (AST),
I mentioned there was an easier way to retrieve the AST so that you didn't have to cast everything
to a script block. There are two .NET static methods,
ParseFile
and
ParseInput,
that are part of the
Parser Class
in the System.Management.Automation.Language
namespace which can be used to retrieve the AST.
First, I’ll store the content of one of my functions in a variable.
1$Code = Get-Content -Path U:\GitHub\Hyper-V\MrHyperV\public\Get-MrVmHost.ps1 -Raw
The ParseInput
static method can be used with the content of the function from the previous
example to retrieve things like the function itself without the
Requires statement
(no Regular Expression needed).
1$Tokens = $null
2$Errors = $null
3[System.Management.Automation.Language.Parser]::ParseInput($Code, [ref]$Tokens, [ref]$Errors)
Due to the way that .NET works, you'll first need to define the variable used for Tokens
and
Errors
otherwise an error will be generated.
1[System.Management.Automation.Language.Parser]::ParseInput($Code, [ref]$Tokens, [ref]$Errors)
1[ref] cannot be applied to a variable that does not exist.
2At line:1 char:1
3+ [System.Management.Automation.Language.Parser]::ParseInput($Code, [re …
4+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5+ CategoryInfo : InvalidOperation: (Tokens:VariablePath) [], RuntimeException
6+ FullyQualifiedErrorId : NonExistingVariableReference
If you don't need the information contained in them, instead of setting a variable to $null
and
then using it, you can reduce the number of steps necessary by simply using $null
for them when
calling the .NET method.
1[System.Management.Automation.Language.Parser]::ParseInput($Code, [ref]$null, [ref]$null)
One last tip before moving onto the ParseFile
static method. If you're going to use the
Get-Content
cmdlet to retrieve the code for working with ParseInput
, be sure to add its Raw
parameter
otherwise the formatting of the code in the results will be skewed as shown in the following
example.
1$Code = Get-Content -Path U:\GitHub\Hyper-V\MrHyperV\public\Get-MrVmHost.ps1
2[System.Management.Automation.Language.Parser]::ParseInput($Code, [ref]$null, [ref]$null)
If you're going to retrieve all of the content from a file similarly to what I've shown so far in
this blog article, save yourself a step or two by simply using the ParseFile
static method instead
of ParseInput
.
1$FilePath = 'U:\GitHub\Hyper-V\MrHyperV\public\Get-MrVmHost.ps1'
2[System.Management.Automation.Language.Parser]::ParseFile($FilePath, [ref]$null, [ref]$null)
Consider storing the results in a variable while prototyping with this or any command. Remember that any command that produces object based output can be piped to Get-Member to determine its methods and properties.
1$Results = [System.Management.Automation.Language.Parser]::ParseFile($FilePath, [ref]$null, [ref]$null)
2$Results | Get-Member
Note that the System.Management.Automation.Language
namespace only exists in Windows PowerShell
version 3.0 or higher, although that shouldn't be a problem since
Windows PowerShell version 2.0 is deprecated.
All examples shown in this blog article were tested on Windows 10 Enterprise Edition version 1809
with both Windows PowerShell 5.1 and
PowerShell Core 6.1
(PowerShell Core installs side by side on Windows based systems).
The examples shown in this blog article only return the top level AST. In Part 3 of this blog article series, I'll dive into searching for AST instances recursively.
- Learning about the PowerShell Abstract Syntax Tree (AST)
- Learn about the PowerShell Abstract Syntax Tree (AST) – Part 2
- Learn about the PowerShell Abstract Syntax Tree (AST) – Part 3
µ