Expiring Outdated Stand-Alone Media

 

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…

image

 

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

Comments

  • Anonymous
    January 01, 2003
    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.

  • Anonymous
    January 01, 2003
    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 binx86 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

  • Anonymous
    January 01, 2003
    Phil, I was referring to using winpeshl.ini instead of tsconfig.ini to start a customized script while using MDT.  With that being said... With this script, you could technically look at the date stamp of any file.  I have not run this script against it, so I cannot claim it will work; however, I can't see a reason why it wouldn't.

  • Anonymous
    January 01, 2003
    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.

  • Anonymous
    January 01, 2003
    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.  

  • Anonymous
    January 01, 2003
    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>OSDbooti386 and x64 if used
  3. On the SCCM central server mount the boot image, example: mkdir c:mount cd Program FilesWindows AIKToolsx86 ImageX /MountRW d:sccmOSDbooti386boot.wim 1 c:mount
  4. Copy the script to the image copy osd_tb.vbs c:mountWindows  
  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
  • Anonymous
    February 15, 2012
    So with this solution, one has to manually edit the WinPE WIM each time it is regenerated?

  • Anonymous
    February 17, 2012
    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?

  • Anonymous
    September 23, 2013
    Brad, I'm looking at doing this with MDT 2012 and Lite Touch Deployment. Are you saying you can replace policy.xml with winpeshl.ini in the script and it will work in a similar fashion? My scripting skills are limited, but we are looking at expiring media for remote sites.

  • Anonymous
    July 13, 2014
    Is there any Powershell version for the above script....i do not VB...we want our script to check the version number of boot image and match it with the approved image version list on a network..and if the image versionis not in the approved list ..we want to terminate the image boot process