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