Eu tenho uma lista genérica de tabelas hash derivadas de chaves de desinstalação no registro, que preciso pesquisar. Cada membro da lista é um dicionário ordenado contendo essas chaves. O valor real de cada chave é definido separadamente, pois alguns são valores direto do registro e outros são calculados.
[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'
}
Depois de ter essa coleção em uma variável, $rawUninstallKeys
preciso pesquisá-la, e a pesquisa é complicada porque a Autodesk tende a ter várias chaves de desinstalação com dados iguais ou semelhantes, mas apenas uma funcionará. Por exemplo, haverá uma chave GUID com um DisplayName
que Autodesk Revit 2025
fornece uma string de desinstalação que realmente funciona e outro GUID com um DisplayName
que Revit 2025
não faz nada. Portanto, para extrair a UninstallString correta, preciso procurar uma chave que corresponda ao primeiro padrão E que tenha uma segunda chave que corresponda ao segundo padrão. E na verdade existem muitas variações porque a Autodesk é péssima em qualquer tipo de consistência. Então, estou com isso funcionando agora onde apenas faço um foreach nas chaves brutas procurando pelo primeiro padrão, e se encontrar eu derivo o segundo padrão (neste caso substituo 'Autodesk' por $null
) e depois procuro com outro foreach . E funciona, mas meu Deus, é lento. Então, quero tentar usar o .Where()
método da lista para obter a otimização do .NET. Mas isso significa construir uma coleção de fechamentos a serem aplicados.
Então, isso vai funcionar
$rawUninstallKeys.Where({$_.publisher -like "Autodesk*"})
mas estou lutando para descobrir como colocar o fechamento em uma variável que ainda permite $_
a expansão adequada. Isso é ainda mais complicado pelo fato de que meu encerramento pode ser simplesmente {$_.DisplayName}
quando eu só preciso ver se esse valor existe, ou {-not $_.DisplayName}
quando eu quero apenas uma chave que não contenha essa propriedade, ou o primeiro exemplo onde preciso comparar o valor das propriedades para outro valor, que pode ser um curinga. Efetivamente, o que preciso fazer é expandir a variável na string de fechamento dentro do .Where()
, mas isso não funciona
.Where({$($ExecutionContext.InvokeCommand.ExpandString($closure))})
De acordo com o comentário de @sirtao, você não precisa restringir e desstringificar seu scriptblock - basta passá-lo diretamente para
.Where()
:Vamos configurar alguns dados de teste:
e então, se você tiver uma série de filtros que deseja aplicar:
você pode simplesmente fazer isso:
que dá a saída:
Você pode estender isso para apenas executar os filtros em ordem até encontrar o primeiro que retorne um resultado, se for isso que você precisa...