Why on earth are ActiveDirectory permission errors terminating?

I’m writing a script that batch modifies and deletes computers using Move-ADObject, Set-ADComputer, and Remove-ADComputer. I would prefer to use pipelines with the -ErrorVariable parameter, because it’s a bit cleaner and faster than instantiating a try/catch for each loop iteration. This is my current code:

try {
    # all errors will be caught in move_errors or description_change_errors; successes will be passed through and recorded in the CSV
    # if there's a terminating error, it will be bubbled up to the caller after running the finally block
    $computers_to_archive |
        Move-ADObject -TargetPath $ArchiveOU -ErrorVariable move_errors -PassThru |
        Set-ADComputer -Description "Archived on $(Get-Date -Format 'yyyy-MM-dd')" -ErrorVariable description_change_errors -PassThru |
        Export-Csv -Path "$LogDir\$(Get-Date -Format 'yyyy-MM-dd')-archived.csv"
} finally {
    # export info about any errors we encountered
    $archive_errors = $move_errors + $description_change_errors
    if ($archive_errors.Count -ne 0) {
        $archive_errors | Select-Object -Property \* | Export-Csv -Path "$LogDir\$(Get-Date -Format 'yyyy-MM-dd')-archive-errors.csv"
    }
}

This would work great if the ActiveDirectory module followed PowerShell’s own best practices for reporting terminating versus non-terminating errors (Cmdlet Error Reporting - PowerShell | Microsoft Learn), since if a terminating error occurred, it would be something catastrophic where I wouldn’t want to try processing more objects anyway.

However, Move-ADObject/Set-ADComputer/Remove-ADComputer treat permissions errors as terminating. So if just one computer object in this pipeline is protected against accidental deletion (or if I don’t have access rights to it), the pipeline will throw a terminating error, and other objects will not get processed. Additionally, the terminating error will end up in -ErrorVariable, but it will have a different type than non-terminating errors in the same array, which makes the exported CSV potentially not that useful.

I know how to get around this by using try/catch inside a foreach loop, but this seems really inconsistent. A permissions issue with a single object in a pipeline should not terminate the whole pipeline. This is exactly the case that non-terminating errors were designed for.

Is there any rationale for why it’s like this? Is there any plan to fix this behavior to be consistent?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.