Skip to content

Instantly share code, notes, and snippets.

@keithga
Created March 14, 2019 02:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keithga/21007d2aeb310a57f58392dfa0bdfcc2 to your computer and use it in GitHub Desktop.
Save keithga/21007d2aeb310a57f58392dfa0bdfcc2 to your computer and use it in GitHub Desktop.
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