Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Discovering Aliases with the PowerShell AST

Posted on December 15, 2021December 15, 2021

I've been working on a new PowerShell module that incorporates code from a few of my recent posts on converting PowerShell scripts and functions to files. I even whipped up a script, think of it as a meta-script, to create the module using the commands that I am adding to the module. I'll cover that another day. In the process of writing this script, I realized I also wanted to identify aliases for functions defined in the files.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Specifically, I wanted to find aliases defined in the function itself.

Function Get-Foo {
  [cmdletbinding()]
  [alias("gf")]
  Param (...)
...

I could have simply dot sourced the script file and then looked for the aliases. But I didn't want to assume that dot sourcing was an option. Instead, I went back to parsing the file with the AST.

Unfortunately, I couldn't find anything in the AST that specifically retrieved command aliases. If I'm missing something, please let me know. Instead, I relied on regular expressions to parse the function body. Using the code I've shown in the previous posts, it is simple by now to find functions in files.

match [alias()] regex

This is merely a proof-of-concept. I still need to extract the alias names. I'll use a regular expression pattern that uses lookahead and lookbehind.

[regex]$rx = "(?<=alias\().*(?=\)\])"

The expression says to match on anything using .* where the text that comes before (lookbehind) is "alias(" and where the text after (lookahead) is ")]". Parentheses and square brackets are regex characters so I need to escape them with a slash. I can then clean up the match and get the aliases.

Here's my PowerShell function.

Function Get-FunctionAlias {
    [cmdletbinding()]
    [alias("gfal", "ga")]
    [outputType("string")]
    Param(
        [Parameter(Position = 0, Mandatory, HelpMessage = "Specify the .ps1 or .psm1 file with defined functions.")]
        [ValidateScript( {
            If (Test-Path $_ ) {
                $True
            }
            Else {
                Throw "Can't validate that $_ exists. Please verify and try again."
                $False
            }
        })]
        [ValidateScript( {
            If ($_ -match "\.ps(m)?1$") {
                $True
            }
            Else {
                Throw "The path must be to a .ps1 or .psm1 file."
                $False
            }
        })]
        [string]$Path
    )

    New-Variable astTokens -Force
    New-Variable astErr -Force
    $Path = Convert-Path -Path $path
    [regex]$rx = "(?<=alias\().*(?=\)\])"
    Write-Verbose "Parsing $path for functions."
    $AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)

    #parse out functions using the AST
    $functions = $ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)
    if ($functions.count -gt 0) {
        foreach ($f in $functions) {
            if ($rx.IsMatch($f.body)) {
                [pscustomobject]@{
                    Name  = $f.name
                    #remove quotes from the alias names and join as a comma-separated array
                    Alias = ($rx.matches($f.body).value -replace """|'", "") -split ","
                }
            }
        }
    }
}

Let's use the function to discover its own aliases.

Get-FunctionAlias example

My PowerShell script file has two functions with defined aliases. I can use this information when scripting the build of a new PowerShell module. That topic is next on the agenda.

In the meantime, I hope you'll give this a spin and let me know how you might use it or what would make it even more helpful.

Update

Shortly after posting this, Przemysław Kłys was kind enough to share some code that uses the PowerShell AST to extract alias information. His approach is much more elegant, although I'm always looking for a way to use regular expressions. Here is a revised version of the function. The output is unchanged.


Behind the PowerShell Pipeline
Function Get-FunctionAlias {
    [cmdletbinding()]
    [alias("gfal", "ga")]
    [outputType("string")]
    Param(
        [Parameter(Position = 0, Mandatory, HelpMessage = "Specify the .ps1 or .psm1 file with defined functions.")]
        [ValidateScript( {
            If (Test-Path $_ ) {
                $True
            }
            Else {
                Throw "Can't validate that $_ exists. Please verify and try again."
                $False
            }
        })]
        [ValidateScript( {
            If ($_ -match "\.ps(m)?1$") {
                $True
            }
            Else {
                Throw "The path must be to a .ps1 or .psm1 file."
                $False
            }
        })]
        [string]$Path
    )

    New-Variable astTokens -Force
    New-Variable astErr -Force
    $Path = Convert-Path -Path $path
    Write-Verbose "Parsing $path for functions."
    $AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)

    #parse out functions using the AST
    $functions = $ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)
    if ($functions.count -gt 0) {
        foreach ($f in $functions) {
            #thanks to https://twitter.com/PrzemyslawKlys for this suggestion
            $aliasAST =  $f.FindAll( {
                $args[0] -is [System.Management.Automation.Language.AttributeAst] -and
                $args[0].TypeName.Name -eq 'Alias' -and
                $args[0].Parent -is [System.Management.Automation.Language.ParamBlockAst]
            }, $true)

            if ($aliasAST.positionalArguments) {
                [pscustomobject]@{
                    Name  = $f.name
                    Alias = $aliasAST.PositionalArguments.Value
                }
            }
        }
    }
}

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

2 thoughts on “Discovering Aliases with the PowerShell AST”

  1. Pingback: Discovering Aliases with the PowerShell AST - The Lonely Administrator - Syndicated Blogs - IDERA Community
  2. Pingback: PowerShell SnippetRace 49&50 2021 (X-Mas busy edition) | PowerShell Usergroup Austria

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d