Public/Invoke-Parser.ps1
using namespace System.Management.Automation.Language using namespace System.Collections.ObjectModel function Invoke-Parser { <# .SYNOPSIS Parses a PowerShell script, scriptblock, or function definition to extract used commands and variables. .DESCRIPTION The Invoke-Parser function analyzes PowerShell code from a file, a code snippet, or a function definition. It extracts and lists all the commands and variables used in the input. It supports three modes of input: File, Code, and FunctionName. .PARAMETER Path Specifies the path to a PowerShell script file. The function parses the file and extracts commands and variables used in it. .PARAMETER Code Specifies a string containing a block of PowerShell code. The function parses the code to extract commands and variables. .PARAMETER FunctionName Specifies the name of a PowerShell function. The function parses the function definition to extract commands and variables. .EXAMPLE Invoke-Parser -Path 'C:\temp\random-script.ps1' Parses the PowerShell script at the specified path and returns the commands and variables used in the script. .EXAMPLE Invoke-Parser -Code '$a = 1; Write-Output $a' Parses the provided code snippet and returns the commands and variables used in it. .EXAMPLE Invoke-Parser -FunctionName 'Get-Process' Parses the definition of the 'Get-Process' function and returns the commands and variables used in it. .INPUTS String .OUTPUTS PSCustomObject #> [CmdletBinding()] param( [Parameter( Mandatory, ParameterSetName = 'File' )] [ValidateScript({ if (-not ($_ | Test-Path -PathType Leaf)) { throw 'File does not exist' } return $true })] # Specifies the path to a PowerShell script file. The function parses the file and extracts commands and variables used in it. [string]$Path, [Parameter( Mandatory, ParameterSetName = 'Code' )] # Specifies a string containing a block of PowerShell code. The function parses the code to extract commands and variables. [string]$Code, [Parameter( Mandatory, ParameterSetName = 'FunctionName' )] [ValidateScript({ $Cmd = Get-Command -Name $_ -CommandType Alias,Function,Filter -ErrorAction SilentlyContinue if ($Cmd -and $Cmd.CommandType -in ('Function','Filter', 'Alias')) { return $true } throw ('{0} is not a valid Function, Filter, or Alias name.' -f $_) })] # Specifies the name of a PowerShell function. The function parses the function definition to extract commands and variables. [string]$FunctionName ) begin { $Tokens = [Collection[Token]]::new() $ParseErrors = [Collection[ParseError]]::new() } process { switch ($PSCmdlet.ParameterSetName) { 'File' { $PSPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($Path).ProviderPath $Parser = [Parser]::ParseFile($PSPath, [ref]$Tokens, [ref]$ParseErrors) } 'Code' { $SBCode = ($Code -split "`n" | ForEach-Object { $_.TrimEnd() }) -join "`n" $Parser = [Parser]::ParseInput($SBCode, [ref]$Tokens, [ref]$ParseErrors) } 'FunctionName' { $CmdInfo = Get-Command -Name $FunctionName -CommandType Alias,Function,Filter -ErrorAction Stop if ($CmdInfo.CommandType -eq 'Alias') { $CmdInfo = $CmdInfo.ReferencedCommand } $SB = [System.Text.StringBuilder]::new() $null = $SB.Append(('function {0} {1}' -f $CmdInfo.Name,[char]::ConvertFromUtf32(123))) $null = $SB.Append($CmdInfo.Definition) $null = $SB.Append([char]::ConvertFromUtf32(125)) $Parser = [Parser]::ParseInput($SB.ToString(), [ref]$Tokens, [ref]$ParseErrors) } default { throw 'Invalid ParameterSet.' } } if ($ParseErrors.Count -gt 0) { Write-Warning ('Parse errors encountered: {0}' -f $ParseErrors.Count) } $FoundVariables = $Tokens.Where({$_.Kind -eq 'Variable'}).Text | Sort-Object -Unique $FoundCommands = $Tokens.Where({$_.TokenFlags -band 'CommandName'}).Text | Sort-Object -Unique [pscustomobject]@{ Commands = $FoundCommands Variables = $FoundVariables } } } |