Created
March 14, 2019 02:49
-
-
Save keithga/21007d2aeb310a57f58392dfa0bdfcc2 to your computer and use it in GitHub Desktop.
Windows 7 Image Factory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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