简体   繁体   English

如何使用 PSCustomObjects 对不慢的对象进行不变更改?

[英]How to make an in-variable change to objects that isn't slow with PSCustomObjects?

I have two tables as pscustomobjects and I tried doing the equivalent of a SQL join to add some properties back into the primary object that I need to read from.我有两个表作为 pscustomobjects,我尝试执行相当于 SQL 连接的操作,以将一些属性添加回我需要读取的主要对象。 The issue is that my code below ran on an object collection for 5 hours with about 40,000 entries and still didn't finish.问题是我下面的代码在对象集合上运行了 5 个小时,其中包含大约 40,000 个条目,但仍然没有完成。 Is there something I'm doing wrong?我做错了什么吗?

$tableObj = import-csv ".\employeeIDsAndAttributes.csv"

"Getting AD data"
$directoryTable = Get-ADUser -Filter {(employeeid -like "*")} -Properties employeeid,name,samaccountname,distinguishedname | 
Select-Object employeeid,name,samaccountname,distinguishedname
"Finished getting AD data. Joining tables."

foreach ($changeRecordLine in $tableObj) {
    $changeRecordLine | add-member -NotePropertyName "Name" -NotePropertyValue ($directoryTable | Where-Object {($_.employeeid -eq $changeRecordLine.employeeID)} | Select-Object -ExpandProperty name) -Force
    $changeRecordLine | add-member -NotePropertyName "DN" -NotePropertyValue ($directoryTable | Where-Object {($_.employeeid -eq $changeRecordLine.employeeID)} | Select-Object -ExpandProperty distinguishedname) -Force
    $changeRecordLine | add-member -NotePropertyName "ParentDN" -NotePropertyValue ( $changeRecordLine.DN.substring($changeRecordLine.Name.length+4)) -Force
}

Excel let me join my columns without problems by using vlookup, but this should have been fast too. Excel 让我可以通过使用 vlookup 毫无问题地加入我的专栏,但这应该也很快。

I tried running the code above.我尝试运行上面的代码。 When I cancelled the process, I got the $tableObj and inspected it in Excel and noted that some entries had been changed, but not all.当我取消该过程时,我得到了 $tableObj 并在 Excel 中检查它并注意到一些条目已被更改,但不是全部。 I was expecting this process to complete rather quickly.我原以为这个过程会很快完成。

Your code is slow for 2 main reasons, you're doing linear lookups using Where-Object which by itself is slow (this is the slowest technique to filter a collection in PowerShell) but in addition to this, you're doing this linear lookup 2 times per loop iteration when it could be just once :您的代码速度慢有两个主要原因,您正在使用Where-Object进行线性查找,这本身很慢(这是在 PowerShell 中过滤集合的最慢技术),但除此之外,您还在进行线性查找每次循环迭代 2 次,而它可能只有一次

# lookup just once:
$lookUp = $directoryTable | Where-Object { $_.employeeid -eq $changeRecordLine.employeeID }
# then Name and DN are available to you:
$lookUp.Name
$lookUp.DistinguishedName

What you should use instead of a linear lookup is a structure meant specifically for fast lookups: 您应该使用一种专门用于快速查找的结构而不是线性查找:

$tableObj = Import-Csv ".\employeeIDsAndAttributes.csv"
$map = @{}

# `name, samaccountname, distinguishedname` are already default properties
# no need to include them in `-Properties`
foreach($user in Get-ADUser -Filter "EmployeeId -like '*'" -Properties employeeid) {
    $map[$user.employeeid] = $user
}

foreach($changeRecordLine in $tableObj) {
    $value = $map[$changeRecordLine.employeeid]
    $props = $changeRecordLine.PSObject.Properties

    $parentDN = try {
        $changeRecordLine.DN.SubString($changeRecordLine.Name.Length + 4)
    }
    catch { }

    # `Add-Member` adds overhead even though this is the least of your code's issues,
    # adding `NoteProperties` to your objects by accessing
    # the object's PSObject Properties and adding them manually is faster
    $props.Add([psnoteproperty]::new('Name', $value.Name))
    $props.Add([psnoteproperty]::new('DN', $value.DistinguishedName))
    $props.Add([psnoteproperty]::new('ParentDN', $parentDN))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM