简体   繁体   中英

Get-ADUser not caching results

$users = get-aduser -filter 'extensionAttribute10 -notlike "*" -and proxyaddresses -like "*"' -Properties extensionAttribute10,proxyaddresses,company

foreach($user in $users){
    $user
}

In the above sample the get-aduser commandlet returns ~20,000 objects (and takes some time to run). Once Get-ADUser is complete and the script moves onto the foreach loop, PowerShell seems to call Get-ADUser again for each object in the array rather than just returning the values from the variable (and is subsequently really, really slow).

The same behaviour applies if I reference an object in the array by using $users[100] - the first time it is slow to return the user as it makes a call to the Domain Controller, the second time I call it it returns instantly as the result is cached.

Is this expected behaviour, and is there a way of controlling it / caching all results upfront?

PSVersion: 5.1.15063.1563

Update - It seems this only occurs when you're querying objects in a forest which is remote to the user executing the command:

$myForest | Get-ADUser -filter * 
$myForest[0]        # <-- this doesn't reach back to a DC to return the user

$remoteForest | Get-ADUser -filter * -server dc1.remoteforest.com
$remoteForest[0]    # <-- this will call back to a DC to fetch the user even though it's 
                    # been successfully retrieved in the previous line

I have not observed the ActiveDirectory module calling Get-ADUser when the results are referenced in an array. You may be running into a memory issue. I recommend checking the memory allocation settings for PowerShell, and compare with the actual memory utilization when your script is executing.

#Start the Win RM service because it is required for the subsequent command.
Get-Service -Name WinRM | Start-Service

#Get the Max Memory Per Shell in MB
$memLimitPerShellMB = Get-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB

#Write value to console.
$memLimitPerShellMB.Value

#Check PowerShell memory utilization. Capture this information in a separate shell while your other, heavier, process is running.
get-process | Where-Object ProcessName -like "*PowerShell*"

#If needed, the MaxMemoryPerShellMB value can be adjusted using this command:
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB <NEW VALUE>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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