Skip to content

Commit 23d4392

Browse files
authored
Merge pull request #205678 from markwahl-msft/mwahl-prov-existing-err
Add warning on duplicates
2 parents c7e41db + c752d7f commit 23d4392

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

articles/active-directory/governance/identity-governance-applications-existing-users.md

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,25 +226,30 @@ The first time your organization uses these cmdlets for this scenario, you need
226226

227227
1. Retrieve the IDs of those users in Azure AD.
228228

229-
The following PowerShell script uses the `$dbusers`, `$db_match_column_name`, and `$azuread_match_attr_name` values specified earlier. It will query Azure AD to locate a user that has a matching value for each record in the source file. If there are many users in the database, this script might take several minutes to finish.
229+
The following PowerShell script uses the `$dbusers`, `$db_match_column_name`, and `$azuread_match_attr_name` values specified earlier. It will query Azure AD to locate a user that has an attribute with a matching value for each record in the source file. If there are many users in the database, this script might take several minutes to finish. If you don't have an attribute in Azure AD that has the value, and need to use a `contains` or other filter expression, then you will need to customize this script and that in step 11 below to use a different filter expression.
230230

231231
```powershell
232232
$dbu_not_queried_list = @()
233233
$dbu_not_matched_list = @()
234234
$dbu_match_ambiguous_list = @()
235235
$dbu_query_failed_list = @()
236236
$azuread_match_id_list = @()
237+
$azuread_not_enabled_list = @()
238+
$dbu_values = @()
239+
$dbu_duplicate_list = @()
237240
238241
foreach ($dbu in $dbusers) {
239242
if ($null -ne $dbu.$db_match_column_name -and $dbu.$db_match_column_name.Length -gt 0) {
240243
$val = $dbu.$db_match_column_name
241244
$escval = $val -replace "'","''"
245+
if ($dbu_values -contains $escval) { $dbu_duplicate_list += $dbu; continue } else { $dbu_values += $escval }
242246
$filter = $azuread_match_attr_name + " eq '" + $escval + "'"
243247
try {
244-
$ul = @(Get-MgUser -Filter $filter -All -ErrorAction Stop)
248+
$ul = @(Get-MgUser -Filter $filter -All -Property Id,accountEnabled -ErrorAction Stop)
245249
if ($ul.length -eq 0) { $dbu_not_matched_list += $dbu; } elseif ($ul.length -gt 1) {$dbu_match_ambiguous_list += $dbu } else {
246250
$id = $ul[0].id;
247251
$azuread_match_id_list += $id;
252+
if ($ul[0].accountEnabled -eq $false) {$azuread_not_enabled_list += $id }
248253
}
249254
} catch { $dbu_query_failed_list += $dbu }
250255
} else { $dbu_not_queried_list += $dbu }
@@ -261,19 +266,27 @@ The first time your organization uses these cmdlets for this scenario, you need
261266
if ($dbu_not_queried_count -ne 0) {
262267
Write-Error "Unable to query for $dbu_not_queried_count records as rows lacked values for $db_match_column_name."
263268
}
269+
$dbu_duplicate_count = $dbu_duplicate_list.Count
270+
if ($dbu_duplicate_count -ne 0) {
271+
Write-Error "Unable to locate Azure AD users for $dbu_duplicate_count rows as multiple rows have the same value"
272+
}
264273
$dbu_not_matched_count = $dbu_not_matched_list.Count
265274
if ($dbu_not_matched_count -ne 0) {
266275
Write-Error "Unable to locate $dbu_not_matched_count records in Azure AD by querying for $db_match_column_name values in $azuread_match_attr_name."
267276
}
268277
$dbu_match_ambiguous_count = $dbu_match_ambiguous_list.Count
269278
if ($dbu_match_ambiguous_count -ne 0) {
270-
Write-Error "Unable to locate $dbu_match_ambiguous_count records in Azure AD."
279+
Write-Error "Unable to locate $dbu_match_ambiguous_count records in Azure AD as attribute match ambiguous."
271280
}
272281
$dbu_query_failed_count = $dbu_query_failed_list.Count
273282
if ($dbu_query_failed_count -ne 0) {
274283
Write-Error "Unable to locate $dbu_query_failed_count records in Azure AD as queries returned errors."
275284
}
276-
if ($dbu_not_queried_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0) {
285+
$azuread_not_enabled_count = $azuread_not_enabled_list.Count
286+
if ($azuread_not_enabled_count -ne 0) {
287+
Write-Error "$azuread_not_enabled_count users in Azure AD are blocked from sign-in."
288+
}
289+
if ($dbu_not_queried_count -ne 0 -or $dbu_duplicate_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0 -or $azuread_not_enabled_count) {
277290
Write-Output "You will need to resolve those issues before access of all existing users can be reviewed."
278291
}
279292
$azuread_match_count = $azuread_match_id_list.Count
@@ -284,7 +297,7 @@ The first time your organization uses these cmdlets for this scenario, you need
284297

285298
For example, someone's email address might have been changed in Azure AD without their corresponding `mail` property being updated in the application's data source. Or, the user might have already left the organization but is still in the application's data source. Or there might be a vendor or super-admin account in the application's data source that does not correspond to any specific person in Azure AD.
286299

287-
1. If there were users who couldn't be located in Azure AD, but you want to have their access reviewed or their attributes updated in the database, you need to create Azure AD users for them. You can create users in bulk by using either:
300+
1. If there were users who couldn't be located in Azure AD, or weren't active and able to sign in, but you want to have their access reviewed or their attributes updated in the database, you need to update or create Azure AD users for them. You can create users in bulk by using either:
288301

289302
- A CSV file, as described in [Bulk create users in the Azure AD portal](../enterprise-users/users-bulk-add.md)
290303
- The [New-MgUser](/powershell/module/microsoft.graph.users/new-mguser?view=graph-powershell-1.0#examples) cmdlet
@@ -299,17 +312,22 @@ The first time your organization uses these cmdlets for this scenario, you need
299312
$dbu_match_ambiguous_list = @()
300313
$dbu_query_failed_list = @()
301314
$azuread_match_id_list = @()
315+
$azuread_not_enabled_list = @()
316+
$dbu_values = @()
317+
$dbu_duplicate_list = @()
302318
303319
foreach ($dbu in $dbusers) {
304320
if ($null -ne $dbu.$db_match_column_name -and $dbu.$db_match_column_name.Length -gt 0) {
305321
$val = $dbu.$db_match_column_name
306322
$escval = $val -replace "'","''"
323+
if ($dbu_values -contains $escval) { $dbu_duplicate_list += $dbu; continue } else { $dbu_values += $escval }
307324
$filter = $azuread_match_attr_name + " eq '" + $escval + "'"
308325
try {
309-
$ul = @(Get-MgUser -Filter $filter -All -ErrorAction Stop)
326+
$ul = @(Get-MgUser -Filter $filter -All -Property Id,accountEnabled -ErrorAction Stop)
310327
if ($ul.length -eq 0) { $dbu_not_matched_list += $dbu; } elseif ($ul.length -gt 1) {$dbu_match_ambiguous_list += $dbu } else {
311328
$id = $ul[0].id;
312329
$azuread_match_id_list += $id;
330+
if ($ul[0].accountEnabled -eq $false) {$azuread_not_enabled_list += $id }
313331
}
314332
} catch { $dbu_query_failed_list += $dbu }
315333
} else { $dbu_not_queried_list += $dbu }
@@ -319,19 +337,27 @@ The first time your organization uses these cmdlets for this scenario, you need
319337
if ($dbu_not_queried_count -ne 0) {
320338
Write-Error "Unable to query for $dbu_not_queried_count records as rows lacked values for $db_match_column_name."
321339
}
340+
$dbu_duplicate_count = $dbu_duplicate_list.Count
341+
if ($dbu_duplicate_count -ne 0) {
342+
Write-Error "Unable to locate Azure AD users for $dbu_duplicate_count rows as multiple rows have the same value"
343+
}
322344
$dbu_not_matched_count = $dbu_not_matched_list.Count
323345
if ($dbu_not_matched_count -ne 0) {
324346
Write-Error "Unable to locate $dbu_not_matched_count records in Azure AD by querying for $db_match_column_name values in $azuread_match_attr_name."
325347
}
326348
$dbu_match_ambiguous_count = $dbu_match_ambiguous_list.Count
327349
if ($dbu_match_ambiguous_count -ne 0) {
328-
Write-Error "Unable to locate $dbu_match_ambiguous_count records in Azure AD."
350+
Write-Error "Unable to locate $dbu_match_ambiguous_count records in Azure AD as attribute match ambiguous."
329351
}
330352
$dbu_query_failed_count = $dbu_query_failed_list.Count
331353
if ($dbu_query_failed_count -ne 0) {
332354
Write-Error "Unable to locate $dbu_query_failed_count records in Azure AD as queries returned errors."
333355
}
334-
if ($dbu_not_queried_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0) {
356+
$azuread_not_enabled_count = $azuread_not_enabled_list.Count
357+
if ($azuread_not_enabled_count -ne 0) {
358+
Write-Error "$azuread_not_enabled_count users in Azure AD are blocked from sign-in."
359+
}
360+
if ($dbu_not_queried_count -ne 0 -or $dbu_duplicate_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0 -or $azuread_not_enabled_count -ne 0) {
335361
Write-Output "You will need to resolve those issues before access of all existing users can be reviewed."
336362
}
337363
$azuread_match_count = $azuread_match_id_list.Count
@@ -465,6 +491,8 @@ When an application role assignment is created in Azure AD for a user to an appl
465491

466492
If you don't see users being provisioned, check the [troubleshooting guide for no users being provisioned](../app-provisioning/application-provisioning-config-problem-no-users-provisioned.md). If you see an error in the provisioning status and are provisioning to an on-premises application, check the [troubleshooting guide for on-premises application provisioning](../app-provisioning/on-premises-ecma-troubleshoot.md).
467493

494+
1. Check the [provisioning log](../reports-monitoring/concept-provisioning-logs.md). Filter the log to the status **Failure**. If there are failures with an ErrorCode of **DuplicateTargetEntries**, this indicates an ambiguity in your provisioning matching rules, and you'll need to update the Azure AD users or the mappings that are used for matching to ensure each Azure AD user matches one application user. Then filter the log to the action **Create** and status **Skipped**. If users were skipped with the SkipReason code of **NotEffectivelyEntitled**, this may indicate that the user accounts in Azure AD were not matched because the user account status was **Disabled**.
495+
468496
After the Azure AD provisioning service has matched the users based on the application role assignments you've created, subsequent changes will be sent to the application.
469497

470498
## Next steps

0 commit comments

Comments
 (0)