Thats My Shell

Properly Sealing a VDI Image

I have been doing VMware Horizon View for a long time.  I am going to share the skeleton of a script that I have been using during that time to seal an image.  Some VDI admins will call the process ‘sealing an image’ while other’s will call it ‘cleaning up’.  Regardless of what an administrator will call the process, it needs to be a required process to have in place to keep the environment running as smoothly as possible.

My script began its life as a simple batch file to release the images network information. It grew over time to a robust and convoluted PowerShell script to account for every possibility. Recently I stripped the script down to a pure sealing task. My advice to most VDI administrators is to let the image be pure windows with the required optimizations and let the published desktop use GPO or DEM (Dynamic Environment Manager) enforce lock down policies.

Even if you do not use the script that I am providing.  Here are some things that you might want to consider having in  yours.

  • Network Clean Up
  • Disk usage and cleanup.
  • Windows Event Cleanup

Let’s examine the various tasks in detail.   The network cleanup removes any cached ARP tables or DNS information that might cause problems during the provisioning process of a desktop pool.  I would also recommend using these as part of the a shutdown script to help DHCP reclaim the IP Address assignment lease. Network cleanup should happen at the end of the script.

try {
    Start-Process -FilePath "$env:SystemRoot\System32\ipconfig.exe" -ArgumentList "/flushdns" -Verb "RunAs" -WindowStyle Hidden -Wait
    Start-Process -FilePath "$env:SystemRoot\System32\ipconfig.exe" -ArgumentList "/releaseall" -Verb "RunAs" -WindowStyle Hidden -Wait
    Start-Process -FilePath "$env:SystemRoot\System32\netsh.exe" -ArgumentList "interface ip delete arpcache" -Verb "RunAs" -WindowStyle Hidden -Wait
}
catch {
    # log the error
}

Files and disk utilization.  This is tacked on several fronts.  Manually deleting files from common locations.  Using the Disk Cleanup utility to cleanup updates and other tasks.  Using defrag and a SysInternals Tool SDelete

Manually deleting files from common directories is easy in PowerShell and self-explanatory.  Common target folders are the Windows Temp directory, User directories, Windows Prefetch, and Windows Update. 

try {

    $tempfolders = @("C:\Windows\Temp\*", "C:\Windows\Prefetch\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*", "C:\Windows\SoftwareDistribution\*")

    Remove-Item $tempfolders -Force -Recurse -ErrorAction "SilentlyContinue"  
}
catch {
    # log the error
}

The Disk Cleanup wizard can be configured to run a predefined task.  It is configured easily by setting a few registry keys.  I suggest the Internet Cache, Update Cleanup, Temporary Files, and the Windows Error files. 

try {
	Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' -Name StateFlags0001 -ErrorAction SilentlyContinue | Remove-ItemProperty -Name StateFlags0001 -ErrorAction SilentlyContinue

	# create the necessary registry entries for the disk cleanup
	New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Internet Cache Files' -Name StateFlags0001 -Value 2 -PropertyType DWord
	New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup' -Name StateFlags0001 -Value 2 -PropertyType DWord
	New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files' -Name StateFlags0001 -Value 2 -PropertyType DWord
	New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Error Files' -Name StateFlags0001 -Value 2 -PropertyType DWord
	
	# start the automated process, and wait for it to finish
	Start-Process -FilePath CleanMgr.exe -ArgumentList "/sagerun:1" -WindowStyle Hidden -Wait 
}
catch {
    # log the error
}

Lastly, using the defrag goes without saying.  This moves all data near each other.  SDelete however is necessary because it changes sectors that might have data to a zero.  VDI Desktops are naturally thin provisioned and therefore having a large zero out space will help with datastore storage efficiency.  Daily this might only account for a few megabytes of space or during a large patch cycle it could amount to a few gigs.  In a large VDI deployment that could amount to a large amount of space consumed on the SAN. 

# Starting the defrag process
try {
    Start-Process -FilePath "Defrag" -ArgumentList "c: -f" -Wait
}
catch {
    # log the error
}

# Starting the zero out process
try {
    Start-Process -FilePath "sdelete64.exe" -WorkingDirectory "C:\Windows\System32\" -ArgumentList "-z c:" -Verb RunAs -Wait
}
catch {
    # log the error
}

Lastly, the events that have been recorded in Windows needs to be cleared.  This will help going forward with troubleshooting issues during provisioning or daily use.

$EventLogs = Get-EventLog -List | Where-Object { $_.Log -match "Application|Security|System"} | ForEach-Object {$_.Log}

$EventLogs | ForEach-Object -Process {
    try{
        Clear-EventLog -Log $_ 
    }
    catch{
        # log the error
    }
}

The script that I use is written in PowerShell.  I would recommend putting it in a a hidden folder on the drive that regular users are unable to see normally and remove all permissions but administrators from the folder. 

For the full script, please visit the project page on Github page

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: