March, 2011

  • Custom WinPE Boot Image Script

    I’m on a scripting rampage at the moment writing tools for the common things I do for each customer. Here’s my latest script.

    This powershell script will:

    - Check for prereqs (WAIK, DISM)
    - Builds the WinPE dev environment (in either x86 or x64)
    - Mounts the WIM
    - Prompts to install non-default WinPE packages (HTA or Script Host support, for example)
    - Adds Trace32.exe to the image
    - Prompts asking if you want to add any other files to the image
    - Unmounts and saves the custom image ready for SCCM or MDT.

    ################################################################################################
    ##########         Created by Matt Shadbolt                                           ##########
    ################################################################################################
    # Global Variables
    $HTA = 'winpe-hta.cab'
    $LEGACY = 'winpe-legacysetup.cab'
    $MDAC = 'winpe-mdac.cab'
    $PPPOE = 'winpe-pppoe.cab'
    $SCRIPTING = 'winpe-scripting.cab'
    $CLIENT = 'winpe-setup-client.cab'
    $SERVER = 'winpe-setup-server.cab'
    $SETUP = 'winpe-setup.cab'
    $WDS = 'winpe-wds-tools.cab'
    $WMI = 'winpe-wmi.cab'

    $LongHTA = 'HTML Application Support'
    $LongLEGACY = 'The Media Setup features'
    $LongMDAC = 'Microsoft Data Access Components'
    $LongPPPOE = 'PPOE services'
    $LongSCRIPTING = 'Windows Script Host support'
    $LongCLIENT = 'the Client Setup features'
    $LongSERVER = 'the Server Setup features'
    $LongSETUP = 'the Setup features'
    $LongWDS = 'WDS tools'
    $LongWMI = 'WMI support'

    $RequiredCopyCmd = Test-Path "C:\Program Files\Windows AIK\Tools\PETools\copype.cmd"
    $RequiredWinPackages = Test-Path "C:\Program Files\Windows AIK\Tools\PETools\x86\WinPE_FPs\$HTA"
    $RequiredDism = Test-Path "C:\Windows\System32\dism.exe"
    $RequiredTrace32 = Test-Path "C:\Program Files\ConfigMgr 2007 Toolkit\CCM Tools\Trace32.exe"

    # Start Script
    Write-Host "#########################################################" -foregroundcolor yellow
    Write-Host "Welcome to my WinPE Customization Script! Enjoy your stay." -foregroundcolor yellow
    Write-Host "#########################################################" -foregroundcolor yellow

    # Check requirements

    If ($RequiredCopyCmd -eq $False)
        {
        Write-Host "copype.cmd could not be found. Script Exiting!" -foregroundcolor yellow
        exit
        }
    Else {}
    If ($RequiredWinPackages -eq $False)
        {
        Write-Host "WinPE Packages not be found. This may not run!" -foregroundcolor yellow
        }
    Else {}
    If ($RequiredDism -eq $False)
        {
        Write-Host "Dism couple not be found. Script Exiting!" -foregroundcolor yellow
        exit
        }
    Else {}
    If ($RequiredTrace32 -eq $False)
        {
        Write-Host "Trace32 couple not be found. This may not run!" -foregroundcolor yellow
        }
    Else {}

    Start-Sleep -s 3
    Write-Host ""
    $Arch = Read-Host "Would you like x86 or x64?"

    If ($Arch -eq 'x64')
        {
        $PackagePath = "amd64"
        }
    Else
        {
        $PackagePath = "x86"
        }
    Write-Host ""
    Write-Host "I'm just creating your WinPE dev environment (C:\Winpe_$Arch)"  -foregroundcolor yellow
    Write-Host ""
    Start-Sleep -s 3

    If ($Arch -eq "x64")
        {
        CD "C:\Program Files\Windows AIK\Tools\PETools"
        .\copype.cmd amd64 C:\winpe_$Arch
        Write-Host "$Arch dev environment created" -foregroundcolor yellow
        }
    ElseIf ($Arch -eq "x86")
        {
         CD "C:\Program Files\Windows AIK\Tools\PETools"
        .\copype.cmd x86 C:\winpe_$Arch
        Write-Host "$Arch dev environment created" -foregroundcolor yellow
        }
    Else
        {
        Write-Host "$Arch does not match either x86 or x64. Please start this script again" -foregroundcolor yellow
        exit
        }
    Start-Sleep -s 3
    Write-Host ""
    Write-Host "Just going to mount your WIM" -foregroundcolor yellow
    Dism /Mount-Wim /WimFile:C:\winpe_$Arch\winpe.wim /index:1 /MountDir:C:\winpe_$Arch\mount
    Write-Host ""
    Write-Host "Mounted" -foregroundcolor yellow
    Write-Host ""
    Start-Sleep -s 3
    Write-Host "Now we will customize the boot image" -foregroundcolor yellow
    Write-Host ""

    $HTAeqYES = Read-Host "Would you like to install $HTA which enables $LongHTA? Y/N"
    $LEGACYeqYES = Read-Host "Would you like to install $LEGACY which enables $LongLEGACY? Y/N"
    $MDACeqYES = Read-Host "Would you like to install $MDAC which enables $LongMDAC? Y/N"
    $PPPOEeqYES = Read-Host "Would you like to install $PPPOE which enables $LongPPPOE? Y/N"
    $SCRIPTINGeqYES = Read-Host "Would you like to install $SCRIPTING which enables $LongSCRIPTING? Y/N"
    $CLIENTeqYES = Read-Host "Would you like to install $CLIENT which enables $LongCLIENT? Y/N"
    $SERVEReqYES = Read-Host "Would you like to install $SERVER which enables $LongSERVER? Y/N"
    $SETUPeqYES = Read-Host "Would you like to install $SETUP which enables $LongSETUP? Y/N"
    $WDSeqYES = Read-Host "Would you like to install $WDS which enables $LongWDS? Y/N"
    $WMIeqYES = Read-Host "Would you like to install $WMI which enables $LongWMI? Y/N"

    If ($HTAeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$HTA"
        }
    Else {}
    If ($LEGACYeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$LEGACY"
        }
    Else {}
    If ($MDACeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$MDAC"
        }
    Else {}
    If ($PPPOEeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$PPPOE"
        }
    Else {}
    If ($SCRIPTINGeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$SCRIPTING"
        }
    Else {}
    If ($CLIENTeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$CLIENT"
        }
    Else {}
    If ($SERVEReqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$SERVER"
        }
    Else {}
    If ($SETUPeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$SETUP"
        }
    Else {}
    If ($WDSeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$WDS"
        }
    Else {}
    If ($WMIeqYES -eq 'Y')
        {
        dism /image:C:\winpe_$Arch\mount /Add-Package:"C:\Program Files\Windows AIK\Tools\PETools\$PackagePath\WinPE_FPs\$WMI"
        }
    Else {}

    Start-Sleep -s 3

    Write-Host "Windows Package installation complete" -foregroundcolor yellow
    Write-Host ""
    Start-Sleep -s 3

    $Trace32eqYES = Read-Host "Would you like to also add Trace32 to the boot image? Y/N"

    If ($Trace32eqYES -eq 'Y')
        {
        copy "C:\Program Files\ConfigMgr 2007 Toolkit\CCM Tools\Trace32.exe" C:\winpe_$Arch\mount
        }
    Else {}

    MKDIR C:\winpe_$Arch\mount\CustomFiles
    $MorePackage = Read-Host "Are there any other files you want to install? Y/N"

    While ($MorePackage -eq 'Y')
        {
        $FilePath = Read-Host "Please enter source file path (no quotation marks please)"
        Write-Host ""
        copy $FilePath C:\winpe_$Arch\mount\CustomFiles
        $MorePackage = Read-Host "Are there any other files you want to install? Y/N"
        }

    Start-Sleep -s 3

    Write-Host ""
    Write-Host "Custom Package installation complete" -foregroundcolor yellow
    Write-Host ""
    Write-Host "Now we'll clean up and save your custom WIM" -foregroundcolor yellow
    Write-Host ""

    dism /Unmount-Wim /MountDir:C:\winpe_$Arch\mount /Commit
    copy c:\winpe_$Arch\winpe.wim c:\winpe_$Arch\ISO\sources\CustomWIM_Arch.wim
    dism /Unmount-Wim /MountDir:C:\winpe_$Arch\mount /Discard
    dism /Cleanup-Wim

    Write-Host ""
    Write-Host ""
    Write-Host "Complete!" -foregroundcolor yellow
    Write-Host ""
    Write-Host ""
    Write-Host ""
    Write-Host "Your custom WinPE WIM can be found c:\winpe_$Arch\ISO\sources\CustomWIM_Arch.wim"  -foregroundcolor Red -backgroundcolor yellow

     

    Matt Shadbolt

  • USMT Test Environment Setup Script

    I’ve been working hard lately on the various USMT migration scenarios using SCCM with hardlinking and State Migration Points. One of the frustrating things during this process is creating ‘user state’. Creating user state for your test migrations is important as you need to ensure that your testing covers the regular places that users will store files, and that USMT is doing it’s job and migrating this data.

    The frustrating part is the time it takes to create some reasonable user state. You want to add files and folders to users profiles across multiple locations. I’ve written a VB Script to automate this process. The script will work for either Windows XP or Windows 7 environments. It basically creates a bunch of files and folders in the logged in users Desktop, My Documents, My Pictures and App Data directories.

    ''    USMT Environment Setup    ''
    '' Created by Matt Shadbolt ''
    Option Explicit
    'Declare Variables
    Dim objFSO, objFolder, strDirectory
    Dim objNetwork
    Dim profilePath
    Dim x
    Dim filetxt, getname, path
    Dim LocalAppDataPath, RoamingAppDataPath
    Dim MyDocuments, MyDesktop, MyPictures
    'Set Variables
    x = 0
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objNetwork = CreateObject("WScript.Network")
    profilePath = UserInput( "Is this for XP or WIN7?")
    ' Check if XP or Windows 7
    If profilePath = "XP" Then
    profilePath = "C:\Documents and Settings\"
    LocalAppDataPath = "\Local Settings\Application Data\"
    RoamingAppDataPath = "\Application Data\"
    MyDocuments = "My Documents"
    MyDesktop = "Desktop"
    MyPictures = "My Documents\My Pictures"
    ElseIf profilePath = "WIN7" Then
    profilePath = "C:\Users\"
    LocalAppDataPath = "\AppData\Local\"
    RoamingAppDataPath = "\AppData\Roaming\"
    MyDocuments = "Documents"
    MyDesktop = "Desktop"
    MyPictures = "Pictures"
    Else
    MsgBox "You need to enter either XP or WIN7 (CaSe SeNsItIvE) "
    Wscript.Quit
    End If
    ' Desktop Folders
    While x < 10
    strDirectory = profilePath & objNetwork.Username & "\" & MyDesktop & "\DesktopFolder" & x
    Set objFolder = objFSO.CreateFolder(strDirectory)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "TextFile" & x & ".txt", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "Shortcut" & x & ".lnk", True)
    x = x + 1
    Wend
    x = 0
    ' My Documents
    While x < 10
    strDirectory = profilePath & objNetwork.Username & "\" & MyDocuments & "\DocumentsFolder" & x
    Set objFolder = objFSO.CreateFolder(strDirectory)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc1" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc2" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc3" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc4" & x & ".doc", True)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "WordDoc5" & x & ".doc", True)
    x = x + 1
    Wend
    x = 0
    ' My Pictures
    While x < 10
    strDirectory = profilePath & objNetwork.Username & "\" & MyPictures & "\PicturesFolder" & x
    Set objFolder = objFSO.CreateFolder(strDirectory)
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "Picture" & x & ".jpg", True)
    x = x + 1
    Wend
    x = 0
    ' AppDatat\Local
    strDirectory = profilePath & objNetwork.Username & LocalAppDataPath & "SomeAppData"
    Set objFolder = objFSO.CreateFolder(strDirectory)
    While x < 10
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "AppDataFile" & x & ".appData", True)
    x = x + 1
    Wend
    x = 0
    ' AppData\Roaming
    strDirectory = profilePath & objNetwork.Username & RoamingAppDataPath & "SomeAppData"
    Set objFolder = objFSO.CreateFolder(strDirectory)
    While x < 10
    Set filetxt = objFSO.CreateTextFile(strDirectory &"\" & "AppDataFile" & x & ".appData", True)
    x = x + 1
    Wend
    x = 0
    MsgBox "Success!"
    ''' Functions '''
    'Input OS type
    Function UserInput( myPrompt )
    If UCase( Right( WScript.FullName, 12 ) ) = "\CSCRIPT.EXE" Then
    WScript.StdOut.Write myPrompt & " "
    UserInput = WScript.StdIn.ReadLine
    Else
    UserInput = InputBox( myPrompt )
    End If
    End Function
     
    Matt Shadbolt