public/Get-MrAst.ps1
#Requires -Version 3.0 function Get-MrAst { <# .SYNOPSIS Explores the Abstract Syntax Tree (AST). .DESCRIPTION Get-MrAST is an advanced function that provides a mechanism for exploring the Abstract Syntax Tree (AST). .PARAMETER Path Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory. .PARAMETER Code The code to view the AST for. If Get-Content is being used to obtain the code, use its -Raw parameter otherwise the formating of the code will be lost. .PARAMETER ScriptBlock An instance of System.Management.Automation.ScriptBlock Microsoft .NET Framework type to view the AST for. .PARAMETER AstType The type of object to view the AST for. If this parameter is ommited, only the top level ScriptBlockAst is returned. .EXAMPLE Get-MrAST -Path 'C:\Scripts' -AstType FunctionDefinition .EXAMPLE Get-MrAST -Code 'function Get-PowerShellProcess {Get-Process -Name PowerShell}' .EXAMPLE Get-MrAST -ScriptBlock ([scriptblock]::Create('function Get-PowerShellProcess {Get-Process -Name PowerShell}')) .NOTES Author: Mike F Robbins Website: http://mikefrobbins.com Twitter: @mikefrobbins #> [CmdletBinding(DefaultParameterSetName='Path')] param( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ValueFromRemainingArguments, ParameterSetName = 'Path', Position = 1)] [ValidateNotNull()] [Alias('FilePath')] [string[]]$Path = ('.\*.ps1', '.\*.psm1'), [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromRemainingArguments, ParameterSetName = 'Code')] [string[]]$Code, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromRemainingArguments, ParameterSetName = 'ScriptBlock')] [scriptblock[]]$ScriptBlock ) DynamicParam { $ParameterAttribute = New-Object -TypeName System.Management.Automation.ParameterAttribute $ParameterAttribute.Position = 0 $ValidationValues = Get-MrAstType $ValidateSetAttribute = New-Object -TypeName System.Management.Automation.ValidateSetAttribute($ValidationValues) $AttributeCollection = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] $AttributeCollection.Add($ParameterAttribute) $AttributeCollection.Add($ValidateSetAttribute) $ParameterName = 'AstType' $RuntimeParameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection) $RuntimeParameterDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) $RuntimeParameterDictionary } BEGIN { $AstType = $PsBoundParameters[$ParameterName] } PROCESS { switch ($PSCmdlet.ParameterSetName) { 'Path' { Write-Verbose -Message 'Path Parameter Set Selected' Write-Verbose "Path contains $Path" $Files = Get-ChildItem -Path $Path -Exclude *tests.ps1, *profile.ps1 | Select-Object -ExpandProperty FullName if (-not ($Files)) { Write-Warning -Message 'No valid files found.' Return } $AST = foreach ($File in $Files) { [System.Management.Automation.Language.Parser]::ParseFile($File, [ref]$null, [ref]$null) } break } 'Code' { Write-Verbose -Message 'Code Parameter Set Selected' $AST = foreach ($c in $Code) { [System.Management.Automation.Language.Parser]::ParseInput($c, [ref]$null, [ref]$null) } break } 'ScriptBlock' { Write-Verbose -Message 'ScriptBlock Parameter Set Selected' $AST = $ScriptBlock.Ast break } default { Write-Warning -Message 'An unexpected error has occurred' } } if ($PsBoundParameters.AstType) { Write-Verbose -Message 'AstType Parameter Entered' $AST = $AST.FindAll({$args[0].GetType().Name -like "$($ASTType)Ast"}, $true) } Write-Output $AST } } |