AD LDS has a great feature called “bindable proxy objects”. These are objects that refer to an AD DS object by its ‘objectSid’ attribute. For all intents and purposes these can be treated as plain user objects by any consuming application. The real benefit is that the password for the account is stored in AD DS. This can give you a lot of flexibility in the way that you store user data for applications. It provides a layer of indirection between applications and your domain allowing you to keep information that might not be a good fit for AD DS out of the domain while still making use of the users centralized domain credentials.
One place this might come in handy would be in an extranet scenario where you have external user accounts that could be created as normal ‘user’ objects and internal users who can be created as ‘userProxy’ or ‘userProxyFull’ objects. Any applications that service both user communities can use one directory to authenticate either type of account. It’s pretty handy.
They are a little difficult to work with, however. Since the proxy account refers to the domain account via ‘objectSid’ the domain account needs to exist prior to creating the proxy in AD LDS. Once this is done if the domain account is deleted or disabled the proxy account will no longer authenticate the user.
The following PowerShell function will create a ‘userProxyFull’ object with a provided email address.
function Create-ADLDSProxyObject([string] $emailAddr) { #this uses the .Net framework wrapper for ADSI $output = [System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices') #this is the container in LDS where the account will be created $userContainerPath = 'LDAP://DC:50000/CN=Users,CN=APPDIR,DC=DEV,DC=TEST' #get the users AD DS account... $dsUser = Get-ADUser -Filter { mail -eq $emailAddr} if($dsUser) { #this does the work. #first create the object under the parent then set the sid #userprincipalname and mail are set, but are both optional $sid = $dsUser.SID $userContainer = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList $userContainerPath $proxyObject = $userContainer.Children.Add('CN=' + $emailAddr, 'userProxyFull') $proxyObject.InvokeSet('ObjectSID', $sid.Value) $proxyObject.InvokeSet('userPrincipalName', $emailAddr) $proxyObject.InvokeSet('mail', $emailAddr) $proxyObject.CommitChanges() } else { Write-Host "Sorry, pal." } }