powershellactive-directory

powershell foreach-object parallel - Not all properties of piped in object are available


Consider below code

$users = get-aduser -filter $filter -properties samAccountName,lastLogonTimestamp
$users|foreach -parallel {
   [do something with $_.samAccountName]   # --> this works fine. samAccountName can be read properly
   [do something with $_.lastLogonTimestamp]    # --> this doesn't work. lastLogonTimestamp is always NULL regardless if it is actually populated

}

Same issue reading whenChanged, whenCreated. What do I miss here?

NOTE: This question is not about referencing an external variable. It's about property visibility of THE piped in object, which is supposed to be fully accessible in the script block.

Same code in non-parallel flavor works fine

$users = get-aduser -filter $filter -properties samAccountName,lastLogonTimestamp
$users|foreach {
   [do something with $_.samAccountName]   # --> this works fine. samAccountName can be read properly
   [do something with $_.lastLogonTimestamp]    # --> this also always works

}

Solution

  • The adapter used by the Active Directory Module is not loaded automatically in the parallel runspaces which is why the property values are displayed as null by default. The solutions are either to force evaluation of all properties prior to passing the objects to the parallel runspaces:

    $users | Select-Object * | ForEach-Object -Parallel {
    

    Or forcing evaluation of a subset of the properties, the ones of interest:

    $users | Select-Object prop1, prop2 | ForEach-Object -Parallel {
    

    Or to load the module in the parallel runspaces and by doing so the adapter should be accessible:

    $users | ForEach-Object -Parallel {
        Import-Module ActiveDirectory
    

    This is most likely not documented as this behavior happens almost exclusively with the AD Module and its adapter, in addition the source code is closed but if you would like to read more about this you can start from PSPropertyAdapter Class and as an example implementation, CimInstanceAdapter source code.