Initialize hashtable from array of objects?

Viewed 149

I'm brand new to powershell, as in less than a day experience. I have an array of objects returned from a Get-ADUser call. I will be doing a lot of lookups so thought it best to build a hashtable from it.

Is there a shorthand way to initialize the hashtable with this array and specify one of the object's attributes to use as a key?

Or do I have to loop the whole array and manually add to the set?

$adSet = @{}

foreach ($user in $allusers) {

    $adSet.add($user.samAccountname, $user)
}
1 Answers

[...] do I have to loop

Yes

... the whole array ...

No

You don't have to materialize an array and use a loop statement (like foreach(){...}), you can use the pipeline to turn a stream of objects into a hashtable as well, using the ForEach-Object cmdlet - this might prove faster if the input source (in the example below, that would be Get-Service) is slow:

$ServiceTable = Get-Service |ForEach-Object -Begin { $ht = @{} } -Process { $ht[$_.Name] = $_ } -End { return $ht }

The block passed as -Begin will execute once (at the beginning), the block passed to -Process will execute once per pipeline input item, and the block passed to -End will execute once, after all the input has being recevied and processed.

With your example, that would look something like this:

$ADUserTable = Get-ADUser -Filter * |ForEach-Object -Begin { $ht = @{} } -Process { $ht[$_.SAMAccountName] = $_ } -End { return $ht }

Every single "cmdlet" in PowerShell maps onto this Begin/Process/End lifecycle, so generalizing this pattern with a custom function is straightforward:

function New-LookupTable {
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [array]$InputObject,

        [Parameter(Mandatory)]
        [string]$Property
    )

    begin {
        # initialize table
        $lookupTable = @{}
    }

    process {
        # populate table
        foreach($object in $InputObject){
            $lookupTable[$object.$Property] = $object
        }
    }

    end {
        return $lookupTable
    }
}

And use like:

$ADUserTable = Get-ADUser |New-LookupTable -Property SAMAccountName

See the about_Functions_Advanced document and related help topics for more information about writing advanced and pipeline-enabled functions

Related