Been fighting learning how to use PS Runspaces for a large AD user processing task that has to run daily so I can multi-thread the whole thing. The goal is to query AD for all users first so as to not overwhelm the domain controllers with individual queries. The list is about 14K of users and growing, and that takes about a day to process currently as is single threaded.
Powershell:
$Worker = {
Param($EID,$syncallADUsers)
Write-Host "Processing $EID"
#testing if the array is even passed <- I just did this to test if the array was passed at all
Write-Host "First ADUser in list is $($syncallADUsers[0].DistinguishedName)"
$Result = $syncallADUsers | Where-Object {$_.EmployeeID -eq $EID}
Write-Host "Here are the results for $EID : $($Result.DistinguishedName)"
}
$MaxRunspaces = 5
$SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $MaxRunspaces, $SessionState, $Host)
$RunspacePool.Open()
$Jobs = New-Object System.Collections.ArrayList
$syncallADUsers = [System.Collections.ArrayList]::Synchronized($allADUsers)
$termList | ForEach-Object{
Write-Host "Creating runspace for $($_.EmployeeID)"
$PowerShell = [powershell]::Create()
$PowerShell.RunspacePool = $RunspacePool
$PowerShell.AddScript($Worker).AddArgument($_.EmployeeID).AddArgument($syncallADUsers) | Out-Null
$JobObj = New-Object -TypeName PSObject -Property @{
Runspace = $PowerShell.BeginInvoke()
PowerShell = $PowerShell
}
$Jobs.Add($JobObj) | Out-Null
}
Variables that are not shown:
$termlist = A set of EmployeeIDs that were imported with an Import-CSV statement
$allADUsers = A set of ADUsers all queried from Active Directory (Get-ADUser -filter * -Properties EmployeeID)
I get all the output that I expect until I attempt the "Where-Object" statement. I can run this manually with a test EID in the console and it works as expected. In this job it just returns nothing. I see the processor go nuts; so, it's actually trying to search, but never returns anything.
I see the first "Processing $EID" line with the expected EID there.
Then I see "First ADUser in list is $($syncallADUsers[0].DistinguishedName) and array is $($syncallADUsers.count) big" line exactly as it should with the Distinguished Name of the first item of the SyncAllADUser returned (so the array is there) and then I see the count of it as consistent.
Then paradoxically I see the last line "Here are the results for $EID : $($Result.DistinguishedName)" as : "Here are the results for 329334 : " ... No result but I test that in the console and I get what I would expect.
I'm flummoxed! Any help would be greatly appreciated.