Jan 24, 2013 10:17:31 AM
FIM: When products don’t play nice together...

As a consultant, one of the primary responsibilities is to deal with strange problems or issues that arise. And inevitably some obscure issue will come to the surface during a demo… Since I specialize in Microsoft’s Forefront Identity Manager combined with a previous life as a Windows Server Engineer, I run a fairly comprehensive virtual development and demo lab with about every mainstream Microsoft Server product deployed across an average of 80 virtual servers. Given the right set of circumstances you’ll find products that just don’t play nice together.

After my failed SSPR password reset demo, I went through the standard troubleshooting check list including configuration verification. The first thing I found awry was permissions missing for the FIM Service account on WMI's Root/CIMV2 namespace. Since this was a functioning SSPR environment, I know they had been set previously. In addition, the Root/MicrosoftIdentityIntegrationServer namespace was missing from the tree too. My schedule allowed enough time to repair the issue but not fully perform a Root Cause Analysis to the situation.

Fast forward a few more days and I’m now facing issues while making FIM WMI calls to a different FIM environment altogether. I immediately took a look at the WMI namespace to find the same issues as before. To assist with my current projects and personal curiosity, I currently have 4 different FIM environments built out, R1 or R2, all-in-one to scaled out implementations. Looking at the additional environments, they too were all faced with the same missing WMI issues. This includes the server I had just repaired days ago.

So now it’s time to get down to the root of the problem. If you have ever executed the How to register the FIM WMI Provider process as outlined on Microsoft’s TechNet, one of the things you will notice is the warning with regards to the #PARGMA AUTORECOVER. With that in mind, this led me to the conclusion that something was causing a rebuild on the WMI configuration for these servers. Combine that with an excessive amount of event logging with regards to daily SCCM client re-installs and WMI errors, I turned my focus to searching out an SCCM related issue. That’s when I came across KB2796086 titled “Configuration Manager Management Points collocated with clients fail after installing Windows Management Framework 3.0 and running Client Health Evaluation."

As I stated in the beginning, you sometimes find products that don’t play well together. In my lab environment I tend to install everything everywhere including SCCM clients on all servers and all Windows Updates as they are released, thus providing the perfect storm for FIM, SCCM 2012 and WMF 3.0. Fortunately the KB article outlines a registry setting to produce a warning vs. rebuilding the WMI every time, which I can verify has solved my various FIM WMI issues. Additionally the KB article states SCCM SP1 will fix the compatibility issues between SCCM and WMF.

Errors you might see to help identify the issue:

  • SSPR produces client side error: "PWReset activity returned status code PWUnrecoverableError" upon submission of the new password.
  • PowerShell scripting error: "get-wmiobject: Invalid namespace root\MicrosoftIdentityIntegrationServer"

One positive thing to come out of this is a single source of repair instructions based on a combination of previously documents processes and an additional PowerShell script to set permissions on Root/MicrosoftIdentityIntegrationServer.

[sourcecode language="powershell"]
PARAM(
$Principals = $(throw "`nMissing -Principals ('DOMAIN\FIMSyncAdmins','DOMAIN\FIMSyncBrowse','DOMAIN\FIMSyncOperators','DOMAIN\FIMSyncPasswordSet')"),
$Computers = $(throw "`nMissing -Computers ('fimnode01','fimnode02')"))

# USAGE:
#
# .\Set-FIM-WMI.ps1 -Principal ('<FIM admin group>','<FIM browse group>','<FIM operators group>','<FIM password group>') -Computers ('<server1>', '<server2>',...)
#
# EXAMPLE:
# .\Set-FIM-WMI.ps1 -Principal ('DOMAIN\FIMSyncAdmins','DOMAIN\FIMSyncBrowse','DOMAIN\FIMSyncOperators','DOMAIN\FIMSyncPasswordSet') -Computers ('fimsyncprimary', 'fimsyncstandby')
#
# Inspired by Brad Turner's post:
# http://social.technet.microsoft.com/wiki/contents/articles/2261.how-to-use-powershell-to-set-wmi-permissions-for-fim-self-service-password-reset-en-us.aspx
# Which was inspired by Karl Mitschke's post:
# http://unlockpowershell.wordpress.com/2009/11/20/script-remote-dcom-wmi-access-for-a-domain-user/

Write-Host "Set-MIIS-WMI - Updates WMI Permissions for MicrosoftIdentityIntegrationServer object"
Write-Host "`tWritten by Terry Phillips (terry.phillips@css-security.com)"
Write-Host "`tBlog: http://www.css-security.com/category/blog/"

function get-sid
{
PARAM ($DSIdentity)
$ID = new-object System.Security.Principal.NTAccount($DSIdentity)
return $ID.Translate( [System.Security.Principal.SecurityIdentifier] ).toString()
}

foreach ($strprincipal in $Principals)
{
$sid = get-sid $strprincipal

#WMI Permission - Execute Methods, Provider Write, Enable Account, Remote Enable for This namespace only
$WMISDDL = "A;;CCDCRPWP;;;$sid"

#PartialMatch
$WMISDDLPartialMatch = "A;;w+;;;$sid"

foreach ($strcomputer in $computers)
{
write-host "`nWorking on $strcomputer adding $strprincipal..."
$security = Get-WmiObject -ComputerName $strcomputer -Namespace root/MicrosoftIdentityIntegrationServer -Class __SystemSecurity
$binarySD = @($null)
$result = $security.PsBase.InvokeMethod("GetSD",$binarySD)

# Convert the current permissions to SDDL
write-host "`tConverting current permissions to SDDL format..."
$converter = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper
$CurrentWMISDDL = $converter.BinarySDToSDDL($binarySD[0])

# Build the new permissions
write-host "`tBuilding the new permissions..."
if (($CurrentWMISDDL.SDDL -match $WMISDDLPartialMatch) -and ($CurrentWMISDDL.SDDL -notmatch $WMISDDL))
{
write-host "`tperforming SID Update"
}
else
{
$NewWMISDDL = $CurrentWMISDDL.SDDL + "(" + $WMISDDL + ")"
}

# Convert SDDL back to Binary
write-host "`tConverting SDDL back into binary form..."
$WMIbinarySD = $converter.SDDLToBinarySD($NewWMISDDL)
$WMIconvertedPermissions = ,$WMIbinarySD.BinarySD

# Apply the changes
write-host "`tApplying changes..."
if ($CurrentWMISDDL.SDDL -match $WMISDDL)
{
write-host "`tCurrent WMI Permissions matches desired value."
}
else
{
$result = $security.PsBase.InvokeMethod("SetSD",$WMIconvertedPermissions)
if($result='0'){write-host "`tApplied WMI Security complete."}
}
}
}
[/sourcecode]

With all things FIM/WMI related fixed, that leaves me to wonder how many other installed products had their WMI configs "rinsed clean" in the storm? And as a reminder: Always check everything in your demo environment the day before...