This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Virtual Machine Template (Windows) - Deployment and Customization ====== <code powershell> Param( [Parameter(Mandatory=$True)] [string]$VMName ) $AdministratorPassword = "ChangeMe123!" # Copy VHDX $NewDiskPath = "D:\Hyper-V\Virtual Hard Disks\$($VMName.ToLower())-os.vhdx" Copy-Item -Path "C:\Hyper-V\Virtual Hard Disk Template\win2025-template.vhdx" -Destination $NewDiskPath # New VM New-VM -Name $VMName.toUpper() -Generation 2 -MemoryStartupBytes 4GB -Path "C:\Hyper-V\Virtual Machines" -SwitchName "ConvergedSwitch" Set-VMProcessor -VMName $VMName -Count 4 Set-VMFirmware -VMName $VMName -EnableSecureBoot On # Attach Disk Add-VMHardDiskDrive -VMName $VMName -Path $NewDiskPath -ControllerType SCSI Set-VMFirmware -VMName $VMName -FirstBootDevice (Get-VMHardDiskDrive -VMName $VMName) # Unattend $Unattend = @" <?xml version="1.0" encoding="utf-8"?> <unattend xmlns="urn:schemas-microsoft-com:unattend"> <settings pass="specialize"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <ComputerName>$($VMName.ToUpper())</ComputerName> </component> <component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon> </component> <component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <UseDomainNameDevolution>false</UseDomainNameDevolution> <DNSDomain>local</DNSDomain> </component> </settings> <settings pass="oobeSystem"> <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- German keyboard (QWERTZ) --> <!-- 0407 = German (Germany) language ID --> <!-- 00000407 = German keyboard layout --> <InputLocale>0407:00000407</InputLocale> <!-- Everything else US English --> <SystemLocale>en-US</SystemLocale> <UILanguage>en-US</UILanguage> <UILanguageFallback>en-US</UILanguageFallback> <UserLocale>en-US</UserLocale> </component> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <OOBE> <HideEULAPage>true</HideEULAPage> <HideOnlineAccountScreens>true</HideOnlineAccountScreens> <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> <NetworkLocation>Work</NetworkLocation> <ProtectYourPC>3</ProtectYourPC> </OOBE> <UserAccounts> <AdministratorPassword> <Value>$AdministratorPassword</Value> <PlainText>true</PlainText> </AdministratorPassword> </UserAccounts> <TimeZone>W. Europe Standard Time</TimeZone> </component> </settings> </unattend> "@ $Disk = Mount-VHD -Path $NewDiskPath -Passthru $Partition = Get-Partition -DiskNumber $Disk.Number -PartitionNumber 3 If (-not $Partition.DriveLetter) { Set-Partition -DiskNumber $Disk.Number -PartitionNumber 3 -NewDriveLetter X } $Partition = Get-Partition -DiskNumber $Disk.Number -PartitionNumber 3 $Unattend | Set-Content -Path X:\Windows\Panther\Unattend.xml -Encoding UTF8 $Unattend | Set-Content -Path C:\Users\Administrator\Desktop\LastUnattend.xml -Encoding UTF8 Dismount-VHD -Path $NewDiskPath # Start VM Start-VM -Name $VMName # Wait VM provisioned $Seconds = 0 $Stage = 0 Do { $Seconds++ Start-Sleep -Seconds 1 $HeartBeat = Get-VMIntegrationService -VMName $VMName -Name "Heartbeat" # https://learn.microsoft.com/en-us/powershell/module/hyper-v/get-vmintegrationservice?view=windowsserver2025-ps If ($Stage -in @(0, 2) -and $HeartBeat.PrimaryStatusDescription -eq 'OK') { $Stage++ } If ($Stage -eq 1 -and $HeartBeat.PrimaryStatusDescription -ne 'OK') { $Stage++ } Write-Host -NoNewLine "`rWaiting for VM to provision ($Seconds)[$Stage]" } Until ($Stage -ge 3) $Credential = New-Object System.Management.Automation.PSCredential ("Administrator", (ConvertTo-SecureString "$AdministratorPassword" -AsPlainText -Force) ) Invoke-Command -VMName $VMName -Credential $Credential -ScriptBlock { Get-NetAdapter | Rename-NetAdapter -NewName "Access_10.58.5.19_b24" Get-NetAdapter | New-NetIPAddress -IPAddress 10.58.5.19 -PrefixLength 24 Get-Netadapter | Set-DnsClientServerAddress -ServerAddresses 10.4.21.181,10.4.3.50,10.4.3.51 } </code>