ActiveRoles Performance Tip: Use Distinguished Name instead of Canonical Name in OrganizationalUnit Parameters

When making over 100 accounts today for some hard core Skype for Business monitoring, I (re-)discovered that the form of New-QADUser‘s -ParentContainer parameter makes a huge performance difference. I didn’t time it, but noticed that it took about as long to make five accounts using the Canonical Name (mandie.net/Region/State/City/Purpose) as it did to make the rest of the batch using DN, or Distinguished Name (OU=Purpose,OU=City,OU=State,OU=Region,DC=mandie,DC=net).

This was with Quest ActiveRoles Management Shell for AD 1.7, which goes with ARS 6.9. It was an issue back in the QARMS 1.6/ARS 6.8 days, so hopefully Dell has fixed it for recently-released ARS 7.0. I say “hopefully,” because I can’t find QARMS 1.8(?) anywhere in the ARS 7.0 installation download, much less the Release Notes. Anyhow, it is something to do with how ActiveRoles checks your permissions on the Organizational Unit you are attempting to write to.

You might leave the team responsible for ActiveRoles Server at your company, but ActiveRoles Server never really leaves you…

Get-QADUser -ProxyAddress needs the address type or a wildcard

The wonderful colleague who has succeeded me as the main ActiveRoles Server admin here at Awesome German Auto Parts Manufacturer (awesome.com) ran into trouble last week while trying to find out which user had a proxy address that she was trying to assign. firstname.lastname@awesome.com is not quite as unique as one might think, even in a country with loads of rather long family names, and when a holder of a firstname.lastname@awesome.com leaves, there’s possibly another who would like to have it, and who outsiders are trying to reach at that address.

So my successor cleverly noticed that Get-QADUser has a -ProxyAddress parameter, so tried this on the stubborn address:

Get-QADUser -ProxyAddress "firstname.lastname@awesome.com"

Nothing.

She tried it on her own address, as she was quite sure that one was in there.

Nothing.

Resourceful lady that she is, she started Googling.

Nothing beyond this old Dmitry Sotnikov post: http://dmitrysotnikov.wordpress.com/2010/08/13/manage-email-addresses-without-exchange-cmdlets/

His example shows the address type (in this case, x400) prefix on the searched-for address, but doesn’t state that this is necessary for this parameter to work properly.

Because I’d hit my own wall on Lync emergency calling configuration, I experimentally tried:

Get-QADUser -ProxAddress "smtp:myfirst.mylast@awesome.com"

Result!

Just to check, I tried it without whispering “smtp:“, and…

Nothing.

Continue reading

Why would I want to deprovision an Active Directory Group?

Most of my posts are about issues I’ve run into on the job. However, I occasionally look at the search terms that brought people here, and saw the question, “why would I want to deprovision a group?”

Deprovisioning in ActiveRoles Server is mostly focused around user accounts, because those are what most visibly consume resources: mailboxes (Exchange CAL), space on a file server, an ARS license (ARS licensing is completely based on the number of enabled User objects) and are most subject to abuse if there’s no legitimate need for them anymore. You can copy and then modify the sample “Built-in Policy – Default Deprovisioning” that ships with ARS. I recommend that you copy any Built-In Policy and change your copy.

However, groups can also be deprovisioned. Deprovisioning lets you take a group out of action without deleting it. What “out of action” means depends on exactly what groups do in your environment, and what information you need to retain. Do you need to keep the membership list of the group? Do you want to be able to “undeprovision” it, bringing it quickly back into use? Is there any data in the Description or Info (Notes) attributes that other systems use for accounting? Do you need a record of who the secondary owners were? Should a group that granted read privileges on a departmental folder be deprovisioned differently from one that was used to give administrator access to the file server that was at an office that has just been closed?

Deprovisioning policy for groups, just like deprovisioning policy for users, can be configured in both the Policy Object wizard, which is a good idea if it’s a simple attribute change based on a pattern or another attribute in the same object, or a script that you then attach to the Policy Object.

You can configure different deprovisioning policies for different OUs, which you then attach to the container you want to apply them to with Policy Object Links, similar to Access Template Links, except for the lack of a snazzy AD Management Shell cmdlet that will let you do them in bulk, like you can with New-QARSAccessTemplateLink.

If you create your Group Deprovisioning policy actions in a script, you put them in the onPreDeprovision(), onDeprovision() and onPostDeprovision() event handlers. Make sure you put your group-related code inside an if ($Request.class -eq “Group”) {  } black to distinguish it from what you want to do when $Request.class -eq “User”. You should do that object class check even if you have separate Policy Objects for deprovisioning user and deprovisioning groups.

As far as whether something should be in onPreDeprovision(), onDeprovision() or onPostDeprovision(), think about what needs to happen before the group goes offline, what attributes you want to be able to restore, and what needs to happen after everything else is finished.

onPreDeprovision() might do checks to see if it is in the local Administrators group for a specific sensitive server, and this has to happen in onPreDeprovision() if converting the group from a Security Group to a Distribution List is part of your deprovisioning process (Distribution Lists do not have SIDs.)

onPostDeprovision() is for clean-up activity: perhaps dynamically determining who the recipients for the notification email should be.

If it is a property change you wish to revert, however, it should be in the onDeprovision() event handler, because that is what is recorded in the data retrieved by that group’s edsvaDeprovisionRecordXML, which is used if you ever tell ARS to undo the deprovisioning.

Once you’ve got your group deprovisioning the way you want it, you might want to use PowerShell to deprovision them the same way you can deprovision users with Deprovision-QADUser. There’s no native Deprovision-QADGroup cmdlet, but I’ve written one, along with UnDeprovision-QADUser and UnDeprovision-QADGroup: Deprovision and UnDeprovision Users and Groups with PowerShell

Self-Service User Can’t Add Member to Group, or Error (0x800403fb) Unknown to Anyone

The first thing you should do when you get a weird error code is plug it into your favorite search engine or, with ARS, the ActiveRoles Knowledge Base. This time, there was nothing even vaguely related to ActiveRoles Server when I tried searching for 0x800403fb, so here’s something for the next person who runs into this: the group in question has a member that ActiveRoles Server cannot directly access, and that is likely what is causing your user to have problems maintaining that group.

A Secondary Owner was getting a weird error when he tried adding a new user to one of his groups via the ActiveRoles Server Self-Service web interface. A tech at the Help Desk was getting it, too, so it got referred to me. I took a look at the group in the MMC, and it stopped listing users when it got to 1150 of them. We have some groups with over 5,000 users (I do NOT recommend this), so too many users could not have been the problem. I tried

Get-QADGroupMember ProblemGroupName -SizeLimit 0

and got after about the 1150th result:

Get-QADGroupMember : Unknown error (0x800403fb)
At line:1 char:19
+ Get-QADGroupMember <<<< ProblemGroupName -SizeLimit 0
+ CategoryInfo : NotSpecified: (:) [Get-QADGroupMember], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershel
l.Cmdlets.GetGroupMemberCmdlet

So, time to look at the members list as plain strings:

$group = Get-QADGroup ProblemGroupName

$group.members
(listed a whole bunch of distinguished names without complaint)

$group.members.count

1165

Ok, so a few more than were being displayed in the GUI.

I skimmed the list until this jumped out:

CN={17656956-4661-41ad-b4dd-0a1d4ff4fccf},CN=Application Contacts,CN=RTC Service,CN=Services,CN=Configuration,DC=root,DC=hld

root.hld is our infrastructure domain, and regular users should not have anything to do with it.

RTC Service is put in the Configuration container when you first install Lync Server, and the creation date of this object aligned pretty well with when we started our Lync deployment.

So, I removed the offending object from the group:

Remove-QADGroupMember -Member 'CN={17656956-4661-41ad-b4dd-0a1d4ff4fccf},CN=Application Contacts,CN=RTC Service,CN=Services,CN=Configuration,DC=root,DC=hld' -Identity ProblemGroupName

And when I redid Get-QADGroupMember ProblemGroupName … no problem 🙂

To make sure the problem object was no longer a group member:

(Get-QADGroup ProblemGroupName).members.count

1164

The help desk tech who referred the problem to me was able to add and remove users without issues, and will be calling the user to close the ticket.

How to Change the Attributes Get-QADUser Returns

Get-QADUser | where {$_.edsaAccountIsDisabled -eq $false} will usually result in disappointment. Why? edsaAccountIsDisabled is a calculated ActiveRoles Server attribute derived from userAccountControl and is not part of the default return set, along with most of the other AD and ARS attributes.

FatBeard wrote a great explanation of this a few years ago in his article, “Where’s my attribute?” He then shows you how to add a single attribute to the default return set. FatBeard’s blog is full of all sorts of PowerShell goodness; unfortunately, he’s not updated it in quite awhile. Go there and tell him to write more posts 🙂

If you want to add more than one attribute, here’s how:


# please note that employeeNumber and homeMDB
# might not be present in your environment.
# edsaAccountIsDisabled is ARS-only.

$attributes = Get-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject
$attributes += @("edsaAccountIsDisabled","employeeNumber","homeMDB","homeDirectory","homeDrive","msRTCSIP-PrimaryUserAddress")
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $attributes

As FatBeard mentions, this change will only be in effect for the rest of your current session, and if this is an attribute set you want to usually have around, you need to add those limes to your PowerShell profile, after Get-PSSnapIn quest.activeroles.admanagement.

So why not add a whole ton of attributes to the default return set, just so they’re handy? Each attribute you want to pull increases the amount of time it takes AD or ARS to return your results and increases the size of the result set.

Another caveat: once you change the default return set within a session, you cannot go back to the original default return set without opening up a new PowerShell session – unless you saved the “default” default return set before changing it.

Idea: have several return sets available in your profile, oriented around various tasks. For mail, pull more of the Exchange attributes, both msExch-* and edsva-MsExch*. For Lync, the msrtcsip-* attributes. For tracking down a Deprovision/Undeprovision issue, the edsvadepro* and edsvaundepro* sets.

Because I don’t like having to restart PowerGUI in the middle of things, here are the Set-QADPSSnapInSettings related lines from my PowerShell profile:


# Making sure the PSSnapIn for QADMS is loaded

if ( (Get-PSSnapin -Name quest.activeroles.admanagement -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin quest.activeroles.admanagement
}

# Connect to ARS; if connecting to native AD domain,
# Connect-QADService -Service my.domain.com

Connect-QADService -Proxy

$defaultQADuserattributes = Get-QADPSSnapInSettings -DefaultOutputPropertiesForUserObject

#Extra attributes I ALWAYS want to load -
#please note that employeeNumber and homeMDB
# might not be present in your environment.
# edsaAccountIsDisabled is ARS-only.
$defaultQADuserattributes += @("edsaAccountIsDisabled","employeeNumber","homeMDB","homeDirectory","homeDrive")
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $defaultQADuserattributes

# edsva = ARS-only
function Use-QADExchangeUserAttributes {
$attributes = Get-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject
$attributes += @("edsva-msexch-mailboxtypedescription","edsva-msexch-mailboxtypedescription","edsva-msexch-protocolsettings-activesync-enable")
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $attributes
}

function Use-QADLyncUserAttributes {
$attributes = Get-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject
$attributes += @("msrtcsip-line","msrtcsip-internetaccessenabled","msrtcsip-federationenabled","msRTCSIP-UserPolicy")
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $attributes
}

# ARS-only
function Use-QADDeprovisionUserAttributes {
$attributes = Get-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject
$attributes += @("edsvaDeprovisionCommands","edsvaDeprovisionDeletionDate","edsvaDeprovisionReportXML","edsvaDeprovisionStatus","edsvaUnDeprovisionCommand","edsvaUnDeprovisionReportXML","edsvaUnDeprovisionStatus")
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $attributes
}

function Use-QADDefaultUserAttributes {
Set-QADPSSnapInSettings -DefaultOutputPropertiesForUserObject $defaultQADuserattributes
}

Note that if I do Use-QADExchangeUserAttributes and then Use-QADLyncUserAttributes without a Use-QADDefaultUserAttributes in between, I’ll get both extra sets of attributes added to the return set.

Have a nice attribute set you’d like to share? Done something clever for working with groups? Post it, or a link to your blog, in the comments!

The publicDelegates AD Attribute: Change GrantSendOnBehalfTo the ARS Way

While the Active Directory object’s publicDelegates attribute matched the contents of (Get-Mailbox “aliasGoesHere”).GrantSendOnBehalfTo for all the resource mailboxes and distribution groups I checked, I hesitated to give the way of modifying publicDelegates directly with ARS instead of using Set-Mailbox -GrantSendOnBehalfTo with Exchange Management Shell in my previous post on this topic. A little more research (and trial and error) shows that indeed, publicDelegates really is what Exchange uses to decide who gets to send stuff on behalf of another mailbox.

Here is a thread from the [ActiveDir] listserv archive in which Joe Richards, an author of the classic O’Reilly Active Directory reference, states that “[t]he stuff in AD is strictly how Send On Behalf is controlled” and goes on to explain how an update bug in Exchange 2003 might prevent a recent change from being propogated to a user in a different domain from the delegated object. Since the conversation took place before Exchange 2007 was on the scene, I was a bit skeptical about its applicability to Exchange 2010.

To see which one of several dozen edsva-MsExch-blahblahblah attributes does this for the ARS connector to Exchange 2010, I used the ARS web interface to add and remove delegates from the “Send on Behalf” list of one of the test room mailboxes (Exchange Properties -> Delivery Options -> (Send on behalf) “Add”), then looked at the Change History for that room mailbox. The publicDelegates attribute was the only item changed. Still, I was concerned: the publicDelegatesBL for the delegates outside the domain of the room mailbox weren’t getting updated.

For comparison, I added some delegates the Exchange way:

Set-Mailbox “Room Name” -GrandSendOnBehalfTo @{add=”username”}

Then the Quest AD Management Shell way:

Set-QADUser -ObjectAttributes @{publicDelegates=@{append=(Get-QADUser username).DN}}

(trying to append the username directly didn’t work; it wants the distinguishedName)

After some more experimentation, I discovered that when a user in an different domain is added to the publicDelegates attribute, the delegated object will not show up in the user’s publicDelegatesBL, whether you use Exchange, Quest AD Management Shell or the ARS web interface, while the change to publicDelegatesBL occurs immediately for delegates within the domain of the delegated object. Cross-domain delegated objects will only show up in a user’s publicDelegatesBL once that user has connected to the object for the first time.

If anyone knows why this is, what trouble it might cause, or better yet, how to fix it, please post a comment. More importantly, if anyone knows of a reason NOT to use publicDelegates instead of GrandSendOnBehalfTo, please let me know. And let the ActiveRoles Server dev team know 🙂

Fun fact about the CalendarProcessing ResourceDelegates attribute: it is equal to a resource mailbox’s GrantSendOnBehalfTo, which is controlled by the AD attribute publicDelegates.

Next step: figuring out how to control the other CalendarProcessing attributes via ARS.

Goal: Complete management of resource mailboxes via ARS.

Post-Migration Deprovision and UnDeprovision Inconsistencies – Solved!

After a few rounds of email with Quest (Dell) support about our somewhat-successful management history migration, I found out that edsvaDeprovisionStatus and its sister edsvaUnDeprovisionStatus are stored in Change History, not Management History, and therefore are not moved by the Management History Migration Wizard. The helpful support engineer, Jose, suggested I try writing edsvaDeprovisionStatus directly. Since I couldn’t write to edsvaDeprovisionReportXml, I assumed that edsvaDeprovisionStatus and edsvaUnDeprovisionStatus were also unwritable. I was wrong.

If we had done this Management History migration in a more timely manner, I could have used Steps 6 and 9 of Matt Hitchcock’s migration process. If I’d paid a bit more attention to those steps, I might have given fiddling with those attributes manually a try earlier.

Since we ran split for over a year, I would do the following to avoid crushing subsequent changes that were made in 6.7 by simply copying over deprovision status from 6.5:

1) Find objects with dubious deprovisioning status in 6.7 and store them in lists.


Get-QADUser -Disabled -SearchAttributes @{DisplayName="Deprovisioned*";edsvaDeprovisionStatus=''} -IncludedProperties edsvaDeprovisionStatus, edsvaUnDeprovisionStatus, edsvaDeprovisionReportXml -SizeLimit 0 | Where { $_.edsvaDeprovisionReportXml -ne $null } | select name, edsvaDeprovisionStatus, edsvaUnDeprovisionStatus | export-csv C:\Temp\Deprovision-Problems.csv -notypeinformation

A lot of objects were “manually” undeprovisioned – enabled, attributes changed, but edsvaDeprovisionStatus was not changed. For reasons unknown to me, the -Enabled flag does not play nice with -SearchAttributes @{edsvaDeprovisionStatus=1}, and the calculated attribute edsaAccountIsDisabled is not searchable server-side. Icky.


Get-QADUser -SearchAttributes @{edsvaDeprovisionStatus=1} -SizeLimit 0 -IncludedProperties edsvaDeprovisionStatus, edsvaUnDeprovisionStatus, edsaAccountIsDisabled | where {$_.edsaAccountIsDisabled -eq $false} | select name, displayName, edsvaDeprovisionStatus, edsvaUnDeprovisionStatus | Export-Csv -NoTypeInformation -Path U:\Temp\UndeprovisionProblems.csv

2) Using those lists, get their edsvaDeprovisionStatus and edsvaUnDeprovisionStatus from 6.5.
3) Write the edsvaDeprovisionStatus and edsvaUnDeprovisionStatus from 6.5 into 6.7, then try deprovisioning/undeprovisioning my test objects.

Continue reading