Skip to content

Commit 475f283

Browse files
author
James Brundage
committed
Adding Search-PipeScript (#114)
1 parent 7fa2a7c commit 475f283

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

Search-PipeScript.ps1.ps1

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
function Search-PipeScript
2+
{
3+
<#
4+
.Synopsis
5+
Searches PowerShell and PipeScript ScriptBlocks
6+
.Description
7+
Searches PowerShell and PipeScript ScriptBlocks, files, and text
8+
.Example
9+
Search-PipeScript -ScriptBlock {
10+
$a
11+
$b
12+
$c
13+
"text"
14+
} -AstType Variable
15+
.LINK
16+
Update-PipeScript
17+
#>
18+
[OutputType('Search.PipeScript.Result')]
19+
[Alias('Search-ScriptBlock')]
20+
param(
21+
# The ScriptBlock that will be searched.
22+
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
23+
[Alias('ScriptBlock','Text')]
24+
[ValidateTypes(TypeName={[string], [scriptblock],[IO.FileInfo]})]
25+
$InputObject,
26+
27+
# The AST Condition.
28+
# These Script Blocks
29+
[Parameter(ValueFromPipelineByPropertyName)]
30+
[Alias('ASTDelegate')]
31+
[ScriptBlock[]]
32+
$AstCondition,
33+
34+
# A shortname for the abstract syntax tree types.
35+
[Parameter(ValueFromPipelineByPropertyName)]
36+
[ValidateTypes(TypeName={[string], [Regex], [string[]], [regex[]]})]
37+
$AstType,
38+
39+
# One or more regular expressions to match.
40+
[Parameter(ValueFromPipelineByPropertyName)]
41+
[Alias('RegEx')]
42+
[ValidateTypes(TypeName={[string], [Regex], [string[]], [regex[]]})]
43+
$RegularExpression
44+
)
45+
46+
process {
47+
$ScriptBlock = $null
48+
$Text = $null
49+
50+
# If the input was a file
51+
if ($InputObject -is [IO.FileInfo]) {
52+
$inputCommand = # get the resolved command
53+
$ExecutionContext.SessionState.InvokeCommand.GetCommand(
54+
$InputObject.Fullname, 'ExternalScript,Application')
55+
# If the command was an external script
56+
if ($inputCommand -is [Management.Automation.ExternalScriptInfo]) {
57+
# Use it's ScriptBlock
58+
$ScriptBlock = $inputCommand.ScriptBlock
59+
}
60+
# If the command was an application, and it looks like PipeScript
61+
elseif (
62+
$inputCommand -is [Management.Automation.ApplicationInfo] -and
63+
$inputCommand.Source -match '\.ps$'
64+
) {
65+
# Load the file text
66+
$text = [IO.File]::ReadAllText($inputCommand.Source)
67+
# and create a script block.
68+
$scriptBlock = [ScriptBlock]::Create($text)
69+
}
70+
# Otherwise
71+
else
72+
{
73+
# Read the file contents as text.
74+
$text = [IO.File]::ReadAllText($inputCommand.Source)
75+
}
76+
}
77+
78+
# If the inputObject was a [ScriptBlock]
79+
if ($InputObject -is [scriptblock]) {
80+
$scriptBlock = $InputObject # set $ScriptBlock
81+
}
82+
83+
# If the InputObject is a string
84+
if ($InputObject -is [string]) {
85+
$Text = $InputObject # set $Text.
86+
}
87+
88+
# If we have a ScriptBlock
89+
if ($scriptBlock) {
90+
# Reset $text to the ScriptBlock contents.
91+
$Text = "$scriptBlock"
92+
93+
# If we have an ASTType to find
94+
if ($AstType) {
95+
foreach ($astTypeName in $AstType) {
96+
# See if it's a real type
97+
$realAstType =
98+
foreach ($potentialType in $AstType,
99+
"Management.Automation.Language.$AstType",
100+
"Management.Automation.Language.${AstType}AST"
101+
) {
102+
if ($potentialType -as [type]) {
103+
$potentialType -as [type]; break
104+
}
105+
}
106+
107+
# If it was a real type, but in the wrong namespace
108+
if ($realAstType -and $realAstType.Namespace -eq 'Management.Automation.Language') {
109+
Write-Error "'$astType' is not an AST type" # error and continue.
110+
continue
111+
}
112+
113+
# Set the search condition
114+
$condition =
115+
if ($realAstType) {
116+
# If there was a real type, search for it.
117+
[ScriptBlock]::Create('param($ast) $ast -is [' + $realAstType.FullName + ']')
118+
}
119+
elseif ($astType -is [Regex]) {
120+
[scriptblock]::Create((
121+
'param($ast)
122+
$ast.GetType().Name -match ([Regex]::New(' +
123+
$astType.ToString().Replace("'", "''") + "','" +
124+
$astType.Options + "','" +
125+
$(if ($AstType.MatchTimeout -lt 0) {
126+
'00:00:05'
127+
} else {
128+
$AstType.MatchTimeout.ToString()
129+
}) + '))'
130+
))
131+
}
132+
elseif ($astType -as [regex]) {
133+
[ScriptBlock]::Create('param($ast) $ast.GetType().Name -match ' + $astType +'')
134+
} else {
135+
[ScriptBlock]::Create('param($ast) $ast.GetType().Name -like "*' + $astType +'*"')
136+
}
137+
138+
$AstCondition += $condition
139+
}
140+
}
141+
142+
if ($AstCondition) {
143+
foreach ($condition in $AstCondition) {
144+
$ScriptBlock.Ast.FindAll($condition, $true) |
145+
.InputObject = $inputObject .Result {
146+
$_
147+
} .Expression = $condition .ScriptBlock {
148+
$ScriptBlock
149+
} .PSTypeName = "Search.PipeScript.Result"
150+
}
151+
}
152+
}
153+
154+
if ($text) {
155+
if ($RegularExpression) {
156+
foreach ($regex in $RegularExpression) {
157+
$realRegex =
158+
if ($regex -is [regex]) {
159+
$regex
160+
} else {
161+
[Regex]::new($regex)
162+
}
163+
164+
$realRegex.Matches($text) |
165+
.InputObject = $InputObject .Result {
166+
$_
167+
} .Expression = $realRegex .RegularExpression {
168+
$realRegex
169+
} .PSTypeName = "Search.PipeScript.Result"
170+
}
171+
}
172+
}
173+
}
174+
}
175+

0 commit comments

Comments
 (0)