Monday, March 3, 2014

Dastardly Dissections: Recipe for Cooking a Web-Based SCCM "ReRun Advertisement" Tool

If you are familiar with Microsoft System Center Configuration Manager, you've probably heard of the infamous "Right-Click Tools".  Maybe the "Client Center" as well.  There are quite a few such add-on or enhancement applications out there ranging from MMC extensions to HTA scripts to Powershell cmdlets and so on.  The IT world is increasingly becoming a big Lego kit.  Let's rummage through some bins and build something!

This post is just a slightly different spin on the typical "how-to" article concept, and comes with a slight twist:  I'm not giving the code away.  I find it more fun to follow a treasure map and find the goodies at the end.  So I will guide you through the process and you can connect the dots.  If you're half-way decent at scripting and know how to make a table in a database you should be fine.  If not, there are plenty of web sites you can scour to get help.

It's sleeting and snowing outside today and will continue through the night.  Yesterday, it was 68 F and I was on a bike ride in shorts and a t-shirt.  I still have a light sunburn to remind me it wasn't a dream.  After a glass of wine I'm ready to get all verbose on yo ass, so you've been warned.  Enjoy. :)

Since most of Configuration Manager is accessible, and manageable, from "under-the-hood" using command-line and API features, it makes it really nice to build a "kit" to suit your own needs.  This is just one such "kit".  Apologies for the "icky-looking" formatting, but Google seems to have put Blogger on hold while it focuses on Drive updates.  Hopefully they'll come around to improving Blogger editing tools soon.

The Goal

To be able to run a Configuration Manager Advertisement on a remote computer at-will, using a web browser as the interface.  This makes it possible access and use the capability from anywhere you have access to a web browser and sufficient permissions to invoke the process.  More on that last part later.  The benefits are slim, but include not having to install anything on any computer where you wish to leverage this feature.  You can remote in from home and use it.  Open it on your phone or tablet, and use it, and so on.

The Ingredients

  • System Center Configuration Manager 2007 or 2012
  • An Active Directory environment
  • A computer running Windows 7, 8.x, Server 2008 R2 or Server 2012 (or higher)
  • A database (preferably SQL Server, but SQL Express will just fine)
  • A little scripting
  • A little time and coffee

The Process

The way a "re-run" request works is actually a bit odd, but it makes senses once you think it through. Basically, an Advertisement has properties you can configure regarding re-run behavior, but they can be overridden in certain situations.  In short, you capture the current "rerunBehavior" setting, replace it with "always" (as in always let it be re-run), run it again, and then set it back to the original setting.

This requires you to have an account within the SCCM environment (site) that allows you to create and/or modify Advertisements and their settings.  If not, stop right here and take care of that or switch into a lab environment where you have more control over things. Actually, I should say here: Do this in a lab or "non-production" environment before you try it in the real production environment.  Okay, back to the cooking show...

The Building Blocks - Part 1: The Database Side

  1. Create a new Database and create a Table inside of it.  I chose the name "SCCMTools" for the database name, and "ClientActions" for the table name.  If you already have a database to play with (hopefully SQL Server or SQL Server Express), you can simply add a new table (see step 2)
  2. The Table should have some basic fields.  I've suggested a few below:
    • ID (to identify the unique row.  I prefer making this an Integer value, and assigning it as the primary key and also making it a Identity(1,1) setting, akin to the old MS-Access "autonumber" fields. This should be NOT NULL of course)
    • ComputerName (to identify the computer on which the advertisement will be launched.  This can be a Varchar or nVarchar data type, but only has to be as long as your longest client computer name.  Generally, the default of 50 is fine.  This should be NOT NULL)
    • AdvID (to identify the Configuration Manager Advertisement ID.  This can also be a Varchar or nVarchar value and should be NOT NULL.  The length is always going to be less than 12 chars due to the format of Site Code + 5 chars = 8 but you never know)
    • DateAdded (to record when you submitted the request.  This should be a SmallDateTime value, but that's up to you.  NOT NULL also)
    • AddedBy (to record who added it; in case you share this with others. In most cases this will contain a user account name (aka sAMAccountName value). This is an optional field, but should be Varchar or nVarchar and NOT NULL if you're going to use it at all).
    • ResultCode (to record the exit code or result value from your attempt to re-run the Advertisement on each computer.  This should be NULL and could be an Integer value).
    • DateProcessed (to record when the request was actually completed.  Since this won't contain a value until the request is processed, this can be left as a NULL column)
  3. You can add other columns/fields as you prefer.  The list above is only a suggestion, not a mandatory requirement or anything.  Some other columns you might consider include "Comment", or "Site" or "Group" or whatever.  Be creative, but be careful to not over-complicate it too soon as well.
  4. Grant permissions to the Database and the Table for access by whomever you will allow to use it.  That same account will be used for setting up the web interface later on.  You can (and probably should) use a Security Group instead of an individual user, or you could use a SQL user account and secure password, but that's entirely up to you.  Regardless, the account, group or role assignment you use should have rights to the table for select, insert, delete and update.
  5. After step 4 I strongly recommend you test the connectivity by using a small script.  First, shove some sample data into the table, it doesn't matter what as long as it makes sense.  Then use the script to run a "select * from whatever" query and see if you get anything back.  Make sure you consider the security "context" under which the script is running, as well as whether you employ internal credentials within the script itself.  I hope that makes sense.  If not, drink up and it'll either make sense or you'll pass out and forget what the question was.
As a sample, assuming your SCCM Site code is "ABC" and the remote computer which has already run a given advertisement is named "12345DT", your table row might look like this:

ID: 1
ComputerName: 12345DT
AdvID: ABC0012D
DateAdded: 2014-03-03 20:07:01AddedBy:  dstein
DateProcessed: (NULL)

Part 2 - The Electric Web Side Boogaloo

This is where you put some rubber to the electronic pavement.  You can build this with whatever web platform/language/toolkit you prefer.  The only basic needs are that it must support interfacing with the database and the Configuration Manager site Management Point server via WMI/SWBEM scripting.  If you are comfortable with .NET and use the framework tools to connect and interact that, have a blast.  It doesn't matter as long as it works for you.

I would recommend Visual Studio Web Express, or Visual Studio (full-blown) if you have access to it.  However, if Java, PHP or Ruby is your thing, go for it.

The web code is simple and all it really needs to provide is few files/pages as follows:
  • A "home" page of some sort (so you can put a picture of your cat or dog and a spiffy looking logo thing), and include links to...
  • A list / table report that shows current table entries.  This is important to see what has already been completed and what is still waiting to be run.
  • A "new request" form for submitting, well, a new request.  It should include a box (or even better: a drop-down list) to specify the target computer (or computers), as well as a box (or still even more better: a drop-down list) to specify the Advertisement to re-run on the selected computer(s).
  • Optional pages/files for inserting the request records, or deleting pending requests (which haven't yet been processed, obviously).
  • Feel free to go nuts.  Maybe add files to truncate or clear table entries, batch update rows, etc.  It's your baby, raise however you want.

Part 3 - The 12-Cylinder Engine with NOS

Okay, that's a little excessive, but this is really where it all "happens".

This is actually a combination of two things:  A script that performs the actual operation, and a scheduled task the repeatedly checks the database for pending requests, and then runs those pending requests through the script process. The actual process is as follows, and it's not complicated, trust me:
  1. Query the database table for rows, using something like "Select * from ClientActions WHERE DateProcessed IS NULL".
  2. Loop through the recordset (do-while or do-until, etc.), and for each record grab the "ComputerName" and "AdvID" values.
  3. Pass those two values to the script, and run that script under a context which has access into both the SCCM site and the remote client desktop.  It needs local admin rights (or something suitable enough to allow it to invoke COM operations remotely) and that means you may need to tinker with firewall stuff, but you already knew that, right?  Mmmhmmm. Okay.
  4. The script connects to the remote client computer, does it's thing, and if the exit code (return/result value) is 0 (zero, or "success", etc.) update the matching table row to enter the current Date/Time into the "DateProcessed" column.
  5. Capturing the exit or result code is very important.  This is why I suggested the ResultCode" column earlier.  It allows you to capture the successes and failures as well.  If you just have a "DateProcessed" value, you can't really distinguish successes from failures.
If you need some pointers for making the script processor part, here are just a few links that I found by entering "re-run SCCM advertisement script" in a Google or Bing search:

Baking Time - 2 - 4 Hours

Okay, sooner if your brain is a microwave and you've consumed some caffeine.

Fetch a computer from your SCCM environment and get a list of the Advertisements it has already run.  Identify one of the Advertisements which can be re-run on it without causing any harm to the computer.  You might want to make a fake or shell package that just runs a script to create a log file on the client.  Something to demonstrate it was run once and that will leave a trace when it's run again afterwards.

Using the computer name and the Advertisement ID value, enter that information into your database table using your web form.  It's okay if you just directly edit the table using something like SQL Server Management Studio, or the database tools in Visual Studio.  It's just nice to test it all together if you can.

Place the script in a folder on a computer where you intend to host it for future use.  Use that computer to configure the scheduled task, along with the credentials to run the script itself, and save it.

Run the scheduled task.  This will help you verify the following:
  • The script can connect to the database and obtain records
  • The script can connect to the remote client computer
  • The script can modify the Advertisement properties for re-run behavior
  • The script can invoke the SCCM client agent actions to re-run the Advertisement
  • The script can update the matching rows in the database table to indicate completion
  • The script can do all of this under the security context by which the task scheduler is invoking it
Now, it's time for a desert.  Post a comment to let me know how this works out for you?

No comments: