是否可以延迟管道执行或修改先前的管道?我正在寻找的是与ODATA端点进行交互的能力。我想使用标准(或自定义)powershell命令来过滤数据,但是我不想检索整个列表。例如
function Get-Records() {
Invoke-RestMethod -Method Get -Uri $endpoint.Uri.AbsoluteUri ...
}
调用此方法可以返回500多个记录。通常,有时我不想检索所有500条记录。因此,如果我需要全部500个,我可能会打电话给Get-Records
。但是,如果我只想要特定的电话,我会想做的
Get-Records | Where {$_.Name -eq 'me'}
以上内容仍接收所有500条记录,然后将其过滤。我想以某种方式希望Where {$_.Name -eq 'me'}
传递回上一个管道,将过滤器传递到Invoke-RestMethod
并附加到URI $filter=Name eq 'me'
答案 0 :(得分:1)
您不能通过Where-Object
之类的后处理过滤器来追溯修改管道。
相反,您必须使用数据提供者的语法在源位置过滤 。
PowerShell内置的cmdlet(例如Get-ChildItem
)是通过[string]
类型的-Filter
参数来实现的。
如果要传递PowerShell 脚本块作为过滤器,则必须自己将其转换为提供程序的语法- 。
很少有PowerShell表达式与提供程序的过滤器功能的一对一映射,因此也许更好的方法是要求用户直接使用提供程序的语法:
function Get-Records() {
param(
[Parameter(Mandatory)]
[uri] $Uri
,
[string] $Filter # Optional filter in provider syntax; e.g. "Name eq 'me'"
)
if ($Filter) { $Uri += '?$filter=' + $Filter }
Invoke-RestMethod -Method Get -Uri $uri
}
# Invoke with a filter in the provider's syntax.
Get-Records "Name eq 'me'"
如果您希望用户能够传递脚本块,则必须对提供程序语法进行自己的翻译,并确保可以进行翻译。
要稳健地执行此操作,您必须处理脚本块的AST(抽象语法树),可以通过其.Ast
属性来访问它,这是不平凡的。
如果您愿意对允许用户传递的表达式类型做出假设,则可以通过 string解析摆脱困境,例如下面的简单示例:
function Get-Records {
param(
[Parameter(Mandatory)]
[uri] $Uri
,
[scriptblock] $FilterScriptBlock # Optional filter
)
if ($FilterScriptBlock) {
# Translate the script block' *string representation*
# into the provider-native filter syntax.
# Note: This is overly simplistic in that it simply removes '$_.'
# and '-' before '-eq'.
$Uri += '?$filter=' + $FilterScriptBlock -replace '\$_\.' -replace '-(?=[a-z]+\b)'
}
Invoke-RestMethod -Method Get -Uri $Uri
}
# Invoke with a filter specified as a PowerShell script block.
Get-Records { $_.Name -eq 'me' }