Using SCCM Configuration Baselines for Automatic IIS Backup

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):

Windows 2008:  

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%”

Windows 2012:

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”

FTP Services:

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:

imageSuffice 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.

try{

    $enabled = $false

    $schedule = New-Object -ComObject "Schedule.Service"

    $schedule.Connect()

    $tasks = $schedule.GetFolder("\").GetTasks(0)

    foreach ($schtask in $tasks){

        # FIND THE BACKUP TASK

        if ($schtask.Name -eq "Backup-IIS-Config"){

            [xml]$task = schtasks /query /TN Backup-IIS-Config /XML

            # Task is there... validate it is enabled

            if ($task.Task.Triggers.CalendarTrigger.Enabled -eq "true") {

            # Calendar is enabled, validate the task is enabled

                if ($task.Task.Settings.Enabled -eq "true") {

                $enabled = $true

                } else {

                $enabled = $false

                }

            }

        }

    }

} catch {

    $enabled = $false

    $error.clear()

} finally {

    # Close COM Objects

    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null

    Remove-Variable schedule

    $enabled

}

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.

   1: try {

   2:     $schedule = New-Object -ComObject "Schedule.Service"

   3:     $schedule.Connect()

   4:     $tasks = $schedule.GetFolder("\").GetTasks(0)

   5:     foreach ($schtask in $tasks){

   6:         # FIND THE BACKUP TASK

   7:         if ($schtask.Name -eq "Backup-IIS-Config"){

   8:             $result = schtasks /delete /TN Backup-IIS-Config /F

   9:         }

  10:     }

  11: } finally {

  12:     try {

  13:         $result = schtasks /create /TN Backup-IIS-Config /SC Weekly /ST 06:00 /RU SYSTEM /TR "%windir%\system32\inetsrv\appcmd.exe add backup Weekly-IIS-Backup"

  14:         if ($result.Substring(0,7) -eq "SUCCESS"){

  15:             $enabled = $true

  16:             $result = schtasks.exe /RUN /TN Backup-IIS-Config

  17:         } else {

  18:             $enabled = $false

  19:         }

  20:     } catch {

  21:         $enabled = $false

  22:     }

  23:     $enabled

  24: }

 

imageCOMPLIANCE RULE:

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.image

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:

   1: %windir%\system32\inetsrv\appcmd.exe restore backup "Backup-IIS-Config"

Then you simply restart your IIS Services.

About Robert

An IT nerd with 10+ years of experience in almost *anything* windows (server and desktop), Citrix, Exchange, Google Apps, and WordPress. I like to dabble in just about anything IT related, and read blogs and tech books like crazy!

Find Robert on , and Twitter.

Comments

  1. I’d also like to add: Since this is scheduled as a weekly backup, and the backup is a number of flat files saved in %windir%\system32\inetsrv\backups\Backup-IIS-Config, it’s very easy to go back in time with your typical system backup software (Netbackup, DPM, etc…).

Speak Your Mind

*