Our HR core integration with Azure AD is failing to match users correctly due to UPN mismatches in D365 10.0.39. When new employees are onboarded in Azure AD, the automatic sync to HR core creates incomplete records because the User Principal Name format doesn’t match what HR core expects.
We’re using Power Automate to handle the sync, triggered when a user is created in Azure AD. The flow attempts to match the Azure AD UPN to the Worker’s email address in HR core, but many employees have different email formats (some use firstname.lastname@domain.com, others use employee.number@domain.com). This causes the matching logic to fail and creates duplicate or incomplete HR records.
How should I configure the Azure AD attribute mapping and user matching logic to handle these UPN variations? What’s the best practice for reconciling identity differences between Azure AD and D365 HR?
I explored the native integration option but our organization has specific business rules for employee onboarding that require custom logic. I think a hybrid approach might work - use native integration for basic sync, but add Power Automate for the custom matching and reconciliation logic.
The extension attribute approach sounds promising. How do I populate that attribute in Azure AD? Do I need to sync employee IDs from D365 HR to Azure AD first, or can I set it during the initial Azure AD user creation process?
Your UPN mismatch issue requires a systematic approach addressing Azure AD attribute mapping, user matching logic, and reconciliation workflows. Here’s a comprehensive solution:
Azure AD Attribute Mapping:
Establish a reliable matching key independent of UPN or email variations. The most robust approach uses a custom Azure AD extension attribute to store the D365 employee identifier:
-
Register an Azure AD extension attribute (requires Azure AD Premium):
- Navigate to Azure AD > App registrations > Your HR Integration App
- Go to Manifest and add extension attribute definition
- Name it “extension_EmployeeID” to store D365 personnel numbers
-
Populate the extension attribute during user provisioning:
- If using Azure AD Connect: Add custom attribute mapping in synchronization rules
- If using manual provisioning: Include employee ID in user creation workflow
- If using automated provisioning: Ensure HR system provides employee ID to identity provider
-
Configure attribute mapping in D365:
- Navigate to Human resources > Setup > Azure Active Directory integration
- Map the extension attribute to Worker.PersonnelNumber field
- Set this as the primary matching attribute
This creates a stable, unique identifier that doesn’t change with email format variations or UPN updates.
User Matching Logic:
Implement a multi-tiered matching strategy in your Power Automate flow that handles various scenarios:
// Pseudocode for user matching logic:
1. Primary Match - Extension Attribute:
IF Azure AD extensionAttribute1 is populated
THEN query D365 HR Workers where PersonnelNumber = extensionAttribute1
IF single match found THEN proceed with sync
2. Secondary Match - Email Domain:
IF primary match fails
THEN extract email from Azure AD UPN
THEN query D365 HR Workers where Email = extracted email
IF single match found THEN update Azure AD extension attribute and proceed
3. Tertiary Match - Name and Hire Date:
IF secondary match fails
THEN query D365 HR Workers where:
FirstName = Azure AD givenName AND
LastName = Azure AD surname AND
HireDate within 30 days of Azure AD creation date
IF single match found THEN update Azure AD extension attribute and proceed
4. No Match - Create Pending Record:
IF all matches fail
THEN create record in staging table with status "Pending Manual Review"
THEN send notification to HR administrators
THEN do NOT create duplicate HR record
Implement this in Power Automate using nested conditions and variables to track match status at each tier.
Power Automate Reconciliation Flow:
Build a comprehensive sync flow with proper error handling:
Trigger Configuration:
- Trigger: When a user is created or updated in Azure AD
- Filter: Only users in specific organizational units (exclude service accounts)
- Frequency: Real-time for creates, batch for updates (every 4 hours)
Flow Steps:
-
Initialize Variables:
- MatchFound (boolean, default false)
- MatchMethod (string, tracks which tier succeeded)
- EmployeeID (string, stores matched personnel number)
- SyncErrors (array, collects validation errors)
-
Primary Match Attempt:
- Get Azure AD user with extension attributes
- If extensionAttribute1 exists:
- Query D365 HR using OData: Workers?$filter=PersonnelNumber eq ‘{extensionAttribute1}’
- If result count = 1, set MatchFound = true, MatchMethod = “ExtensionAttribute”
-
Secondary Match Attempt (if primary failed):
- Extract email domain from UPN
- Query D365 HR: Workers?$filter=Email eq ‘{extractedEmail}’
- If result count = 1:
- Set MatchFound = true, MatchMethod = “Email”
- Update Azure AD user extension attribute with found PersonnelNumber
-
Tertiary Match Attempt (if secondary failed):
- Build composite filter for name and date range
- Query D365 HR with multiple conditions
- If result count = 1:
- Set MatchFound = true, MatchMethod = “NameDate”
- Update Azure AD user extension attribute with found PersonnelNumber
-
Sync or Stage:
- Condition: If MatchFound = true
- Update D365 HR worker record with Azure AD attributes:
- Email, Phone, Department, JobTitle
- Create or update Worker.User association
- Log successful sync with MatchMethod to audit table
- Else (no match):
- Create record in custom Dataverse table “PendingHRReconciliation”
- Include all Azure AD attributes for manual review
- Send email notification to HR team with user details
- Do NOT create new Worker record automatically
-
Error Handling:
- Wrap entire flow in Scope action
- Configure run after to catch failures
- Log errors to SharePoint or Dataverse
- Send error notifications with user context
Reconciliation Workflow:
Create a separate scheduled flow for ongoing data quality:
- Runs daily at 3 AM
- Queries Azure AD for users without extension attribute populated
- Attempts matching using secondary/tertiary logic
- Updates extension attributes for successful matches
- Flags remaining mismatches for review
Manual Review Process:
Build a Power Apps canvas app for HR administrators:
- Displays pending reconciliation records from Dataverse
- Shows side-by-side comparison of Azure AD and potential D365 HR matches
- Allows administrators to:
- Confirm match and trigger sync
- Create new worker record if truly new employee
- Mark as false positive (contractor, external user)
- Updates Azure AD extension attribute after manual resolution
Testing and Validation:
Test these specific scenarios:
- New employee with matching email format → Should match via secondary tier
- New employee with employee ID pre-populated → Should match via primary tier
- New employee with no existing HR record → Should create pending record
- Email format change in Azure AD → Should maintain match via extension attribute
- Rehired employee → Should match to existing worker record
- Contractor with Azure AD account → Should not create HR worker record
Monitoring and Maintenance:
Implement ongoing monitoring:
- Track match success rate by method (extension attribute vs email vs name)
- Monitor pending reconciliation queue size
- Alert if match rate drops below 85%
- Review and update matching logic quarterly based on failure patterns
This comprehensive solution eliminates UPN mismatch issues by establishing a reliable matching key, implementing intelligent fallback logic, and providing a safety net for edge cases through manual review. The extension attribute approach ensures long-term stability even as email formats or UPN conventions change in your organization.
UPN matching is notoriously problematic for HR integrations. Instead of relying solely on UPN or email, use a more stable identifier like Employee ID or a custom attribute in Azure AD. You can add an extension attribute to Azure AD user profiles (like extensionAttribute1) to store the D365 worker number, then use that for matching. This requires synchronizing the employee ID from your HR system back to Azure AD during initial setup, but it creates a reliable matching key.
Don’t forget about the HR core’s built-in integration capabilities. D365 HR has a Common Data Service integration that can handle Azure AD synchronization with proper configuration. Instead of building everything in Power Automate, leverage the platform’s native integration. Go to System administration > Setup > Microsoft Azure Active Directory applications and configure the HR data integration. This handles many edge cases automatically, including UPN variations and attribute mapping.
I dealt with this exact issue last year. The problem is that Azure AD and D365 HR have different concepts of user identity. Azure AD is authentication-focused (UPN, email), while HR is employee-focused (personnel number, position). Your Power Automate flow needs a two-step matching process: first try exact UPN match, then fall back to fuzzy matching using first name + last name + hire date. If both fail, create a pending record for manual review rather than auto-creating duplicates.
You have two options for populating extension attributes. Option 1: If employees are created in HR first, use a reverse flow that updates Azure AD with the employee ID after HR record creation. Option 2: If employees are created in Azure AD first (more common), ensure your user provisioning process includes the employee ID at creation time. Many organizations use Microsoft Identity Manager or Azure AD Connect with custom attribute mappings to handle this. For Power Automate, you’d need to add a step that updates the Azure AD user after HR record creation.