The *-UnifiedGroupLinks cmdlets now throw proper exceptions

Anyone that uses PowerShell inevitably runs into an error, I do it dozen times every day. PowerShell does offer a robust error handling, however when different teams within Microsoft produce modules and cmdlets, they implement error handling differently, which can cause some inconvenience to us admins. One such example are the Unified Group cmdlets, which returned the exact same CategoryInfo/Reason for different types of exceptions.

To give you a more specific example, imagine trying to remove a user from an Office 365 Group via the Remove-UnifiedGroupLinks cmdlet. Doing so can result in several types of errors, when:

  1. the user does not exist, resulting in error message:
    Couldn’t find object “vasil1”. Please make sure that it was spelled correctly or specify a different object.
  2. the user is an Owner, which means I cannot remove him, resulting in error message:
    Only Members who are not owners can be removed from group. Please remove ‘vasil’ as owners before removing them as members.
  3. the user is the only Owner of a Group, which means it cannot be removed until a new Owner is designated:
    You can’t remove the owner from this group because the person you’re removing is currently the only owner. You need to promote another member to owner before you proceed.

Those are of course all very distinct error messages, however for all of these the error object had the same exact properties, making them undistinguishable. In other words, if we want to handle things programmatically, by using the well-known methods to handle errors in PowerShell, we were unable to do so, because all of the above returned the same value for CateforyInfo:

PS C:\> $Error[0].CategoryInfo

Category   : 1000
Activity   : Remove-UnifiedGroupLinks
Reason     : RecipientTaskException

In contrast, other cmdlets handle things properly and feature different “reason” for different error types. For example, removing permissions from a mailbox can yield: CannotChangePermissionsOnFolderException, CannotRemoveSpecialUserException, ManagementObjectNotFoundException, and so on.

Now, Microsoft has finally addressed this, and the *-UnifiedGroupLinks cmdlets have proper and distinguished error categories/reasons. Here are the corresponding values for the three examples we listed above:

  1. the user does not exist
    Category   : 1000
    Activity   : Remove-UnifiedGroupLinks
    Reason     : ADNoSuchObjectException
    
  2. the user is an Owner
    Category   : 1000
    Activity   : Remove-UnifiedGroupLinks
    Reason     : GroupOwnersCannotBeRemovedException
  3. the user is the only Owner
    Category   : 1000
    Activity   : Remove-UnifiedGroupLinks
    Reason     : MinGroupOwnersCriteriaBreachedException

Listing the full range of exceptions is beyond the scope of this article, the important thing however is that we can now properly handle errors for the Unified Group cmdlets without having to rely on the “description” value and use the CategoryInfo/Reason value instead.

In other news, some improvements in the way Remote Exchange PowerShell cmdlets are handled have been introduced as well. We previously discussed how error handling in Exchange Online can be tricky because the cmdlets didn’t throw terminating errors and you had to resort to some workarounds. Seems this has been changed now, so the example I used to illustrate this a while back is no longer valid, and indeed remote cmdlets now behave the same way as local one. In other words, this will work as expected:

Try { Get-Mailbox non-existant-mailbox -ErrorAction Stop } catch { Write-Host "Oh noes! You made a boo boo." -ForegroundColor DarkGray }
Oh noes! You made a boo boo.

I’m not sure whether this is an improvement introduced in a recent PowerShell update or the module used to host the Exchange Online “proxy” cmdlets, but it’s much welcome nevertheless!

This entry was posted in Azure AD, Exchange Online, Office 365. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *