在散列 Table 值中搜索缺失值

Searching Hash Table Values for Missing Values

我正在尝试搜索包含主机名作为键和应用程序作为值的散列 table。我正在寻找不包含特定值 AKA 应用程序的主机名(密钥)。但是,我的代码似乎无法正常工作,因为我总是收到所有 keys/hostnames 的回复。

foreach ($global:computer in $global:hash.keys){  
  if ($global:hash.$global:computer.values -notcontains 'SnagIt'){
    $global:computer
}

}

示例数据:

键、值

Host1:FireFox,Chrome,IE

Host2:Snagit,FireFox,Chrome,IE

Host3:Chrome,IE

$global:hash.$global:computer:

的示例值输出

{Snagit、FireFox、Chrome、IE...}

散列Table构建代码:

$global:Csv = Import-Csv -LiteralPath $global:ConvertedSNWReport

[HashTable]$global:Hash=@{}

For ($i = 0; $i -lt ($global:Csv."Computer name").Count; $i++)
{
If ($global:Hash.ContainsKey($global:Csv[$i].'Computer name'))
{
    $global:Hash.($global:Csv[$i].'Computer name').Application += $global:Csv[$i].Application
    Continue
}
$global:Hash.($global:Csv[$i].'Computer name') = @{
  Application = @($global:Csv[$i].Application)
}
}

表达式 $hashtable.$key 已经解析为键为 $key

的条目的值

$global:hash.$global:computer.values

中删除 .values 引用

如果值只是带有逗号分隔项的单个字符串,-notcontains 将不起作用,请改用 -notlike 运算符:

if($hash.$computer -notlike '*SnagIt*'){...}

您创建的哈希表将应用程序列表构建为嵌套哈希表:

{
    "Host1": {
        "Application": [ "FireFox", "Chrome", "IE" ]
    },
    "Host2": {
        "Application": [ "Snagit", "FireFox", "Chrome", "IE" ]
    },
    "Host3": {
        "Application": [ "Chrome", "IE" ]
    }
}

像这样导入您的数据:

$hash = @{}
Import-Csv -LiteralPath $global:ConvertedSNWReport | ForEach-Object {
    $hash[$_.'Computer name'] += @($_.Application)
}

获取主机名和应用程序列表之间的直接映射:

{
    "Host1": [ "FireFox", "Chrome", "IE" ],
    "Host2": [ "Snagit", "FireFox", "Chrome", "IE" ],
    "Host3": [ "Chrome", "IE" ]
}

有了它,您可以像这样过滤哈希表:

$hash.GetEnumerator() | Where-Object {
    $_.Value -notcontains 'Snagit'
}

如果你想坚持你的数据导入过程(我不推荐)你需要扩展哈希表值的 Application 键:

$hash.GetEnumerator() | Where-Object {
    $_.Value.Application -notcontains 'Snagit'
}

附带说明:尽可能避免使用全局变量。它们通常是在您的脚本中引入意外状态的旁路。尤其不要使用全局变量作为循环变量。在大多数情况下,最好使用局部变量并通过 script/function 参数从调用者传递数据。