Wednesday, April 8, 2026

The Second Connector Pattern — Writing otherMails to Hybrid Users in Entra ID

ENTRA IDPROVISIONINGHYBRID IDENTITYWORKDAYSSPROTHERMAILS

When you provision hybrid users into Active Directory from Workday and synchronize them to Entra ID via Cloud Sync, you quickly hit a wall: Cloud Sync cannot write otherMails. The attribute exists only on the Entra ID user object — there is no AD equivalent — and Cloud Sync has no mechanism to write cloud-only properties on the accounts it syncs.

For many organizations this matters because otherMails is the personal email address that powers day-one SSPR. Without it populated at account creation, new employees cannot reset their own password until they complete a self-registration flow — which typically requires them to already be logged in.

WHY OTHERMAILS?

otherMails is the Entra ID attribute that SSPR uses as the "Alternate email" reset method. When populated before the user's first login, it enables password reset without prior registration. The personal email originates in Workday's personalEmail field and needs to reach this attribute on the cloud user object.

The Problem in Detail

Here is the flow for a typical hybrid provisioning setup, and where it breaks down:

1

Workday → AD (Connector 1)

The Workday inbound provisioning connector creates the user in on-premises Active Directory. It maps PreferredFirstNameLastNameDepartmentEmployeeID, and other standard attributes. Personal email can be written to an AD extension attribute (e.g. extensionAttribute1) but AD has no otherMails property.

2

AD → Entra ID (Cloud Sync)

Cloud Sync syncs the AD user to Entra ID. It creates the cloud representation of the user with all standard attributes. However, otherMails is a multi-value string array that Entra ID computes and manages — Cloud Sync does not write it. Even if personal email is in extensionAttribute1, there is no supported mapping from that attribute to otherMails in Cloud Sync.

3

otherMails remains empty

The hybrid user lands in Entra ID with no otherMails value. SSPR works only if the user has previously registered, which requires an active account. Day-one password reset fails.

ARCHITECTURE DIAGRAM — SECOND CONNECTOR PATTERN

The key insight is that Entra ID provisioning connectors are not exclusively for creating accounts. They can be configured to update existing accounts only — matching on a stable identifier, skipping creation entirely, and writing a targeted set of attributes via the Microsoft Graph API.

This is the second connector pattern. You deploy a second enterprise application of type "API-driven provisioning to Microsoft Entra ID" (or the Workday → Entra ID cloud connector if you are using the native Workday integration), configured with one critical difference from the primary connector:

THE KEY CONFIGURATION

Create action: OFF. Update action: ON. The connector will only ever match existing accounts and write to them. It will never attempt to create a new user object, regardless of what Workday sends.

Connector Roles Side by Side

CONNECTOR 1 — PRIMARY

Workday → Active Directory

  • Creates hybrid AD accounts
  • Writes all standard AD attributes
  • Manages OU placement
  • Enables / disables accounts
  • Manages manager attribute
  • Handles UPN generation
CONNECTOR 2 — ATTRIBUTE WRITER

Workday → Entra ID (update only)

  • Create: OFF
  • Matches on employeeId
  • Writes otherMails from Workday personalEmail
  • Can also write usageLocation, custom extension attributes
  • Writes any cloud-only property invisible to Cloud Sync

Attribute Mapping Configuration

In the Entra admin center, navigate to the second provisioning app's attribute mappings and configure the following. Keep mappings minimal — only include what this connector is responsible for.

SOURCE (WORKDAY)TARGET (ENTRA ID)APPLY MAPPINGNOTES
WorkerIDemployeeIdMATCH ATTRIBUTEUsed for account matching only — stable Workday identifier
personalEmailotherMailsALWAYSCore purpose of this connector
CountryISOusageLocationALWAYSOptional — also not writable via Cloud Sync
(remove all others)Strip default mappings — this connector should be narrow in scope
IMPORTANT — REMOVE DEFAULT MAPPINGS

When you create the provisioning app, it comes with a full set of default attribute mappings. Delete all of them except the match attribute and otherMails. If you leave displayNameuserPrincipalName, or other attributes mapped, this connector will overwrite values that the primary connector and Cloud Sync are responsible for — potentially causing conflicts and provisioning loops.

Scoping Filter — The Critical Safety Guard

Without a scoping filter, this connector will attempt to process every worker in Workday — including cloud-only users who are already fully managed by a separate cloud-only connector. That creates a race condition where two connectors both write to the same user object.

The scoping filter must match only the hybrid population. Use the same attribute you use to differentiate hybrid from cloud-only workers in Workday — typically Worker_TypeLegal_Entity, or a custom boolean field.

// Scoping filter in the provisioning app — Workday attribute filter
// Only process workers that are in scope for hybrid AD provisioning

Attribute: Worker_Type
Operator:  EQUALS
Value:     "Employee"

// AND

Attribute: Legal_Entity
Operator:  MEMBER_OF
Value:     "Contoso Corp", "Contoso LLC"

// This must mirror the scoping filter on Connector 1 exactly.
// If a worker is in scope for Connector 1 (AD creation),
// they must also be in scope for Connector 2 (attribute enrichment).
SCOPING MUST BE MUTUALLY EXCLUSIVE

The scoping filter on Connector 2 (hybrid attribute writer) and your cloud-only connector must be mutually exclusive. A worker should appear in exactly one connector's scope for update operations. Use the same attribute and values you defined when splitting the two provisioning agents — the same logic that prevents UPN collision applies here.

Provisioning App Settings

In the provisioning app settings, set the following:

// Provisioning app settings (Provisioning > Settings blade)

Provisioning Mode:         Automatic

// Under Mappings > Provision Workday Users
// In the attribute mapping header, set:

Create new objects:        OFF   ← critical
Update matching objects:   ON
Delete matching objects:   OFF   ← never let this connector deprovision

// Matching attribute
Source object attribute:   WorkerID       // Workday
Target object attribute:   employeeId     // Entra ID
Match precedence:          1

What Happens at Runtime

When the provisioning cycle runs for Connector 2:

1

Worker record read from Workday

The connector reads the worker's WorkerID and personalEmail from the Workday data view.

2

Match against Entra ID by employeeId

The provisioning service queries GET /users?$filter=employeeId eq 'WD-12345'. If no match is found — because the AD account has not synced yet — the record is escrowed and retried on the next cycle. No account is created.

3

PATCH otherMails via Graph

The provisioning service issues PATCH /users/{id} with { "otherMails": ["personal@gmail.com"] }. This is a direct Graph write — not through AD, not through Cloud Sync.

4

SSPR is now available on day one

With otherMails populated, the user can reset their password using the alternate email method before their first login — no prior registration required.

Timing Consideration

Connector 2 depends on the account already existing in Entra ID before it runs. The account creation sequence is:

  1. Connector 1 creates the user in AD
  2. Cloud Sync syncs the AD user to Entra ID (~20–40 minutes)
  3. Connector 2 runs its next cycle (~40 minute interval) and finds the account
  4. otherMails is written

In the worst case, otherMails is populated about 80 minutes after account creation. For pre-hire provisioning (account created 1–3 days before start date), this is not an issue. If same-day provisioning is required, a Lifecycle Workflow Logic App custom extension triggered at joiner time is a faster alternative — it fires immediately after the account appears in Entra ID and makes the same Graph PATCH call.

ALTERNATIVE — LIFECYCLE WORKFLOW

If you need otherMails populated within minutes of account creation rather than on the next 40-minute provisioning cycle, deploy a Lifecycle Workflow with a custom task extension (Logic App) that fires on the joiner trigger and calls PATCH /users/{id} with the personal email sourced from a Workday attribute written to an extension attribute at provisioning time.

When to Use This Pattern vs. Alternatives

APPROACHTIMINGCOMPLEXITYBEST FOR
Second connector (this post)~80 min after account creationLow — one additional provisioning appPre-hire provisioning, no Governance license
Lifecycle Workflow + Logic AppMinutes after account appearsMedium — requires Entra ID Governance licenseSame-day onboarding, real-time enrichment
Workday → Entra ID cloud connector (direct)Same cycle as account creationLow — native mapping on cloud-only connectorCloud-only users only — does not help hybrid
Graph API via PowerShell / Azure FunctionOn-demand / scheduledMedium — requires code and scheduled triggerBulk backfill of existing accounts

Summary

Cloud Sync's inability to write otherMails is not a blocker — it is an architectural boundary that the second connector pattern cleanly crosses. The pattern works because Entra ID provisioning connectors are general-purpose Graph API clients: they can update any writable user attribute, and they are not limited to account creation.

The three things that make this pattern safe are:

  1. Create: OFF — the connector cannot create orphan accounts
  2. Narrow attribute mapping — only otherMails and the match key, nothing else
  3. Mutually exclusive scoping — hybrid workers only, mirroring Connector 1's scope exactly

Add this connector to your Workday provisioning architecture alongside the existing AD connector and Cloud Sync, and hybrid users will have their personal email populated in otherMails automatically on every provisioning cycle — no Logic Apps, no custom code, no Governance license required.

LM
Lutz Mueller-HipperCybersecurity Technical Lead & Identity Architect, Insight Enterprises — CISSP — SecAttic • LinkedIn

Soft-delete for Entra ID groups: what changed and when

Microsoft Entra ID · Identity & Access Management


If you've ever accidentally deleted a security group in Microsoft Entra ID and then spent the next hour scrambling to recreate it from memory, you'll know exactly why this update matters. Microsoft has finally extended soft-delete support to cloud security groups — closing a recovery gap that has frustrated admins for years.

A bit of history

Soft-delete isn't new to Entra ID. Microsoft introduced it for Microsoft 365 Groups back in early 2017, giving admins a 30-day window to restore accidentally deleted groups — complete with their connected resources like SharePoint sites and Planner boards. Applications and users followed, also gaining soft-delete status.

But cloud security groups? Until late 2025, deleting one meant it was gone. Permanently. No recycle bin, no restore button. You had to rebuild the group from scratch, re-add all members, and then hope you hadn't missed anyone with access to something critical.

What's new

Announced via Message Center notification MC1183299 on 6 November 2025, Entra ID now places deleted cloud security groups into a soft-deleted state for 30 days — giving admins time to restore them with all settings, membership, and ownership intact.

Here's the rollout timeline:

Late October 2025
Public preview begins. Feature available via Entra admin center, Microsoft Graph v1.0 API, and Graph PowerShell SDK.
November 2025
Public preview rollout completes.
Late February – Early March 2026
General Availability worldwide.
After 30 days
Soft-deleted groups are permanently (hard) deleted and cannot be recovered.

How to restore a soft-deleted group

Head to the Microsoft Entra admin center, navigate to Identity > Groups > All groups, and select Deleted groups. Pick the group and hit Restore group. You can also use PowerShell with Restore-MgDirectoryDeletedItem or the deletedItems Microsoft Graph API.

Keep in mind: while a group sits in the soft-deleted state, its members immediately lose access to any resources protected by that group — SharePoint sites, app assignments, Conditional Access policies, and so on. Restoring the group reapplies all of that access based on the original configuration.

Important caveats

This feature covers cloud-only security groups — both assigned and dynamic membership types. 

Groups that are synced from on-premises Active Directory via Entra Connect Sync or Cloud Sync are not eligible for soft-delete and will still be hard-deleted immediately. 

The 30-day retention window is also not customizable. Distribution lists and mail-enabled security groups remain outside the scope of this feature for now.

What you should do now

If you run automation or scripts that manage group lifecycle — say, a cleanup job that deletes stale groups — review them. Deleted groups will now land in a soft-deleted state rather than disappearing instantly, which could affect your automation logic if it expects immediate hard deletion. Also worth tagging your critical security groups and documenting who's responsible for recovery, so that if something goes wrong, there's a clear escalation path before the 30-day window closes.

It's a small change in Microsoft's changelog — but for any admin who's been burned by an accidental group deletion, it's a very welcome safety net.

Sunday, February 12, 2023

Azure AD Connect - DataValidationFailed

Working with the new Azure AD Lifecycle Workflows I ran into a problem syncing the employee's start (employeeHireDate) and leave date (employeeLeaveDateTime) from on premises AD to Azure AD. First you must have Azure AD Connect version 2.1.20 or better to sync both attributes.

Hear the problem. after I added the attribute flows via a custom sync rule (out to AAD) picking the timestamps up from extensionAttribute1 and 2 I got DataValidationFailed errors (0x8023134a).

here the detail info:

"

Unable to update this object in Azure Active Directory, because the attribute [employeeHireDate], is not valid. Update the value in your local directory services.


Tracking Id: 673b26d2-b793-4b26-91f5-2bb753c97059

ExtraErrorDetails:

[{"Key":"ObjectId","Value":["b1d0b05b-d012-4be5-8259-b1ad1fa88211"]},{"Key":"InvalidAttributeName","Value":["employeeHireDate"]}]

"

the correct date and time format in on premises AD is 20230212100000.0Z. If the format is not correct, or is not a date-time format at all, you will see the error "InvalidAttributeName". The ExtraErrorDetails are confusing because the data is not valid, but the attribute name is correct.

see also How to synchronize attributes for Lifecycle workflows - Microsoft Entra | Microsoft Learn


just to add one more thought: It will be a secret to Microsoft why the attributes are named differently, one just ...Date and the other one ...DateTime, both attributes must have a timestamp in the same format including the time info.


Monday, May 23, 2022

 Default Certificate Mapping in Windows has been changed with Windows Updates May 10th, 2022


Microsoft made a significant change with the May 10th, 2022 updates what is impacting typical Wi-Fi authentication configurations  with NPS or other Radius servers. They decided to allow as default only stronger mapping methods from a certificate to an AD user or machine. See the article below in section "Certificate mappings".


https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16


Saturday, November 16, 2019

SQL Server Linked Server error - OLE DB provider "ADSDSOObject" for linked server "ADSI" reported an error.

I ran into this problem while trying to set up a linked server from SQL server(SQL 2016 Developer Edition) to Active Directory. More information how to do that can be found here https://www.mssqltips.com/sqlservertip/2580/querying-active-directory-data-from-sql-server/

"The OLE DB provider "ADSDSOObject" for linked server "ADSI" reported an error. The provider indicates that the user did not have the permission to perform the operation."

After googling and binging and scratching my head, it turned out that I misspelled the domain name in the user name for the LDAP connection. As I found many other solutions for this problem but no one mentioned a typo I wanted to share this. The OLE DB provider is giving only a little information back about the real problem.

Friday, November 16, 2018

Fun with bitmask math

I had fun today working on queries against Active Directory userAccountControl. In cases like mine where you have 514 and 546 for enabled and disabled accounts, I wanted to check which bit is set.
so 2 to the power of 2 is set if the account is disabled.


see here for more values to play with https://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/

the bitmask.ps1 script gives me all the bits set

param([int]$value=2147483647)

clear
[int]$i=0
$hexvalue = '{0:X}' -f $value
$bitmask = [convert]::tostring($value,2)
write-host "hex original value is 0x$($hexvalue)"
write-host "dec original value is $value"
write-host "bin original value is $bitmask"

do {

$valcheck = [math]::pow(2,$i)

if ( $value -band $valcheck) { write-host "hit: 2 to the power of $i = $valcheck"}

$i++
} until ($i -eq 31)
write-host "info: max tested to 2 to the power of 30, the max value for a int32 value"




In my case, I have userAccountControl as an integer value in a SQL database and I can run the following query to find all objects which are disabled, regardless if it is 514 or 546

select cn, useraccountcontrol
from [dbo].[domain.com_users]
where useraccountcontrol & 2 = 2


Saturday, January 21, 2017

What groups are used in my Microsoft Identity Manager installation

I came across a question today what the actual group names are used in a MIM installation. For a production system that should never be a question but in test labs with one AD and multiple "flying" setups, it can understand that it come sometimes to confusion. So thought it can be helpful to others to show how to find that out.

At first, I was looking into the registry under the FIMsync service but there was nothing to find there.
So I check in the sync database and voila I found the SIDs in the FIMsynchronization database in table [mms_server_configuration]. I copied the value from administrators_sid and pasted it into ldp.exe to run the translation to a human-readable group name. But bummer. The sid format looked already a little bit strange and ldp.exe could not use it as well.

0x010500000000000515000000D1D64379336F47EB77D1D6B32D760C00

I know ldp.exe can use a SID in the format S-1-5-...and so I googled it and found on http://poshcode.org/3181a script to convert the hex sid into the format ldp.exe (and I) like.

S-1-5-21-2034489041-3947327283-3017199991-816685

So now I know the group name is TESTLAB\LAB4711-MIMSyncAdmins ;-)