30 December 2012

How to Backup Multiple Systems to a Single Online Backup Service Account

You might have wondered how to backup multiple computers in your home with a single online backup service. The answer is yes, you can do this and here is how. You can setup one system that will act as a repository for your other computers backups. You will be using the Windows 7 Backup and Restore feature to backup to the other system.

The first thing you need to do is to make sure you have enough HDD space on your system that will be backed up to. For most people, a 1 TB HDD should be more than enough for 2-3 systems. Second, you will want to create the network share. To do this for most people, connect all of your home PCs using the HomeGroup. Of course, if you are a tech savvy or and IT professional, you will know of a more efficient way to network them. Next, create a folder on the HDD that you want to back up. Right click on the folder you just created, click Share With-->HomeGroup (Read/Write). This will now allow the other systems to see the folder you just created and shared out, but it does not have administrative privileges, so it will not be possible yet to backup to it. We need to give it additional privileges  Here is how. Right-click on the folder and click properties-->Sharing-->Advanced Sharing. Make sure Share this folder is checked. Now click on Add and type a share name. It cannot be the same as the folder name. For instance, I named my folder backup and named the share backups. Click on Permissions. If security within your home network is not a concern, then just select Everyone and give them full control over the folder. Click Apply and OK. Click OK again. Click Apply and OK.Click Close. The other systems on your home network can now see and write to that folder with administrative privileges that are necessary for the Backup and Restore function to write to it across the network. Finally, if the master system does not require a username/password to login, in other words, it just boots up to the desktop, you will need to set a password up. This is because the slave systems will require a username/password to access the master system's shared folder. There is no getting around this.

It is now time to go to the systems that you want to back to your master system. In Windows 7, go to Control Panel-->All Control Panel Items-->Backup and Restore. Click on the Set up Backup. Click Save on a network and then click Browse. You will see master system in the list. Click on it to expand the list. You will see both the HomeGroup share and the advanced share. You will want to select the advanced share. This is the share that you created with everyone having administrative privileges to the folder. Enter the username and password for the master system and then click OK. Select the backup destination you just created and click Next. It is now your choice as to whether you want windows to choose what files to backup or if you want to manually select the files to backup. Once you are through this part and are satisfied with the backup settings, click Save Settings and Run Backup.

The final step with this is to make sure the online backup service is backing up the backup files from the slave systems. You may need to manually go in and select the backup files for backup to the online service. It is also possible that the online backup service may not allow for these types of files to be backed up. I hope this helps.

VERY IMPORTANT NOTE: Make sure you contact your ISP if your backups are going to be above 250 gigabytes. That is the usual threshold most ISPs today allow for users to use over a 1 month period. It can differ per ISP, so make sure you know what your ISP allots for your monthly usage. If you exceed that, some will charge you for a certain amount of data and that can become very expensive, very fast. Some will cap your download rate and some will threaten to close your account, so it is best to let them know if you are doing an initial backup and/or a restore. 

NOTE: This will only work on a Windows 7 Professional, Windows 7 Ultimate, or a Windows 7 Enterprise system, as they are the only versions that allow for the Save on a network. There is a way around this though. If your system has enough HDD space, you can back it up to itself and then setup a batch file that will robocopy the backup over to the master system's shared backup directory and then delete the backup from the slave system. I have it setup this way on one of my systems here at the house.

NOTE: Depending on the online backup service, there may be caps as to how much you can backup online. I know a couple of them allow for unlimited, but one that I recently was using put caps on as of last year.

NOTE: The Microsoft Windows 7 Backup service does not purge and/or overwrite old backups, therefor it can easily fill up a terabyte hard drive within 2-3 backup periods. There are two options here. One, manually clean it out by the steps below or two, create a script and set it up to run weekly that will purge the old backups. Microsoft is aware on this, yet they have done nothing to fix it. Of course there is also the final option to select a completely different backup software.



  1. Open the Control Panel (All Items View). 
  2. Click on the Backup and Restore icon.
  3. Under Backup, click on the Manage Space link.
  4. To Select a Backup Location -
    1. Under Backup location, click on the Browse link.
    2. Navigate to the backup location and select it.
    3. Continue to step 5.
  5. Under User file backup, click on the View backups button.
  6. Select the Backup Period that you want to delete, and click on the Delete button.

03 December 2012

Multiple Naming Schemas in the customsettings.ini file

It is nothing new that you can setup MDT or SCCM to automatically create the computer name via the customsettings.ini file. This is a sample I used from a forum on the net:

[ByLaptopType]
Subsection=Laptop-%IsLaptop%

[ByDesktopType]
Subsection=Desktop-%IsDesktop%

[Laptop-True]
OSDComputerName=LT%SerialNumber%

[Desktop-True]
OSDComputerName=DT%SerialNumber%

The problem comes when you also have a SQL database that custom names the computers too. In the scenario I work in, we normally name our computers DT%SERIAL% or LT%SERIAL%. There are exceptions such as our shared and training systems that have unique names I defined in the SQL database. The OSDComputerName variable is first come, first serve. The first thing to put a value in it will be the only value it will accept. Therefore, you will need to rearrange the setup of the Priority field. For my scenario, I re-sequenced the Priority field to first query the SQL server and then do the ByLatopType and ByDesktopType. If it is one of our unique systems being imaged, the value in the SQL database gets assigned first and then the standard name is read in the ByLatopType and ByDesktopType, but can't be written over the SQL injected value. 

This was the original setup of the Priority field:
Priority=ByLaptopType, ByDesktopType, CSettings, CPackages, CApps, CAdmins, CRoles, Default

This is the rearranged setup that works perfectly:
Priority=CSettings, CPackages, CApps, CAdmins, CRoles, ByLaptopType, ByDesktopType, Default

29 November 2012

Stepping through an installation with AutoIT

Programs such as trial versions of Autodesk and Adobe CS6 cannot be packaged up for distribution. You may be put in a situation where you need to deploy a trial version out to a set of users for them to evaluate it. The traditional packaging programs are not going to work here because of the licensing issue. Here is how to use AutoIT to deploy them.

You will want to first step through the program documenting every keystroke required, from start to finish. You do not want to use your mouse. Next, Open up AutoIT. The first thing you will want to do is initiate the installation with the simple Run command. Next, use the WinWait command to wait for the first screen to appear. You will see the title of the window at the top left bar. Use the WinActivate to make sure that window is at the forefront. There are now two ways to proceed to the next page if the window title does not change. I use the WinSetTitle command to change the title of the window. When the next window appears, the title usually changes back to the default, Which is what you next set the WinWait to wait for. If the name does not change on the next page, then you will be forced to guesstimate the time it will take to proceed to the next page on the slowest system you have. Another important thing to remember is to use the Sleep command between each command because the script can go faster than the program is executing, therefor becoming asynchronous, thereby causing the installation script to go in a permanent pause state. I usually use 500 milliseconds, which seems to always be sufficient. Another important thing to do is comment between each screen in the script. That way, you will know where the script is between each window.

Here is an example of an installation script for Autodesk I wrote:




 ; Execute Civil 3D  
 Run( "setup.exe", "\\global.gsp\data\clients\na_clients\Autodesk\2012\CIV3D\64bit\AdminImage" )  
 ;  
 ;Initial Page  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinActivate( "AutoCAD Civil 3D 2012" )  
 WinSetTitle( "AutoCAD Civil 3D 2012", "", "Initial Page" )  
 WinActivate( "Initial Page" )  
 Send( "{ENTER}" )  
 ;  
 ;License Agreement  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinSetTitle( "AutoCAD Civil 3D 2012", "", "License Agreement" )  
 WinActivate( "License Agreement" )  
 Send( "{RIGHT}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{ENTER}" )  
 ;  
 ;Product Information  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinSetTitle( "AutoCAD Civil 3D 2012", "", "Product Information" )  
 WinActivate( "Product Information" )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{UP}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{TAB}" )  
 Sleep( 500 )  
 Send( "{ENTER}" )  
 ;  
 ;Configure Installation  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinSetTitle( "AutoCAD Civil 3D 2012", "", "Configure Installation" )  
 WinActivate( "Configure Installation" )  
 Send( "{ENTER}" )  
 ;  
 ;Installing  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinSetTitle( "AutoCAD Civil 3D 2012", "", "Installation" )  
 WinActivate( "Installation" )  
 ;  
 ;Finish  
 WinWait( "AutoCAD Civil 3D 2012" )  
 WinActivate( "AutoCAD Civil 3D 2012" )  
 Sleep( 500 )  
 Send( "{ENTER}" )  
 Sleep( 500 )  

BOOTMGR is missing after applying a WIM

This is being caused by the 200 MB hidden partition windows creates when the partitioning is done before the OS is laid down. This is done to pre-configure the system for bitlocker, even if it is not going to be used. The bootmgr file is placed in that partition, therefor when you sysprep and machine and then generate a WIM file, it does not capture the data from the hidden partition. This only happens when you are manually building up a machine, installing all of the applications, sysprepping the machine, and then running the imagex to generate an image on a remote share. If you generate an image with MDT or SCCM, this process is properly handled. Obviously, you could just use either of those processes to create your golden image, but if you still need to do it all manually, here is how:

  1. Boot to WinPE and delete all partitions
  2. Create a new single partition. Size does not matter
  3. Begin the installation of Windows 7. Select the partition created in step 1
After researching some with MDT, I could not find any options to install Windows 7 without the hidden partition, so for now, the system to be manually imaged, won't be able to be built with either SCCM or MDT. 

There is also another option. You can place a pause in the initial build of SCCM or MDT. Just write a quick VBScript that launches a message box and waits for the user to click Ok to continue. At that point, you can install whatever software you want and the golden image will be generated at the end. 

28 November 2012

Automate Unmounting WIM Files

This script will allow you to painlessly mount WIM files for editing. It runs relative to its location it was executed from.

Here is the link to download this script.


 '*******************************************************************************  
 '     Program: UnmountWIM.vbs  
 '      Author: Mick Pletcher  
 '        Date: 22 February 2010  
 '    Modified:  
 '  
 ' Description: This script will unmount the current mounted WIM file.  
 '              1) Define Relative Path  
 '              2) Select the WIM file  
 '              3) Mount the WIM file  
 '              4) Cleanup Global Variables  
 '*******************************************************************************  

 Option Explicit  

 REM Define Global Variables  
 DIM RelativePath : Set RelativePath = Nothing  

 DefineRelativePath()  
 UnmountWIM()  
 ImageUnmounted()  
 GlobalVariableCleanup()  

 '*******************************************************************************  

 Sub DefineRelativePath()  

      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  

 End Sub  

 '*******************************************************************************  

 Sub UnmountWIM()  

      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  

      REM Define Local Variables  
     'DIM Unmount    : Unmount    = Chr(34) & "C:\Program Files\Windows AIK\Tools\x86\imagex.exe" & Chr(34) & " /unmount mount /commit"  
      DIM MountDIR   : MountDIR   = Chr(32) & "/MountDir:" & RelativePath & "Mount"  
      DIM Parameters : Parameters = Chr(32) & "/commit"  
      DIM Unmount    : Unmount    = "DISM /Unmount-WIM" & MountDIR & Parameters  

      oShell.Run Unmount, 1, True  

      REM Cleanup Local Variables  
      Set MountDIR   = Nothing  
      Set oShell     = Nothing  
      Set Parameters = Nothing  
      Set Unmount    = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub ImageUnmounted()  

      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  

      If NOT FSO.FolderExists(RelativePath & "Mount\Windows") Then  
           MsgBox("Image is unmounted")  
      Else  
           MsgBox("Image failed to unmount")  
      End If  

      REM Cleanup Local Objects  
      Set FSO = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub GlobalVariableCleanup()  

      Set RelativePath = Nothing  

 End Sub  

27 November 2012

Automate Mounting WIM Files

This script will allow you to painlessly mount WIM files for editing. It runs relative to its location it was executed from.

Here is the link to download the file.


 '*******************************************************************************  
 '     Program: MountWIM.vbs  
 '      Author: Mick Pletcher  
 '        Date: 19 February 2010  
 '    Modified:  
 '  
 ' Description: This script will mount a WIM file. It will display a list of  
 '              WIM files and allow the user to select which one to mount.  
 '              1) Define Relative Path  
 '              2) Select the WIM file  
 '              3) Mount the WIM file  
 '              4) Cleanup Global Variables  
 '*******************************************************************************  
 Option Explicit  

 REM Define Global Variables  
 DIM strImageName : Set strImageName = Nothing  
 DIM RelativePath : Set RelativePath = Nothing  

 DefineRelativePath()  
 SelectImage()  
 MountWIM()  
 ImageMounted()  
 GlobalVariableCleanup()  

 '*******************************************************************************  
 '*******************************************************************************  

 Sub DefineRelativePath()  

      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  

 End Sub  

 '*******************************************************************************  

 Sub SelectImage()  

      REM Define Local Constants  
      CONST ForAppending = 2  

      REM Define Objects  
      DIM strComputer   : strComputer = "."  
      DIM objWMIService : Set objWMIService = GetObject("winmgmts:" _  
                          & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")  
      DIM colFileList   : Set colFileList = objWMIService.ExecQuery _  
                          ("ASSOCIATORS OF {Win32_Directory.Name=" & Chr(39) & Left(RelativePath, Len(RelativePath)-1) & Chr(39) & "} Where " _  
                          & "ResultClass = CIM_DataFile")  
      DIM objFile       : Set ObjFile = Nothing  
      DIM FSO           : Set FSO = CreateObject("Scripting.FileSystemObject")  

      REM Define Local Variables  
      DIM Count      : Count          = 1  
      DIM FileName   : Set FileName   = Nothing  
      DIM FileVerify : Set FileVerify = Nothing  
      DIM strList    : strList        = "Select an Image File:"  

      REM Get List of WIM files  
      For Each objFile In colFileList  
           FileVerify = Right(objFile.Name, 3)  
           If FileVerify = "wim" then  
                FileName = Len(objFile.Name)  
                FileName = FileName - 9  
                FileName = Right(objFile.Name, FileName)  
                strList = strList & vbCrLf & Count & " - " & FileName  
                Count = Count + 1  
           End If  
           Set FileVerify = Nothing  
      Next  
      REM Select WIM File  
      strImageName = InputBox(strList, "Image")  
      strImageName = CInt(strImageName)  
      REM ReInitialize Variables  
      Count = 1  
      Set FileName  = Nothing  
      Set FileVerify = Nothing  
      Set objFile  = Nothing  
      REM Get File Name  
      For Each objFile In colFileList  
           FileVerify = Right(objFile.Name, 3)  
           If FileVerify = "wim" then  
                FileName = Len(objFile.Name)  
                FileName = FileName - 9  
                FileName = Right(objFile.Name, FileName)  
                If Count = strImageName then  
                     strImageName = FileName  
                End If  
                Count = Count + 1  
           End If  
           Set FileVerify = Nothing  
      Next  

      REM Cleanup Local Variables  
      Set colFileList   = Nothing  
      Set Count         = Nothing  
      Set FileName      = Nothing  
      Set FileVerify    = Nothing  
      Set strComputer   = Nothing  
      Set objFile       = Nothing  
      Set FSO           = Nothing  
      Set objWMIService = Nothing  
      Set strList       = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub MountWIM()  

      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  

      REM Define Local Variables  
      DIM WIMFile   : WIMFile   = Chr(32) & "/wimfile:" & RelativePath & strImageName  
      DIM Index     : Index     = Chr(32) & "/index:1"  
      DIM MountDIR  : MountDIR  = Chr(32) & "/mountdir:" & RelativePath & "mount"  
      DIM MountFile : MountFile = "DISM.exe /mount-wim" & WIMFile & Index & MountDIR  

      oShell.Run MountFile, 1, True  

      REM Cleanup Local Variables  
      Set Index     = Nothing  
      Set MountDIR  = Nothing  
      Set MountFile = Nothing  
      Set oShell    = Nothing  
      Set WIMFile   = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub ImageMounted()  

      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  

      If FSO.FolderExists(RelativePath & "Mount\Windows") Then  
           MsgBox(strImageName & Chr(32) & "is mounted")  
      Else  
           MsgBox(strImageName & Chr(32) & "failed to mount")  
      End If  

      REM Cleanup Local Objects  
      Set FSO = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub GlobalVariableCleanup()  

      Set RelativePath = Nothing  
      Set strImageName = Nothing  

 End Sub  

20 November 2012

Internet Access for an application during MDT or SCCM build

You have an application that is installed during the build process of MDT or SCCM and it needs access to the internet to download additional files. There are some programs, such as Autodesk Revit, that you cannot download everything necessary to install it completely offline. The easiest way to grant temporary internet access is by running the installation with a different account that has access. The way you do this in MDT or SCCM is by using PSEXEC.exe. Here is how:

  1. Download and extract PSEXEC to a shared network location that can be accessed by the build
  2. In the application wizard, under Quiet install command, enter the application in the following manor: <UNC Path to PSEXEC folder>\PsExec.exe \\%COMPUTERNAME% /accepteula -u <domain>\<username> -p <password> <command line install>
  3. In the Working directory, enter the network location of where the application resides
That is all that is to it. By using PSEXEC, you are running the application under different credentials, thereby giving it access to the internet. 

Here is an example of what the Quiet install command might look like: 
\\shared-location\PSEXEC\PsExec.exe \\%COMPUTERNAME% /accepteula -u boston\buildaccount -p 123456 cscript.exe /b Install.vbs

NOTE: PSEXEC.EXE is a very touchy application that can be difficult to implement. The above listed is what has worked at the firm I work for. It will vary at most companies due to differences in network configurations. I do enjoy helping others, but an issue like this has to be resolved internally because it is a security matter within your own company.

16 November 2012

Editing Revit INI Files

Here is a script that will make custom changes to the revit.ini file on user machines. You first open the script up and define the changes needed in the EditINIFiles subroutine. Currently, there are 4 changes I have in the script I wrote. Next, you will need to modify the UserDataCacheRevitIniPath to wherever the master revit.ini file is stored on your company's systems. Finally, on line 102, make sure the path to the revit.ini file under each user profile is correct. It may vary per company.

The way the script works is that it first backs up the revit.ini file to revit_old.ini. Next, the ParseFile subroutine is called to make the changes to each line in the file. Upon each call of the subroutine, the ini file is opened, read, the line of change is made, and then closed. The ParseFile subroutine is passed the INI filename, the defined variable representing the line of change to be made, and the string length of the variable in the INI file to be modified. Once this data is passed to the ParseFile, it will parse through the file, replace the line of code requested, and then closes the file. It then writes to the log file, the changes that were made. The AddSpace subroutine is there to add a blank line in between each system edited inside the log file for easier reading.

Here is the file available for download


 '*******************************************************************************  
 '   Author: Mick Pletcher  
 '    Date: 09 November 2012  
 '  Modified:  
 '  
 ' Description: This script will modify the contents of the revit.ini files  
 '*******************************************************************************  
 Option Explicit  

 REM Define Constants  
 CONST TempFolder    = "c:\temp\"  
 CONST LogFolderName = "RevitINI"  

 REM Define Global Variables  
 DIM FSO          : Set FSO          = CreateObject("Scripting.FileSystemObject")  
 DIM LogFolder    : LogFolder        = TempFolder & LogFolderName & "\"  
 DIM LogFile      : LogFile          = LogFolder & LogFolderName & ".txt"  
 DIM RelativePath : Set RelativePath = Nothing  

 REM Define the relative installation path  
 DefineRelativePath()  
 REM Create the Log Folder  
 CreateLogFolder()  
 REM Backup the old ini file and make desired changes to ini files across profiles  
 EditINIFiles()  
 REM Cleanup Global Variables  
 GlobalVariableCleanup()  

 '*******************************************************************************  
 '*******************************************************************************  

 Sub DefineRelativePath()  

      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  

 End Sub  

 '*******************************************************************************  

 Sub CreateLogFolder()  

      REM Define Local Objects  
      DIM objFile : Set objFile = Nothing  

      If NOT FSO.FolderExists(TempFolder) then  
           FSO.CreateFolder(TempFolder)  
      End If  
      If NOT FSO.FolderExists(LogFolder) then  
           FSO.CreateFolder(LogFolder)  
      End If  
      If FSO.FileExists(LogFile) then  
           FSO.DeleteFile Logfile, True  
      End If  
      If NOT FSO.FileExists(LogFile) then  
           Set objFile = FSO.CreateTextFile(LogFile)  
      End If  

      REM Cleanup Local Memory  
      Set objFile = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub EditINIFiles()  

      On Error Resume Next  

      REM Define Local Objects  
      DIM Folder     : Set Folder     = FSO.GetFolder("C:\Users")  
      DIM SubFolder  : Set SubFolder  = Nothing  
      DIM SubFolders : Set SubFolders = Folder.Subfolders  

      REM Define Local Variables  
      DIM DataLibraryLocations      : DataLibraryLocations      = "DataLibraryLocations=Imperial Library=\\global.gsp\data\gspm\CAD_ADSK_STDS\Revit\GSP\Libraries\US Imperial\, Imperial Detail Library=\\global.gsp\data\gspm\CAD_ADSK_STDS\Revit\GSP\Libraries\US Imperial\Detail Items\, GSP CADD=\\global.gsp\data\cadd\"  
      DIM DefaultTemplate           : DefaultTemplate           = "DefaultTemplate=\\global.gsp\data\gspm\CAD_ADSK_STDS\Revit\GSP\Templates\US Imperial\Architectural_default.rte"  
      DIM Username                  : Username                  = "Username="  
      DIM DisplayRecentFilesPage    : DisplayRecentFilesPage    = "DisplayRecentFilesPage=0"  
      DIM FamilyTemplatePath        : FamilyTemplatePath        = "FamilyTemplatePath=\\global.gsp\data\gspm\CAD_ADSK_STDS\Revit\GSP\Family Templates\English_I"  
      DIM UserDataCacheRevitIniPath : UserDataCacheRevitInipath = "C:\Program Files\Autodesk\Revit Architecture 2012\Program\UserDataCache\revit.ini"  
      DIM INIFile                   : INIFile                   = 0  

      REM Backup and edit the master INI file  
      If FSO.FileExists(UserDataCacheRevitInipath) Then  
           REM Backup revit.ini file  
           FSO.CopyFile UserDataCacheRevitInipath, Left(UserDataCacheRevitInipath, InStr(1,UserDataCacheRevitInipath,".")-1) & "_old.ini", True  
           REM Make changes to ini file  
           Call ParseFile(UserDataCacheRevitIniPath, DataLibraryLocations, Len(Left(DataLibraryLocations, InStr(1,DataLibraryLocations,"=")-1)))  
           Call ParseFile(UserDataCacheRevitIniPath, DefaultTemplate, Len(Left(DefaultTemplate, InStr(1,DefaultTemplate,"=")-1)))  
           Call ParseFile(UserDataCacheRevitIniPath, DisplayRecentFilesPage, Len(Left(DisplayRecentFilesPage, InStr(1,DisplayRecentFilesPage,"=")-1)))  
           Call ParseFile(UserDataCacheRevitIniPath, FamilyTemplatePath, Len(Left(FamilyTemplatePath, InStr(1,FamilyTemplatePath,"=")-1)))  
           Call AddSpace()  
      End If  
      REM Make changes to the revit.ini file under each profile  
      For Each Subfolder in Subfolders  
           IF (Subfolder.Name <> "Administrator") AND (Subfolder.Name <> "win2kload") AND _  
             (Subfolder.Name <> "All Users") AND (Subfolder.Name <> "Default") AND _  
             (Subfolder.Name <> "Default User") AND (Subfolder.Name <> "Public") THEN  
                INIFile = Folder & Chr(92) & Subfolder.Name & "\AppData\Roaming\Autodesk\Revit\Autodesk Revit Architecture 2012\revit.ini"  
                If FSO.FileExists(INIFile) then  
                     REM Backup the INI file  
                     FSO.CopyFile INIFile, Left(INIFile, InStr(1,INIFile,".")-1) & "_old.ini", True  
                     REM Parse through the INI file to make changes to each of the desired fields  
                     Call ParseFile(INIFile, DataLibraryLocations, Len(Left(DataLibraryLocations, InStr(1,DataLibraryLocations,"=")-1)))  
                     Call ParseFile(INIFile, DefaultTemplate, Len(Left(DefaultTemplate, InStr(1,DefaultTemplate,"=")-1)))  
                     Call ParseFile(INIFile, DisplayRecentFilesPage, Len(Left(DisplayRecentFilesPage, InStr(1,DisplayRecentFilesPage,"=")-1)))  
                     Call ParseFile(INIFile, FamilyTemplatePath, Len(Left(FamilyTemplatePath, InStr(1,FamilyTemplatePath,"=")-1)))  
                     Call AddSpace()  
                End If  
           End If  
      Next  

      REM Cleanup Local Memory  
      Set DataLibraryLocations      = Nothing  
      Set DefaultTemplate           = Nothing  
      Set DisplayRecentFilesPage    = Nothing  
      Set FamilyTemplatePath        = Nothing  
      Set Folder                    = Nothing  
      Set INIFile                   = Nothing  
      Set SubFolder                 = Nothing  
      Set SubFolders                = Nothing  
      Set UserDataCacheRevitInipath = Nothing  
      Set Username                  = Nothing  
 
 End Sub  

 '*******************************************************************************  

 Sub ParseFile(FileName, TxtString, StringLength)  

      REM Define Local Variables  
      DIM Count        : Count        = 0  
      DIM ForAppending : ForAppending = 8  
      DIM ForReading   : ForReading   = 1  
      DIM ForWriting   : ForWriting   = 2  
      DIM LineCount    : LineCount    = 0  
      DIM StrContents  : StrContents  = 0  
      DIM Written      : Written      = False  

      REM Define Local Objects  
      DIM File  : Set File = FSO.OpenTextFile(FileName, ForReading)  
      DIM strText : strText = File.ReadAll  

      File.Close  
      REM Divide contents into lines  
      StrContents = Split(strText, vbNewLine)  
      REM Count the number of lines  
      LineCount = UBound(StrContents)  
      REM Open File to write to it  
      Set File = FSO.OpenTextFile(FileName, ForWriting)  
      do while Count < LineCount  
           IF NOT Left(StrContents(Count), StringLength) = "Username=" Then  
                If (Left(StrContents(Count), StringLength) = Left(TxtString, StringLength)) Then  
                     File.WriteLine(TxtString)  
                     Written = True  
                Else  
                     File.WriteLine(StrContents(Count))  
                End If  
           End If  
           Count = Count + 1  
      Loop  
      If NOT Written Then  
           File.WriteLine(TxtString)  
      End If  
      File.Close  
      If FSO.FileExists(FileName) Then  
           If FSO.FileExists(LogFile) Then  
                Set File = FSO.OpenTextFile(LogFile, ForAppending)  
                If Count = LineCount Then  
                     File.Write(Left(TxtString, InStr(1,TxtString,"=")-1) & Chr(32) & "was written to" & Chr(32) & FileName & Chr(13))  
                     File.Close  
                Else  
                     File.Write(TxtString & Chr(32) & "was not written to FileName!")  
                End If  
           End If  
      End If  

      REM Cleanup Local Memory  
      Set Count        = Nothing  
      Set File         = Nothing  
      Set ForAppending = Nothing  
      Set ForReading   = Nothing  
      Set ForWriting   = Nothing  
      Set LineCount    = Nothing  
      Set StrContents  = Nothing  
      Set strText      = Nothing  
      Set Written      = Nothing  
 End Sub  

 '*******************************************************************************  

 Sub AddSpace()  

      REM Define Local Variables  
      DIM ForAppending : ForAppending = 8  
      DIM ForReading   : ForReading   = 1  
      DIM ForWriting   : ForWriting   = 2  

      REM Define Local Objects  
      DIM File : Set File = FSO.OpenTextFile(LogFile, ForAppending)  

      File.Write(Chr(13))  
      File.Close  

      REM Cleanup Local Memory  
      Set File         = Nothing  
      Set ForAppending = Nothing  
      Set ForReading   = Nothing  
      Set ForWriting   = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub GlobalVariableCleanup()  

      Set FSO          = Nothing  
      Set LogFolder    = Nothing  
      Set RelativePath = Nothing  

 End Sub  

15 November 2012

Autodesk Installation Error 1603

While installing Autodesk 2012, we were confronted with an error 1603. The error is caused by the Microsoft Visual C++, as outlined in this blog. Specifically, it is the design review portion of the package that requires the Visual C++. The solution provided does work, but the issue is not resolved if you need the newer version installed for other applications, such as Newforma. The solution for this is:

  1. Uninstall both x86 and x64 versions of Visual C++
  2. Install Autodesk, which will reinstall the old version of C++
  3. Again, uninstall both x86 and x64 versions of Visual C++
  4. Install the most current version of Visual C++
The older version of C++ is only required during the installation process. Once the application is installed, it can run off of the newer version. 

NOTE: The same process will have to be taken when uninstalling the product. It will require the older version of C++. 

14 November 2012

USMT 4.0 MDT/SCCM Migration


This script will execute the USMT, creating a MIG file located on the selected location, either on the local machine, or on the network location. This is intended to be used for generating the MIG file for the MDT/SCCM imaging process to be included in the build. This was written so that this script can be executed from any machine which then executes the USMT process locally on the target machine. PSTools will need to be downloaded and extracted to the USMTLocation, specified below in the Global constants. The global constants should be the primary changes needed to be made to run this script on any machine. The other change that will be needed is in the USMTMigrate Subroutine. There are additional XML files I have written for the USMT process that would need to be removed.

NOTE: To expedite the USMT process, I would suggest going to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProfileList and deleting all keys except for the following (You can find the key name under ProfileImagePath): SystemProfile, LocalService, NetworkService, Administrator, and the user profile being migrated. This will dramatically speed up the process otherwise it will scan each profile 20 times, with a 5 second delay upon each failure. You need not delete the profile directory, as the USMT only scans the profiles listed under that registry key.

You can download the script from here.

 REM ***************************************************************************   
 REM ***     Program: USMT_Capture.vbs   
 REM ***      Author: Mick Pletcher   
 REM ***     Created: 23 July 2010   
 REM ***      Edited: 21 March 2011   
 REM ***   
 REM *** Description: This script will execute the USMT, creating a MIG file   
 REM ***              located on the selected location, either on the local   
 REM ***              machine, or on the network location. This is intended to   
 REM ***              be used for generating the MIG file for the MDT/SCCM   
 REM ***              imaging process to be included in the build. This was written   
 REM ***              so that this script can be executed from any machine   
 REM ***              which then executes the USMT process locally on the   
 REM ***              target machine. PSTools will need to be downloaded and   
 REM ***              extracted to the USMTLocation, specified below in the   
 REM ***              Global constants. The global constants should be the   
 REM ***              primary changes needed to be made to run this script   
 REM ***              on any machine. The other change that will be needed   
 REM ***              is in the USMTMigrate Subroutine. There are   
 REM ***              additional XML files I have written for the USMT   
 REM ***              process that would need to be removed.   
 REM ***   
 REM ***              NOTE: To expedite the USMT process, I would suggest   
 REM ***              going to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\   
 REM ***              CurrentVersion\ProfileList and deleting all keys except for   
 REM ***              the following (You can find the key name under   
 REM ***              ProfileImagePath): SystemProfile, LocalService,   
 REM ***              NetworkService, Administrator, and the user profile   
 REM ***              being migrated. This will dramatically speed up the process   
 REM ***              otherwise it will scan each profile 20 times, with a 5   
 REM ***              second delay upon each failure. You need not delete   
 REM ***              the profile directory, as the USMT only scans the   
 REM ***              profiles listed under that registry key.   
 REM ***   
 REM ***              Script Process:   
 REM ***              1) Create HTML Display Status Window   
 REM ***              2) Enter Source, Destination, and Username   
 REM ***              3) Delete Old USMT folders and Create New USMT Folders   
 REM ***              4) Determine if the system is x86 or x64   
 REM ***              5) Perform USMT Migration on Old Machine   
 REM ***              6) Exit Script if USMT Migration Failed   
 REM ***              7) Verify USMT   
 REM ***              8) Cleanup Global Variables   
 REM ***    
 REM ***************************************************************************   
 Option Explicit   

 REM Define Global Constants   
 'Used in the query for retrieving the SID   
 CONST NetDomain = "nash"   
 ' Specifies where to find the USMT executables   
 CONST USMTLocation = "\\global.gsp\data\special\Deploy\USMT40\"   
 ' Specifies where to write the MIG file locally   
 CONST USMTLocalStore = "c:\temp\MigData\"   
 ' Specifies where to write the MIG file on the network share   
 CONST USMTNetworkStore = "\\MDT02\USMT\"   

 REM Define Global Objects   
 DIM objIE : Set objIE = CreateObject("InternetExplorer.Application")   

 REM Define Global Variables   
 DIM OldComputer   : Set OldComputer = Nothing   
 DIM ReturnCode    : ReturnCode      = "0"   
 DIM SID           : Set SID         = Nothing   
 DIM UserName      : Set UserName    = Nothing   
 DIM USMTOutput    : Set USMTOutput  = Nothing   
 DIM USMTSourceCMD : USMTSourceCMD   = "0"   
 DIM USMTDestCMD   : USMTDestCMD     = "0"   

 REM Create HTML Display Status Window   
 CreateDisplayWindow()   
 REM Enter Source, Destination, and Username   
 GetComputerInfo()   
 REM Delete Old USMT folders, if exists, and Create New USMT Folders   
 CreateUSMTFolders()   
 REM Determine if the system is x86 or x64   
 DetermineArchitecture()   
 REM Retrieve SID from Old Computer   
 GetSID()   
 REM Perform USMT Migration on Old Machine   
 USMTMigrate()   
 REM Verify the ScanState ran with no errors   
 VerifyScanState()   
 REM Cleanup Global Variables   
 GlobalVariableCleanUp()   

 '******************************************************************************   
 '******************************************************************************   

 Sub CreateDisplayWindow()   

   REM Define Local Constants   
   CONST strComputer = "."   

   REM Define Local Objects   
   DIM objWMIService : Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")   
   DIM colItems      : Set colItems      = objWMIService.ExecQuery ("Select PelsWidth,PelsHeight From Win32_DisplayConfiguration")   
   DIM objItem       : Set objItem       = Nothing   

   REM Define Local Variables   
   DIM intWidth        : intWidth            = 320   
   DIM intHeight       : intHeight           = 240   
   DIM intScreenWidth  : Set intScreenWidth  = Nothing   
   DIM intScreenHeight : Set intScreenHeight = Nothing   

   For Each objItem in colItems   
     intScreenWidth = objItem.PelsWidth   
     intScreenHeight = objItem.PelsHeight   
   Next   
   objIE.Navigate "about:blank"   
   objIE.Toolbar  = 0   
   objIE.StatusBar = 0   
   objIE.AddressBar = 0   
   objIE.MenuBar  = 0   
   objIE.Resizable = 0   
   While objIE.ReadyState <> 4   
     WScript.Sleep 100   
   Wend   
   objIE.Left = (intScreenWidth / 2) - (intWidth / 2)   
   objIE.Top = (intScreenHeight / 2) - (intHeight / 2)   
   objIE.Visible = True   

   REM Cleanup Local Variables   
   Set colItems        = Nothing   
   Set intScreenWidth  = Nothing   
   Set intScreenHeight = Nothing   
   Set intWidth        = Nothing   
   Set intHeight       = Nothing   
   Set objItem         = Nothing   
   Set objWMIService   = Nothing   

 End Sub   

 '******************************************************************************   

 Sub GetComputerInfo()   

   OldComputer = InputBox( "Enter the old computer name:" )   
   UserName    = InputBox( "Enter the username:" )   
   USMTOutput  = MsgBox("Output USMT to Network Location?", 4)   
   If USMTOutput = 6 then   
     USMTOutput = USMTNetworkStore & UserName & "\" & OldComputer   
   Else   
     USMTOutput = USMTLocalStore & UserName & "\" & OldComputer   
   End If   
   objIE.Document.WriteLn "<FONT SIZE=8>USMT migration of " & UserName & " from " & OldComputer & " to " & USMTOutput &_   
               Chr(32) & "</FONT><BR><BR><BR>"   

 End Sub   

 '******************************************************************************   

 Sub CreateUSMTFolders()   

   On Error Resume Next   

   REM Define Local Objects   
   DIM FSO    : SET FSO    = CreateObject("Scripting.FileSystemObject")   
   DIM oShell : Set oShell = WScript.CreateObject("WScript.Shell")   

   REM Define Local Variables   
   DIM CreateFolder : CreateFolder = "cmd.exe /c md" & Chr(32) & USMTOutput

   objIE.Document.WriteLn "Creating USMT Folders....."   
   REM Create the USMT folders if they do not exist   
   If NOT FSO.FolderExists(USMTOutput) then   
     oShell.Run CreateFolder, 7, True   
   End If   

   REM Cleanup Local Variables   
   Set FSO          = Nothing   
   Set CreateFolder = Nothing   
   Set oShell       = Nothing   

 End Sub   

 '******************************************************************************   

 Sub DetermineArchitecture()   

   REM Define Local Objects   
   DIM FSO                 : SET FSO                 = CreateObject("Scripting.FileSystemObject")   
   DIM objWMIService       : Set objWMIService       = Nothing   
   DIM objWMIServiceSet    : Set objWMIServiceSet    = Nothing   
   DIM colOperatingSystems : Set colOperatingSystems = Nothing   
   DIM objOperatingSystem  : Set objOperatingSystem  = Nothing   

   REM Define Local Variables   
   DIM x86RUNPATH  : x86RUNPATH  = USMTLocation & "x86"   
   DIM x64RUNPATH  : x64RUNPATH  = USMTLocation & "x64"   
   DIM OSSourceType : OSSourceType = "\\" & OldComputer & "\c$\Program Files (x86)"   
   DIM msgSource  : Set msgSource = Nothing   

   Set objWMIService = GetObject("winmgmts:\\" & OldComputer & "\root\cimv2")   
   Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")   

   For Each objOperatingSystem in colOperatingSystems   
     msgSource = objOperatingSystem.Caption   
   Next   
   objIE.Document.WriteLn "Determining Source Architecture....."   
   If FSO.FolderExists(OSSourceType) Then   
     USMTSourceCMD = x64RUNPATH   
   else   
     USMTSourceCMD = x86RUNPATH   
   End IF   
   If NOT USMTSourceCMD = "0" then   
     objIE.Document.WriteLn "Success" & "<BR>"   
   else   
     objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR>"   
   End If   
   objIE.Document.WriteLn "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Source:&nbsp; " & msgSource &_   
               Chr(32) & Right(USMTSourceCMD,3) & "<BR><BR>"   

   REM Cleanup Variables   
   Set colOperatingSystems = Nothing   
   Set FSO                 = Nothing   
   Set msgSource           = Nothing   
   Set x86RUNPATH          = Nothing   
   Set x64RUNPATH          = Nothing   
   Set objWMIService       = Nothing   
   Set objWMIServiceSet    = Nothing   
   Set OSSourceType        = Nothing   
   Set objOperatingSystem  = Nothing   

 End Sub   

 '******************************************************************************   

 Sub GetSID()   

   REM Define Local Objects   
   DIM objWMIService : Set objWMIService = GetObject("winmgmts:\\" & OldComputer & "\root\cimv2")   
   DIM objAccount  : Set objAccount  = Nothing   

 '  Set objAccount = objWMIService.Get _   
 '    ("Win32_UserAccount.Name=" & Chr(39) & UserName & Chr(39) & ",Domain='nash'")   
   Set objAccount = objWMIService.Get _   
     ("Win32_UserAccount.Name=" & Chr(39) & UserName & Chr(39) & ",Domain=" & Chr(39) & NetDomain & Chr(39))   
   SID = objAccount.SID   

   REM Local Variable Cleanup   
   Set objAccount    = Nothing   
   Set objWMIService = Nothing   

 End Sub   

 '******************************************************************************   

 Sub USMTMigrate()   

   REM Define Local Objects   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM Debug       : Debug       = "13"   
   DIM IgnoreProfs : IgnoreProfs = "cmd.exe /c Set MIG_IGNORE_PROFILE_MISSING=1"   
   DIM TMP         : TMP         = "c:\Temp"   
   DIM MigData     : MigData     = TMP & "\MigData"   
   DIM LOGPATH     : LOGPATH     = MigData & "\" & UserName   
   DIM RemoteExec  : RemoteExec  = USMTLocation & "PSTools\PsExec.exe \\" & OldComputer &_   
                                   Chr(32) & "-s" & Chr(32)   
   DIM USMT        : USMT        = RemoteExec & USMTSourceCMD & "\scanstate.exe " & USMTOutput & Chr(32) & "/v:" & Debug & Chr(32) & "/i:" &_   
                                   USMTSourceCMD & "\Migapp.xml" & Chr(32) & "/i:" & USMTSourceCMD & "\MigDocs.xml" & Chr(32) & "/i:" &_   
                                   USMTSourceCMD & "\miguser.xml" & Chr(32) & "/i:" & USMTSourceCMD & "\MigExclude.xml" & Chr(32) &_   
                                   "/progress:" & LOGPATH & "\ScanStateProg.log" & Chr(32) & "/l:" & LOGPATH & "\ScanState.log" &_   
                                   Chr(32) & "/ui:" & SID & Chr(32) & "/ue:*\* /c /vsc"   

   objIE.Document.WriteLn "Executing Scanstate on " & OldComputer & "....."   
   ReturnCode = oShell.Run(IgnoreProfs, 7, True)   
   ReturnCode = oShell.Run(USMT, 7, True)   
   If ReturnCode = "0" Then   
     objIE.Document.WriteLn "Success" & "<BR><BR>"   
   else   
     objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR><BR>"   
   End If   

   REM Cleanup Variables   
   Set Debug       = Nothing   
   SET IgnoreProfs = Nothing   
   SET oShell      = Nothing   
   SET TMP         = Nothing   
   SET MigData     = Nothing   
   SET LOGPATH     = Nothing   
   Set RemoteExec  = Nothing   
   Set USMT        = Nothing   

 End Sub   

 '******************************************************************************   

 Sub VerifyScanState()   

   If NOT ReturnCode = "0" then   
     MsgBox("The data migration on " & OldComputer & " failed due to error" & ReturnCode &_   
         ". Please check the log file located at & \\" & OldComputer & "\c$\Temp\MigData\ScanLog.log.")   
     GlobalVariableCleanUp()   
     WScript.Quit   
   Else   
     Set ReturnCode = Nothing   
   End If   

 End Sub   

 '******************************************************************************  
 
 Sub GlobalVariableCleanUp()   

   Set OldComputer   = Nothing   
   Set objIE         = Nothing   
   Set ReturnCode    = Nothing   
   Set UserName      = Nothing   
   Set USMTOutput    = Nothing   
   Set USMTSourceCMD = Nothing   
   Set USMTDestCMD   = Nothing   

 End Sub  

09 November 2012

SCCM Package Doesn't Update

You have a small package in SCCM that you needed to make a couple of lines of changes in the deployment script and it doesn't seem to update when you update the package in SCCM. This is because the changes are so minute that SCCM cannot detect any changes were made and therefor the package is not updated.

The best strategy when make small changes is to do the following:

  1. Remove the package from the distribution points
  2. Redistribute the package back to the distribution points
  3. Clear the CCM cache on all of the machines
  4. If you have already run the package on the machines, re-run it. The package will most likely fail on all of the machines.
  5. Update the distribution point one more time
  6. Rerun the package for the last time and it should not successfully deploy the package with the new updates

05 November 2012

Using Sysprep to upgrade or replace a failed HDD


This script will sysprep the HDD on one machine so that it can be swapped out in another PC. This can save considerable money in shipping when replacing a bad HDD or upgrading the OS in a remote office. You can use any model PC to build up the OS with all of the applications installed and configured. USMT can also be run to include the user's profile.

To start, you will need to create a unattend.xml file using Windows System Image Manager. This will include the installation of the SID based apps that get uninstalled from this script. The next thing that will need to be done is to create a directory tree of the different computer models with the drivers under each Folder Model. This is imperative and this script reads the folder names (computer models) and displays the list to choose from to copy the drivers down to the machine for sysprepping.

Next, you will need to create a setupcomplete.cmd file and place it in the same directory as the sysprep.vbs file. This file will be copied down locally to the HDD and will execute a list of commands once the sysprep setup is complete. I have two lines in mine:

del /Q /F c:\windows\system32\sysprep\unattend.xml
RMDIR /s /q c:\drivers

It deletes the unattend.xml file because of network credentials and then deletes the c:\drivers folder where the drivers were copied for the sysprep setup.

To setup this script, you will need to configure the sourcedrivers and sourcefolders variables to point to the correct location on your network. These variables are located in the various subroutines. You may also need to remove or add additional applications to the Uninstall list. These applications are SID based apps and have to be installed on each specific machine. They cannot be included in an image. SID based apps are usually antivirus, SMS/SCCM type apps.

To use this script, you will be prompted for the computer model. This is the computer model of the final machine that the HDD will be placed into. The second thing will be to enter the computer name of the final machine. You do not need to move the final machine in active directory, as this HDD will have the same computer name. The script will continue through and will shut down the machine when complete. At that point, you can remove the HDD and insert it into the user’s computer. This will be a seamless setup. There will be no prompts for the end-user. Once it is completed, the system will be sitting at ctrl+alt+del.

NOTE: It is very important that you make sure the BIOS is configured correctly to your company’s specs. If the BIOS on the user’s computer is not, the OS can become corrupt and a complete rebuild will be required.

You can download the script from here.


 '*******************************************************************************  
 '   Program: sysprep.vbs  
 '   Author: Mick Pletcher  
 '    Date: 12 May 2011  
 '  Modified:  
 '  
 '   Program: Sysprep.vbs  
 '   Version:  
 ' Description: This script will sysprep the HDD on one machine so that it can  
 '                 be swapped out in another PC. This can save considerable money  
 '                 in shipping when replacing a bad HDD or upgrading the OS in a  
 '                 remote office. You can use any model PC to build up the OS with  
 '                 all of the applications installed and configured. USMT can also  
 '                 be run to include the user's profile.  
 '  
 '                 To start, you will need to create a unattend.xml file using  
 '                 Windows System Image Manager. This will include the  
 '                 installation of the SID based apps that get uninstalled from  
 '                 this script. The next thing that will need to be done is to  
 '                 create a directory tree of the different computer models with  
 '                 the drivers under each Folder Model. This is imperative and  
 '                 this script reads the folder names (computer models) and displays  
 '                 the list to choose from to copy the drivers down to the machine  
 '                 for sysprepping.   
 '  
 '                 Next, you will need to create a setupcomplete.cmd file and place  
 '                 it in the same directory as the sysprep.vbs file. This file will  
 '                 be copied down locally to the HDD and will execute a list of  
 '                 commands once the sysprep setup is complete. I have two lines in mine:  
 '  
 '                 del /Q /F c:\windows\system32\sysprep\unattend.xml  
 '                 RMDIR /s /q c:\drivers  
 '  
 '                 It deletes the unattend.xml file because of network credentials  
 '                 and then deletes the c:\drivers folder where the drivers were  
 '                 copied for the sysprep setup.  
 '  
 '                 To setup this script, you will need to configure the sourcedrivers  
 '                 and sourcefolders variables to point to the correct location on  
 '                 your network. These variables are located in the various subroutines.  
 '                 You may also need to remove or add additional applications to the  
 '                 Uninstall list. These applications are SID based apps and have to  
 '                 be installed on each specific machine. They cannot be included in  
 '                 an image. SID based apps are usually antivirus, SMS/SCCM type apps.  
 '  
 '                 To use this script, you will be prompted for the computer model.  
 '                 This is the computer model of the final machine that the HDD will  
 '                 be placed into. The second thing will be to enter the computer name  
 '                 of the final machine. You do not need to move the final machine in  
 '                 active directory, as this HDD will have the same computer name. The  
 '                 script will continue through and will shut down the machine when  
 '                 complete. At that point, you can remove the HDD and insert it into  
 '                 the user’s computer. This will be a seamless setup. There will be no  
 '                 prompts for the end-user. Once it is completed, the system will be  
 '                 sitting at ctrl+alt+del.   
 '  
 '                 NOTE: It is very important that you make sure the BIOS is configured  
 '                          correctly to your company’s specs. If the BIOS on the user’s  
 '                          computer is not, the OS can become corrupt and a complete  
 '                          rebuild will be required.   
 '  
 '                 1) Define the relative installation path  
 '                 2) Create the Log Folder  
 '                 3) Enable Administrator Account  
 '                 4) Stop Services  
 '                 5) Get Computer Model  
 '                 6) Robocopy drivers folders to Sysprep Folder  
 '                 7) Copy sysprep folder to c:\sysprep  
 '                 8) Insert Computer Name into unattend.xml  
 '                 9) Create SetupComplete  
 '                10) Copy Copy Forefront to local directory  
 '                11) Copy Forefront Threat Management Gateway to local directory  
 '                12) Copy Junk Email Reporting Add-in to local directory  
 '                13) Copy SMS to local directory  
 '                10) Uninstall Forefront Client Security Antimalware Service  
 '                11) Uninstall Microsoft Forefront Client Security State Assessment Service  
 '                12) Uninstall Microsoft Operations Manager 2005 Agent  
 '                13) Uninstall Microsoft Forefront TMG Client  
 '                14) Uninstall Microsoft Junk E-mail Reporting Add-in  
 '                15) Uninstall SMS Advanced Client  
 '                16) Defrag Machine  
 '                17) Sysprep machine  
 '                18) Cleanup Global Variables  
 '*******************************************************************************  
 Option Explicit  
 REM Define Constants  
 CONST TempFolder  = "c:\temp\"  
 CONST LogFolderName = "sysprep"  
 REM Define Global Objects  
 DIM objIE : Set objIE = CreateObject("InternetExplorer.Application")  
 REM Define Global Variables  
 DIM ComputerModel : Set ComputerModel = Nothing  
 DIM ComputerName : Set ComputerName = Nothing  
 DIM LogFolder   : LogFolder     = TempFolder & LogFolderName & "\"  
 DIM RelativePath : Set RelativePath = Nothing  
 DIM UAC      : Set UAC      = Nothing  
 REM Create HTML Display Status Window  
 CreateDisplayWindow()  
 REM Minimize Folder  
 MinimizeFolder()  
 REM Define the relative installation path  
 DefineRelativePath()  
 REM Create the Log Folder  
 CreateLogFolder()  
 REM Get Computer Model  
 GetComputerModel()  
 REM Get Computer Name  
 GetComputerName()  
 REM Disable UAC?  
 DisableUAC()  
 REM Enable Administrator Account  
 EnableAdministratorAccount()  
 REM Stop Services  
 StopServices()  
 REM Robocopy drivers folders to Sysprep Folder  
 CopyDriverFolders()  
 REM Copy SCCM and Endpoint  
 CopySCCMEndPoint()  
 REM Copy sysprep folder to c:\sysprep  
 CopySysprepFiles()  
 REM Insert Computer Name into unattend.xml  
 InsertComputerName()  
 REM Create SetupComplete  
 CreateSetupComplete()  
 REM Copy UAC Script  
 CopyUAC()  
 REM Uninstall Endpoint Protection  
 UninstallEndpoint()  
 REM Uninstall SCCM Client  
 UninstallSCCM()  
 REM Defrag Machine  
 Defrag()  
 REM Sysprep machine  
 Sysprep()  
 REM Cleanup Global Variables  
 GlobalVariableCleanup()  
 '*******************************************************************************  
 '*******************************************************************************  
 Sub CreateDisplayWindow()  
      REM Define Local Constants  
      CONST strComputer = "."  
      REM Define Local Objects  
      DIM objWMIService : Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")  
      DIM colItems   : Set colItems   = objWMIService.ExecQuery ("Select PelsWidth,PelsHeight From Win32_DisplayConfiguration")  
      DIM objItem    : Set objItem    = Nothing  
      REM Define Local Variables  
      DIM intWidth : intWidth = 320  
      DIM intHeight : intHeight = 240  
      DIM intScreenWidth : Set intScreenWidth = Nothing  
      DIM intScreenHeight : Set intScreenHeight = Nothing  
      For Each objItem in colItems  
           intScreenWidth = objItem.PelsWidth  
           intScreenHeight = objItem.PelsHeight  
      Next  
      objIE.Navigate "about:blank"  
      objIE.Toolbar  = 0  
      objIE.StatusBar = 0  
      objIE.AddressBar = 0  
      objIE.MenuBar  = 0  
      objIE.Resizable = 0  
      While objIE.ReadyState <> 4  
           WScript.Sleep 100  
      Wend  
      objIE.Left = (intScreenWidth / 2) - (intWidth / 2)  
      objIE.Top = (intScreenHeight / 2) - (intHeight / 2)  
      objIE.Visible = True  
      objIE.Document.WriteLn "<FONT SIZE=8>Sysprep</FONT><BR><BR><BR>"  
      REM Cleanup Local Variables  
      Set colItems    = Nothing  
      Set intScreenWidth = Nothing  
      Set intScreenHeight = Nothing  
      Set intWidth    = Nothing  
      Set intHeight    = Nothing  
      Set objItem     = Nothing  
      Set objWMIService  = Nothing  
 End Sub  
 '******************************************************************************  
 Sub MinimizeFolder()  
      REM Define Local Variables  
      DIM Active  
      DIM FolderWindow : FolderWindow = "sysprepWin7"  
      DIM oShell    : SET oShell = CreateObject("Wscript.Shell")  
      Active = oshell.appactivate(FolderWindow)  
      If Active Then  
           oshell.sendkeys "% n"  
      End If  
      REM Cleanup Local Memory  
      Set Active    = Nothing  
      Set FolderWindow = Nothing  
      Set oShell    = Nothing  
 End Sub  
 '******************************************************************************  
 Sub DefineRelativePath()  
      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  
 End Sub  
 '*******************************************************************************  
 Sub CreateLogFolder()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      If NOT FSO.FolderExists(TempFolder) then  
           FSO.CreateFolder(TempFolder)  
      End If  
      If NOT FSO.FolderExists(LogFolder) then  
           FSO.CreateFolder(LogFolder)  
      End If  
      REM Cleanup Local Variables  
      Set FSO = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub EnableAdministratorAccount()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      objIE.Document.WriteLn "Enabling Administrator Account....."  
      oShell.Run "net.exe user administrator /active:yes", 7, True  
      objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      REM Cleanup Local Variables  
      Set oShell   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub StopServices()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Parameters1 : Parameters1 = Chr(32) & "stop"  
      DIM Parameters2 : Parameters2 = Chr(32) & "start= disabled"  
      DIM Service   : Service   = Chr(32) & "WMPNetworkSvc"  
      DIM StopSvc   : StopSvc   = "sc.exe" & Parameters1 & Service  
      DIM DisableSvc : DisableSvc = "sc.exe config" & Service & Parameters2  
      objIE.Document.WriteLn "Disabling Windows Media Player Service....."  
      oShell.Run StopSvc, 7, True  
      oShell.Run DisableSvc, 7, True  
      objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      REM Cleanup Local Variables  
      Set DisableSvc = Nothing  
      Set oShell   = Nothing  
      Set Parameters1 = Nothing  
      Set Parameters2 = Nothing  
      Set Service   = Nothing  
      Set StopSvc   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub GetComputerModel()  
      REM Define Local Constants  
      CONST strFolder = "\\mdt01\c$\DeploymentShare\Drivers\Windows 7 Drivers\"  
      REM Define Local Objects  
      DIM FSO    : Set FSO    = CreateObject("Scripting.FileSystemObject")  
      DIM oFolder  : Set oFolder  = FSO.GetFolder(strFolder)  
      DIM colFolders : Set colFolders = oFolder.SubFolders  
      REM Define Local Variables  
      DIM Count   : Count     = 1  
      DIM Folder   : Set Folder   = Nothing  
      DIM oSubFolder : Set oSubFolder = Nothing  
      DIM StrList  : StrList    = "Select the model for Sysprepping:"  
      REM Get list of current model PCs  
      strList = strList & vbCrLf  
      For Each oSubFolder in colFolders  
           Folder = Right(oSubFolder.Path, Len(oSubFolder.Path) - InStrRev(oSubFolder.Path, "\"))  
           If Count < 10 then  
                strList = strList & vbCrLf & Chr(32) & Chr(32) & Count & " - " & Folder  
           Else  
                strList = strList & vbCrLf & Count & " - " & Folder  
           End If  
           Count = Count + 1  
      Next  
      REM Select Computer Model  
      ComputerModel = InputBox(strList, "ComputerModel")  
      If ComputerModel = "" then  
           GlobalVariableCleanup()  
           WScript.quit  
      End If  
      ComputerModel = CInt(ComputerModel)  
      REM Reinitialize Variables  
      Count     = 1  
      Set Folder   = Nothing  
      Set oSubFolder = Nothing  
      REM Get Computer Model  
      For Each oSubFolder in colFolders  
           If Count = ComputerModel then  
                Folder = Right(oSubFolder.Path, Len(oSubFolder.Path) - InStrRev(oSubFolder.Path, "\"))  
           End If  
           Count = Count + 1  
      Next  
      ComputerModel = Folder  
      REM Cleanup Local Variables  
      Set colFolders = Nothing  
      Set Count   = Nothing  
      Set Folder   = Nothing  
      Set FSO    = Nothing  
      Set oFolder  = Nothing  
      Set oSubFolder = Nothing  
      Set StrList  = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub GetComputerName()  
      ComputerName = InputBox( "Enter the user's computer name:" )  
 End Sub  
 '*******************************************************************************  
 Sub DisableUAC()  
      UAC = MsgBox( "Disable UAC?", 4, "UAC" )  
 End Sub  
 '*******************************************************************************  
 Sub CopyDriverFolders()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Robocopy   : Robocopy   = "robocopy.exe" & Chr(32)  
      DIM SourceDrivers : SourceDrivers = "\\mdt01\Drivers\Windows 7 Drivers\"  
      DIM DestDrivers  : DestDrivers  = "c:\Drivers"  
      DIM Parameters  : Parameters  = "/e /eta /r:1 /w:0 /mir"  
      DIM Install    : Install    = Robocopy & Chr(34) & SourceDrivers & ComputerModel &_  
                                                        Chr(34) & Chr(32) & DestDrivers & Chr(32) & Parameters  
      objIE.Document.WriteLn "Copying " & ComputerModel & Chr(32) & "drivers to local directory....."  
      oShell.Run Install, 7, True  
      If FSO.FolderExists(DestDrivers) Then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set DestDrivers  = Nothing  
      Set FSO      = Nothing  
      Set Install    = Nothing  
      Set oShell    = Nothing  
      Set Robocopy   = Nothing  
      Set SourceDrivers = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CopySysprepFiles()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      REM Define Local Variables  
      DIM MyFile : MyFile = RelativePath & "unattend.xml"  
      DIM Dest  : Dest  = "C:\windows\system32\sysprep\"  
      objIE.Document.WriteLn "Copying sysprep files....."  
      FSO.CopyFile MyFile, Dest, True  
      If FSO.FileExists(Dest & "unattend.xml") then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set Dest  = Nothing  
      Set MyFile = Nothing  
      Set FSO   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub InsertComputerName()  
      REM Define Local Constants  
      CONST ForReading = 1   
      CONST ForWriting = 2   
      REM Define Local Objects  
      DIM File     : File       = "C:\windows\system32\sysprep\unattend.xml"  
      DIM strOld    : strOld      = "<ComputerName></ComputerName>"  
      DIM strNew    : strNew      = "<ComputerName>" & ComputerName & "</ComputerName>"  
      DIM objFSO    : Set objFSO    = CreateObject("Scripting.FileSystemObject")   
      DIM objFile    : Set objFile    = objFSO.getFile(File)   
      DIM objTextStream : Set objTextStream = objFile.OpenAsTextStream(ForReading)   
      DIM strInclude  : strInclude    = objTextStream.ReadAll   
      DIM Written    : Written      = False  
      objIE.Document.WriteLn "Injecting Computer Name into unattend.xml file....."  
      objTextStream.Close  
      Set objTextStream = Nothing  
      If InStr(strInclude,strOld) > 0 Then   
           strInclude = Replace(strInclude,strOld,strNew)   
           Set objTextStream = objFile.OpenAsTextStream(ForWriting)   
           objTextStream.Write strInclude   
           objTextSTream.Close   
           Set objTextStream = Nothing   
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
           Written = True  
      End If  
      If NOT Written Then  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set File     = Nothing  
      Set objFile    = Nothing   
      Set objFSO    = Nothing  
      Set objTextStream = Nothing  
      Set strInclude  = Nothing  
      Set strNew    = Nothing  
      Set strOld    = Nothing  
      Set Written    = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CopySCCMEndPoint()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      REM Define Local Variables  
      DIM SourceFolder : SourceFolder = "\\global.gsp\data\clients\na_clients\Microsoft\SCCM\Client"  
      DIM DestFolder  : DestFolder  = "C:\sysprepfolders\"  
      DIM SysprepFolder : SysprepFolder = "C:\sysprepfolders"  
      objIE.Document.WriteLn "Copying SCCM and Endpoint installation files....."  
      If NOT FSO.FolderExists(SysprepFolder) then  
           FSO.CreateFolder(SysprepFolder)  
      End If  
      If NOT FSO.FolderExists(DestFolder) then  
           FSO.CreateFolder(DestFolder)  
      End If  
      FSO.CopyFolder SourceFolder, DestFolder, True  
      If FSO.FolderExists(DestFolder & "Client") then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set DestFolder  = Nothing  
      Set FSO      = Nothing  
      Set SourceFolder = Nothing  
      Set SysprepFolder = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CopyUAC()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      REM Define Local Variables  
      DIM SourceFolder : SourceFolder = "\\global.gsp\data\clients\na_clients\GSP\UserAccountControl"  
      DIM DestFolder  : DestFolder  = "C:\sysprepfolders\"  
      DIM SysprepFolder : SysprepFolder = "C:\sysprepfolders"  
      objIE.Document.WriteLn "Copying UAC files....."  
      If NOT FSO.FolderExists(SysprepFolder) then  
           FSO.CreateFolder(SysprepFolder)  
      End If  
      If NOT FSO.FolderExists(DestFolder) then  
           FSO.CreateFolder(DestFolder)  
      End If  
      FSO.CopyFolder SourceFolder, DestFolder, True  
      'MsgBox( UAC )  
      If UAC = 6 then  
           FSO.CopyFile SourceFolder & "\DisableUAC.txt", DestFolder  
      End If  
      If FSO.FolderExists(DestFolder & "UserAccountControl") then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
 End Sub  
 '*******************************************************************************  
 Sub CopyPageFileSize()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      REM Define Local Variables  
      DIM SourceFolder : SourceFolder = "\\global.gsp\data\clients\na_clients\Build\PageFileSize"  
      DIM DestFolder  : DestFolder  = "C:\sysprepfolders\"  
      DIM SysprepFolder : SysprepFolder = "C:\sysprepfolders"  
      objIE.Document.WriteLn "Copying Pagefile Size Script....."  
      If NOT FSO.FolderExists(SysprepFolder) then  
           FSO.CreateFolder(SysprepFolder)  
      End If  
      If NOT FSO.FolderExists(DestFolder) then  
           FSO.CreateFolder(DestFolder)  
      End If  
      FSO.CopyFolder SourceFolder, DestFolder, True  
      If FSO.FolderExists(DestFolder & "PageFileSize") then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set DestFolder  = Nothing  
      Set FSO      = Nothing  
      Set SourceFolder = Nothing  
      Set SysprepFolder = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CreateSetupComplete()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      REM Define Local Variables  
      DIM Dest  : Dest    = "C:\windows\setup\scripts\"  
      DIM MyFile : MyFile   = RelativePath & "SetupComplete.cmd"  
      DIM NewDIR : Set NewDIR = Nothing  
      objIE.Document.WriteLn "Copying setup completion script....."  
      If NOT FSO.FolderExists(Dest) then  
           Set NewDIR = FSO.CreateFolder(Dest)  
      End If  
      FSO.CopyFile MyFile, Dest, True  
      If FSO.FileExists(Dest & "SetupComplete.cmd") then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set Dest  = Nothing  
      Set FSO  = Nothing  
      Set MyFile = Nothing  
      Set NewDIR = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub UninstallEndpoint()  
      REM Define Local Objects  
      DIM FSO  : Set FSO  = CreateObject("Scripting.FileSystemObject")  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      objIE.Document.WriteLn "Uninstalling Endpoint Protection....."  
      If FSO.FileExists("C:\Windows\ccmsetup\SCEPInstall.exe") Then  
           oShell.Run "C:\Windows\ccmsetup\SCEPInstall.exe /u /s", 7, True  
      End If  
      If NOT FSO.FileExists("C:\Windows\ccmsetup\SCEPInstall.exe") Then  
           objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      Else  
           objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
      End If  
      REM Cleanup Local Variables  
      Set FSO  = Nothing  
      Set oShell = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub UninstallSCCM()  
      REM Define Local Objects  
      DIM FSO  : Set FSO  = CreateObject("Scripting.FileSystemObject")  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      If FSO.FileExists("C:\Windows\ccmsetup\ccmsetup.exe") Then  
           objIE.Document.WriteLn "Uninstalling SCCM Client....."  
           oShell.Run "C:\Windows\ccmsetup\ccmsetup.exe /uninstall", 7, True  
           If NOT FSO.FileExists("C:\Windows\CCM\CcmExec.exe") Then  
                objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
           Else  
                objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
           End If  
      End If  
      If FSO.FileExists("C:\Windows\ccmsetup\WindowsFirewallConfigurationProvider.msi") Then  
           objIE.Document.WriteLn "Uninstalling Windows Firewall Configuration Provider....."  
           oShell.Run "msiexec.exe /x C:\Windows\ccmsetup\WindowsFirewallConfigurationProvider.msi /qb- /norestart", 7, True  
           If NOT FSO.FileExists("C:\Windows\ccmsetup\WindowsFirewallConfigurationProvider.msi") Then  
                objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
           Else  
                objIE.Document.WriteLn "<FONT COLOR=RED>Failed</FONT>" & "<BR>"  
           End If  
      End If  
      REM Cleanup Local Variables  
      Set FSO  = Nothing  
      Set oShell = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub Defrag()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      objIE.Document.WriteLn "Defragmenting....."  
      oShell.Run "defrag c: -v -w", 7, True  
      objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      REM Cleanup Local Variables  
      Set oShell = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub Sysprep()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Dir    : Dir    = "C:\Windows\System32\sysprep\"  
      DIM Parameters : Parameters = Chr(32) & "/generalize /oobe /shutdown /unattend:C:\Windows\System32\sysprep\unattend.xml"  
      DIM Execute  : Execute  = Dir & "sysprep.exe" & Parameters  
      objIE.Document.WriteLn "Sysprepping....."  
      oShell.Run Execute, 7, True  
      objIE.Document.WriteLn "<FONT COLOR=BLUE>Complete</FONT>" & "<BR>"  
      REM Cleanup Local Variables  
      Set Dir    = Nothing  
      Set Execute  = Nothing  
      Set oShell   = Nothing  
      Set Parameters = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub GlobalVariableCleanup()  
      Set ComputerModel = Nothing  
      Set ComputerName = Nothing  
      Set LogFolder   = Nothing  
      Set objIE     = Nothing  
      Set RelativePath = Nothing  
 End Sub  

02 November 2012

Uninstalling Adobe CS3 Applications

Here is a script that silently uninstalls most all of the Adobe CS3 applications and suites. This same script can be run on all CS3 apps. In order to use this, it has to be in the root directory of the Adobe application installation directories.

NOTE: Flash Professional and Dreamweaver do not have the Deployment subdirectory containing the uninstall.xml file. The XML files are in the root installation directory. For those, remove deployment\ from line 43. Acrobat and Photoshop Elements can both be uninstalled using a simple msiexec.exe /x command.

You can download the script from here.

 '*******************************************************************************  
 '      Author: Mick Pletcher  
 '        Date: 02 November 2012  
 '    Modified:   
 '  
 '     Program: Adobe Design Standard CS3 Uninstaller  
 '     Version:   
 ' Description: This will uninstall Design Standard CS3  
 '*******************************************************************************  
 Option Explicit  

 REM Define Global Variables  
 DIM RelativePath : Set RelativePath = Nothing  

 REM Define the relative installation path  
 DefineRelativePath()  
 REM Install   
 Uninstall()  
 REM Cleanup Global Variables  
 GlobalVariableCleanup()  

 '*******************************************************************************  
 '*******************************************************************************  

 Sub DefineRelativePath()  

      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  

 End Sub  

 '*******************************************************************************  

 Sub Uninstall()  

      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  

      REM Define Local Variables  
      DIM Uninstall : Uninstall = RelativePath & "setup.exe" & Chr(32) & "--mode=silent --deploymentFile=" &_  
                                  RelativePath & "deployment\uninstall.xml --skipProcessCheck=1"  

      oShell.Run Uninstall, 1, True  

      REM Cleanup Local Variables  
      Set Uninstall = Nothing  
      Set oShell    = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub GlobalVariableCleanup()  

      Set RelativePath = Nothing  

 End Sub  

31 October 2012

SCCM/MDT BIOS Settings

If you have ever wondered how to automate setting the BIOS settings before an image is laid down on a machine using MDT or SCCM, here is the solution. This VBScript will inject the Dell CCTK into the WIM boot files that SCCM/MDT generate for booting a machine into the image setup. This allows the BIOS settings to be set before the SCCM/MDT image setup screen appears. There are certain BIOS settings, such as the Serial ATA controller setting that must be set before the image is laid down. This is where this script comes into play.

This will do the following to the MDT/SCCM generated boot WIM files: inject the Dell CCTK, inject the HAPI drivers, and modify the unattend.xml file so that the BIOS settings are updated before the Windows Deployment Wizard appears.

You can download this script from here.


 '*******************************************************************************   
 '      Program: Install.vbs   
 '       Author: Mick Pletcher   
 '         Date:   
 '     Modified:   
 '   
 '  Description: This will do the following to the MDT/SCCM generated WIM files:   
 '               inject the Dell CCTK, inject the HAPI drivers, and modify the   
 '               unattend.xml file.   
 ' Requirements: Microsoft WAIK, location for the locally stored WinPE files   
 '               (WinPEDIR Global Variable), MDT Server (I have 2 servers   
 '               MDT01 and MDT02), designation of architecture, and Dell CCTK.   
 '               NOTE: This script has been created to automate the update process   
 '               on a Windows 7 64-bit PC, therefor the directory locations of   
 '               the CCTK files will differ for an x86 machine.   
 '*******************************************************************************   
 Option Explicit   

 REM Define Constants   
 CONST TempFolder    = "c:\temp\"   
 CONST LogFolderName = "CCTK"   
 CONST MDT01         = "MDT01"   
 CONST MDT02         = "MDT02"   
 CONST WinPEDIR      = "c:\winpe\"   
 CONST x64           = "x64"   
 CONST x86           = "x86"   

 REM Define Global Variables   
 DIM LogFolder    : LogFolder        = TempFolder & LogFolderName & "\"   
 DIM RelativePath : Set RelativePath = Nothing   

 DefineRelativePath()   
 REM Refresh Local WIM Files from MDT Servers   
   DeleteLocalWIMFiles()   
   CopyWIMFiles( MDT01 )   
   RenameWIMFiles( MDT01 )   
   CopyWIMFiles( MDT02 )   
   RenameWIMFiles( MDT02 )   
 REM Process Local x86 file for MDT01   
   MountWIM MDT01,x86   
   AddWMI(x86)   
   CopyHAPIFiles( x86 )   
   CopyCCTKFiles( x86 )   
   EditUnattend( x86 )   
   DismountWIM()   
 REM Process Local x64 File for MDT01   
   MountWIM MDT01,x64   
   AddWMI(x64)   
   CopyHAPIFiles( x64 )   
   CopyCCTKFiles( x64 )   
   EditUnattend( x64 )   
   DismountWIM()   
 REM Process Local x86 File for MDT02   
   MountWIM MDT02,x86   
   AddWMI(x86)   
   CopyHAPIFiles( x86 )   
   CopyCCTKFiles( x86 )   
   EditUnattend( x86 )   
   DismountWIM()   
 REM Process Local x64 File for MDT02   
   MountWIM MDT02,x64   
   AddWMI(x64)   
   CopyHAPIFiles( x64 )   
   CopyCCTKFiles( x64 )   
   EditUnattend( x64 )   
   DismountWIM()   
 Complete()   
 GlobalVariableCleanup()   

 '*******************************************************************************   
 '*******************************************************************************   

 Sub DefineRelativePath()   

   REM Get File Name with full relative path   
   RelativePath = WScript.ScriptFullName   
   REM Remove file name, leaving relative path only   
   RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))   

 End Sub   

 '*******************************************************************************   

 Sub DeleteLocalWIMFiles()   

   REM Define Local Objects   
   DIM FSO    : Set FSO    = CreateObject("Scripting.FileSystemObject")   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM Parameters : Parameters = "/F /Q"   
   DIM sCMD_1     : sCMD_1   = "%COMSPEC% /c del " & RelativePath & "*MDT01.wim"   
   DIM sCMD_2     : sCMD_2   = "%COMSPEC% /c del " & RelativePath & "*MDT02.wim"   
   DIM sCMD_3     : sCMD_3   = "%COMSPEC% /c del " & RelativePath & "generic*.wim"   

   oShell.Run sCMD_1 & Parameters, 1, True   
   oShell.Run sCMD_2 & Parameters, 1, True   
   oShell.Run sCMD_3 & Parameters, 1, True   

   REM Cleanup Local Variables   
   Set sCMD_1     = Nothing   
   Set sCMD_2     = Nothing   
   Set sCMD_3     = Nothing   
   Set FSO        = Nothing   
   Set oShell     = Nothing   
   Set Parameters = Nothing   

 End Sub   

 '*******************************************************************************   

 Function CopyWIMFiles(Server)   

   REM Define Local Objects   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM Source      : Source      = "\\" & Server & "\DeploymentShare\Boot"   
   DIM Destination : Destination = "c:\winpe"   
   DIM Parameters  : Parameters  = "*.wim /eta /r:1 /w:0"   
   DIM Command01   : Command01   = "robocopy" & Chr(32) & Source & Chr(32) & Destination & Chr(32) & Parameters   

   oShell.Run Command01, 1, True   

   REM Cleanup Local Variables   
   Set Command01   = Nothing   
   Set Destination = Nothing   
   Set oShell      = Nothing   
   Set Parameters  = Nothing   
   Set Source      = Nothing   

 End Function   

 '*******************************************************************************   

 Function RenameWIMFiles(Server)   

   REM Define Local Objects   
   DIM FSO  : Set FSO  = CreateObject("Scripting.FileSystemObject")   

   REM Define Local Variables   
   DIM Source_x86 : Source_x86 = RelativePath & "LiteTouchPE_x86.wim"   
   DIM Source_x64 : Source_x64 = RelativePath & "LiteTouchPE_x64.wim"   
   DIM Dest_x86   : Dest_x86   = RelativePath & "LiteTouchPE_x86_" & Server & ".wim"   
   DIM Dest_x64   : Dest_x64   = RelativePath & "LiteTouchPE_x64_" & Server & ".wim"   

   If FSO.FileExists(Source_x86) then   
     If NOT FSO.FileExists(Dest_x86) then   
       FSO.MoveFile Source_x86, Dest_x86   
     End If   
   End If   
   If FSO.FileExists(Source_x64) then   
     If NOT FSO.FileExists(Dest_x64) then   
       FSO.MoveFile Source_x64, Dest_x64   
     End If   
   End If   

   REM Cleanup Local Variables   
   Set Dest_x86   = Nothing   
   Set Dest_x64   = Nothing   
   Set FSO        = Nothing   
   Set Source_x86 = Nothing   
   Set Source_x64 = Nothing   

 End Function   

 '*******************************************************************************   

 Function MountWIM(Server,Architecture)   

   REM Define Local Objects   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM MountDIR  : MountDIR  = RelativePath & "Mount"   
   DIM WIMFile   : WIMFile   = RelativePath & "LiteTouchPE_" & Architecture & "_" & Server & ".wim"   
   DIM Command01 : Command01 = "DISM /Mount-Wim /WIMFile:" & WIMFile & Chr(32) & "/Index:1 /MountDIR:" & MountDIR   

   oShell.Run Command01, 1, True   

   REM Cleanup Local Variables   
   Set Command01 = Nothing   
   Set MountDIR  = Nothing   
   Set oShell    = Nothing   
   Set WIMFile   = Nothing   

 End Function   

 '*******************************************************************************   

 Sub AddWMI(Architecture)   

   REM Define Local Objects   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM Image           : Image           = "/Image:" & RelativePath & "Mount"   
   DIM AddPackage      : AddPackage      = "/Add-Package"   
   DIM PackagePath     : Set PackagePath = Nothing   
   DIM PackagePath_x86 : PackagePath_x86 = "/PackagePath:" & Chr(34) &_   
                         "C:\Program Files\Windows AIK\Tools\PETools\x86\WinPE_FPs\winpe-wmi.cab" & Chr(34)   
   DIM PackagePath_x64 : PackagePath_x64 = "/PackagePath:" & Chr(34) &_   
                         "C:\Program Files\Windows AIK\Tools\PETools\amd64\WinPE_FPs\winpe-wmi.cab" & Chr(34)   
   DIM Command01       : Set Command01  = Nothing   

   If Architecture = "x86" Then   
     PackagePath = PackagePath_x86   
   Else   
     PackagePath = PackagePath_x64   
   End If   
   Command01 = "DISM" & Chr(32) & Image & Chr(32) & AddPackage & Chr(32) & PackagePath   
   oShell.Run Command01, 1, True   

   REM Cleanup Local Variables   
   Set AddPackage      = Nothing   
   Set Command01       = Nothing   
   Set Image           = Nothing   
   Set oShell          = Nothing   
   Set PackagePath     = Nothing   
   Set PackagePath_x86 = Nothing   
   Set PackagePath_x64 = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub CreateFolderStructure(Architecture)   

   REM Define Local Objects   
   DIM FSO    : Set FSO    = CreateObject("Scripting.FileSystemObject")   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM Command01     : Set Command01 = Nothing   
   DIM Directory     : Set Directory = Nothing   
   DIM Directory_x86 : Directory_x86 = RelativePath & "Mount\CCTK\x86\HAPI"   
   DIM Directory_x64 : Directory_x64 = RelativePath & "Mount\CCTK\x86_64\HAPI"  
 
   If Architecture = "x86" Then   
     Directory = Directory_x86   
   Else   
     Directory = Directory_x64   
   End If   
   If NOT FSO.FolderExists(Directory) then   
     FSO.CreateFolder(Directory)   
   End If   

   REM Cleanup Local Variables   
   Set Command01     = Nothing   
   Set Directory     = Nothing   
   Set Directory_x86 = Nothing   
   Set Directory_x64 = Nothing   
   Set FSO           = Nothing   
   Set oShell        = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub CopyHAPIFiles(Architecture)   

   REM Define Local Objects   
   DIM FSO    : Set FSO    = CreateObject("Scripting.FileSystemObject")   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM sCMD_1     : Set sCMD_1 = Nothing   
   DIM sCMD_2     : Set sCMD_2 = Nothing   
   DIM Source     : Set Source = Nothing   
   DIM Source_x86 : Source_x86 = "C:\Program Files (x86)\Dell\CCTK\X86\HAPI\*.*"   
   DIM Source_x64 : Source_x64 = "C:\Program Files (x86)\Dell\CCTK\X86_64\HAPI\*.*"   
   DIM Dest       : Set Dest   = Nothing   
   DIM Dest_x86   : Dest_x86   = RelativePath & "mount\CCTK\x86\HAPI"   
   DIM Dest_x64   : Dest_x64   = RelativePath & "mount\CCTK\x86_64\HAPI"   

   If Architecture = "x86" Then   
     Source = Source_x86   
     Dest  = Dest_x86   
   Else   
     Source = Source_x64   
     Dest  = Dest_x64   
   End If   
   sCMD_1 = "%COMSPEC% /c mkdir " & Dest   
   If NOT FSO.FolderExists(Dest) then   
     oShell.Run sCMD_1, 1, True   
   End If   
   sCMD_2 = "%COMSPEC% /c copy " & Chr(34) & Source & Chr(34) & Chr(32) & Dest & Chr(32) & "/V /Y"   
 '  If FSO.FolderExists(Source) then   
     oShell.Run sCMD_2, 1, True   
 '  End If   

   REM Cleanup Local Variables   
   Set Dest       = Nothing   
   Set Dest_x86   = Nothing   
   Set Dest_x64   = Nothing   
   Set FSO        = Nothing   
   Set oShell     = Nothing   
   Set sCMD_1     = Nothing   
   Set sCMD_2     = Nothing   
   Set Source     = Nothing   
   Set Source_x86 = Nothing   
   Set Source_x64 = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub CopyCCTKFiles(Architecture)   

   REM Define Local Objects   
   DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")   

   REM Define Local Variables   
   DIM CCTKFile   : CCTKFile   = "cctk.exe"   
   DIM MXMLFile   : MXMLFile   = "mxml1.dll"   
   DIM INIFile    : INIFile    = "multiplatform.ini"   
   DIM PCIFile    : PCIFile    = "pci.ids"   
   DIM NetSource  : NetSource  = "\\global.gsp\data\clients\na_clients\Dell\BIOS\"   
   DIM Source     : Set Source = Nothing   
   DIM Source_x86 : Source_x86 = "C:\Program Files (x86)\Dell\CCTK\X86\"   
   DIM Source_x64 : Source_x64 = "C:\Program Files (x86)\Dell\CCTK\X86_64\"   
   DIM Dest       : Set Dest   = Nothing   
   DIM Dest_x86   : Dest_x86   = RelativePath & "mount\CCTK\x86\"   
   DIM Dest_x64   : Dest_x64   = RelativePath & "mount\CCTK\x86_64\"   

   If Architecture = "x86" Then   
     Source = Source_x86   
     Dest  = Dest_x86   
   Else   
     Source = Source_x64   
     Dest  = Dest_x64   
   End If   
   If NOT FSO.FolderExists(Dest) then   
     FSO.CreateFolder(Dest)   
   End If   
   If FSO.FolderExists(Source) then   
     FSO.CopyFile Source & CCTKFile, Dest, 1   
   End If   
   If FSO.FolderExists(Source) then   
     FSO.CopyFile NetSource & INIFile, Dest, 1   
   End If   
   If FSO.FolderExists(Source) then   
     FSO.CopyFile Source & PCIFile, Dest, 1   
   End If   
   If FSO.FolderExists(Source) then   
     FSO.CopyFile Source & MXMLFile, Dest, 1   
   End If   

   REM Cleanup Local Variables   
   Set CCTKFile   = Nothing   
   Set INIFile    = Nothing   
   Set MXMLFile   = Nothing   
   Set PCIFile    = Nothing   
   Set Dest       = Nothing   
   Set Dest_x86   = Nothing   
   Set Dest_x64   = Nothing   
   Set FSO        = Nothing   
   Set Source     = Nothing   
   Set Source_x86 = Nothing   
   Set Source_x64 = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub EditUnattend(Architecture)   

       REM Define Local Constants   
   CONST ForReading = 1   
   CONST ForWriting = 2   

   REM Define Local Objects   
   DIM File     : File       = "C:\winpe\mount\unattend.xml"   
   DIM strOld1    : strOld1      = "<Order>1</Order>"   
   DIM strNew1    : strNew1      = "<Order>4</Order>"   
   DIM strOld2    : strOld2      = "<RunSynchronous>"   
   DIM strNew2    : strNew2      = "<RunSynchronous>" & Chr(10) &_   
                     "<RunSynchronousCommand wcm:action=" & Chr(34) & "add" & Chr(34) & ">" & Chr(10) &_   
                     "<Description>Map BIOS Drive</Description>" & Chr(10) &_   
                     "<Order>1</Order>" & Chr(10) &_   
                     "<Path>net use \\global.gsp\data\clients\na_clients\dell\bios /user:{username/password}</Path>" & Chr(10) &_   
                     "</RunSynchronousCommand>" & Chr(10) &_   
                     "<RunSynchronousCommand wcm:action=" & Chr(34) & "add" & Chr(34) & ">" & Chr(10) &_   
                     "<Description>Initiate HAPI</Description>" & Chr(10) &_   
                     "<Order>2</Order>" & Chr(10) &_   
                     "<Path>X:\CCTK\x86_64\HAPI\hapint -i -k C-C-T-K -p X:\CCTK\x86_64\HAPI\</Path>" & Chr(10) &_   
                     "</RunSynchronousCommand>" & Chr(10) &_   
                     "<RunSynchronousCommand wcm:action=" & Chr(34) & "add" & Chr(34) & ">" & Chr(10) &_   
                     "<Description>Set BIOS Settings</Description>" & Chr(10) &_   
                     "<Order>3</Order>" & Chr(10) &_   
                     "<Path>x:\CCTK\x86_64\cctk.exe -i \\global.gsp\data\clients\na_clients\Dell\BIOS\multiplatform.ini</Path>" & Chr(10) &_   
                     "</RunSynchronousCommand>"   
   DIM objFSO        : Set objFSO        = CreateObject("Scripting.FileSystemObject")   
   DIM objFile       : Set objFile       = objFSO.getFile(File)   
   DIM objTextStream : Set objTextStream = objFile.OpenAsTextStream(ForReading)   
   DIM strInclude    : strInclude        = objTextStream.ReadAll   

   objTextStream.Close   
   Set objTextStream = Nothing   
   If InStr(strInclude,strOld1) > 0 Then   
      strInclude = Replace(strInclude,strOld1,strNew1)   
      Set objTextStream = objFile.OpenAsTextStream(ForWriting)   
      objTextStream.Write strInclude   
      objTextSTream.Close   
      Set objTextStream = Nothing   
   End If   
   If InStr(strInclude,strOld2) > 0 Then   
      strInclude = Replace(strInclude,strOld2,strNew2)   
      Set objTextStream = objFile.OpenAsTextStream(ForWriting)   
      objTextStream.Write strInclude   
      objTextSTream.Close   
      Set objTextStream = Nothing   
   End If   

   REM Cleanup Local Variables   
   Set File          = Nothing   
   Set objFile       = Nothing   
   Set objFSO        = Nothing   
   Set objTextStream = Nothing   
   Set strInclude    = Nothing   
   Set strNew1       = Nothing   
   Set strNew2       = Nothing   
   Set strOld1       = Nothing   
   Set strOld2       = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub DismountWIM()   

   REM Define Local Objects   
   DIM oShell : SET oShell = CreateObject("Wscript.Shell")   

   REM Define Local Variables   
   DIM MountDIR  : MountDIR  = RelativePath & "Mount"   
   DIM Command01 : Command01 = "DISM /Unmount-WIM /MountDir:" & MountDIR & Chr(32) & "/commit"   

   oShell.Run Command01, 1, True   

   REM Cleanup Local Variables   
   Set Command01 = Nothing   
   Set MountDIR  = Nothing   
   Set oShell    = Nothing   

 End Sub   

 '*******************************************************************************   

 Sub Complete()   

   MsgBox "Process Complete"   

 End Sub   

 '*******************************************************************************   

 Sub GlobalVariableCleanup()   

   Set LogFolder    = Nothing   
   Set RelativePath = Nothing   

 End Sub