我希望我的函数能够根据参数输入来累积过滤数据。这是我的尝试:
function Get-People {
[cmdletbinding()]
param(
[parameter(mandatory=$false,position=0)]
[string]$Name,
[parameter(mandatory=$false)]
[string]$Country,
[parameter(mandatory=$false)]
[string]$State,
[parameter(mandatory=$false)]
[string]$City,
[parameter(mandatory=$false)]
[string]$IDNumber
)
$uri = "https://some.site.com/api/endpoint"
$header = $script:HeaderData
$response = invoke-restmethod -uri $uri -header $header -method get -contenttype "application/json"
if ($IDNumber) {$response = $response | ?{$_.idnumber -eq $IDNumber}}
if ($Name) {$response = $response | ?{$_.name -like $Name}}
if ($City) {$response = $response | ?{$_.city -like $City}}
if ($State) {$response = $response | ?{$_.state -like $State}}
if ($Country) {$response = $response | ?{$_.country -like $Country}}
$response
}
效果很好。我可以运行下面的命令
get-people -Country US -State Texas -City Austin -Name Jo*
它将返回名称以“Jo”开头的美国德克萨斯州奥斯汀市的所有人。
这只是一个非常笨拙的解决方案,我想知道是否有更好的方法可以做到这一点。
最佳答案
我建议采用以下方法。
为此,可以将过滤器脚本块存储到列表变量中,然后通过将所有条件组合为一个条件来创建新条件。
结果函数看起来像这样
(请注意,添加
$FakeResponse
的唯一目的是使用伪造的数据集演示最终结果,因为我无法对您的未知API进行API调用)function Get-People {
[cmdletbinding()]
param(
$FakeResponse,
[parameter(mandatory = $false, position = 0)]
[string]$Name,
[parameter(mandatory = $false)]
[string]$Country,
[parameter(mandatory = $false)]
[string]$State,
[parameter(mandatory = $false)]
[string]$City,
[parameter(mandatory = $false)]
[string]$IDNumber
)
if ($PSBoundParameters.ContainsKey('FakeResponse')) {
$response = $FakeResponse
}
else {
$uri = "https://some.site.com/api/endpoint"
$header = $script:HeaderData
$response = invoke-restmethod -uri $uri -header $header -method get -contenttype "application/json"
}
$Conditions = [System.Collections.Generic.List[scriptblock]]::new()
Foreach ($k in $PSBoundParameters.Keys) {
switch ($k) {
'Name' { $Conditions.Add( { $_.name -like $Name }) }
'Country' { $Conditions.Add( { $_.country -like $Country }) }
'State' { $Conditions.Add( { $_.state -like $State }) }
'City' { $Conditions.Add( { $_.city -like $City } ) }
'IDNumber' { $Conditions.Add( { $_.idnumber -eq $IDNumber }) }
}
}
if ($Conditions.Count -ge 1) {
$FinalCondition = [scriptblock]::Create(($Conditions -join ' -and '))
Write-Verbose "Filter applied: $($FinalCondition.ToString())"
return $response.Where($FinalCondition)
}
else {
return $Response
}
}
为了演示,我为结束过滤器添加了
Write-Verbose
。同样出于演示目的,这里有一个伪造的数据集,用于对其进行测试。
$TestData = @(
[PSCustomObject]@{
Name = 'Morty'
IDNumber = 'C-299'
City = 'Montreal'
State = 'Quebec'
Country = 'Canada'
},
[PSCustomObject]@{
Name = 'Rick'
IDNumber = 'C-137'
City = 'Seattle'
State = 'Washinton'
Country = 'USA'
},
[PSCustomObject]@{
Name = 'Jerry'
IDNumber = '?'
City = 'Seattle'
State = 'Washinton'
Country = 'USA'
}
)
最后,实际调用:
get-people -City 'Seattle' -Country USA -FakeResponse $TestData -Verbose | ft
结果:
关于powershell - 是否有更好的方法基于参数输入创建过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59431927/