Before I had access to VM's, money or had any PowerShell knowledge I made this script that would do some image customizations for me. I used physical computers and would be reinstalling the OS while I was testing my image creation process. The process was long and tedious but I used this to save some of the repetition.

What this code focused on was ..

  • Registry changes such as that for disabling some of IE's unwanted behaviour.
  • Making changes to the default user profile such as desktop backround.
  • Copying over the base driver set for the os collection

This was one of the first real PowerShell scripts I made. I would run this before I ran another script for sysprep.

    Script     : Customize Image
    Created By : Matt Something
    Created    : October 6, 2011
    Modified   : November 7, 2011

    This script is designed to run on a computer image as it is being built. It will help automated tasks to ensure that certain steps are performed everytime.
    script does the following tasks
        Disable IE Welcome Wizards and Prompts
        Connects\Disconnects image share for copying drivers, picture files and sysprep data

# Functions and Subroutines
function Set-ConsoleColours([string]$pBack, [string]$pFront){
    # Change the foreground and background colours of the console based on $pFront and $pBack respectively
    (Get-Host).UI.RawUI.ForegroundColor = $pFront
    (Get-Host).UI.RawUI.BackgroundColor = $pBack    
    # Clear the screen to show new colours properly

Function Test-RegistryValue($regkey, $name) {
    # Will test to see if a key value exists of not. The presence of an error is tested to determine existence. 
    Get-ItemProperty $regkey $name -ErrorAction SilentlyContinue | Out-Null

function ConvertTo-PlainText( [security.securestring]$secure ) {
    $marshal = [Runtime.InteropServices.Marshal]
    $marshal::PtrToStringAuto( $marshal::SecureStringToBSTR($secure) )

### Main ###
$sysPrepDirectory = "c:\sysprep"
$misTempDirectory = "c:\temp\mis"
$architecture = (Get-WmiObject Win32_Processor -namespace "root\cimv2" | where {$_.DeviceID -eq “CPU0"}).AddressWidth

Set-ConsoleColours "DarkBlue" "White"

# Disable IE First Time Run Prompts. The keys involved dont normally exist. Create them if they don't.
Write-Host "Disabled the Welcome Wizard of IE" 
If ((Test-Path "HKLM:\software\policies\microsoft\Internet Explorer") -eq $False){ [void](New-Item "HKLM:\software\policies\microsoft\Internet Explorer") }
If ((Test-Path "HKLM:\software\policies\microsoft\Internet Explorer\Main") -eq $False){ [void](New-Item "HKLM:\software\policies\microsoft\Internet Explorer\Main") }
If (Test-RegistryValue "HKLM:\software\policies\microsoft\Internet Explorer\Main" "DisableFirstRunCustomize"){
    Write-Warning "The Key DisableFirstRunCustomize already exists. Doing Nothing."
} Else {
    [void](New-ItemProperty "HKLM:\software\policies\microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -PropertyType DWord -Value 00000001)

# Disable Java Update. Different Path depending on architecture
$updateKey = "EnableJavaUpdate"
If ($architecture -eq 32){
    $javaUpdatePath = "hklm:\software\javasoft\java update\policy"
} Else {
    $javaUpdatePath = "hklm:\software\Wow6432Node\javasoft\java update\policy"
If (Test-RegistryValue $javaUpdatePath $updateKey) {
    [void](Set-ItemProperty $javaUpdatePath -Name $updateKey -Value 00000000)
    Write-Host "Disabled Java Updates"

# Set IE Layout and Favorites and Home Page
$ieToolbarSettings = "HKCU:\software\microsoft\Internet Explorer\MINIE"
$statusBarElement = "ShowStatusBar"
$favoritesBarElement = "LinksBandEnabled"
$homePage = "http://7fweb"
$homePageData = "Start Page"
$homePageKey = "HKCU:\Software\Microsoft\Internet Explorer\Main"
If ((Test-Path $ieToolbarSettings) -eq $False){ [void](New-Item $ieToolbarSettings) }
# Enable and show the status bar
If (Test-RegistryValue $ieToolbarSettings $statusBarElement){ 
    [void](Set-ItemProperty $ieToolbarSettings -Name $statusBarElement -Value 00000001 )    
} Else {
    [void](New-ItemProperty $ieToolbarSettings -Name $statusBarElement -PropertyType DWord -Value 00000001) 
# Enable and show the favorites bar
If (Test-RegistryValue $ieToolbarSettings $favoritesBarElement){ 
    [void](Set-ItemProperty $ieToolbarSettings -Name $favoritesBarElement -Value 00000001 )
} Else {
    [void](New-ItemProperty $ieToolbarSettings -Name $favoritesBarElement -PropertyType DWord -Value 00000001) 
Set-ItemProperty $homePageKey -Name $homePageData -Value $homePage

# Connect to the image share so that we can copy down the required files
$driveLetter = "i:"
$imageSharePath = "\\yowfpw2k3\mis\image"
If ( Test-Path $driveLetter ) {
    Write-Warning "The drive $driveLetter already exists. Doing Nothing."
} Else {
    Write-Host "Please type your username and password in the box to come. Remeber to use the format domain\username format."; Start-Sleep -Seconds 2
    $credentials = Get-Credential
    net use $driveLetter $imageSharePath "/USER:$($credentials.UserName)" $(ConvertTo-PlainText($credentials.Password))
    # Re-run the script now that the drive is mapped.
    Write-Host "Script needs to be reloaded in order to see new drive. Exiting now."
    Start-Sleep -Seconds 2; Exit

# Populate the favorites bar. Start by cleaning out whats already there
$userFavorites = "$env:USERPROFILE\favorites\links"
Remove-Item $userFavorites\*
Copy-Item $driveLetter\defaultUser\favorites\* $userFavorites

# Copy drivers  library
If ((Test-Path "c:\sysprep\drivers") -eq $False){ [void](New-Item "c:\sysprep\drivers" -type directory)}
Write-Host "Copying Drivers"

# Determine which drivers are being copied
$title = "Copy Drivers Files"
$message = "Which driver pack do you need to copy?"
$windows7x86 = New-Object System.Management.Automation.Host.ChoiceDescription "7 &32-Bit", "Windows 7 32-bit driver package"
$windows7x64 = New-Object System.Management.Automation.Host.ChoiceDescription "7 &64-Bit", "Windows 7 64-bit driver package"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($windows7x86, $windows7x64)
$result = $host.ui.PromptForChoice($title, $message, $options, 0) 
switch ($result)
    0 {$osFolder = "7x86"}
    1 {$osFolder = "7x64"}

# Copy appropriate driver files and unattend files.
$scriptBlock = [scriptblock]::Create("Copy-Item $driveLetter\drivers\scrubbed\$osFolder\* c:\sysprep\drivers -Force -Recurse;`
            Copy-Item $driveLetter\sysprep\$osFolder\* c:\sysprep -Force")
$job = Start-Job -ScriptBlock $scriptBlock
while (($job.State -eq "Running") -and ($job.State -ne "NotStarted")){Write-Host '.' -NoNewline; Start-Sleep -Seconds 1}
Write-Host "Done"

# Copy sysprep files
Write-Host "Copying Sysprep Files"
Copy-Item $driveLetter\sysprep\*.exe c:\sysprep -Force

# Copy hidden files
Write-Host "Copy Hidden Installs"
If ((Test-Path "c:\temp\mis") -eq $False){ [void](New-Item "c:\temp\mis" -type directory)}
Write-Host "Getting Portable Apps / After Image Installs"
Copy-Item $driveLetter\hidden\* c:\temp\mis -Force -Recurse

# Copy default user pictures and backgroud
Write-Host "Copy default user pictures and backgroud"
$userThumbnail = "C:\programdata\microsoft\user account pictures\user.bmp"
If ( Test-Path $userThumbnail ){ Remove-Item $userThumbnail } 
Copy-Item "$driveLetter\defaultUser\FAThumb.bmp" $userThumbnail
Copy-Item "$driveLetter\defaultUser\firstAirBackround.bmp" "$env:windir"

# Copy BGinfo and load it into the startup
Copy-Item $driveLetter\bginfo\* c:\temp -Force -Recurse

# Make a shortcut in the users startup folder to bginfo
$shortcut = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\FirstAir_Data.lnk"
If ( Test-Path $shortcut ){ Remove-Item $shortcut } 
$objShell = New-Object -ComObject ("WScript.Shell")
$objShortCut = $objShell.CreateShortcut($shortcut)
$objShortCut.TargetPath = "C:\temp\Bginfo.exe"
$objShortCut.Arguments = "C:\temp\bginfov1.bgi /log:C:\temp\log.log /timer:0"

#Prompt the user to get the image version. If there is a current one display it on the screen.
$goldenRegistryPath = "hklm:\software\golden"
$goldenImageVersionElement = "Version"
# Check to see if the key $goldenRegistryPath is present
If (-not(Test-Path $goldenRegistryPath)){[void](New-Item $goldenRegistryPath); Write-Host "Created: $goldenRegistryPath as it does not exist"}
If (Test-RegistryValue $goldenRegistryPath $goldenImageVersionElement){
    # Element is already there. Display the current one. 
    $version = (Get-ItemProperty $goldenRegistryPath).Version
    Write-Host "Current Image Version is :$version"
} Else {
    # Element is not present. Create it.
    [void](New-ItemProperty $goldenRegistryPath -Name $goldenImageVersionElement -PropertyType DWord)

$title = "Update Image Verion"
$message = "Do you want to update the image version number?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Input Prompt to add new version number."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Leave it as is."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 1) 
switch ($result)
    0 {$version = Read-Host "Type in new version number."; Set-ItemProperty $goldenRegistryPath -Name $goldenImageVersionElement -Value $version}
    1 {#do nothing}

# Disconnect the image share
net use $driveLetter /delete
# Wait 5 seconds in case of errors and allow reader to catch up 
Start-Sleep -Seconds 5

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.