Problem Statement
When using the provider-agnostic step IdLE.Step.CreateIdentity together with IdLE.Provider.AD, authoring a first simple joiner workflow is unnecessarily error-prone:
New-ADUser requires -SamAccountName, but IdLE currently does not derive it from IdentityKey. Users must duplicate the same value in both With.IdentityKey and With.Attributes.SamAccountName.
- If
IdentityKey is provided as a UPN (user@domain) it is intuitive to treat this as the UPN, but IdLE currently does not auto-set Attributes.UserPrincipalName when missing.
- The AD object CN/RDN name (
New-ADUser -Name) should not be coupled to IdentityKey. Users want the directory object name to follow explicit values (e.g., DisplayName or GivenName Surname) without needing AD-specific steps.
Path must be reliably passed through to the AD RSAT cmdlets (New-ADUser -Path ...) to avoid default-container placement (and frequent “Access is denied” due to ACL differences).
Goal: Improve usability for AD joiner workflows while keeping IdLE.Step.CreateIdentity provider-agnostic (changes must be in the AD provider/adapter only).
Proposed Solution
Implement AD-specific convenience behavior in IdLE.Provider.AD (and/or its adapter) for CreateIdentity(IdentityKey, Attributes):
1) Derive SamAccountName from IdentityKey (conservative)
If Attributes.SamAccountName is missing/empty:
- Classify
IdentityKey using the same/consistent logic as AD identity resolution (GUID vs UPN vs SamAccountName-like).
- If
IdentityKey is SamAccountName-like:
- Set
Attributes.SamAccountName = IdentityKey.
- If
IdentityKey is a UPN (user@domain):
- Fail fast (B1) with an actionable error explaining that
SamAccountName is mandatory for New-ADUser and must be provided explicitly when IdentityKey is a UPN.
Never override explicitly provided Attributes.SamAccountName.
2) Auto-set UserPrincipalName when IdentityKey is a UPN
If IdentityKey is a UPN and Attributes.UserPrincipalName is missing/empty:
- Set
Attributes.UserPrincipalName = IdentityKey.
Never override explicitly provided Attributes.UserPrincipalName.
3) Derive the AD object CN/RDN -Name independently of IdentityKey
When calling New-ADUser -Name ..., determine the name with this priority order:
Attributes.Name (explicit CN/RDN)
Attributes.DisplayName
- If
Attributes.GivenName and Attributes.Surname are present: "<GivenName> <Surname>"
- Fallback:
IdentityKey (with a warning/debug event to highlight the fallback)
This ensures Name != IdentityKey by default in typical joiner workflows, while remaining deterministic.
4) Ensure Path is passed through to RSAT
Continue to accept Attributes.Path and ensure it is consistently passed through to New-ADUser -Path ... (no additional derivation required).
5) Logging / events
When any derivation occurs (SamAccountName, UserPrincipalName, CN/RDN Name):
- Emit a structured provider/engine event (or debug log) indicating what was derived and why.
- Avoid logging sensitive values (e.g., do not log full credentials; attribute values may be logged only if safe per existing logging rules).
Alternatives Considered
-
Document-only approach (require users to always specify SamAccountName and manage -Name themselves).
- Rejected: leads to repetitive workflows and confusing first-time experience.
-
Make IdLE.Step.CreateIdentity AD-aware.
- Rejected: step must remain provider-agnostic by design.
-
Automatically derive SamAccountName from UPN left-part (truncate/sanitize/collision handling).
- Rejected for now: introduces org-specific policy decisions and risk of unexpected collisions. The chosen approach is B1 fail-fast for UPN identity keys.
Impact
Additional Context
Acceptance Criteria
Example Workflow Snippet
With = @{
IdentityKey = 'foo.bar@contoso.com' # treated as UPN
Attributes = @{
Path = 'OU=Users,DC=contoso,DC=com'
GivenName = 'Bar'
Surname = 'Foo'
DisplayName = 'Bar Foo'
# SamAccountName intentionally omitted -> should fail fast (B1) with clear guidance
}
}
With = @{
IdentityKey = 'foo.bar' # samAccountName-like
Attributes = @{
Path = 'OU=Users,DC=contoso,DC=com'
GivenName = 'Bar'
Surname = 'Foo'
DisplayName = 'Bar Foo'
# SamAccountName omitted -> derived from IdentityKey
# New-ADUser -Name derived from DisplayName (or GivenName+Surname)
}
}
Implementation Notes (non-binding)
- Prefer a shared helper for IdentityKey classification to keep
ResolveIdentity and CreateIdentity consistent.
- Keep behavior provider-scoped; do not change the generic CreateIdentity step contract.
Problem Statement
When using the provider-agnostic step
IdLE.Step.CreateIdentitytogether withIdLE.Provider.AD, authoring a first simple joiner workflow is unnecessarily error-prone:New-ADUserrequires-SamAccountName, but IdLE currently does not derive it fromIdentityKey. Users must duplicate the same value in bothWith.IdentityKeyandWith.Attributes.SamAccountName.IdentityKeyis provided as a UPN (user@domain) it is intuitive to treat this as the UPN, but IdLE currently does not auto-setAttributes.UserPrincipalNamewhen missing.New-ADUser -Name) should not be coupled toIdentityKey. Users want the directory object name to follow explicit values (e.g.,DisplayNameorGivenName Surname) without needing AD-specific steps.Pathmust be reliably passed through to the AD RSAT cmdlets (New-ADUser -Path ...) to avoid default-container placement (and frequent “Access is denied” due to ACL differences).Goal: Improve usability for AD joiner workflows while keeping
IdLE.Step.CreateIdentityprovider-agnostic (changes must be in the AD provider/adapter only).Proposed Solution
Implement AD-specific convenience behavior in
IdLE.Provider.AD(and/or its adapter) forCreateIdentity(IdentityKey, Attributes):1) Derive
SamAccountNamefromIdentityKey(conservative)If
Attributes.SamAccountNameis missing/empty:IdentityKeyusing the same/consistent logic as AD identity resolution (GUID vs UPN vs SamAccountName-like).IdentityKeyis SamAccountName-like:Attributes.SamAccountName = IdentityKey.IdentityKeyis a UPN (user@domain):SamAccountNameis mandatory forNew-ADUserand must be provided explicitly whenIdentityKeyis a UPN.Never override explicitly provided
Attributes.SamAccountName.2) Auto-set
UserPrincipalNamewhenIdentityKeyis a UPNIf
IdentityKeyis a UPN andAttributes.UserPrincipalNameis missing/empty:Attributes.UserPrincipalName = IdentityKey.Never override explicitly provided
Attributes.UserPrincipalName.3) Derive the AD object CN/RDN
-Nameindependently ofIdentityKeyWhen calling
New-ADUser -Name ..., determine the name with this priority order:Attributes.Name(explicit CN/RDN)Attributes.DisplayNameAttributes.GivenNameandAttributes.Surnameare present:"<GivenName> <Surname>"IdentityKey(with a warning/debug event to highlight the fallback)This ensures
Name != IdentityKeyby default in typical joiner workflows, while remaining deterministic.4) Ensure
Pathis passed through to RSATContinue to accept
Attributes.Pathand ensure it is consistently passed through toNew-ADUser -Path ...(no additional derivation required).5) Logging / events
When any derivation occurs (SamAccountName, UserPrincipalName, CN/RDN Name):
Alternatives Considered
Document-only approach (require users to always specify
SamAccountNameand manage-Namethemselves).Make
IdLE.Step.CreateIdentityAD-aware.Automatically derive SamAccountName from UPN left-part (truncate/sanitize/collision handling).
Impact
Does this affect existing workflows?
Attributes.SamAccountName,Attributes.UserPrincipalName,Attributes.Name, no behavior changes.SamAccountNamemay start working automatically whenIdentityKeyis samAccountName-like.Any backward compatibility concerns?
IdentityKeyas UPN and missingSamAccountNamewill now fail fast with a clearer, earlier error (explicitly guiding users to setSamAccountName).Additional Context
Acceptance Criteria
SamAccountName derivation
Attributes.SamAccountNameis missing/empty andIdentityKeyis samAccountName-like,SamAccountNameis set toIdentityKey.IdentityKeyis a UPN andSamAccountNameis missing/empty, creation fails fast with a clear error.UPN convenience
IdentityKeyis a UPN andAttributes.UserPrincipalNameis missing/empty,UserPrincipalNameis set toIdentityKey.CN/RDN name selection
New-ADUser -Nameuses the defined priority order:Name>DisplayName>GivenName+Surname>IdentityKeyfallback.IdentityKey.Path pass-through
Attributes.Pathis provided, it is used asNew-ADUser -Path(no defaulting).Tests
Example Workflow Snippet
Implementation Notes (non-binding)
ResolveIdentityandCreateIdentityconsistent.