Commands/Search-Script.ps1
|
function Search-Script { <# .SYNOPSIS Searches Scripts .DESCRIPTION Searches PowerShell scripts, using the Abstract Syntax Tree. This can quickly and easily find any part of any script in any file. .EXAMPLE # Get every part of every script in this module. Get-Command -Module SearchScript | SearchScript .EXAMPLE # Get every part of every script in the current directory dir *.ps1 | SearchScript .EXAMPLE # Search for scripts that may be impacted by CVE-2025-54100 Search-Script { Invoke-WebRequest } { param($ast) if (-not $ast.CommandElements -or ( $ast.CommandElements[0] -notmatch 'Invoke-WebRequest|curl|iwr' )) { return $false } if (-not ($ast.CommandElements -match '-UseBasicParsing')) { return $true } return $false } #> [Alias('srsb', 'srScript','SearchScript')] param( # The script to search [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias('ScriptBlock','Definition','Haystack')] [ScriptBlock] $Script, # What we're searching for. # Can be a ScriptBlock, string, regex, or ast function # If a strign is provided, it will be treated as a pattern. [ValidateScript({ $validTypes = [ScriptBlock], [string], [Regex], [Func[Management.Automation.Language.Ast,bool]] foreach ($validType in $validTypes) { if ($_ -is $validType) { return $true} } throw "must be [$($validTypes -join '] or [')]" })] [Alias('Pattern','Needle','Predicate','SearchScript')] [PSObject] $For = [string]".", # If set, will perform a shallow search. # By default will search a scriptblock and nested blocks. [switch] $Shallow ) process { if ($for -is [string]) { $for = [ScriptBlock]::Create("param(`$ast) `$ast -match '$($for -replace "'","''")'") } if ($for -is [Regex]) { $for = [ScriptBlock]::Create("param(`$ast) `$pattern = [Regex]::new('$($for -replace "'","''")','$($for.Options)'); `$ast -match `$pattern") } if (-not $script.Ast) { return } $Script.Ast.FindAll($for, -not $Shallow) } } |