Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz
Verfasst: 19.03.2021, 20:22
Hallo Mitstreiter,
ich habe in der letzten Zeit viel mit Hyper-V experimentiert. Ich wollte einen Ansatz, die VM automatisch erstellen zu lassen. Es geht zwar auch recht einfach über den Hyper-V Manager, aber ich automatisiere bekanntlich gerne.
Folgendes Setup:
im Wurzelverzeichnis der Festplatte im Ordner ISO liegt das extrahierte Windows (oder auch jedes andere Betriebssystem).
Dann gibt es folgendes Powershell-Script Datei (Hyper-V erstellen_neu.ps1):
Diese starte ich mit folgender CMD-Batch (Hyper-V erstellen_neu.bat); der Name muss gleich der Powershell.ps1 Datei sein!:
Die CMD-Batch erstellt aus dem ISO Ordner auf dem Desktop eine ISO-Datei mit dem Namen Hyper-V und dann wird mit den Powershell Befehlen die VM angelegt (Name ebenfalls Hyper-V) und letztendlich wird die VM auch gleich gestartet.
Wenn man jetzt noch eine autounattend.xml im C:\ISO\ Ordner hat, die richtig konfiguriert ist, dann braucht man gar nichts mehr zu machen. Nach ca. 15 Minuten (auf meinem Rechner) kommt man dann zurück an den PC und die VM läuft schon.
Hier meine autounattend.xml:
Es gibt ein kleines Problem:
bei einer normalen Windows ISO muss nach dem Start der Installation (eigentlich kurz davor) eine Taste gedrückt werden ("Press any key to continue").
Bei einer VM geht das so schnell, dass man wohl noch ein zweites mal Starten muss. Aber auch dies kann man ändern.
Mit dem folgenden Powershell-Script werden die für dieses Verhalten erforderlichen Datei umbenannt und die Aufforderung entfällt:
Natürlich habe ich auch ein Script, welches mir die VM wieder löscht und den Speicherplatz freigibt für eine nächste Runde:
Achtung: die VM, alle damit verbunden Daten und die auf dem Desktop angelegte ISO wird gelöscht!!
Was haltet ihr davon?
Habt ihr Verbesserungsvorschläge?
ich habe in der letzten Zeit viel mit Hyper-V experimentiert. Ich wollte einen Ansatz, die VM automatisch erstellen zu lassen. Es geht zwar auch recht einfach über den Hyper-V Manager, aber ich automatisiere bekanntlich gerne.
Folgendes Setup:
im Wurzelverzeichnis der Festplatte im Ordner ISO liegt das extrahierte Windows (oder auch jedes andere Betriebssystem).
Dann gibt es folgendes Powershell-Script Datei (Hyper-V erstellen_neu.ps1):
Code: Alles auswählen
# Set VM Name, Switch Name, and Installation Media Path.
$VMName = 'Hyper-V'
# Switch is nothing but network adapter
$Switch = 'Default Switch'
# OS Iso file should be assigned to InstallMedia
$InstallMedia = 'C:\Users\Darth Vader\Desktop\Hyper-V.iso'
# Create New Virtual Machine
# MemoryStartupBytes contents the RAM size of VM.
# NewVHDSizeBytes contents the size of HD.
New-VM -Name $VMName -MemoryStartupBytes 2GB -Generation 2 -NewVHDPath "$VMName.vhdx" -NewVHDSizeBytes 50GB -SwitchName $Switch
# Add DVD Drive to Virtual Machine
Add-VMScsiController -VMName $VMName
Add-VMDvdDrive -VMName $VMName -Path $InstallMedia
# Mount Installation Media
$DVDDrive = Get-VMDvdDrive -VMName $VMName
# Configure Virtual Machine to Boot from DVD
Set-VMFirmware -VMName $VMName -FirstBootDevice $DVDDrive
# Die VM bekommt 2 virtuelle Prozessoren
Set-VMProcessor -VMName $VMName -Count 2
# Checkpoints nicht automatisch erstellen
Set-VM -VMName $VMName -AutomaticCheckpointsEnabled $false
# Gastdienste aktivieren (WINDOWS English, WINDOWS German)
# Enable-VMIntegrationService -VMName $VMName -Name 'Guest Service Interface'
Enable-VMIntegrationService -VMName $VMName -Name 'Gastdienstschnittstelle'
# Videoauflösung einstellen
set-vmvideo -VMName $VMName -ResolutionType Maximum -HorizontalResolution 1920 -VerticalResolution 1200
# Start the VM and connect to it
Start-VM -Name $VMName
vmconnect $env:COMPUTERNAME $VMName
Code: Alles auswählen
@ECHO OFF
"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe" -m -o -u2 -udfver102 -bootdata:2#p0,e,b"c:\iso\boot\etfsboot.com"#pEF,e,b"c:\iso\efi\microsoft\boot\efisys.bin" "c:\iso" "%USERPROFILE%\Desktop\Hyper-V.iso"
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}"
exit
Wenn man jetzt noch eine autounattend.xml im C:\ISO\ Ordner hat, die richtig konfiguriert ist, dann braucht man gar nichts mehr zu machen. Nach ca. 15 Minuten (auf meinem Rechner) kommt man dann zurück an den PC und die VM läuft schon.
Hier meine autounattend.xml:
Code: Alles auswählen
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-PnpCustomizationsWinPE" 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">
<DriverPaths>
<PathAndCredentials wcm:keyValue="1" wcm:action="add">
<Path>$WinPEDriver$</Path>
</PathAndCredentials>
</DriverPaths>
</component>
<component name="Microsoft-Windows-International-Core-WinPE" 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">
<SetupUILanguage>
<UILanguage>de-de</UILanguage>
</SetupUILanguage>
<InputLocale>0407:00000407</InputLocale>
<SystemLocale>de-de</SystemLocale>
<UILanguage>de-de</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>de-de</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" 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">
<DiskConfiguration>
<Disk wcm:action="add">
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Size>500</Size>
<Type>Primary</Type>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Size>100</Size>
<Type>EFI</Type>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>3</Order>
<Size>16</Size>
<Type>MSR</Type>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>4</Order>
<Extend>true</Extend>
<Type>Primary</Type>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Order>1</Order>
<PartitionID>1</PartitionID>
<Label>WinRE</Label>
<Format>NTFS</Format>
<TypeID>de94bba4-06d1-4d40-a16a-bfd50179d6ac</TypeID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Order>2</Order>
<PartitionID>2</PartitionID>
<Label>System</Label>
<Format>FAT32</Format>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Order>3</Order>
<PartitionID>3</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Order>4</Order>
<PartitionID>4</PartitionID>
<Label>Windows</Label>
<Format>NTFS</Format>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
</Disk>
<WillShowUI>OnError</WillShowUI>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/INDEX</Key>
<Value>1</Value>
</MetaData>
</InstallFrom>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>4</PartitionID>
</InstallTo>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
<WillShowUI>Never</WillShowUI>
</OSImage>
</ImageInstall>
<UserData>
<ProductKey>
<!-- Do not uncomment the Key element if you are using trial ISOs -->
<!-- You must uncomment the Key element (and optionally insert your own key) if you are using retail or volume license ISOs -->
<Key></Key>
<WillShowUI>Never</WillShowUI>
</ProductKey>
<AcceptEula>true</AcceptEula>
<FullName>Max Mustermann</FullName>
<Organization>HRi</Organization>
</UserData>
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" 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">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-Security-SPP" 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">
<SkipRearm>1</SkipRearm>
</component>
</settings>
<settings pass="specialize">
<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">
<InputLocale>0407:00000407</InputLocale>
<SystemLocale>de-de</SystemLocale>
<UILanguage>de-de</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>de-de</UserLocale>
</component>
<component name="Microsoft-Windows-Security-SPP-UX" 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">
<SkipAutoActivation>false</SkipAutoActivation>
</component>
<component name="Microsoft-Windows-SQMApi" 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">
<CEIPEnabled>0</CEIPEnabled>
</component>
<component name="Microsoft-Windows-Shell-Setup" 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">
<OEMInformation>
<Manufacturer>DARKSTAR Inc</Manufacturer>
<SupportURL>https://www.deskmodder.de/</SupportURL>
<SupportPhone>+49 176 12345678</SupportPhone>
<SupportHours>24/7</SupportHours>
<Model>LENOVO</Model>
<HelpCustomized>false</HelpCustomized>
</OEMInformation>
<ComputerName>Hyper-V</ComputerName>
<RegisteredOrganization>Sith</RegisteredOrganization>
<CopyProfile>true</CopyProfile>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" 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">
<AutoLogon>
<Password>
<Value></Value>
<PlainText>true</PlainText>
</Password>
<Enabled>true</Enabled>
<Username>Max Mustermann</Username>
</AutoLogon>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Home</NetworkLocation>
<SkipUserOOBE>true</SkipUserOOBE>
<SkipMachineOOBE>true</SkipMachineOOBE>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value></Value>
<PlainText>true</PlainText>
</Password>
<Description></Description>
<DisplayName>Max Mustermann</DisplayName>
<Group>Administrators</Group>
<Name>Max Mustermann</Name>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<RegisteredOrganization>Sith</RegisteredOrganization>
<RegisteredOwner>Max Mustermann</RegisteredOwner>
<DisableAutoDaylightTimeSet>false</DisableAutoDaylightTimeSet>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Description>Password Never Expires</Description>
<CommandLine>cmd /C wmic useraccount where name="Max Mustermann" set PasswordExpires=false</CommandLine>
<Order>1</Order>
<RequiresUserInput>false</RequiresUserInput>
</SynchronousCommand>
</FirstLogonCommands>
<TimeZone>W. Europe Standard Time</TimeZone>
</component>
</settings>
</unattend>
bei einer normalen Windows ISO muss nach dem Start der Installation (eigentlich kurz davor) eine Taste gedrückt werden ("Press any key to continue").
Bei einer VM geht das so schnell, dass man wohl noch ein zweites mal Starten muss. Aber auch dies kann man ändern.
Mit dem folgenden Powershell-Script werden die für dieses Verhalten erforderlichen Datei umbenannt und die Aufforderung entfällt:
Code: Alles auswählen
Rename-Item -Path c:\iso\efi\microsoft\boot\cdboot.efi -NewName cdboot-prompt.efi
Rename-Item -Path c:\iso\efi\microsoft\boot\cdboot_noprompt.efi -NewName cdboot.efi
Rename-Item -Path c:\iso\efi\microsoft\boot\efisys.bin -NewName efisys_prompt.bin
Rename-Item -Path c:\iso\efi\microsoft\boot\efisys_noprompt.bin -NewName efisys.bin
Code: Alles auswählen
$VMName = 'Hyper-V'
Stop-VM -Name $VMName
Remove-VM -Name $VMName -Force
Remove-Item "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhdx"
Remove-Item $env:USERPROFILE\Desktop\$VMName.iso
Achtung: die VM, alle damit verbunden Daten und die auf dem Desktop angelegte ISO wird gelöscht!!
Was haltet ihr davon?
Habt ihr Verbesserungsvorschläge?