Background
This is one of those posts that has been “years in the making”. I’ve been working with SMS / ConfigMgr 2007 since version 2.0. In my IT career, I’ve used SMS / ConfigMgr 2007 on the server side exclusively. Traditionally SMS / ConfigMgr has been mainly a desktop software deployment, management tool. I’ve never talked with anyone who has used ConfigMgr strictly “ in a Server environment” for other things besides patching, OSD. Using ConfigMgr for DCM, Software Distribution, Querying, reporting etc.
Problem
I recently came across a situation where I was getting inconsistent status messages being sent back to the site server. Here is the message Failed to submit event to the Status Agent. Attempting to create pending event. For those familiar with ConfigMgr, all components send their status messages through the StatusAgent component. Advertisements, task sequences would work. the status messages would not be updated however.
Side Bar
Introduced in IIS 7 was the ability to set the Anonymous Authentication module to inherit from the application pool identity automatically. Here is a screenshot of the setting.
In previous IIS versions, the IUSR account was a local account with it’s own SID (Security Identifier). The administrator had to be aware of this account along with the application pool account (App pools started in Windows 2003/IIS 6). The IUSR account was introduced in Windows Server 2008 as a ‘machine’ account with the same SID across all boxes. In IIS 6, I would set the IUSR_MachineName and application pool identity accounts the same. Although I was administering two locations, it made troubleshooting a lot easier only dealing with one account. When Windows Server 2008 came out and provided the ability to inherit the application pool identity automatically, from an IIS Administrators perspective, I quickly adopted this architecture. PS – I’m not 100% sure why inheriting Application Pool Identity isn’t the default setting, I once heard it was to support Classic ASP applications. Not sure.
Back to ConfigMgr 2007
From an IIS perspective, administrators may implement this type of architecture (I did!). What I discovered, the IUSR setting at server level is required if a machine has IIS installed. What I did to prove the ConfigMgr client was checking for the existing of the IUSR account.
- I enabled more logging on the ConfigMgr client. Here is article showing How to enable DebugLogging & Verbose logging on ConfigMgr client.
- I set the IUSR account at server level to the picture above. All sites would inherit the application pool identity
- Execute an advertisement (task sequence or advertisement)
Here is the status messages that appeared in the logs. Notice the highlighted sections, and the function being called.
ccmperf.log:<![LOG[Security::LookupIUSRAccountSid(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1484)]LOG]!><time=”00:14:21.853+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”14748″ file=”perfobject.cpp:1484″>
ccmperf.log:<![LOG[GetIISAccounts(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1559)]LOG]!><time=”00:14:21.853+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”14748″ file=”perfobject.cpp:1559″>
ccmperf.log:<![LOG[Security::LookupIUSRAccountSid(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1484)]LOG]!><time=”00:14:21.862+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”14748″ file=”perfobject.cpp:1484″>
ccmperf.log:<![LOG[GetIISAccounts(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1559)]LOG]!><time=”00:14:21.862+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”14748″ file=”perfobject.cpp:1559″>
ccmperf.log:<![LOG[Security::LookupIUSRAccountSid(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1484)]LOG]!><time=”00:14:22.678+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”13344″ file=”perfobject.cpp:1484″>
ccmperf.log:<![LOG[GetIISAccounts(sIUSRSid), HRESULT=80004005 (e:nts_sms_fresmsframeworkccmperfperfobject.cpp,1559)]LOG]!><time=”00:14:22.680+240″ date=”01-09-2022″ component=”ccmperf” context=”” type=”0″ thread=”13344″ file=”perfobject.cpp:1559″>
StatusAgent.log:<![LOG[Security::LookupIUSRAccountSid(sAccount), HRESULT=80004005 (e:nts_sms_fresmsframeworkcoreccmcorecomobjectsecurity.cpp,58)]LOG]!><time=”00:14:58.883+240″ date=”01-09-2022″ component=”StatusAgent” context=”” type=”0″ thread=”11300″ file=”comobjectsecurity.cpp:58″>
As I mentioned earlier, I work strictly in a server environment, which many boxes have IIS installed (Mostly Windows Server 2008 / R2 boxes). For some reason Microsoft has logic in SCCM to check for the existence of the IUSR account. Here is a post I did “IUSR Account and ConfigMgr 2007 R3 agent”. This explains I temporarily had to set the IUSR account enabled at server level so the ConfigMgr agent would install.
A configuration workaround
The ConfigMgr agent doesn’t seem to check for IUSR at site level. This means an administrator who has ConfigMgr installed on a server OS with IIS can enable the IUSR setting at server level, and set the inherit application pool identity at site level. From my testing, this configuration works. I did a PowerShell script to:
- Backup current applicationHost.config with appcmd
- Enable IUSR at server level
- Disable IUSR and inherit application pool identity.
- Stop / Start SMS Agent Host
- Watch the SCCM logs
A little precaution before running the script. The logic assumes you are using the application pool identity for securing resources. I’d recommend you review your IIS architecture to ensure this setup would work in your environment. I ALWAYS encourage people to try scripts in a non-production environment first. The script does make a backup copy of the applicationHost.config before making changes. If something happens, just restore the applicationHost.config.
After years of not quite understanding how IUSR was used. I thank God for helping me finally understand what is happening! I hope you find this post useful. Hope this workaround isn’t needed in CM2012. Time will tell.
Thank you,
Steve Schofield
Windows Server MVP – IIS
http://www.iislogs.com/steveschofield
http://www.IISLogs.com
Log archival solution
Install, Configure, Forget
Questions on Microsoft SMTP Service – visit http://www.smtp.ws
IIS Community Newsletter – visit http://www.iisnewsletter.com
Here is the script.
$ExitCode = 0
try
{
function EnableIUSRServerLevel
{
$Command = “$Env:SystemRootsystem32inetsrvappcmd.exe set config /section:system.webServer/security/authentication/anonymousAuthentication /userName:`”IUSR`” /commit:apphost”
Write-Host $Command
Invoke-Expression -Command $Command
}
function DisableIUSRSiteLevel([string]$SiteName)
{
$Command = “$Env:SystemRootsystem32inetsrvappcmd.exe set config `”$SiteName`” /section:system.webServer/security/authentication/anonymousAuthentication /userName:`”`” /commit:apphost”
Write-Host $Command
Invoke-Expression -Command $Command
}
#Use Powershell provider to get a list of sites, one of these will error
#windows Server 2008 needs powershell provider installed before using
#Windows Server 2008 R2 has powershll provider already
#There is some better logic that could be implemented on this option
Import-Module -Name “WebAdministration”
Add-PSSnapin -Name “WebAdministration”
#Backup ApplicationHostConfig
$FileDate = (Get-Date).tostring(‘dd-mm-yyyy-mm-hh’)
$Command = “$Env:SystemRootsystem32inetsrvappcmd.exe add backup `”BeforeSettingIUSRData$FileDate`””
Write-Host $Command
Write-Host “applicationHost.config backed up”
Invoke-Expression -Command $Command
#Set IUSR at server level
Write-Host “Set IUSR at server level enabled”
EnableIUSRServerLevel
#Get List of Sites using get-childitem
$sites = gci IIS:Sites
#Set Each site on the box with IUSR disabled
foreach($site in $sites)
{
Write-Host $site.name
Write-Host “”
DisableIUSRSiteLevel -SiteName $site.name
}
Write-Host “Done”
}
catch
{
$ExitCode = 1
Write-Host “error”
}