In my previous post ‘How to Limit or Restrict the Use of Bootable Media Devices for OS Deployment Using SCCM’, I showed you how to limit or restrict outdated boot media devices. As promised, I am now going to offer a solution for stand-alone media.
I need to start by saying that there or MANY possible ways to resolve this issue. This is but one, but I have found it works pretty well.
As a little background, I will tell you that this solution came about because my customer at the time asked for a way to keep stand-alone media from being deployed after it was no longer current. They wanted this to work for non-networked devices. This meant I couldn’t point back to a file on a network share and check its contents/properties. It all had to be contained within the media.
Once it was implemented they decided to use this same solution for networked devices as well that use stand-alone media.
I created a script called ExpiredUFDCheck.vbs. The purpose of this script was to check the creation date of the policy.xml file on the media itself. This file contains the task sequence information and is created when the media is generated. My customer wanted to refresh the reference image and task sequence every quarter, so I added logic in the script that checked to see if the policy.xml file was older than 3 months old. If it wasn’t, the task sequence would launch and run as normal. If it was, the script would pop up a message box notifying the tech that the task sequence was expired and would then shutdown the box and not launch the task sequence. Pretty simple, right?
' // *************************************************************************** ' // ' // File: ExpiredUFDCheck.vbs ' // ' // Version: 1.0 ' // ' // Purpose: Check to see if stand-alone media is expired ' // ' // Usage: cscript ExpiredUFDCheck.vbs ' // ' // ***************************************************************************
On Error Resume Next
' // --------------------------------------------------------------------- ' // Find the environment variable %configpath% for location of UFD ' // ---------------------------------------------------------------------
'Set objShell = CreateObject("WScript.Shell") 'Set objExecObject = objShell.Exec("%comspec% /c echo %configpath%") 'configPath1 = objExecObject.StdOut.ReadAll() 'configPath = Mid(configPath1, 1, Len(configPath1) -2)
' // ----------------------------------------------------------------------------------------- ' // Find the environment variable %TEMP% for location of tool files (e.g. shutdown.exe) ' // -----------------------------------------------------------------------------------------
Set objShell = CreateObject("WScript.Shell") Set objExecObject = objShell.Exec("%comspec% /c echo %temp%") temp = objExecObject.StdOut.ReadAll() tempdir = Mid(temp, 1, Len(temp) -2)
' // --------------------------- ' // Find driver letter for UFD '// ----------------------------
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Drives = FSO.Drives
For Each DiskDrive In Drives If DiskDrive.DriveType = "1" Then USBPath = DiskDrive.Path End If Next
' // ----------------------------------------------------------------- ' // Query WMI for creation date of the Policy.xml file on the UFD ' // -----------------------------------------------------------------
strComputer = "." Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' // ---------------------------- ' // Media Check - Policy.xml ' // ----------------------------
Set colFiles = objWMIService.ExecQuery("Select * From CIM_DataFile Where Name = '" & USBPath & "\\SMS\\Data\\Policy.xml'")
' // ----------------------------------------- ' // Set the date 3 months ago from today ' // -----------------------------------------
dt3MonthsAgo = DateAdd("m", -3, Now)
' // ----------------------------------------------------------------------------------------------------------- ' // If the Policy.xml file creation date is less than the date 3 months ago from today, it is an expired UFD. ' // -----------------------------------------------------------------------------------------------------------
For Each objFile in colFiles dtCreationDate = WMIDateStringToDate(objFile.CreationDate) dtEndDate = DateAdd("m", 3, dtCreationDate) If dtCreationDate < dt3MonthsAgo then Set WshShell = CreateObject("WScript.Shell") Command = TEMPDIR & "\scripts\Shutdown.exe /s /t 0" MsgBox "This task sequence expired on " & dtEndDate, vbMsgBoxSetForeground, "Expired Task Sequence" Set oExec = WshShell.Exec(Command) Else WScript.Quit(1) End If Next
' // ----------------------------------------------------------------------------------------- ' // Converting the WMI date query response to a simple date format. (e.g. 09/21/2010) ' // -----------------------------------------------------------------------------------------
Function WMIDateStringToDate(dtmInstallDate) WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) & " " & Mid(dtmInstallDate, 9, 2) & ":" & Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, 13, 2)) End Function
Now comes the fun. I had to make sure the script ran on the media. We also wanted it to run before the task sequence fired.
Inside WinPE itself, there is a file on the root called TSConfig.ini (X:\TSConfig.ini). This file is a ‘pre-execution hook’ file and determines if any extra actions are required when WinPE is launching and initializing. I mounted the WinPE wim and copied my script file to the root. Then inside the TSConfig.ini file I set the command to launch my script.
[CustomHook]
CommandLine=”cscript.exe X:\ExpiredUFDCheck.vbs”
When a machine is booted with an expired UFD, the following message box will be displayed during the WinPE initialization…
Hitting OK, will shut down the computer.
This post was contributed by Brad Tucker, a Senior Consultant with Microsoft Services, East Region, United States
Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use
So with this solution, one has to manually edit the WinPE WIM each time it is regenerated?
Not at all.
You could create the tsconfig.ini and ExpiredUFDCheck.vbs files and put them in a source location. Then modify the osdinjection.xml file located in bin\x86 folder within your SCCM install folder. When you regenerate your boot images, they will be injected.
I have attached the Configuration Manager Support Team blog that explains this process...
blogs.technet.com/.../osd-how-to-add-a-script-to-a-configmgr-2007-boot-image.aspx
I did one a long time ago that toggles on a TS parameter:
1. Create a script named osd_tb.vbs containing:
dim todayDate
dim toDate
todayDate = Date
toDate = WScript.Arguments(0)
If DateValue(todayDate) < DateValue(toDate) Then
wscript.quit(0)
Else
wscript.echo "This deployment DVD expired on " & toDate & ". Contact your administrator for the latest version"
wscript.quit(1)
End If
2. Back up the BOOT.WIM file to be changed in
<sccm install dir>\OSD\boot\i386 and x64 if used
3. On the SCCM central server mount the boot image, example:
mkdir c:\mount
cd \Program Files\Windows AIK\Tools\x86
ImageX /MountRW d:\sccm\OSD\boot\i386\boot.wim 1 c:\mount
4. Copy the script to the image
copy osd_tb.vbs c:\mount\Windows
5. Unmount and save image
6. Add command to the task sequence to run first in PE (Right after restart in Windows PE)
%WINDIR%\osd_tb.vbs 3/1/2009
The parameter is the date to expire
7. Create stand alone DVD Media
Good one.
I started this one doing something similar, but was informed that remote and international IT teams will most likely be able to modify the TS (add their unique drivers, configs, etc...) within the console. This meant they could modify the date.
Like I said, MANY possible solutions. Use these examples and build your own. As long as you understand where the limitations are with each solution, you can plan/build around them.
Additionally, if you are going to have it run within the TS, you will need to make sure you check prior to any Diskpart attempt. You will need to have that check run before wiping the machine.
This is another reason I chose to do it outside the TS.
Thanks for the information about the osdinjection.xml file, Brad. Is there an equivalent process for MDT? Would you recommend something like Winpeshl.ini or Startnet.cmd in this case?
It has been a LOOOOOONG time since I had to do something similar for MDT, but winpeshl.ini was what I used at the time.