powershell 关于如何实现同一属性上的多个条件的简化Where-Object的概念证明
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了powershell 关于如何实现同一属性上的多个条件的简化Where-Object的概念证明相关的知识,希望对你有一定的参考价值。
function whereEx {
[CmdletBinding()]
Param
(
[Parameter(ValueFromPipeline=$true)]
$InputObject,
[Parameter(Mandatory=$true,
Position=0)]
$predicateString
)
Begin{
try{
$predicate = [ScriptBlock]::Create($predicateString)
}
catch{
$errors = $null
$oldTokens = [System.Management.Automation.PSParser]::Tokenize($predicateString, [ref]$errors)
$errors = $tokens = $null
$AST= [Management.Automation.Language.Parser]::ParseInput($predicateString, [ref]$tokens, [ref]$errors)
#join the Start property from the old parser output with the AST parser output
for ($i=0; $i -lt $tokens.Count-1;$i++){
Add-Member -InputObject $tokens[$i] -type NoteProperty -name 'Start' -value $oldTokens[$i].Start
}
$openParens = $tokens | where Kind -eq 'LParen'
foreach ($openParen in $openParens){
$closeParen = ($tokens | where {$_.Kind -eq 'RParen' -and $_.Start -gt $openParen.Start} | sort -Descending)[0]
$tokensInBlock = $tokens | where {$_.Start -gt $openParen.Start -and $_.Start -lt $closeParen.Start}
$variableTxt = ($tokens[[Array]::IndexOf($tokens, $openParens) - 1]).Text
#check if we are dealing with qualified membernames (e.g. $_.Name)
if (!$variableTxt.StartsWith('$')){
#go back until variable is found and join the txt
$variable = ($tokens | where {$_.Start -lt $openParen.Start -and $_.Kind -eq 'Variable'} | sort Start -Descending)[0]
$name = ($tokens | where {$_.Start -lt $openParen.Start -and $_.Start -gt $variable.Start}).Text
$variableTxt = $variable.Text + ($name -join '')
}
#check for consecutive parameter tokens
$operators = $tokensInBlock | where {$_.Kind -eq 'Parameter' -and $_.Text -ne '-not'}
foreach ($operator in $operators ){
$nextToken = $tokens[[Array]::IndexOf($tokens, $operator) + 1]
if ($nextToken.Kind -eq 'Parameter'){
#insert variable into predicate string
$predicateString = $predicateString.Insert($nextToken.Start, "$($variableTxt) ")
}
}
}
#remove the parentheses and rebuild the scriptBlock
$predicateString = $predicateString.Replace('(','').Replace(')','')
$predicate = [ScriptBlock]::Create($predicateString)
}
}
Process{
$_ | where $predicate
}
}
1..10 | whereEx '$_ (-gt 5 -and -lt 8)'
Get-Process | whereEx '$_.Name (-like "power*" -and -notlike "*ise")'
以上是关于powershell 关于如何实现同一属性上的多个条件的简化Where-Object的概念证明的主要内容,如果未能解决你的问题,请参考以下文章
PowerShell脚本到尾部日志文件的多个远程服务器
如何使用 PowerShell 在 IIS 中停止和启动各个网站?
将输出流以外的两个或多个 Powershell 流重定向到同一个文件
如何在整个 Azure 管理组上运行 powershell 脚本以跨越多个订阅?
同一页面上的多个版本的脚本 (d3.js)
如何让多个域名解析到同一台服务器上的不同网站