Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell hashtable.containskey始终返回true_Powershell_Containskey - Fatal编程技术网

Powershell hashtable.containskey始终返回true

Powershell hashtable.containskey始终返回true,powershell,containskey,Powershell,Containskey,下面的代码试图做一件事。它试图查找自上次运行作业以来已添加到Active Directory组的ID 它通过从Active Directory组读取用户ID并将其与前一天保存在文件中的ID进行比较来实现这一点 我首先将广告组读入一个哈希表($ADUsersHashtable) 然后,我将该文件读入一个类似的哈希表($YesterdaysADUsersFile) 两个哈希表都使用UserID作为键。 然后我检查$ADUsersHashtable中的每个ID是否在$YesterdaysADUsers

下面的代码试图做一件事。它试图查找自上次运行作业以来已添加到Active Directory组的ID

它通过从Active Directory组读取用户ID并将其与前一天保存在文件中的ID进行比较来实现这一点

我首先将广告组读入一个哈希表($ADUsersHashtable) 然后,我将该文件读入一个类似的哈希表($YesterdaysADUsersFile) 两个哈希表都使用UserID作为键。 然后我检查$ADUsersHashtable中的每个ID是否在$YesterdaysADUsersFile中。$ADUsersShashTable中但不在$YesterdaysADUsersFile中的ID是自上次运行此作业以来添加到AD中的ID

问题是,如果$YesterdaysADUsersFile中有多个条目,containskey方法总是返回true(请参见下面的输出)

如果我删除文件中除一个条目外的所有条目,代码将按预期工作

如果文件中有多个条目,代码将无法按预期工作

下面的代码将AD和文件读入哈希表,然后比较键

$scriptName = $MyInvocation.MyCommand.Name
$LogFile = "D:\Polarion\data\logs\User Access Dates\$scriptName.log"
$Today = Get-Date
$outDate = get-date -format "yyyy-MM-dd"
Add-content $LogFile "$Today Running $scriptName"
$MyServer = $env:computername
Add-content $LogFile "`t$Today Running on $MyServer"

#Will be populated with IDs from AD that i didn't find yesterday
$NewUsersFile = "D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt" 
clear-content $NewUsersFile #I only want the new users from todays AD group.

$ADUsersHashtable = @{} #Contains IDs of the members in the AD Group.
Get-ADGroupMember -Identity PEALM_ALL_USERS -Recursive `
    | Get-ADObject -Properties SamAccountName, mail `
    | select SamAccountName, mail `
    | foreach {$ADUsersHashtable.Add($_.SamAccountName, $_.mail)}
#$ADUsersHashtable

$YesterdaysADUsersFile = "D:\Polarion\data\logs\User Access Dates\UserIdFromPEALM_ALL_USERS.txt" #Contains the IDs that I knew about the last time this ran.
$YesterdaysADUsersHashTable = @{}
$YesterdaysADUsersHashTable = Get-Content($YesterdaysADUsersFile) | 
    foreach {$_.ToString().Replace(":", "=")} | 
    ConvertFrom-StringData
$YesterdaysADUsersHashTable

$NoNewUsersFound = $true
foreach ($UserIDFromAD in $ADUsersHashtable.keys){ #For each user ID in Todays AD group
    if ($YesterdaysADUsersHashTable.containsKey($UserIDFromAD)){ #If the UserID is in Yesterdays list ignore it.
        write-host YesterdaysADUsersHashTable contains key $UserIDFromAD
    } else {
        $NoNewUsersFound = $false
        write-host YesterdaysADUsersHashTable Doesnt contains key $UserIDFromAD 
        write-host "`tadding $UserIDFromAD to the $NewUsersFile file."
        Add-content $LogFile "`t$Today Adding $UserIDFromAD to $NewUsersFile file"
        Add-Content $NewUsersFile "$UserIDFromAD : $outDate" #if its not in yesterdays list write it to the new users file.
    }
}
if ($NoNewUsersFound){
    Add-content $LogFile "`t$Today No new users IDs found in Active Directory."
}
#Clear-Content $YesterdaysADUsersFile #we want to overwrite the file, not append to it. 
#$ADUsersHashtable.keys `
#    | %{ Add-Content $YesterdaysADUsersFile "$_ : $($ADUsersHashtable.$_)" } #writes the content of the hashtable to a file.
以下是文件(因此$YesterdaysADUsersHashTable)中有两个条目时的输出。 前四行是$YesterdaysADUsersHashTable的转储。 接下来的五行是if containskey块中write host命令的输出。它们显示hashtable.containskey为$ADUsersHashtable中的每个键返回true。但是那些密钥不在$YesterdaysADUsersHashTable中,这是我不理解的

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
QZMRW2                         xxxx.xxxx@xxxx.com                                                                                                                 
dzrbcn                         xxxx.xxxx@xxxx.com  

YesterdaysADUsersHashTable contains key QZMRW2
YesterdaysADUsersHashTable contains key dzrbcn
YesterdaysADUsersHashTable contains key MZDP2G
YesterdaysADUsersHashTable contains key BZ5LBQ
YesterdaysADUsersHashTable contains key FZ080Y
$YesterdaySADUsersShashTable显然不包含“MZDP2G”、“BZ5LBQ”或“FZ080Y”

而且,如果我从文件中删除除一个用户ID之外的所有内容,代码似乎可以工作。 $YesterdaysADUsersHashTable现在只有一个条目“QZMRW2”,代码似乎可以正常工作

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
QZMRW2                         xxxx.xxxx@xxxx.com  

YesterdaysADUsersHashTable contains key QZMRW2
YesterdaysADUsersHashTable Doesnt contains key dzrbcn
    adding dzrbcn to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key MZDP2G
    adding MZDP2G to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key BZ5LBQ
    adding BZ5LBQ to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key FZ080Y
我显然不明白什么

任何建议都将不胜感激。

仅仅因为存在一个键并不意味着相应的值不是
$null

请参见下面的示例:

$a = @{ keyName = "Value" }
$b = @{ keyName = $null }

foreach($key in $a.Keys){
    if($b.ContainsKey($key)){
        $bValue = $b[$key] # or `$b.$key` if the key is a string

        if($null -eq $bValue){
            Write-Host "Key '$key' exists in '`$b', but its value is `$null :("
        }
    }
}
如果没有关于如何填充哈希表的详细信息,很难说为什么:)

仅仅因为键存在并不意味着相应的值不是
$null

请参见下面的示例:

$a = @{ keyName = "Value" }
$b = @{ keyName = $null }

foreach($key in $a.Keys){
    if($b.ContainsKey($key)){
        $bValue = $b[$key] # or `$b.$key` if the key is a string

        if($null -eq $bValue){
            Write-Host "Key '$key' exists in '`$b', but its value is `$null :("
        }
    }
}

如果没有关于如何填充哈希表的详细信息,很难说为什么:)

我通过将hashtable.containskey更改为-contains来获得代码。在下面的代码snippit中,我对包含.containsKey($useridfromd)的行进行了注释,并添加了包含$UserIDsFromFile.keys的行-包含$useridfromd。代码现在按预期工作

这与按引用检查和按值检查之间的差异有关。我知道这在Java中是如何工作的,但在Powershell中却不知道

#if ($UserIDsFromFile.containsKey($UserIDFromAD)){ #If the UserID is in Yesterdays list ignore it.
if ($UserIDsFromFile.keys -contains $UserIDFromAD){ #If the UserID is in Yesterdays list ignore it.

通过将hashtable.containskey更改为-contains,我使代码正常工作。在下面的代码snippit中,我对包含.containsKey($useridfromd)的行进行了注释,并添加了包含$UserIDsFromFile.keys的行-包含$useridfromd。代码现在按预期工作

这与按引用检查和按值检查之间的差异有关。我知道这在Java中是如何工作的,但在Powershell中却不知道

#if ($UserIDsFromFile.containsKey($UserIDFromAD)){ #If the UserID is in Yesterdays list ignore it.
if ($UserIDsFromFile.keys -contains $UserIDFromAD){ #If the UserID is in Yesterdays list ignore it.

仅仅因为一个键存在并不意味着它引用的值不是
$null
:)@MathiasR.Jessen可能解决了它-重现错误:
$hash=@{MyKey=$null}$hash.MyKey$hash.MyKey.GetType()
。因为哈希表查找键,但返回值,
$UserIDsFromPEALM\u ALL\u users文件哈希表。$key.GetType()
尝试获取值的类型。我不确定是否有可能获得这样的键类型。如果您希望在循环中获得键的类型,只需执行
$key.GetType()
:)@MathiasR.Jessen好的,但我的意思是,在我的示例中,当没有循环时。如果您只需要第一个键,可以有多个键:
$hash.keys[0]。GetType()
仅仅因为一个键存在并不意味着它引用的值不是
$null
:)@MathiasR.Jessen可能解决了它-重现错误:
$hash=@{MyKey=$null}$hash.MyKey$hash.MyKey.GetType()
。因为哈希表查找键,但返回值,
$UserIDsFromPEALM\u ALL\u users文件哈希表。$key.GetType()
尝试获取值的类型。我不确定是否有可能获得这样的键类型。如果您希望在循环中获得键的类型,只需执行
$key.GetType()
:)@MathiasR.Jessen好的,但我的意思是,在我的示例中,当没有循环时。如果您只需要第一个键,可以有多个键:
$hash.keys[0]。GetType()
@SteveGray请,注释不适合代码:)@SteveGray请,注释不适合代码:)您能告诉我您使用的是哪个版本的PowerShell和.NET吗?我无法用以下内容复制它:
$innerhash1=@{Key1=“innerhash1”}$innerhash2=@{Key2=“innerhash2”}$outerhash=@{$innerhash1=“outerhash1”}$outerhash+=@{$innerhash2=“outerhash2”}$outerhash
-如果我像
$outerhash.$innerhash1这样查询,则在此之后$包含($innerhash1)$outerhash.ContainsKey($innerhash1)$Keys-包含$innerhash1
,所有这些都给出了正确的结果。你能测试一下吗?您的结果是否相同(
outerhash1 True
)?我发现下面的文章解释了发生的事情。谢谢,但对于.NET 4.7.2和PowerShell 5.1,情况并非如此:对于
$hash.ContainsKey($key)
,我得到了
True
。您能告诉我您使用的是哪个版本的PowerShell和.NET吗?我无法用以下内容复制它:
$innerhash1=@{Key1=“innerhash1”}$innerhash2=@{Key2=“innerhash2”}$outerhash=@{$innerhash1=“outerhash1”}$outerhash+=@{$innerhash2=