How to Use the PowerShell AST to Get Meta with Your Scripts? 1 Best Example

PowerShell must understand how distinct tokens combine to create executable structures in order to run code. The Abstract Syntax Tree (PowerShell AST), which is created by the parser from the tokens, essentially arranges the tokens into useful structures.

PowerShell AST

Getting to the AST

With the introduction of the Abstract Syntax Tree in PowerShell AST, you can now examine PowerShell code and discover its fundamental structure.

The AST can be accessed primarily in two ways:

  1. ScriptBlock: A script block is a legitimate section of PowerShell code that has previously been processed by the parser, ensuring that the code is free of syntax problems. The PowerShell AST of the code included in a scriptblock is exposed by a property called AST that is present in every scriptblock.
  2. Parser: The PowerShell parser can be instructed to parse any piece of code and return tokens and PowerShell AST. When you enter and run code with PowerShell, you are essentially imitating its actions. The code’s syntactic correctness cannot be guaranteed because the parser works with raw text. Because of this, the parser also returns any syntax mistakes it discovered.

What is PowerShell AST?

PowerShell AST (Abstract Syntax Tree) refers to a data structure used by the PowerShell scripting language to represent the syntactic structure of a PowerShell script.

When you write a PowerShell script, it needs to be parsed and understood by the PowerShell engine in order to execute the desired commands. During the parsing process, the script is converted into an Abstract Syntax Tree, which is a hierarchical representation of the script’s structure. The AST breaks down the script into individual elements such as statements, expressions, variables, loops, and function definitions.

The AST provides a way for PowerShell to analyze and manipulate the script’s code at a higher level of abstraction. It allows PowerShell tools and utilities to perform various operations on the script, such as static analysis, code generation, refactoring, and optimization.

By working with the PowerShell AST, you can programmatically examine and modify PowerShell code. It enables you to extract information about the script’s structure, traverses the different elements, and apply transformations to the code. This can be particularly useful for tasks like writing PowerShell extensions, developing code analyzers, or building automation tools.

In summary, PowerShell AST is a representation of a PowerShell script’s syntax in a structured format, which facilitates the analysis and manipulation of the script’s code programmatically.

Using The Language.Parser Class With PowerShell

You must familiarize yourself with the System before you can begin.Management.Automation.Language.parser kind. There are a few useful static methods in this class that we can utilize to read scripts and code

You’ll frequently utilize the two methods ParseInput() and ParseFile() of this class, which effectively accomplish the same task. While ParseFile() helps you transform a text file containing PowerShell code into a string for processing, ParseInput() reads the code as a large string. Both come to the same conclusion.

Let’s imagine I have a straightforward script that says the following:

Write-Host 'Something Cooking'
Write-Verbose 'Noodles is Cooking'
Write-Host 'Again, Cooking something.'
$var1 = 'abc'
$var2 = '123'

I want to know all the references to every variable and cmdlet I have from within the script itself. 

You must first devise a method for obtaining the full script’s contents as a single, long string. I can accomplish that by using the $MyInvocation.MyCommand.ScriptContents attribute of the PowerShell AST object

Once I get the script’s contents, I can use the ParseInput() method—which was already mentioned—to create a “tree” from the script. That $MyInvocation.MyCommand.ScriptContents will be changed.

[System.Management.Automation.Language.Parser]::ParseInput($MyInvocation.MyCommand.ScriptContents, [ref]$null, [ref]$null)

But it doesn’t really accomplish much. I want to be able to investigate this and identify only the functions and variables in my script. I must assign our AST to a variable in order to accomplish that. My own I’ll call $ast.

PS> $ast = C:\test.ps1
PS> $ast = C:\test.ps1

I am given an object with a variety of methods and properties that I may utilize after doing this.

How To Find Items with the FindAll() Method?

The FindAll() function is the most beneficial to utilize. Using this technique, you can search the AST for specific categories of linguistic constructions. In this instance, function calls and variable assignments are what we’re seeking.

We must first determine what class each type represents in order to limit our search to language constructs that match that class. For function calls in our examples, these classes are CommandAst, and for variable assignments, they are VariableExpression. The MSDN System allows you to view all of the various class types.Namespace page for Management.Automation.Language.

All of the function references are located here.

PS> $ast.FindAll({$args[0] -is [System.Management.Automation.Language.CommandAst]}, $true)

Now let’s locate every variable assignment as well.

PS> $ast.FindAll({$args[0] -is [System.Management.Automation.Language.VariableExpressionAst]},$true)
PS> $ast.FindAll({$args[0]

You can see that each construct has now been transformed into a usable object. Now that you are knowledgeable, you can dissect your script pretty much however you desire. 

Your PowerShell scripts can now become self-aware by utilizing the AST.