Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
437 views
in Technique[技术] by (71.8m points)

powershell - Initialize hashtable from array of objects?

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)
}
question from:https://stackoverflow.com/questions/66067500/initialize-hashtable-from-array-of-objects

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

[...] 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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...