Windows 7 Image Factory
#Requires -RunAsAdministrator | |
<# | |
.Synopsis | |
Auto create a VM from your MDT Deployment Media | |
.DESCRIPTION | |
Given an MDT Litetouch Deployment Share, this script will enumerate | |
through all "Offline Media" shares, allow you to select one or more, | |
and then auto-update and auto-create the Virtual Machine. | |
Ideal to create base reference images (like Windows7). | |
.NOTES | |
IN Addition to the default settings for your CustomSettings.ini file, | |
you should also have the following defined for each MEdia Share: | |
SKIPWIZARD=YES ; Skip Starting Wizards | |
SKIPFINALSUMMARY=YES ; Skip Closing Wizards | |
ComputerName=* ; AUto-Generate a random computername | |
DoCapture=SYSPREP ; Run SysPrep, but don't capture the WIM. | |
FINISHACTION=SHUTDOWN ; Just Shutdown | |
AdminPassword=P@ssw0rd ; Any Password | |
TASKSEQUENCEID=ICS001 ; The ID for your TaskSequence (allCaps) | |
Also requires https://github.com/keithga/DeploySharedLibrary powershell library | |
#> | |
[cmdletbinding()] | |
param( | |
[Parameter(Mandatory=$true)] | |
[string] $DeploymentShare = 'G:\Projects\DeploymentShares\DeploymentShare.Win7SP1', | |
[int] $VMGeneration = 1, | |
[int64] $MemoryStartupBytes = 4GB, | |
[int64] $NewVHDSizeBytes = 120GB, | |
[version]$VMVersion = '5.0.0.0', | |
[int] $ProcessorCount = 4, | |
[string] $ImageName = 'Windows 7 SP1', | |
$VMSwitch, | |
[switch] $SkipMediaRebuild | |
) | |
Start-Transcript | |
#region Initialize | |
if ( -not ( get-command 'Convert-WIMtoVHD' ) ) { throw 'Missing https://github.com/keithga/DeploySharedLibrary' } | |
# On most of my machines, at least one switch will be external to the internet. | |
if ( -not $VMSwitch ) { $VMSwitch = get-vmswitch -SwitchType External | ? Name -NotLike 'Hyd-CorpNet' | Select-object -first 1 -ExpandProperty Name } | |
if ( -not $VMSwitch ) { throw "missing Virtual Switch" } | |
write-verbose $VHDPath | |
write-verbose $VMSwitch | |
#endregion | |
#region Open MDT Deployment Share | |
$MDTInstall = get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Deployment 4' | % Install_dir | |
if ( -not ( test-path "$MDTInstall\Bin\microsoftDeploymentToolkit.psd1" ) ) { throw "Missing MDT" } | |
import-module -force "C:\Program Files\Microsoft Deployment Toolkit\Bin\microsoftDeploymentToolkit.psd1" -ErrorAction SilentlyContinue -Verbose:$false | |
new-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $DeploymentShare -Description "MDT Deployment Share" -Verbose -Scope script | out-string | write-verbose | |
$OfflineMedias = dir DS001:\Media | select-object -Property * | Out-GridView -OutputMode Multiple | |
$OfflineMedias | out-string | Write-Verbose | |
#endregion | |
#region Create a VM for each Offline Media Entry and Start | |
foreach ( $Media in $OfflineMedias ) { | |
$Media | out-string | write-verbose | |
$VMName = split-path $Media.Root -Leaf | |
get-vm $VMName -ErrorAction SilentlyContinue | stop-vm -TurnOff -Force -ErrorAction SilentlyContinue | |
get-vm $VMName -ErrorAction SilentlyContinue | Remove-VM -Force | |
$VHDPath = join-path ((get-vmhost).VirtualHardDiskPath) "$($VMName).vhdx" | |
remove-item $VHDPath -ErrorAction SilentlyContinue -Force | out-null | |
$ISOPath = "$($media.root)\$($Media.ISOName)" | |
if (-not $SkipMediaRebuild) { | |
write-verbose "Update Media $ISOPath" | |
Update-MDTMedia $Media.PSPath.Substring($Media.PSProvider.ToString().length+2) | |
} | |
$NewVMHash = @{ | |
Name = $VMName | |
MemoryStartupBytes = $MemoryStartupBytes | |
SwitchName = $VMSwitch | |
Generation = $VMGeneration | |
Version = $VMVersion | |
NewVHDSizeBytes = $NewVHDSizeBytes | |
NewVHDPath = $VHDPath | |
} | |
New-VM @NewVMHash -Force | |
Add-VMDvdDrive -VMName $VMName -Path $ISOpath | |
set-vm -Name $VMName -ProcessorCount $ProcessorCount | |
start-vm -Name $VMName | |
} | |
#endregion | |
#region Wait for process to finish, and extract VHDX | |
foreach ( $Media in $OfflineMedias ) { | |
$VMName = split-path $Media.Root -Leaf | |
[datetime]::Now | write-verbose | |
get-vm -vm $VMName <# -ComputerName $CaptureMachine #> | out-string | write-verbose | |
while ( $x = get-vm -vm $VMName | where state -ne off ) { write-progress "$($x.Name) - Uptime: $($X.Uptime)" ; start-sleep 1 } | |
$x | out-string | write-verbose | |
[datetime]::Now | write-verbose | |
start-sleep -Seconds 10 | |
$VHDPath = join-path ((get-vmhost).VirtualHardDiskPath) "$($VMName).vhdx" | |
dismount-vhd -path $VHDPath -ErrorAction SilentlyContinue | |
$WIMPath = join-path ((get-vmhost).VirtualHardDiskPath) "$($VMName).WIM" | |
write-verbose "Convert-VHDToWIM -ImagePath '$WIMPath' -VHDFile '$VHDPath' -Name '$ImageName' -CompressionType None -Turbo -Force" | |
Convert-VHDtoWIM -ImagePath $WIMPath -VHDFile $VHDPath -Name $ImageName -CompressionType None -Turbo -Force | |
write-verbose "Convert-WIMtoVHD -ImagePath $WIMPath -VHDFile '$($VHDPath).Compressed.vhdx' -Name $ImageName -Generation $VMGeneration -SizeBytes $NewVHDSizeBytes -Turbo -Force" | |
Convert-WIMtoVHD -ImagePath $WIMPath -VHDFile "$($VHDPath).Compressed.vhdx" -Name $ImageName -Generation $VMGeneration -SizeBytes $NewVHDSizeBytes -Turbo -Force | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment