OS Imaging via Web Page

OSD is a powerful imaging tool but setting up systems to be imaged may require a user have access to the SCCM console.  This often means that the SCCM staff gets assigned the task of imaging.  Wouldn’t it be cool if the OSD users could setup imaging themselves without having to use the SCCM console?  Yeah, I thought so too. 

I have just completed building a sample web page that allows users to choose their own imaging scenarios.  A screenshot of the web page is below.

image[18]

Before I continue detailing the solution, the required disclaimer.  This solution is provided as a sample only. The solution is not supported and should be tested thoroughly in a lab before considering production use. There are some modifications that will need to be made (detailed below) and the improper use of this solution can result in negative effects to your environment – so make sure you know what it does before you use it!

The particular run of the web page shown here is to image a bare metal system.  It is also possible to use the page to reimage an existing system.  There are a few moving parts to make the web page work – the web page itself, pre-defined collections, a pre-configured task sequence that makes use of the settings chosen in the web page and a script that will be used in the task sequence to clean up after imaging.  Let’s go through how to set this up – starting with the web page.

The first choice in the web page is which site you want to operate against.  Once a site is chosen all further web page operation is directed against that site only.  Note that the web page makes heavy use of task sequence variables.  It is not possible to set a variable on a system that is not assigned to the current site so the choice of the correct site when starting through the web page is vital.  In my lab there are two sites to choose from – CEN and PRI.  Note that I also have a secondary site but since clients can’t assign to or be owned by secondaries there is no reason to list them here.

image

With the site chosen I need to select what type of imaging I want to do – either bare metal or a reimage.

Bare Metal

image

For the example I’ve chose bare metal.  Selecting bare metal will require you to enter a computer name and also the MAC address for the system and optionally will allow you to specify an OU for the system.  If specifying the OU it will need to be in LDAP format shown.image

In this version, the MAC address and name are required even if the bare metal system already exists in the database and will simply overwrite the data that is already there if present.  If the bare metal system to be imaged is already present in the database you could use the reimage option but would lose the ability to specify a new OU – you could still specify a new computer name.

If an OU is not specified the default of the computer container will be used during domain join.  If the imaged system will not be joined to a domain then there is no need to specify a system OU as the task sequence (covered later) will not make use of it.

Reimage

If the option to reimage is chosen the drop down list showing all known systems at the selected site activates.  Simply choose your target system from the list.  The chosen system will be looked up in active directory and it’s OU displayed for confirmation.  The OU for a system that already exists in AD cannot be changed through OSD so there is no mechanism to change it on the web page.image

Next, the image to be deployed needs to be chosen from the drop down.  I’ve chosen my Windows 7 test image.  Note that the only task sequences shown in the drop down will be those built for imaging.

image

This is where customization of the web page source is required.  The chosen image must have a default collection created for it already in the SCCM console and the source code must be adjusted to reflect the collection name.

In the SCCM console I have created my collection for deploying the Windows 7 image.  The task sequence (covered later) used to deploy the image is already advertised at this collection.

image

image

Note that the collection shown was not defined at this site (you can tell because of the lock).  Defining the collection at the central and making use of it/advertising to it at a child site works fine.

With the collections setup and advertisements in place there is some adjustment to the source code required.  This is the first time I’ve mentioned source so it’s a good time to mention that both the source and a complied project are attached to this blog post.  Also, the source was created in Visual Studio 2010 and that is what you will need to open it.

In the source you will find the section below.  Following the pattern shown simply adjust to include the collections you have created in your environment.  You could continue with the ElseIf pattern shown or could adjust this to a case statement, whatever you like.

image

The next choices are for Region, Market, Location and Timezone.  I included these as generic choices that might be of interest for organizations to track the location of imaged systems.  Whether or not to use these or to modify them is up to you.

image

Each of these four drop down boxes are populated by four text files in the root of the C drive at web page startup.  Simply modify the content of the text files to change the contents of the drop down.  Note that the time zone settings configured in the time zone file need to match exactly the supported time zones.  In other words – specifying Eastern in the time zone file will not result in the imaged system being set to the Eastern time zone – you must specify Eastern Standard Time.  You can see a full list of the time zone formats at the bottom of the web page available here.

The section of source code below shows the filenames of interest and the corresponding drop downs that they populate.

Dim oFSO, oFile, Value, i

'================================================================
'Populate drop down lists with data from files and then autoselect
'default values for drop down lists
'================================================================
RegionDdl.Items.Clear()
MarketDdl.Items.Clear()
LocationDdl.Items.Clear()
TimezoneDdl.Items.Clear()

oFSO = CreateObject("Scripting.FileSystemObject")

'Populate Region drop down list
oFile = oFSO.OpenTextFile("c:\Region.txt", 1)
i = 0
Do Until oFile.atEndOfStream
    i = i + 1
    Value = oFile.Readline
    RegionDdl.Items.Add(Value)
Loop

'Populate Market drop down list
oFile = oFSO.OpenTextFile("c:\Market.txt", 1)
i = 0
Do Until oFile.atEndOfStream
    i = i + 1
    Value = oFile.Readline
    MarketDdl.Items.Add(Value)
Loop

'Populate Location drop down list
oFile = oFSO.OpenTextFile("c:\location.txt", 1)
i = 0
Do Until oFile.atEndOfStream
    i = i + 1
    Value = oFile.Readline
    LocationDdl.Items.Add(Value)
Loop

'Populate Timezone drop down list
oFile = oFSO.OpenTextFile("c:\Timezone.txt", 1)
i = 0
Do Until oFile.atEndOfStream
    i = i + 1
    Value = oFile.Readline
    TimezoneDdl.Items.Add(Value)
Loop

If you don’t like the default labels and want to change them or eliminate them altogether you will need to further edit the following section of code which is where the variables used by the task sequence are set.

'===============================================================================
'Handle Region, Market, Location
'Add Error Checking here in the event something isn't selected
'===============================================================================
If (RegionDdl.SelectedItem.Value <> "" And MarketDdl.SelectedItem.Value <> "" And LocationDdl.SelectedItem.Value <> "") Then
     ComputerVariable = gService.Get("SMS_MachineVariable").SpawnInstance_()
     ComputerVariable.Name = "Region"
     ComputerVariable.Value = RegionDdl.SelectedItem.Value
     ComputerVariable.IsMasked = False
     ReDim Preserve ComputerVariables(UBound(ComputerVariables) + 1)
     ComputerVariables(UBound(ComputerVariables)) = ComputerVariable

     ComputerVariable = gService.Get("SMS_MachineVariable").SpawnInstance_()
     ComputerVariable.Name = "Market"
     ComputerVariable.Value = MarketDdl.SelectedItem.Value
     ComputerVariable.IsMasked = False
     ReDim Preserve ComputerVariables(UBound(ComputerVariables) + 1)
     ComputerVariables(UBound(ComputerVariables)) = ComputerVariable

     ComputerVariable = gService.Get("SMS_MachineVariable").SpawnInstance_()
     ComputerVariable.Name = "Location"
     ComputerVariable.Value = LocationDdl.SelectedItem.Value
     ComputerVariable.IsMasked = False
     ReDim Preserve ComputerVariables(UBound(ComputerVariables) + 1)
     ComputerVariables(UBound(ComputerVariables)) = ComputerVariable
End If
'===============================================================================

'===============================================================================
'Handles Time zone
'===============================================================================
If (TimezoneDdl.SelectedItem.Value <> "") Then
    ComputerVariable = gService.Get("SMS_MachineVariable").SpawnInstance_()
    ComputerVariable.Name = "TimeZone"
    ComputerVariable.Value = TimezoneDdl.SelectedItem.Value
    ComputerVariable.IsMasked = False
    Session("SummaryText") = Session("SummaryText") + "Theme timezone will be set to " & ComputerVariable.Value & vbCrLf
    ReDim Preserve ComputerVariables(UBound(ComputerVariables) + 1)
    ComputerVariables(UBound(ComputerVariables)) = ComputerVariable
End If
'===============================================================================

The next section allows the user to select applications that will be deployed as part of the imaging process.  As the note says, the only packages shown here are those that are set to run as administrator and whether or not a user is logged on. 

image

The window allows multi click selection of packages.  Each application selected will result in a unique task sequence variable being created that is later used in the task sequence during imaging.

The last configuration option is available only if selecting bare metal imaging and is used to clear the last PXE advertisement against a machine to allow reimaging of that machine.

image

Once the form is filled our as you like, select Confirm!  Note the warning – once the confirm button is selected there is no further check – the settings configured are put in place immediately.

After selecting Confirm! take a look at the collection properties.

image
The web page has created a direct membership rule on this collection to include the bare metal system imagingtest1.  Note that the background is grey here – that means that the collection in question was created at a site above.  As such, there is no way through the UI to delete this direct membership rule.  I will discuss a step that should be included at the end of your task sequence a bit later to clean this up but if you want to have UI access to clean this up you will need to create the collection manually at each site where you want to do imaging.

With this direct membership rule intact simply refresh the collection and imagingtest1 will show up.  Looking at the properties of imagingtest1 we see a slew of machine task sequence variables that have been created.

image

All of the collection variables above are generated from the web page.  Those in yellowsed to direct the flow of the task sequence – discussed later.  The ones in green are used as placeholders for cleanup at the end of the imaging process.  Cleanup will be discussed later.

Just a couple of more modifications you need to make before we leave discussion of the web page.  To populate information on the web page connections to SQL are used.  All but the initial data source are populated dynamically but for the initial connection (SqlDSGetPrimarySites) you will need to adjust it for your environment.

image

image

OK, we understand the web page component – it is just taking information and creating task sequence variables on the target machine.  Now what do we need in terms of the task sequence to tie this all together?  I’ve put together a simple task sequence – yours may be more complex – that makes use of all of the information we’ve configured on the web page.  Remember the idea of this solution is that non-SCCM console users will be able to use the web page, configure needed information and initiate imaging (by adding the web page configured system to the target collection).  To make this work the SCCM dministrators will need to have generic task sequences pre-configured and targeted to the various collections.  One cool thing about task sequencing is it’s flexibility – you can set this up several different ways – the sample task sequence is just one possible solution.

The steps that make use of our configured task sequence variables are highlighted.

image

The Set New Computer Name step simply maps our custom new computer name variable to the default OSD variable used for naming the computer as shown.

image

Next, we set the time zone similarly – mapping the custom time zone variable to the internal OSD time zone variable. 

image

Note that the default time zone for the image is Pacific Standard Time – for our example we have set the time zone custom variable to Eastern Standard Time so when the image is complete the system should be in the Eastern time zone, not Pacific.

image

Next I have a separate step to join my domain – you don’t have to have this extra step but I just like to do it as a standalone action.  I specify my OU information by variable as shown.

image

The next step is to write branding information.  This is where you could make use of the Market, Location and Region information if you would like.  I have not built this section out in the task sequence but would envision using this step to either run a script to write the information to a file, the registry or WMI.

The Install Defined Software step will install all of the software packages selected in the web page.  Note that I have provided a ‘seed’ variable that is the same format as the variables configured from the web page.  This step will start and look for this ‘seed’ variable.  If it finds it the step will install the software defined by that variable and then will look for the next variable in sequence.  If it finds it, that package is installed – and so on until the next consecutive variable is not found.  If no variables are found matching the ‘seed’ variable the step is simply skipped.

image

The last step in the task sequence does a cleanup to remove the imaged system from the collection targeted for imaging.

image
The script that is called here is contained in a package and is used to connect back to the site server where imaging originated and remove the now imaged system from the collection.  The script does NOT clean up the task sequence variables assigned to the imaged system.. The script could be easily modified to do so but I chose against it thinking that if there were errors while imaging it would be helpful to retain the variables and values for troubleshooting. 

Note that in the script itself I’m passing credentials for connecting with WMI on the site server where imaging originated. You might wonder why I’m providing credentials in the script rather than simply specifying an account to use for running the script.  Good question – the reason is that the script makes use of the task sequence variables we declared earlier.  Since these variables are only accessible to the system context we need to execute the script under that context and since we are making a remote connection to WMI, we need to pass those credentials in the script.

The script also creates a file called output.txt – I use this for troubleshooting but it can be eliminated if you don’t want the extra file.

RemovefromCollection.vbs
---------------------------------
Dim osd:  set env = CreateObject("Microsoft.SMS.TSenvironment")
Dim CollectionID, SystemName, SMSServer, SMSSiteCode, oCollection, collListItem, CollectionRule, RuleSet, Rule
Dim CollectionRuleName, ILocator, gService, fso, fsofile, struser, strpassword

On error resume next

‘Replace user and password as appropriate
struser = "XXXXXXXXXXXXXXXX"
strpassword = "XXXXXXXXX"

CollectionID = env("ImagingCollectionChoice")
SystemName = env("NewComputerName")
SMSServer = env("ChosenSMSServerName")
SMSSiteCode = env("ChosenSMSSite")
CollectionRuleName = env("CollectionRuleName")

set fso = CreateObject("Scripting.FileSystemObject")
set fsofile=fso.CreateTextFile("c:\output.txt")
fsofile.writeline("Variables retrieved" & CollectionID & SystemName & SMSServer & SMSSteCode & CollectionRuleName)

set ILocator = CreateObject("WbemScripting.sWbemlocator")
fsofile.writeline("Set ILocator")
set gService = ILocator.ConnectServer(SMSServer, "Root\SMS\Site_" & SMSSiteCode, struser, strpassword)
If err.number <> 0 Then
    fsofile.writeline(err.number)
End If

fsofile.writeline("Got Connection")

set oCollection = gService.Get("SMS_Collection='" & CollectionID & "'")

RuleSet = oCollection.CollectionRules  
 
For Each Rule In RuleSet  
   If Rule.Path_.Class = "SMS_CollectionRuleDirect" Then  
       If LCase(Trim(Rule.RuleName)) = LCase(CollectionRuleName) Then  
            oCollection.DeleteMembershipRule Rule  
        End If
End If  
Next  

oCollection.RequestRefresh false
 
I would recommend running the cleanup step in every case – even if imaging fails.  The reason is that if mandatory images are targeted to the collection and the image fails the system could end up in an endless imaging loop.

So we have run the web page and the task sequence – did our customizations take?  Let’s take a look.

First we assigned a computer name of imaging test  - this avoids the random name of minint…  We also set the time zone to eastern standard time.  Looking at the resulting load of the image we see these customizations did work.

image

A further customization was to add the imaged system to the TestOU OU when joining the domain.  Looking at AD Users and Computers we see that this was successful as well.

image

OK, we’ve got the web page and the task sequence – can we get to the setup instructions already?  Sure.  Configuring this in your environment is easy.  The instructions below assume this web page is being installed on a primary site server.  Generally the central is preferred.  You can make this work installing external to the site server but setup is a bit more complex.  Also, these instructions are for setup on IIS 7.0 – other versions of IIS will differ.

1.  Configure Region, Market, Location and Time Zone files in the root of the C drive on the system where the web page is installed.  If you don’t want to use Region, Market, Location or Time Zone or you want a different location, just modify the web page as shown above before you deploy.
2.  Copy the web page virtual directory to the folder where you will run the web page.
3.  Configure the web page in IIS
     -Create a new application pool ensuring .NET framework is set to v4.0 (if you 
     haven’t installed .NET framework 4.0 you will need to do so.)
     clip_image002

     -Right-click on the default web site and add a new application.  Select your custom
     application pool and specify the path to the web page files and set an account to
     use that has rights to SCCM and the SCCM Database.  Click to test settings and
     you should see two green tests if all is configured properly.
     clip_image002[5]
     -Grant everyone read access to the web page source files.

     clip_image002[7]

     -On the application pool properties set the account for the pool to use.  I used the
     same account as configured earlier.
     clip_image001
And that’s it – download and enjoy your testing!

OSDWebPage.zip