Thursday, September 18, 2014

Getting SCCM DP Name During Imaging

Overview

In my company we had a desire to know what server a machine is being serviced by during imaging.  We do this because we have a concept of Image anywhere for anywhere.  This gives us the ability to create London, UK machine with all of its regional settings (monetary symbols, keyboard layout, etc) in Boston, MA, USA.  However we would like to know both what office the machine was imaged for and at what office it was imaged.

We store this information along with several other details of the imaging process in a custom Registry key.  In our pure MDT days getting this I was imaged from this server detail was fairly easy, there where values in the TS environment I could use to get this detail.

In SCCM 2012/MDT integrated environment I struggled to find a similar value in a reliable way. 

I hit on the Answer Yesterday.

This is a code snippet in VB (yes I could have written it in Powershell, maybe I will in the future, but I was enhancing an existing older script I had written based on ZTITemplate.wsf)  ready to be integrated into a standard LTI/ZTI script or a Userexit script and fired off by ZTIGather when it reads Customsettings.ini.  I choose to put it into my existing script which does our custom registry stamping.  I have it inline in the script, but it could also easily be dropped into a function.

Keep in mind this code assumes a running Task Sequence environment with the toolkit loaded so that ZTIUtility.wsf is available.  I have it integrated with a script written based on ZTITemplate.
See http://scriptimus.wordpress.com/2011/07/11/mdt-scripting-creating-custom-scripts-getting-started/ for details on using ZTITemplate

Also don't forget to declare the variables used by the script if your integrating it with an existing script that used "Option Explicit"

Description of the Script

In order to figure out what DP the Task Sequence is being run from we need something in the SCCM TS environment that contains the server name.  There is no TS variable that contains just this information, so thus it must be derived from other data.  Well this is easy enough the Environment contains plenty of TS Variables that point to the paths to get various packages from on the DP, we just need to choose one, BUT which one.

The SCCM OSD Deployment Environment and especially the list of packages that will be used is highly dynamic, I had two goals.

1. Write a script that didn't hard code the package name that will be used to extract the DP information
2. Write a script that doesn't need to know the name of SCCM site, so that its easily portable between environments.  Part of the Task Sequence Variable we will go after is the package name which is of course based on the Site Name.

It is formatted as such _SMSTSHTTPPackagename 

Packagename is composed of sitecodepackagenumber

So the challenge is to find a package name that can be dynamically determined from the imaging environment.  The answer to this is the package for the boot image, its name is reflected in its own Task Sequence Variable  _SMSTSBootMediaPackageID.

We can get that Package ID by reading that Task Sequence Variable.

s_SMSTSBootMediaPackageID = oEnvironment.Item("_SMSTSBootMediaPackageID")
Then build a new string to represent the Task Sequence Variable to find that contains the path to the package on the DP. 

s_SearchTSVariable = "_SMSTSHTTP" & s_SMSTSBootMediaPackageID
Next we ask the Task Sequence Environment for the value of the Variable name we just created. This will contain the path to the boot image package.

sDPPathtoBootImage = oEnvironment.Item(s_SearchTSVariable)

Next we need to do 2 Split commands in a row to break down the path and get the name of the DP.
Recall that split drops the results into an array, so once we have done this we just need to read the right indexes to get the value we want.

First Split the path on the "/" character.
HTTP: will be in Index 0 of the array
Nothing will be in Index 1 of the array
The DP's FQDN will now be in Index 2 of the array

aBrokenDownPath = Split(sDPPathtoBootImage,"/",-1,1)

Now to get the DP name (I wanted just the server name and not the FQDN) Split the Contents of Index 2 of the aBrokenDownPath array on the "." character

Index 0 will contain the simple machine name

aSMSDPName = split(aBrokenDownPath(2),".",-1,1)

Finally output the contents of the aSMSDPName array index 0 to a string variable for later consumption.

sSMSDPName = aSMSDPName(0)

Script Run Log Output

I have sanitized the output...no real sitenames, packageIDs,  server names or domains appear here

++++++++++++++ Begin: Figure Out What SMSDP is being used to support the imaging Process++++++++++++++++++++ ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Got Package ID = ES10030K ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Searching for Value of Task Sequence Variable = _SMSTSHTTPES10030K ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Searching for Value of Task Sequence Variable =
http://EPISCCMDP01v.EPI.local/SMS_DP_SMSPKG$/ES10030K  ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Broken Down Path Index 0 = http: ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Broken Down Path Index 1 =  ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Broken Down Path Index 2 = EPISCCMDP01v.EPI.local ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
Got SMSDPName = EPISCCMDP01v ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)
++++++++++++++ End: Figure Out What SMSDP is being used to support the imaging Process++++++++++++++++++++ ZTIImageInfo 9/17/2014 11:44:44 PM 0 (0x0000)


The Script

''++++++Dim required variables++++++
'This might be in a different part of the code, or might not be needed at all depending on your use case

Dim s_SMSTSBootMediaPackageID
Dim s_SearchTSVariable
Dim sDPPathtoBootImage
Dim aBrokenDownPath
Dim aSMSDPName
Dim sSMSDPName

'end of DIM Variables

'******* Figure out what DP is being used ********************************
'keep in mind that this script snippet is meant to be run in a existing Task Sequence Environment, the toolkit package should have already been called when the script is invoked. 
oLogging.CreateEntry "+++ Begin: Figure Out What SMSDP is being used to support the imaging Process+++", LogTypeInfo

'First find out the Package ID of the Boot Image used for the Task Sequence
s_SMSTSBootMediaPackageID = oEnvironment.Item("_SMSTSBootMediaPackageID")
  
oLogging.CreateEntry "Got Package ID = " & s_SMSTSBootMediaPackageID, LogTypeInfo
  
'now find the reference to this package in the SMSTS Environment and Collect it's path
  
'Create a string to contain the package ID this will be the name of the Task Sequence Variable we are looking for in the environment
s_SearchTSVariable = "_SMSTSHTTP" & s_SMSTSBootMediaPackageID
  
oLogging.CreateEntry "Searching for Value of Task Sequence Variable = " & s_SearchTSVariable, LogTypeInfo
  
'Get the path into a string variable
 sDPPathtoBootImage = oEnvironment.Item(s_SearchTSVariable)
  
oLogging.CreateEntry "Searching for Value of Task Sequence Variable = " & sDPPathtoBootImage, LogTypeInfo
  
'Use Split to break the path string down so we can extract the DP Name
aBrokenDownPath = Split(sDPPathtoBootImage,"/",-1,1)
  
oLogging.CreateEntry "Broken Down Path Index 0 = " & aBrokenDownPath(0), LogTypeInfo
oLogging.CreateEntry "Broken Down Path Index 1 = " & aBrokenDownPath(1), LogTypeInfo
oLogging.CreateEntry "Broken Down Path Index 2 = " & aBrokenDownPath(2), LogTypeInfo
  
'Do a Spilt of the Broken down path index 2 this will contain the DP Name in Index 0
  
aSMSDPName = split(aBrokenDownPath(2),".",-1,1)
  
' Put the value into a string for later use
sSMSDPName = aSMSDPName(0)
  
oLogging.CreateEntry "Got SMSDPName = " & sSMSDPName, LogTypeInfo
  
oLogging.CreateEntry "++++++++++++++ End: Figure Out What SMSDP is being used to support the imaging Process++++++++++++++++++++", LogTypeInfo
  
'***************Finished with getting SMS DP Name ***********************************