entra-powershell icon indicating copy to clipboard operation
entra-powershell copied to clipboard

Get-EntraDirectoryObjectOnPremisesProvisioningError output is very poor and not actionable

Open NuAlex opened this issue 1 year ago • 5 comments

Describe the bug

Summary The Get-EntraDirectoryObjectOnPremisesProvisioningError outputs an array of hashtables with insufficient information. There are 4 main issues with the output of this cmdlet:

  1. Confusing output
  2. Missing some objects with OnPremisesProvisioningErrors
  3. Missing identifier properties which makes it impossible to identify the objects in conflict
  4. No parameters to filter the query (nit pick)

Description

  1. The output in hashtables makes it unnecessarily confusing to read because each object entry is composed by 4 lines/rows. When there's multiple objects with OnPremisesProvisioningError, it's hard to understand where each object starts and ends since the output is an array of hashtables with a Name/Value header, instead of an array of objects with columns separating each property. For example:
Get-EntraDirectoryObjectOnPremisesProvisioningError | where propertyCausingError -eq 'UserPrincipalName'
Name                           Value
----                           -----
category                       PropertyConflict
value                          [email protected]
occurredDateTime               9/27/2023 2:13:58 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               7/4/2024 12:06:16 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               9/27/2023 2:13:59 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               7/4/2024 12:06:04 AM
propertyCausingError           UserPrincipalName
  1. The output is missing objects. On my case the Get-EntraDirectoryObjectOnPremisesProvisioningError is returning 7 entries while Get-MsolDirSyncProvisioningError returns 10 objects. (see my output from the legacy MSOL module at the end of this text).

  2. The output does not include any identifier of what is the Entra ID object holding the OnPremisesProvisioningError. This leaves up to the user to go find out which object have these conflicts based on the conflict value. On top of the hassle of try searching for the object with the value in conflict (which could be in UPN or ProxyAddresses attributes of a user, group or contact), this will only return the user currently owning that value and will not be possible to determine what is the other object causing the conflict since that object's value is "quarantined" (automatically removed to prevent the conflict), i.e. the conflicting object does not have that value so it's not possible to search for it. So, this cmdlet must also output the ObjectID and UserPrincipalName of the directory object that contains each OnPremisesProvisioningError, similarly to what existed in the legacy MSOL module (see my output from the legacy MSOL module at the end of this text).

  3. As an IT Pro I would expect to see some parameters in the cmdlet similar to what was available on the legacy MSOL module. The main ones would be: -ErrorCategory The error category that needs to be searched. -PropertyName The property whose conflicts will be searched. -PropertyValue The property value on which conflicts will be searched. -SearchString The search string to be used in the search. Only objects with DirSyncProvisioningErrors due to a PropertyConflict returned from a search on this string will be returned. Note: ok, this one might be nit picking because we can achieve the same filtering by pipelining the results to Select-Object, but having these parameters can help in terms of usability, backward compatibility and it's a more efficient service-side query.

To Reproduce Steps to reproduce the behavior:

  1. Import the module (Beta version has the same issue): Import-Module -Name Microsoft.Graph.Entra.Beta
  2. Connect to Entra ID: Connect-Entra -Scopes 'User.Read.All', 'Directory.Read.All', 'Group.Read.All', 'Contacts.Read'
  3. Call the cmdlet: Get-EntraDirectoryObjectOnPremisesProvisioningError

Expected behavior The expected output (like any other normal PowerShell cmdlet) would be an array of objects, plus the identifiers of each object line ObjectId and UPN: For example (mock output):

Get-EntraDirectoryObjectOnPremisesProvisioningError | where propertyCausingError -eq 'UserPrincipalName'
Category           Value                         OccurredDateTime       PropertyCausingError   ObjectId                               UserPrincipalName
--------           -----                         ----------------       --------------------   --------                               -----------------
PropertyConflict   [email protected]   9/27/2023 2:13:58 AM   UserPrincipalName      ########-8c06-4e9e-b30c-############   [email protected]
PropertyConflict   [email protected]   7/4/2024 12:06:16 AM   UserPrincipalName      ########-8c06-4e9e-b30c-############   [email protected]
PropertyConflict   [email protected]   9/27/2023 2:13:59 AM   UserPrincipalName      ########-8c06-4e9e-b30c-############   [email protected]
PropertyConflict   [email protected]   7/4/2024 12:06:04 AM   UserPrincipalName      ########-8c06-4e9e-b30c-############   [email protected]

Debug Output

Get-EntraDirectoryObjectOnPremisesProvisioningError -Debug
DEBUG: ============================ TRANSFORMATIONS ============================
DEBUG: =========================================================================

DEBUG: GET /v1.0/users?$select=onPremisesProvisioningErrors HTTP/1.1
HTTP: graph.microsoft.com
User-Agent: PowerShell/7.4.6 EntraPowershell/0.19.0 Get-EntraDirectoryObjectOnPremisesProvisioningError


DEBUG: GET https://graph.microsoft.com/v1.0/users?$select=onPremisesProvisioningErrors
HTTP/2.0 200 OK
Cache-Control: no-cache
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: ###########-12fe-4195-a30b-###########
client-request-id: ###########-9304-4d5c-814b-###########
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"West US 2","Slice":"E","Ring":"4","ScaleUnit":"001","RoleInstance":"MW2PEPF00008D4F"}}
x-ms-resource-unit: 1
odata-version: 4.0
Date: Fri, 17 Jan 2025 21:00:27 GMT
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; IEEE754Compatible=false; charset=utf-8
Content-Encoding: gzip

{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users(onPremisesProvisioningErrors)","@odata.nextLink":"https://graph.microsoft.com/v1.0/users?$select=onPremisesProvisioningErrors&$skiptoken=####AAAAAAAAAAAAA","value":[{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[{"value":"[email protected]","category":"PropertyConflict","propertyCausingError":"UserPrincipalName","occurredDateTime":"2023-09-27T02:13:58.4084034Z"}]},{"onPremisesProvisioningErrors":[{"value":"[email protected]","category":"PropertyConflict","propertyCausingError":"UserPrincipalName","occurredDateTime":"2024-07-04T00:06:16.5714411Z"}]},{"onPremisesProvisioningErrors":[{"value":"[email protected]","category":"PropertyConflict","propertyCausingError":"UserPrincipalName","occurredDateTime":"2023-09-27T02:13:59.3459395Z"}]},{"onPremisesProvisioningErrors":[{"value":"[email protected]","category":"PropertyConflict","propertyCausingError":"UserPrincipalName","occurredDateTime":"2024-07-04T00:06:04.4399944Z"}]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[{"value":"SMTP:[email protected]","category":"PropertyConflict","propertyCausingError":"ProxyAddresses","occurredDateTime":"2022-03-14T23:46:44.9596664Z"}]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[{"value":"smtp:[email protected]","category":"PropertyConflict","propertyCausingError":"ProxyAddresses","occurredDateTime":"2024-11-04T18:11:02.9935096Z"}]},{"onPremisesProvisioningErrors":[{"value":"SMTP:[email protected]","category":"PropertyConflict","propertyCausingError":"ProxyAddresses","occurredDateTime":"2024-11-21T18:56:21.9850797Z"}]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]}]}
DEBUG: GET /v1.0/groups?$select=onPremisesProvisioningErrors HTTP/1.1
HTTP: graph.microsoft.com
User-Agent: PowerShell/7.4.6 EntraPowershell/0.19.0 Get-EntraDirectoryObjectOnPremisesProvisioningError


DEBUG: GET https://graph.microsoft.com/v1.0/groups?$select=onPremisesProvisioningErrors
HTTP/2.0 200 OK
Cache-Control: no-cache
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: ###########-4fd0-4276-abf0-###########
client-request-id: ###########-d495-428f-9a06-###########
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"West US 2","Slice":"E","Ring":"4","ScaleUnit":"001","RoleInstance":"MW2PEPF00008D4F"}}
x-ms-resource-unit: 1
odata-version: 4.0
Date: Fri, 17 Jan 2025 21:00:27 GMT
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; IEEE754Compatible=false; charset=utf-8
Content-Encoding: gzip

{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups(onPremisesProvisioningErrors)","value":[{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]},{"onPremisesProvisioningErrors":[]}]}

Name                           Value
----                           -----
category                       PropertyConflict
value                          [email protected]
occurredDateTime               9/27/2023 2:13:58 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               7/4/2024 12:06:16 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               9/27/2023 2:13:59 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          [email protected]
occurredDateTime               7/4/2024 12:06:04 AM
propertyCausingError           UserPrincipalName
category                       PropertyConflict
value                          SMTP:[email protected]
occurredDateTime               3/14/2022 11:46:44 PM
propertyCausingError           ProxyAddresses
category                       PropertyConflict
value                          smtp:[email protected]
occurredDateTime               11/4/2024 6:11:02 PM
propertyCausingError           ProxyAddresses
category                       PropertyConflict
value                          SMTP:[email protected]
occurredDateTime               11/21/2024 6:56:21 PM
propertyCausingError           ProxyAddresses

Module Version

Get-Module Microsoft.Graph.Entra*

ModuleType Version    PreRelease Name
---------- -------    ---------- ----
Script     0.19.0     preview    Microsoft.Graph.Entra
Script     0.19.0     preview    Microsoft.Graph.Entra.Beta

Environment Data

$PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.6
PSEdition                      Core
GitCommitId                    7.4.6
OS                             Microsoft Windows 10.0.26100
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Screenshots Image

Additional context Please compare with the output from the legacy module MSOnline module:

  • returns a properly formatted output based on an array of objects
  • returns all the objects with provisioning errors (10 in my case)
  • also returns the objectId, and UPN to identity the object holding the provisioning error
  • it has multiple parameters to filter the query, e.g. -PropertyName
Get-MsolDirSyncProvisioningError -PropertyName UserPrincipalName


ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : BlockSoftMatch1
ImmutableId        :
LastDirSyncTime    :
ObjectId           : 64ef4d51-736b-4c85-bfb6-ad903fad1e50
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : BlockSoftMatch1
ImmutableId        : D92CwNc2nUyF/hkg/H3I0g==
LastDirSyncTime    : 9/30/2023 12:42:46 AM
ObjectId           : cea7b86b-ef66-4d70-b374-a93802b08b67
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : BlockSoftMatch2
ImmutableId        :
LastDirSyncTime    :
ObjectId           : 7684c12c-f496-4f39-b76e-19422536c6ce
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : BlockSoftMatch2
ImmutableId        : IZdqf+RtbUCqdmEOH1DNFA==
LastDirSyncTime    : 9/30/2023 12:42:46 AM
ObjectId           : a50fb612-4ec5-436a-9d29-7102ef3e6dab
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError1
ImmutableId        : kjnLa9zBJEieFkckaXnPvg==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : 09b65398-6f7e-4e99-91a4-9201b221c6af
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError2
ImmutableId        : NJHdBwfcSUKavTXgt2bqbA==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : 138d3807-1291-4dea-9d18-b76addd32b43
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError3
ImmutableId        : kQl8cU4WPke1dW+ZduI5qA==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : 18ee3518-86b7-403f-822a-ec81ba1c9bfa
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError4
ImmutableId        : 6FkCs9VPoU229MuzIOgQAw==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : f0e92eba-8429-4ab0-a5dd-96559c938f8d
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError5
ImmutableId        : j74wJexTuUe+owXTj9oVLA==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : 13b57899-d01a-4bae-a910-ffa3d4f3bb58
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

ExtensionData      : System.Runtime.Serialization.ExtensionDataObject
DisplayName        : StaleDirSyncError6
ImmutableId        : g1q4jBUsA06Gfy9LPp2shA==
LastDirSyncTime    : 11/15/2023 7:14:24 AM
ObjectId           : 37492395-8c06-4e9e-b30c-4315aeb6b51c
ObjectType         : User
ProvisioningErrors : {UserPrincipalName}
ProxyAddresses     : {}
UserPrincipalName  : [email protected]

NuAlex avatar Jan 17 '25 21:01 NuAlex

Hi @NuAlex, thank you so much for your feedback! We’ll prioritize improving this command and will tag you for review/testing.

PS: We appreciate the clarity and detailed framing of the issue.

SteveMutungi254 avatar Jan 21 '25 06:01 SteveMutungi254

This is a great point about usability of the function's output, and it also raises some important questions about the design of PowerShell modules and functions. How much work should one function do, and what data is available in the Graph API?

Updating the script to provide rich object output is fairly simple with something like this:

    end {
        if ([string]::IsNullOrWhiteSpace($response)) {
            Write-Output 'False'
        } else {
            $Results = New-Object -TypeName System.Collections.Generic.List[PSObject]
            foreach ($item in $response) {
                $Results.Add(
                    [PSCustomObject]@{
                        Category             = $item.category
                        Value                = $item.Value
                        OccurredDateTime     = $item.OccurredDateTime
                        PropertyCausingError = $item.PropertyCausingError
                    }
                )
            }
            $Results
        }
    }

And with the function's OutputType attribute changed to [OutputType([System.Collections.Generic.List[PSObject]])].

I agree 100% with the intent of wanting to make it easier to identify the object that the provisioning error was found on. However, it may be worth creating that functionality in a new, separate function. The current function is relatively simple because it does one thing and pulls a specific resource type: onPremisesProvisioningError. This Graph resource type only includes the four properties already included in the output: category, value, occuredDateTime, and PropertyCausingError (see Microsoft Learn: onPremisesProvisioningError resource type ).

It would be extremely useful to create a new function that takes the output of this one and maps the found value/property to any items that have that value. Did the Get-MsolDirSyncProvisioningError cmdlet already provide that aggregated data directly in its output? Have you already peeked at its code to see if it can be replicated with the Graph API?

SamErde avatar Jan 21 '25 20:01 SamErde

Hi,

also Get-EntraDirectoryObjectOnPremisesProvisioningError had an issue merging the errors into PropertyCausingError,Category, Value and OccuredDateTime; so if you have multiple errors you get an array in those properties.

I did a quick workaround

...
$Results.Add(
            [PSCustomObject]@{
                Id                    = $item.Id
                UserPrincipalName     = $upn
                DisplayName           = $item.displayName
                OnPremisesSyncEnabled = $item.onPremisesSyncEnabled 
                Mail                  = $item.mail
                ProxyAddresses        = $item.proxyAddresses
                ObjectType            = $item.ObjectType
                onPremisesProvisioningErrors = 
                (
                    $item.onPremisesProvisioningErrors | foreach {
                        [PSCustomObject]@{
                            PropertyCausingError  = $_.PropertyCausingError
                            Category              = $_.category
                            Value                 = $_.Value
                            OccurredDateTime      = $_.OccurredDateTime                            
                        }
                    }
                )
            }
        )

for the time being. Unfortunatelly this approach breaks the object structure, but it is similiar to the one that is used in MSOL module.

martin-rublik avatar Mar 06 '25 12:03 martin-rublik

@martin-rublik : Could you help me with MSOL output for directory objects with errors? We want to improve the command further. I cannot reproduce this behavior in my tenant.

SteveMutungi254 avatar May 02 '25 07:05 SteveMutungi254

Hi,

It is more hidden in the Get-MSOLUser DirSyncProvisioningErrors attribute. In that case you will see array of errors when multiple values are in conflict for a single object. An example follows:

PS > $usr=Get-MsolUser -UserPrincipalName "[email protected]"
PS > $usr.DirSyncProvisioningErrors | ConvertTo-Json
[
    {
        "ExtensionData":  {

                          },
        "ErrorCategory":  "PropertyConflict",
        "PropertyName":  "ProxyAddresses",
        "PropertyValue":  "x500:/o=ExchangeLabs/ConflictingValue",
        "WhenStarted":  "\/Date(1747835619000)\/"
    },
    {
        "ExtensionData":  {

                          },
        "ErrorCategory":  "PropertyConflict",
        "PropertyName":  "ProxyAddresses",
        "PropertyValue":  "SMTP:[email protected]",
        "WhenStarted":  "\/Date(1737835619000)\/"
    }
]

Unfortunatelly the Get-MsolDirSyncProvisioningError is already disabled for all tenants where I have access. But the issue is that the output of the entra command is as follows:

{
    "Id":  "f37ce565-d8ea-4613-ab07-a0430b893b98",
    "PropertyCausingError":  [
                                 "ProxyAddresses",
                                 "ProxyAddresses"
                             ],
    "UserPrincipalName":  "",
    "Category":  [
                     "PropertyConflict",
                     "PropertyConflict"
                 ],
    "Value":  [
                  "x500:/o=ExchangeLabs/ConflictingValue",
                  "SMTP:[email protected]"
              ],
    "OccurredDateTime":  [
                             "\/Date(1747835619000)\/",
                             "\/Date(1737835619000)\/"
                         ],
    "DisplayName":  "user with error",
    "OnPremisesSyncEnabled":  true,
    "Mail":  null,
    "ProxyAddresses":  [
                           "some data"
                       ],
    "ObjectType":  "contacts"
}

and merges the structure. You then need to take the category as an array and index the errors and later on check on correct Value and OccuredDateTime properties.

martin-rublik avatar May 21 '25 14:05 martin-rublik

Resolved by #1305

KenitoInc avatar Aug 07 '25 03:08 KenitoInc