Digging into the power behind SCCM has been quite eye opening. There are plenty of opportunities to combine SCCM’s inherent functionality to make life in the IT world a much better place to live. Having recently worked on an issue with IIS, and having utilized the functionality of the appcmd.exe command for backup/restore, I thought it time to see if I could use SCCM to automate this process.
NOTE: For more information, refer to the post on how to backup and restore IIS with Appcmd.exe at IIS.NET Blogs.
NOTE #2: Yes, I know IIS creates automatic backups as the configuration changes, but you know sometimes late nights and panic modes set in and folks blow straight through those 10 historical configuration change backups….
Setting up an IIS Collection:
I created a limiting collection for Windows 2008 servers and Windows 2012 servers (the only servers in my environment that would have a compatible version of IIS installed). This collection was limited to “All Systems.” The membership was determined by the following two query rules (be sure to remove spaces where appropriate – I had to add some for post formatting):
select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType, SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier, SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.OperatingSystemNameandVersion like “%Server 6.1%”
select SMS_R_System.ResourceId, SMS_R_System.ResourceType, SMS_R_System.Name, SMS_R_System.SMSUniqueIdentifier, SMS_R_System.ResourceDomainORWorkgroup, SMS_R_System.Client from SMS_R_System where SMS_R_System.OperatingSystemNameandVersion like “%Server 6.2%”
I then created a Collection (IIS Web Servers – Version 7.0 and higher) limited this collection to the above collection (Windows 2008 and 2012 servers). The two queries I used for membership to this collection was as follows (note, we don’t use NNTP or SMTP on IIS for any of the servers I wanted to back up):
World Wide Web Publishing Service:
select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name, SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup, SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_SERVICE on SMS_G_System_SERVICE.ResourceID = SMS_R_System.ResourceId where SMS_G_System_SERVICE.Name = “W3SVC” and SMS_G_System_SERVICE.StartMode = “Auto”
select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name, SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup, SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_SERVICE on SMS_G_System_SERVICE.ResourceID = SMS_R_System.ResourceId where SMS_G_System_SERVICE.Name = “Msftpsvc” and SMS_G_System_SERVICE.StartMode = “Auto”
Give it some time for SCCM to update collection memberships and you should have these collections populated according to your update schedule.
Setting up Compliance Items:
Suffice to say there are numerous blog posts out on the web covering “How to set up Compliance Items and Configuration Baselines.” I’ll spare you the details from that and get to the meat of this post. I set up the following details about my configuration item:
- Supported Platforms: Selected “All Windows 2008 R2” and “All Windows Server 2012” as I don’t have any Non-R2 Windows 2008 machines.
- I configured the “Setting Type” as “Script,” and configured the “Data Type” as “Boolean.”
DISCOVERY SCRIPT (Powershell Script):
I used the following script to determine compliance. Basically, I’m testing that a scheduled task named “Backup-IIS-Config” exists and is enabled. If that task exists, the script returns the boolean value “true.”
NOTE: I had to invoke the COM object for scheduled tasks, as running “schtasks /query” causes the script to return with non-zero return code if the task doesn’t exist. A non-zero return code for the discovery script causes the Compliance Item to return a weird error and halt compliance discovery.
REMEDIATION SCRIPT (Powershell):
In the remediation script, I first delete a pre-existing “Backup-IIS-Config” scheduled task if it exists. I then recreate the scheduled task and initiate a first-run of the scheduled task to create a backup of the IIS configuration.
NOTE: I’m basically making the assumption that if my compliance script has found the task disabled, I should re-create it.
For the Compliance Rule, I configured the return value from the script to be true and also checked the box to run the remediation script when the device was non-compliant.
Publishing the Configuration Baseline:
I created a new configuration baseline for “IIS Servers” and added the Configuration Item created in the previous steps to the baseline. I then deployed that new baseline against my IIS Server collection (“IIS Web Servers – Version 7.0 and higher”) with the option to remediate non-compliant items. As I configured this in a test lab, I also checked the option to remediate regardless of maintenance window.
NOTE: I’ll state the obvious here and mention that YOU should opt to automatically remediate non-compliant items ONLY after thorough testing, management approval, and ONLY if you can do it while still maintaining compliance with any Service Management or Regulatory rules… and other legal mumbo jumbo…. basically… don’t complain to me if YOU create a RGE (resume-generating-event)!!!
Using your Newly Created IIS Backups:
So what happens when someone has made a horrendously bad change to one of your IIS web servers? Perhaps noone can log-in to a website, or perhaps an application pool just won’t seem to start. Maybe someone corrupted the ApplicationHost.config for the web server. No worries, you have your automated weekly backup.
To Restore the Backup:
First, you need to use appcmd to restore the backup you’re creating on a weekly basis:
Then you simply restart your IIS Services.