Bill Long's Exchange Blog

Exchange Server stuff, focusing on Public Folders, PFDAVAdmin, ExFolders, and Powershell scripting.

Removing Unresolved SIDs in Exchange 2010

Removing Unresolved SIDs in Exchange 2010

  • Comments 20
  • Likes

In this post, I'm going to describe how to remove unresolved SIDs from public folders in Exchange 2010. But first, let’s talk about what they are and why we care about them.

What are unresolved SIDs?

When you view the permissions on a file in Windows or an object in Active Directory, you get a nice friendly list of names, each one with its associated access rights displayed. However, the security descriptor does not actually contain the names of the users – it only contains their SIDs. When an application such as Explorer or ADUC displays the permissions, it attempts to resolve each SID to a name, so when you look at it you can make some sense of what you’re seeing.

An unresolved SID is a SID that no longer resolves, usually because the user has been deleted. If you look at an object in ADUC, it looks like this:

sec1

In Exchange, folders have security descriptors that are very similar to the ones in Windows, except that things are ordered differently. But you still have SIDs and rights, and when a SID doesn’t resolve anymore, you’ll see that in Outlook:

sec2

Why do we care about them?

Unresolved SIDs don’t cause a problem; they just look ugly. Some customers want to remove them for that reason alone, and some customers have other reasons. A lot of customers used PFDAVAdmin for this, but there was a specific reason PFDAVAdmin removed these.

Back in Exchange 2000 and Exchange 2003, it was possible to expose the Information Store database as a drive in Windows. This was the infamous M: drive. It became infamous because applications that were not Exchange-aware would access folders through the M: drive and mess up the permissions. Above, I briefly mentioned that things are ordered differently in an Exchange ACL than a Windows ACL. Applications that looked at the folders in M: and thought they were plain old Windows folders would reorder the stuff in the security descriptor to fit the Windows format. This meant it no longer matched the Exchange canonical format, and the permissions wouldn’t work as expected.

After an application had run through the M: drive and made all the ACLs non-canonical, it was a huge pain to go through and manually correct them. This was one of the main reasons I wrote the PFDAVAdmin tool. PFDAVAdmin provided an easy way to put all the ACLs back in canonical order.

One thing about Exchange canonical order is that the SIDs need to go in a particular order based on the object type. Users need to be at the top of the ACL, followed by groups. If you’re trying to reorder the ACL to make it canonical again, and you run into an unresolved SID, this presents a problem. Since you can’t resolve the SID, you don’t know what type of object it is, so where should it go?

There are a few ways you could approach this problem. For instance, you could just pretend it’s a user SID. If the object has been deleted, then the SID will never again resolve, so it won’t matter. If the SID is only unresolvable because of a temporary issue with a DC or something, then this could result in the ACL becoming non-canonical once the SID resolves again.

However, the approach I took with PFDAVAdmin was to have it remove the unresolved SIDs. I couldn’t be sure what they were and why they were unresolvable, and the whole point was to force the ACL into a canonical state, so this seemed like a sensible approach.

Why doesn’t ExFolders remove them?

When I rewrote the guts of PFDAVAdmin for Exchange 2010, I renamed it ExFolders. While the GUI looks almost identical, the code underneath is not the same and required a lot of rewriting. When it came time to look at the “Fix Folder DACL” code and decide whether to move it into ExFolders, I just didn’t see any need for it. The widespread non-canonical ACL issues from the Exchange 2000/2003 days were gone, so I left this functionality out of ExFolders entirely. Unresolved SID removal was a side-effect of fixing the DACL, so it likewise fell by the wayside.

How can I remove them now?

OK, so you want to remove them from your public folders in Exchange 2010, but there’s no tool to do that anymore. Fortunately, it’s easy to remove them with a simple script. I’ve included one below. This script will be far slower than PFDAVAdmin was, but it will get the job done.

If you run it with the following syntax, it will only report the unresolved SIDs:

.\Check-UnresolvedSIDs.ps1 -Server MyPFServer

If you want it to actually remove them, you must add the –Remove parameter:

.\Check-UnresolvedSIDs.ps1 -Server MyPFServer -Remove $true

The output will look something like this:

\Folder1: Checking folder
\Folder2: Checking folder
\Folder2 has unresolved SIDs:
     NT User:S-1-5-21-1016452943-3003584382-490080582-2161
\Folder3: Checking folder
\MyNewFolder: Checking folder
\SomeOtherFolder: Checking folder
\SomeOtherFolder has unresolved SIDs:
     NT User:S-1-5-21-1016452943-3003584382-490080582-1136
     NT User:S-1-5-21-1016452943-3003584382-490080582-1135

If you add the –Remove parameter, it will also tell you that it’s removing them.

Here’s the script. Enjoy!

# Check-UnresolvedSIDs.ps1
#
# This script will remove all unresolved SIDs from public folder permissions.
# This will take quite some time to run against a large hierarchy.

param([string]$Server, [bool]$Remove)

if ([System.String]::IsNullOrEmpty($Server))
{
    "You must specify a server."
    return
}

function CheckUnresolvedForFolder($folder)
{
    ($folder.Identity.ToString() + ": Checking folder")
    $unresolved = Get-PublicFolderClientPermission -Identity $folder -Server $Server| WHERE { $_.User -like "NT User:S-*" }
    if ($unresolved -ne $null)
    {
        ($folder.Identity.ToString() + " has unresolved SIDs:")
        foreach ($item in $unresolved)
        {
            ("     " + $item.User.ToString())
        }

        if ($Remove)
        {
            ("     Removing the unresolved SIDs...")
            foreach ($item in $unresolved)
            {
                $item | Remove-PublicFolderClientPermission -Identity $folder -Server $Server -Confirm:$false
            }
            ("     Unresolved SIDs were removed.")
        }
    }
}

function DoFolderRecursive($folder)
{
    CheckUnresolvedForFolder($folder)
    $subfolders = Get-PublicFolder -Identity $folder -GetChildren
    if ($subfolders -ne $null)
    {
        foreach ($subfolder in $subfolders)
        {
            DoFolderRecursive($subfolder)
        }
    }
}

$ipmSubtree = Get-PublicFolder "\" -Server $Server
DoFolderRecursive($ipmSubtree)
$nonIpmSubtree = Get-PublicFolder "\NON_IPM_SUBTREE" -Server $Server
DoFolderRecursive($nonIpmSubtree)

"Done!"

Comments
  • why don't you use this?

    $ipmSubtree = Get-PublicFolder "\" -Server $Server -Recurse -Resultsize unlimited

    Btw. the -ResultSize parameter is necessary if this should work in unknown environments.

  • You could do it that way. However, I like to avoid building massive result sets like that when I can, because it is harder on the server in larger environments. Remember, the server is going to hold all that info in memory until the script is done iterating over the folders. That's why this script only enumerates one level at a time.

    In most environments it's not a big deal, but I've seen environments with staggering numbers of public folders. :)

  • As a admin in a Hosted environment, I was very disturbed to see that this feature was gone from ExFolders. We use that option many many times as new customers migrate with existing PF data numerous times a week and want the SIDs gone.

    The script is a viable workaround although when you have 100K PF folders (1.5TB+ of data)  it could take forever and ever to finish especially since PF cmdlets are already slow. So for us, we would have to tweak the script to start at the top of customer1's PF structure to get results sooner than days later :)

    So please add it back to ExFolders for us in the Hosting world, we will send you the biggest cookie we can find.

  • Thanks for the feedback, DJ. I'll keep this on my radar for when I have more time to work on ExFolders.

  • Hi Bill - nice script, however I've noticed that SIDs are not removed if the permission level is set to "None".

    Is there a way to get around this you've found?

    Regards

    Matt

  • Hi Bill,

    is this working for exchange 2007 public folders too?

  • Hi Matt, somehow I missed your comment. I would have responded earlier. It certainly should remove entities that have a role of "None". However, keep in mind that Default and Anonymous should always appear in the ACL, so even if you clear the permissions, those will still be there, and will appear with "None". Were you talking about those, or actual users?

    Hi Max, yes you can use this with an Exchange 2007 server as the target server. However, ExFolders itself must be executed from an Exchange 2010 server.

  • Hey Bill why do i need to specify the server?  I have mutiple copies of PF running accross different MBX servers. WIll doing this on just one server handle them all, or do i need to run this on each server? Thanks!

  • Each PF database has a copy of the hierarchy. The hierarchy contains the security descriptor of the folder, and changes to the security descriptor on one copy of the hierarchy will replicate to all the other copies.

    You need to specify a server just to tell the script which copy to use to make the changes. Once those changes are made, they will replicate to the other servers, typically within 15 minutes.

  • Excellent my friend. No more 2028 errors!

  • Sadly, I too am having the same problem Matt has. If the permission level is none, the script says it removes them, but doesn't.

  • I tested the script against Exchange 2013 and had to modify it to use -Mailbox in place of -Server and it appears to work. Be sure you specify the mailbox that contains the primary hierarchy.

  • Nice! Thanks Jeremy. I'm also considering adding this functionality to a new MAPI-based tool, which would be much faster.

  • Also I had to remove –mailbox $mailbox from the following line to get it to remove permissions.
    $item | Remove-PublicFolderClientPermission -Identity $folder -mailbox $mailbox -Confirm:$false

  • The script has the same requirement as MAPIFolders, to change permissions the public folder/s must reside in the mailbox that is the primary hierarchy. This has created issues with one of our customers in that you have to exit Outlook after the public folders are moved or you cannot mark multiple items or an entire folder as read. I am seeing unresolved SIDS as NT:S- instead of NT User:S-.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment