字符串变量中 .Where() 的 Powershell 闭包

问题描述 投票:0回答:1

我有一个从注册表中的卸载项派生的哈希表的通用列表,我需要对其进行搜索。每个列表成员都是包含这些键的有序字典。每个键的实际值是单独定义的,因为有些是直接来自注册表的值,有些是计算出来的。

[Ordered]@{
        displayName = 'DisplayName'
        displayVersion = 'DisplayVersion'
        installSource = 'InstallSource'
        publisher = 'Publisher'
        quietUninstallString = 'QuietUninstallString'
        uninstallParam = 'UninstallParam'
        uninstallPath = 'UninstallPath'
        uninstallString = 'UninstallString'
        installDate = 'InstallDate'
        keyID = '$keyID'
        keyName = '$keyName'
        keyGUID = '$keyGUID'
        keyPath = '$keyPath'
        architecture = '$architecture'
    } 

一旦我将此集合放入变量中

$rawUninstallKeys
,我需要搜索它,并且搜索很复杂,因为 Autodesk 往往有多个具有相同或相似数据的卸载密钥,但只有一个可以工作。例如,将有一个
DisplayName
Autodesk Revit 2025
的 GUID 密钥提供实际有效的卸载字符串,而另一个
DisplayName
Revit 2025
的 GUID 不执行任何操作。因此,要提取正确的 uninstallString,我需要搜索与第一个模式匹配的键,并且具有与第二个模式匹配的第二个键。实际上有很多变化,因为 Autodesk 在任何一致性方面都很糟糕。 所以,我现在正在工作,我只是在原始键上执行 foreach 来查找第一个模式,如果找到它,我会派生出第二个模式(在这种情况下,我将“Autodesk”替换为
$null
),然后搜索与另一个foreach。它确实有效,但亲爱的上帝,它很慢。 所以,我想尝试使用列表中的
.Where()
方法来获得.NET优化。但这意味着构建一个要应用的闭包集合。

所以,这会起作用

$rawUninstallKeys.Where({$_.publisher -like "Autodesk*"})

但我正在努力解决如何将闭包放入变量中,但仍允许

$_
适当扩展。当我只需要查看该值是否存在时,我的闭包可能只是
{$_.DisplayName}
,或者当我只想要一个不包含该属性或第一个属性的键时,这使情况变得更加复杂。例如,我需要将属性值与另一个值(可能是通配符)进行比较。 实际上,我需要做的是扩展
{-not $_.DisplayName}
内闭包字符串中的变量,但这不起作用
.Where()

	
powershell closures variable-expansion
1个回答
0
投票
.Where({$($ExecutionContext.InvokeCommand.ExpandString($closure))})

让我们设置一些测试数据:

.Where()

然后,如果您想要应用一系列过滤器:

$rawUninstallKeys = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() $rawUninstallKeys.Add( [ordered] @{ publisher = "Autodesk Revit 2025" } ) $rawUninstallKeys.Add( [ordered] @{ displayname = "displayname" publisher = "Revit 2025" } )

然后你可以这样做:

$filters = @( { $_.Publisher -like 'Autodesk*' }, { $_.DisplayName } )

给出输出:

foreach( $filters in $filter ) { write-host "testing for $scriptblock" $rawUninstallKeys.Where($closure) | ft | out-string }

您可以扩展它以按顺序运行过滤器,直到找到第一个返回结果的过滤器,如果这是您需要的......

© www.soinside.com 2019 - 2024. All rights reserved.