Search code examples
powershellhashtable

How can i split up the results of this hashtable search?


I'm trying to use this to compare my AD NT hashdump with https://haveibeenpwned.com/Passwords hashes. I'm having trouble with the results grouping multiple usernames with the same password together.

the code:

  param(
        [Parameter(Mandatory = $true)]
        [System.IO.FileInfo] $ADNTHashes,

        [Parameter(Mandatory = $true)]
        [System.IO.FileInfo] $HashDictionary
    )
    #>

    process {
        $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()

        #Declare and fill new hashtable with ADNThashes. Converts to upper case to 
        $htADNTHashes = @{} 
        Import-Csv -Delimiter ":" -Path $ADNTHashes -Header "User","Hash" | % {$htADNTHashes[$_.Hash.toUpper()] += @($_.User)}

        #Create empty output object
        $mrMatchedResults = @()

        #Create Filestream reader 
        $fsHashDictionary = New-Object IO.Filestream $HashDictionary,'Open','Read','Read'
        $frHashDictionary = New-Object System.IO.StreamReader($fsHashDictionary) 

        #Iterate through HashDictionary checking each hash against ADNTHashes
        while (($lineHashDictionary = $frHashDictionary.ReadLine()) -ne $null) {
            if($htADNTHashes.ContainsKey($lineHashDictionary.Split(":")[0].ToUpper())) {
                $foFoundObject = [PSCustomObject]@{
                    User = $htADNTHashes[$lineHashDictionary.Split(":")[0].ToUpper()]
                    Frequency = $lineHashDictionary.Split(":")[1]
                    Hash = $linehashDictionary.Split(":")[0].ToUpper()
                }
                $mrMatchedResults += $foFoundObject               
            }
        }
        $stopwatch.Stop()
        Write-Verbose "Function Match-ADHashes completed in $($stopwatch.Elapsed.TotalSeconds) Seconds"
    }

    end {
        $mrMatchedResults
    }
}

I tried commenting out | % {$htADNTHashes[$_.Hash.toUpper()] += @($_.User)} which seems to be close, but that somehow removed the Frequency column.

The results look like this:

User                            Frequency Hash                            
----                            --------- ----                            
{TestUser2, TestUser3}          20129     H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1
{TestUser1}                     1         H2H2H2H2H2H2H2H2H2H2H2H2H2H2H2H2

I would like them separated:

User                            Frequency Hash                            
----                            --------- ----                            
{TestUser2}                     20129     H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1
{TestUser3}                     20129     H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1H1
{TestUser1}                     1         H2H2H2H2H2H2H2H2H2H2H2H2H2H2H2H2

i'm sure this is a simple change, but i have very little powershell experience.

The suggestion to change $FormatEnumerationLimit to -1 is not what i want either, that just fixes the list truncating. {user1, user2, user3...}


Solution

  • while (($lineHashDictionary = $frHashDictionary.ReadLine()) -ne $null) {
                if($htADNTHashes.ContainsKey($lineHashDictionary.Split(":")[0].ToUpper())) {
                    $Users = $htADNTHashes[$lineHashDictionary.Split(":")[0].ToUpper()]
                    foreach($User in $Users){
                    $foFoundObject = [PSCustomObject]@{
                        User = $User
                        Frequency = $lineHashDictionary.Split(":")[1]
                        Hash = $linehashDictionary.Split(":")[0].ToUpper()
                    }
                    $mrMatchedResults += $foFoundObject
                    }
                }
            }