Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Deine Frage passt nicht in die anderen Bereiche, dann stelle sie hier.
Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 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):

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
Diese starte ich mit folgender CMD-Batch (Hyper-V erstellen_neu.bat); der Name muss gleich der Powershell.ps1 Datei sein!:

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
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:

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>
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:

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
Natürlich habe ich auch ein Script, welches mir die VM wieder löscht und den Speicherplatz freigibt für eine nächste Runde:

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?

Tante Google

Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Tante Google » 19.03.2021, 20:22


ecerer

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von ecerer » 19.03.2021, 21:04

Man kann bei der Erstellung der VM auf die Erstellung .vhdx verzichten und sie manuell erstellen und das Image mounten.
Das überspringt die ISO Erstellung und das "Press any key to continue" Problem gleich mit.
Ansonsten nettes Tut, gut dokumentiert ;)

Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 19.03.2021, 23:42

Interessant! Kannst du das etwas genauer ausführen? Wo müßte was geändert werden?
Und bedenke: es geht ja auch darum, z.B. die autounattend.xml mal eben zu verändern und zu testen.
Kann man denn aus einem ISO Ordner mit den Windows-Installationsdateien (u.a install.wim oder install.esd) auch direkt eine vhdx "basteln"?
Nur so könnte ich mir vorstellen, auf die ISO-Erstellung zu verzichten und somit vhdx direkt aufzurufen.
Zuletzt geändert von Holgi am 20.03.2021, 13:49, insgesamt 1-mal geändert.

ecerer

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von ecerer » 20.03.2021, 12:38

Der entscheidende Befehl ist: "DISM.exe /Apply-Image /ImageFile:install.wim /Index:1 /ApplyDir:D:\", bzw. "ism /Apply-Image /ImageFile:N:\Images\my-windows-partition.wim /Index:1 /ApplyDir:W:\"
Die vhdx könntest du natürlich auch wie gehabt erstellen und aber vor dem Befehl dann noch standardmäßig Einrichten.
Dazu gibt es gute MS Hilfe hier.

Viel Spaß beim Probieren.

Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 21.03.2021, 14:51

meinst du etwas wie dieses hier? Ist nicht von mir; das habe ich im Netz gefunden.

Code: Alles auswählen

# Variablen mit Werte füllen

$VMName="TEST02"

$CPU=2

$RAMmax=8GB

$RAMmin=2GB

$RAMStartup=2GB

$VMTemplate="E:\Templates\WS2019\Virtual Hard Disks\"

$Switchname="VMs"

$VMPath="E:\VMs\"

$TargetVHDXPath=$VMPath+$VMName

$VMVHDXFile=$TargetVHDXPath+ "\Virtual Hard Disks\WS2019_Template.vhdx"

Write-Host "Erstelle VM $VMName" -BackgroundColor Black -ForegroundColor White

New-VM -Name $VMName -MemoryStartupBytes $RAMStartup -SwitchName $Switchname -Path $VMPath -Generation 2

Write-Host "Kopiere VHDx Template..." -BackgroundColor Black -ForegroundColor Green

Copy-item $VMTemplate -Destination $TargetVHDXPath -Recurse

Write-Host "VHDx Disk zur VM hinzufügen..." -BackgroundColor Black -ForegroundColor Green

Add-VMHardDiskDrive -VMName $VMName -ControllerType SCSI -ControllerNumber 0 -Path $VMVHDXFile

Write-Host "Virtual Maschine anpassen..." -BackgroundColor Black -ForegroundColor Green

Set-VM -Name $VMName -DynamicMemory -MemoryMaximumBytes $RAMmax -MemoryMinimumBytes $RAMmin -MemoryStartupBytes $RAMStartup -ProcessorCount $CPU

$bootdevicenetwork=(Get-VMFirmware -VMName $VMName).BootOrder[0]

$bootdevicevhdx=(Get-VMFirmware -VMName $VMName).BootOrder[1]

Set-VMFirmware -VMName $VMName -BootOrder $bootdevicevhdx,$bootdevicenetwork

Write-Host "Virtual Maschine: $VMName... starten" -BackgroundColor Black -ForegroundColor Green

Start-VM -Name $VMName


Benutzeravatar
DK2000
Legende
Legende
Beiträge: 5151
Registriert: 03.04.2018, 00:07
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von DK2000 » 21.03.2021, 17:17

Eigentlich hast Du im ersten Beitrag schon alles gemacht um den ("Press any key to continue") los zu werden. Habe das extra noch einmal so nachvollzogen und bei mir klappt das. Die ISO boote ohne diese Abfrage sofort durch.

Entpackte ISO liegt bei mir in D:\Test\ISO

Und danach auch die Dateien umbenannt:

Code: Alles auswählen

Rename-Item -Path D:\Test\iso\efi\microsoft\boot\cdboot.efi -NewName cdboot-prompt.efi
Rename-Item -Path D:\Test\iso\efi\microsoft\boot\cdboot_noprompt.efi -NewName cdboot.efi
Rename-Item -Path D:\Test\iso\efi\microsoft\boot\efisys.bin -NewName efisys_prompt.bin
Rename-Item -Path D:\Test\iso\efi\microsoft\boot\efisys_noprompt.bin -NewName efisys.bin
Und am Ende den langen Rattenschwanz:

Code: Alles auswählen

oscdimg -m -o -u2 -udfver102 -bootdata:2#p0,e,b"D:\Test\iso\boot\etfsboot.com"#pEF,e,b"D:\Test\iso\efi\microsoft\boot\efisys.bin" "D:\Test\iso" "D:\Test\windows_noprompt.iso"
Die jetzt erstellte ISO "windows_noprompt.iso" hat besagt Abfrage beim Booten nicht mehr und startet sofort in das Setup.

Also der Weg ist der Richtige. Aber warum klappt das bei Dir jetzt nicht? Gut, habe da die Verzeichnisse geändert, aber daran sollte es jetzt nicht liegen. Oder bootest Du im reinen BIOS Modus?

Und das was ecerer meint, ist Windows ohne Setup in der Anfangsphase installieren, also virtuelle Platte bereitstellen, partitionieren, Windows mittels DISM in die Startpartition entpacken bei Bedarf Antwortdatei hinzufügen, mittels bcdboot bootfähig machen und wenn man will noch das WinRE einrichten. Virtuelle Platte wieder aushängen. Ab hier ist die Platte bootfähig und in der VM wird dann die Installation abgeschlossen. Funktioniert im Übrigen auch gut mit realer Hardware.

Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 21.03.2021, 20:05

Aber warum klappt das bei Dir jetzt nicht?
Hallo DK 2000,
nee, das ist jetzt wohl ein Missverständnis. Das klappt bei mir auch. Es war für mich zunächst ein Problem, welches aber in meinem Lösungsvorschlag mit der Umbenennung gelöst wurde.
Was noch offen war, ist die Alternative, die ecerer vorgeschlagen hatte:
auf die Erstellung .vhdx verzichten und sie manuell erstellen und das Image mounten.
die mir jetzt nicht ganz klar war.
Du hast es jetzt zwar etwas weiter ausgeführt mit
Windows ohne Setup in der Anfangsphase installieren, also virtuelle Platte bereitstellen, partitionieren, Windows mittels DISM in die Startpartition entpacken bei Bedarf Antwortdatei hinzufügen, mittels bcdboot bootfähig machen und wenn man will noch das WinRE einrichten. Virtuelle Platte wieder aushängen. Ab hier ist die Platte bootfähig und in der VM wird dann die Installation abgeschlossen.
aber ob das jetzt schneller oder einfacher ist, weiß ich nicht.
Wie aus der Überschrift dieses Postings hervorgeht, sollte es ja um die Erstellung der Hyper-V VM per Script gehen (die möglichst von allen nachvollziehbar sind; also ohne großartige Anpassungen).
Wenn ihr also fertige Scripte habt, dann würde ich es schon mal ausprobieren. Ich bin immer offen für Experimente und Neues. Aber ich habe nicht so viel Ahnung von der Materie wir ihr.

Ich habe mein Powershell-Script (Hyper-V erstellen_neu.ps1) noch mal etwas gepimpt:

Code: Alles auswählen

# Set VM Name, Switch Name, and Installation Media Path.
$VMName = 'Hyper-V'
# Switch is nothing but network adapter
$Switch = (Get-VMSwitch).Name
# 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.

Write-Host "Erstelle VM $VMName" -BackgroundColor Black -ForegroundColor White

New-VM -Name $VMName -MemoryStartupBytes 2GB -Generation 2 -NewVHDPath "$VMName.vhdx" -NewVHDSizeBytes 50GB -SwitchName $Switch

Write-Host "Virtual Maschine anpassen..." -BackgroundColor Black -ForegroundColor Green

# Add DVD Drive to Virtual Machine
# Add-VMScsiController -VMName WIN10IOT
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

# Dynamischen Arbeitsspeicher einrichten
Set-VM -VMName $VMName -DynamicMemory -MemoryMinimumBytes 512mb -MemoryMaximumBytes 2GB -Confirm:$false

# automatische Start-/StoppAktionen einrichten
Set-VM -VMName $VMName -AutomaticStartAction StartIfRunning -AutomaticStopAction Save -Confirm:$false

Write-Host "Virtual Maschine: $VMName... starten" -BackgroundColor Black -ForegroundColor Green

# Start the VM and connect to it
Start-VM -Name $VMName
vmconnect $env:COMPUTERNAME $VMName

ecerer

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von ecerer » 22.03.2021, 11:16

Holgi hat geschrieben: 21.03.2021, 20:05 aber ob das jetzt schneller oder einfacher ist, weiß ich nicht.
Schneller auf jeden Fall, einfacher naja wie gesagt: Das "Press any key to continue" Problem wäre aus der Welt und du könntest einiges aus der autounattend.xml weglassen und anders lösen.
Ich war der Meinung, in dem Link wovon es viele gibt, aber alles gesehen zu haben. ;)

ecerer

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von ecerer » 22.03.2021, 11:23

Code: Alles auswählen

<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>
Das hab ich gar nicht gesehen :lol:
Kannst ja mal beim Support anrufen.

Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 22.03.2021, 20:13

dann meint ihr bestimmt so etwas in dieser Art, oder? :smile:

Code: Alles auswählen

@echo off
setlocal enabledelayedexpansion

set Hinweis=Bitte lesen Sie unbedingt die Anleitung zu diesem Skript in c't 20/2020!


rem --------- Variablen fuer das Skript setzen  -----------

rem *** Arbeitsverzeichnis ***
rem Pfad des Ordners, in dem das Skript liegt.
rem Falls eine Antwortdatei in die VHD-Datei soll, muss sie 
rem als "autounattend.xml" ebenfalls hier liegen.
set workdir=%~d0%~p0

rem *** Temporaerer Unterordner ***
rem Wird standardmaessig im Arbeitsverzeichnis erstellt.
set folder=%~n0-tmp

rem --------- Variablen fuer die VM setzen  -----------

rem *** VM: Anzahl der virtuellen CPUs
set cpu=4

rem *** VM: Start-RAM-Groesse in MByte ***
set startram=2048

rem *** VM: Minmale RAM-Groesse in MByte ***
set minram=1024

rem *** VM: Maximale RAM-Groesse in MByte ***
set maxram=4096

rem *** VM: Netzwerkswitch auswaehlen. Zum Aktivieren "rem" vor der naechsten Zeile entfernen und bei Bedarf Switchname in Anfuehrungsstrichen (') anpassen
rem set switch=-switchname 'default switch'

rem *** VM: Automatische Pruefpunkte an (1) oder aus (0)
set autocheckpoints=0

rem *** VM: Generation 1 (Legacy BIOS) oder 2 (UEFI)? ***
set gen=1

rem --------- Variablen fuer die VHD(x) setzen  -----------

rem *** VHD: (maximale) Dateigroesse in MByte ***
set vhdsize=127000

rem *** VHD-Typ: 0 (feste Groesse) oder 1 (dynamisch wachsend) ***
set vhdtyp=1

rem *** VHD: Partitionsgroesse Boot-/EFI-Partition ***
set partboot=500

rem *** VHD: Partitionsgroesse MSR-Partition ***
set partmsr=128

rem *** VHD: Partitionsgroesse Recovery-Partition ***
set partre=1000

rem --------- Variablen fuer die unbeaufsichtigte Installation -----------

rem *** 64-Bit-Antwortdatei ***
set autox64=Autounattendx64.xml

rem *** 32-Bit-Antwortdatei ***
set autox86=Autounattendx86.xml

rem ------------- Ende der Anpassungen -----------

set operation=*** Hilfe erwuenscht? ***
if /i %1.==. goto hilfe
if /i %1.==/?. goto hilfe
if /i %1.==-?. goto hilfe
if /i %1.==/h. goto hilfe
if /i %1.==-h. goto hilfe
if /i %1.==--h. goto hilfe
if /i %1.==/help. goto hilfe
if /i %1.==-help. goto hilfe
if /i %1.==--help. goto hilfe

rem *** Optik anpassen ***
cls
color 0F
set farbtmp=
for /f "tokens=3" %%b in ('reg query ^"HKLM^\Software^\Microsoft^\Windows NT^\CurrentVersion^" /v ^"ReleaseID^" 2^>nul') do set farbtmp=%%b >nul 2>nul
if "%farbtmp%."=="." goto start

set ESC=
set weiss=%esc%[97m
set gruen=%esc%[92m
set rot=%esc%[91m
set gelb=%esc%[93m

:start
echo.%gelb%
echo ****************************************************
echo ***        Willkommen bei c't-Win2Hyper-V        ***
echo ****************************************************
echo.
echo %hinweis%%weiss%
echo.

echo *** Einige Pruefungen vorab ... ***
echo.

set operation=*** Temporaerer Ordner bereits vorhanden? ***
if not exist %workdir%%folder% goto istfrei
set /a foldernr=1
set tempfolder=%folder%
:ring
set /a foldernr=%foldernr%+1 
set folder=%tempfolder%-%foldernr%
if exist %workdir%%folder% goto ring
:istfrei

set operation=*** Skript braucht mindestens Windows 10 Versin 1709 ***
for /f "tokens=3" %%a in ('reg query ^"HKLM^\SOFTWARE^\Microsoft^\Windows NT^\CurrentVersion^" /v ^"ReleaseID^"') do set versionhost=%%a
if %versionhost% lss 1709 goto fehler1

set operation=*** Skript muss mit Administratorrechten laufen ***
whoami /groups | find "S-1-16-12288" > nul
if errorlevel 1 goto fehler1

set operation=*** Hyper-V muss aktiviert sein ***
dism /online /get-features /format:table | find "Microsoft-Hyper-V " | find "Aktiviert" > nul
if errorlevel 1 goto fehler1

set operation=*** Hyper-V-Modul fuer Windows PowerShell muss aktiviert sein ***
dism /online /get-features /format:table | find "Microsoft-Hyper-V-Management-PowerShell" | find "Aktiviert" > nul
if errorlevel 1 goto fehler1

set operation=*** Es muss eine ISO-, WIM- oder ESD-Datei uebergeben werden ***
set pfad=%*
set pfad="%pfad:"=%"
if .%pfad:~-4,3% neq .wim if .%pfad:~-4,3% neq .esd if .%pfad:~-4,3% neq .iso goto fehler1

echo *** Keine Probleme gefunden, jetzt geht es los ***
echo.

if .%pfad:~-4,3% neq .iso (
  set wim=%pfad%
  goto wahl
)

set operation=*** ISO-Datei einbinden ***
echo %weiss%%operation%%gruen%
set iso="%pfad:"=%"
powershell "mount-diskimage '%iso%'"
if errorlevel 1 goto fehler2
set isolw=
for /f "skip=3" %%i in ('powershell "get-diskimage '%iso%' | get-volume | select driveletter"') do set isolw=%%i
if "%isolw%."=="." goto fehler2

set operation=*** ISO-Datei muss WIM- oder ESD-Datei enthalten ***
if exist %isolw%:\sources\install.esd (
  set wim=%isolw%:\sources\install.esd
) else if exist %isolw%:\sources\install.wim (
  set wim=%isolw%:\sources\install.wim
) else (
  goto fehler1
)
if errorlevel 1 goto fehler2

:wahl
set operation=*** Image auswaehlen ***
echo %weiss%%operation%%gruen%
set index=1
set letztenummer=1
for /f "tokens=1,2* delims=: " %%L in ('%windir%\system32\dism /get-wiminfo /wimfile:%wim%') do (
   if "%%L"=="Index" set /a letztenummer=%%M
)
if %letztenummer% equ 1 goto weiter
%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% 
if errorlevel 1 goto fehler2
echo.%gelb%
set /p Index=Nummer des Images eingeben:
echo.

set operation=*** Pruefe ausgewaehltes Image ***
echo %weiss%%operation%%gruen%

set operation=*** Ausgewaehltes Image muss vorhanden sein ***
if %index% gtr %letztenummer% goto fehler1
if %index% lss 1 goto fehler1
echo.
:weiter

set Operation=*** In Generation-2-VMs laeuft nur x64-Windows ***
for /f "tokens=*" %%L in ('%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% /index:%index% ^| find "Architecture"') do (set archtmp=%%L)
set architektur=%archtmp:~15%
if %gen%==2 if not %architektur%==x64 goto fehler1

set Operation=*** In Generation-2-VMs laufen weder Vista noch Windows 7 ***
for /f "tokens=*" %%L in ('%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% /index:%index% ^| find "Version"') do (set vertmp=%%L)
set version=%vertmp:~10%
set alter=neu
if not %version:~0,3%==6.2 if not %version:~0,3%==6.3 if not %version:~0,3%==6.4 if not %version:~0,3%==10. set alter=alt
if %gen%==2 if %alter%==alt goto fehler1

echo %gruen%OK
echo.

set Operation=*** Speicherpfad fuer VMs auslesen ***
echo %weiss%%operation%%gruen%
echo.
set vmpfad=
for /f "tokens=3" %%a in ('reg query ^"HKLM^\SOFTWARE^\Microsoft^\Windows NT^\CurrentVersion^\Virtualization^" /v ^"DefaultExternalDataRoot^" 2^>nul') do set vmpfad=%%a
if "%vmpfad%."=="." set vmpfad=%allusersprofile%\Microsoft\Windows\Hyper-V\
echo Gespeichert wird die VM unter: %vmpfad%
echo.

set Operation=*** Temporaeren Ordner anlegen *** 
echo %weiss%%operation%%gruen%
echo.
md %workdir%%folder%
echo Temporaerer Ordner angelegt: %workdir%%folder%
echo.

set operation=*** Release-ID auslesen ***
echo %weiss%%operation%%gruen%
echo.
%workdir%7z.exe e %wim% -o%workdir%%folder% %index%\Windows\System32\config\Software >nul 2>nul
reg load HKLM\VHD %workdir%%folder%\software >nul 2>nul
if errorlevel 1 goto fehler2
set reltmp=
for /f "tokens=3" %%b in ('reg query ^"HKLM^\VHD^\Microsoft^\Windows NT^\CurrentVersion^" /v ^"ReleaseID^" 2^>nul') do set reltmp=%%b >nul 2>nul
if "%reltmp%."=="." echo Keine Release-ID gefunden. && goto unload
echo Release-ID ist %reltmp% 
set release=%reltmp%_
:unload
reg unload HKLM\VHD >nul 2>nul
if errorlevel 1 goto fehler2
echo.

set operation=*** Name der VM zusammenstellen ***
echo %weiss%%operation%%gruen%
echo.
for /f "tokens=*" %%L in ('%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% /index:%index% ^| find "Name"') do (set edittmp=%%L)
set edition=%edittmp:~7%
set edition=%edition: =_%
set edition=%edition:~0,41%
for /f "tokens=*" %%L in ('%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% /index:%index% ^| find "Default"') do (set langtmp=%%L)
set sprache=%langtmp:~0,5%
set VMname=%edition%_%release%%architektur%_%sprache%_Gen%gen%_%version%
set vmname=%vmname: =%
chcp 65001 >nul
set vmname=%vmname:ä=ae%
set vmname=%vmname:ö=oe%
set vmname=%vmname:ü=ue%
set vmname=%vmname:ß=ss%
set vmname=%vmname:Ä=Ae%
set vmname=%vmname:Ö=Oe%
set vmname=%vmname:Ü=Ue%
set vmname=%vmname::=.%
chcp 850 >nul
if not exist %vmpfad%%vmname% goto nunaber
set /a nr=1
set tempvmname=%vmname%
:schleife
set /a nr=%nr%+1 
set vmname=%tempvmname%-%nr%
if exist %vmpfad%%vmname% goto schleife
:nunaber
md %vmpfad%%vmname%
echo Als Name der VM wird festgelegt: %vmname%
echo.

set operation=*** Freien Laufwerksbuchstaben fuer Windows-Partition in VHD(X) suchen ***
echo %weiss%%operation%%gruen%
echo.
for %%l in (P Q R S T U V W X Y Z D E F G H I J K L M N O) do (  
  set vhdlw=%%l
  mountvol %%l: /L >nul
  if errorlevel 1 (
    subst | findstr /B "%%l:" >nul
    if errorlevel 1 (
      net use %%l: >nul 2>&1
      if errorlevel 1 goto weiter2
    )
  )
)
goto fehler1
:weiter2
echo Verwende %vhdlw%:
echo.

subst %vhdlw%: %workdir%%folder% 
set operation=*** Freien Laufwerksbuchstaben fuer Boot-Partition in VHD(X) suchen ***
echo %weiss%%operation%%gruen%
echo.
for %%l in (P Q R S T U V W X Y Z D E F G H I J K L M N O) do (  
  set efilw=%%l
  mountvol %%l: /L >nul
  if errorlevel 1 (
    subst | findstr /B "%%l:" >nul
    if errorlevel 1 (
      net use %%l: >nul 2>&1
      if errorlevel 1 goto weiter3
    )
  )
)
goto fehler1
:weiter3
subst %vhdlw%: /d
echo Verwende %efilw%:
echo.

set operation=*** VHD erzeugen ***
echo %weiss%%operation%%gruen%
if %vhdtyp%==1 (set typ=expandable) else set typ=fixed
set format=vhd
if %gen%==2 set format=vhdx
echo create vdisk file=%vmpfad%%vmname%\%vmname%.%format% maximum=%vhdsize% type=%typ% > %workdir%%folder%\diskpart.txt
echo attach vdisk >> %workdir%%folder%\diskpart.txt
if %gen%==2 (
  echo convert gpt >> %workdir%%folder%\diskpart.txt
  echo create partition efi size=%partboot% >> %workdir%%folder%\diskpart.txt
  echo format fs=fat32 quick label="System" >> %workdir%%folder%\diskpart.txt
) else (
  echo create partition primary size=%partboot% >> %workdir%%folder%\diskpart.txt
  echo format quick fs=ntfs label="System" >> %workdir%%folder%\diskpart.txt
  echo active >> %workdir%%folder%\diskpart.txt
)
echo assign letter=%efilw% >> %workdir%%folder%\diskpart.txt
if %gen%==2 echo create partition msr size=%partmsr% >> %workdir%%folder%\diskpart.txt
echo create partition primary >> %workdir%%folder%\diskpart.txt
echo shrink minimum=%partre% >> %workdir%%folder%\diskpart.txt
echo format fs=ntfs quick label="Windows" >> %workdir%%folder%\diskpart.txt
echo assign letter=%vhdlw% >> %workdir%%folder%\diskpart.txt
echo create partition primary >> %workdir%%folder%\diskpart.txt
echo format quick fs=ntfs label="Recovery" >> %workdir%%folder%\diskpart.txt
if %gen%==1 (
  echo set id=27 >> %workdir%%folder%\diskpart.txt
) else (
  echo set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac" >> %workdir%%folder%\diskpart.txt
  echo gpt attributes=0x8000000000000001 >> %workdir%%folder%\diskpart.txt
)
echo exit >> %workdir%%folder%\diskpart.txt
diskpart /s %workdir%%folder%\diskpart.txt
if errorlevel 1 goto fehler2

echo.
set operation=*** Image in VHD kopieren ***
echo %weiss%%operation%%gruen%
dism /apply-image /imagefile=%wim% /index:%index% /applydir=%vhdlw%:
if errorlevel 1 goto fehler2

echo.
set auto=%autox64%
if not %architektur%==x64 set auto=%autox86%
if not exist %~d0%~p0%auto% goto bcdboot
set operation=*** autounattend.xml ergaenzen ***
echo %weiss%%operation%%gruen%
echo.
md %vhdlw%:\windows\panther\unattend
copy %~d0%~p0%auto% %vhdlw%:\windows\panther\unattend\unattend.xml

:bcdboot
echo.
set operation=*** Bootloader ergaenzen ***
echo %weiss%%operation%%gruen%
echo.
if %gen%==1  bcdboot /d %vhdlw%:\windows /s %efilw%: /addlast /l de-de /f BIOS
if %gen%==2  bcdboot /d %vhdlw%:\windows /s %efilw%: /addlast /l de-de /f UEFI
if errorlevel 1 goto fehler2
echo.

set operation=*** Entfernen von Registry-Schluessel "MountedDevices" aus der VHD ***
reg load HKLM\VHD %vhdlw%:\windows\system32\config\system >nul 2>nul
if errorlevel 1 goto fehler2
reg query HKLM\VHD\MountedDevices >nul 2>nul
if errorlevel 1 goto unload 
echo %weiss%%operation%%gruen%
echo.
reg delete HKLM\VHD\MountedDevices /f >nul 2>nul
if errorlevel 1 goto fehler2
echo Registry-Schluessel entfernt
echo.
:unload
reg unload HKLM\VHD >nul 2>nul
if errorlevel 1 goto fehler2

set operation=*** VM erzeugen ***
echo %weiss%%operation%%gruen%
powershell new-vm -name '%vmname%' -path '%vmpfad%%vmname%' -VHDpath '%vmpfad%%vmname%\%vmname%.%format%'  -MemoryStartupBytes %startram%MB -generation %gen% %switch%
powershell set-vm -name '%vmname%' -ProcessorCount %cpu% -DynamicMemory -MemoryMaximumBytes %maxram%MB -MemoryMinimumBytes %minram%MB -AutomaticCheckpointsEnabled %autocheckpoints%
if %alter%==alt (
  powershell Remove-VMNetworkAdapter -vmname '%vmname%'
  powershell Add-VMNetworkAdapter -vmname '%vmname%' -IsLegacy $true
)

set operation=*** Temporaere Laufwerke wieder aushaengen ***
echo %weiss%%operation%%gruen%
echo.
if exist %workdir%%folder% rd /q /s %workdir%%folder%
if not %efilw%.==. if not %vhdlw%.==. if not %efilw%.==%vhdlw%. mountvol %efilw%: /d >nul 2>nul
if exist %vhdlw%: powershell dismount-vhd -path '%vmpfad%%vmname%\%vmname%.%format%'
if exist %isolw%: powershell "dismount-diskimage '%iso%'"

set operation=*** Starte VM ***
echo %weiss%%operation%%gruen%
echo.
powershell Start-VM -name '%vmname%'

echo %weiss%*** Fertig! ***
echo.
pause
goto :eof

rem *** Fehlerbehandlung ***

rem Bedingung nicht erfuellt
:fehler1
set text=Folgende Bedingung wurde nicht erfuellt: 
goto Fehlerausgabe

rem Fehler bei der Durchfuehrung
:fehler2
set text=Operation fehlgeschlagen:
goto Fehlerausgabe


:fehlerausgabe
echo.
echo %rot%%text%
echo.
echo %rot%%operation%
echo.
echo %rot%%hinweis%
echo.

:aufraeumen
set operation=*** Raeume hinter mir auf ***
pause
echo.
echo %weiss%%operation%%gruen%
echo.
if exist %workdir%%folder% rd /q /s %workdir%%folder%
if not %efilw%.==. mountvol %efilw%: /d >nul 2>nul
if exist %vhdlw%: powershell dismount-vhd -path '%vmpfad%%vmname%\%vmname%.%format%' >nul 2>nul
if exist %isolw%: powershell "dismount-diskimage '%iso%'" >nul 2>nul
echo.
set operation=*** Fertig! ***
echo %weiss%%operation%%gruen%
echo.
pause
echo.
goto :eof

:hilfe
echo.
echo %~nx0 erzeugt Hyper-V-VMs
echo.
echo Als Quelle akzeptiert %~nx0 WIM- und ESD-Dateien sowie 
echo ISOs und DVDs, die solche Dateien im Ordner "Sources" enthalten.
echo.
echo %~nx0 muss mit Administratorrechten gestartet werden!
echo.
echo %Hinweis%
echo.
pause
goto :eof
;
REM Erstellt 2020 von Axel Vahldiek/c't
REM mailto: axv@ct.de

Benutzeravatar
DK2000
Legende
Legende
Beiträge: 5151
Registriert: 03.04.2018, 00:07
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von DK2000 » 22.03.2021, 20:26

Ja, so ist das gemeint, wenn ich den Scrip da von Dir jetzt richtig deute.
aber ob das jetzt schneller oder einfacher ist, weiß ich nicht.
Schneller ist immer relativ. Spart halt das Booten vom Installationsmedium.

So schnell und schmutzig könnte das so aussehen, wobei das jetzt kein Scrip ist, sondern alles nur im Terminal eingegeben.

Neue leere VHDX mit 64GB erstellen (GPT) und im Host bereitstellen :

Code: Alles auswählen

$NewVMDisk=(New-VHD -Path D:\Test.vhdx -Dynamic -SizeBytes 64GB)|Mount-VHD -PassThru

Initialize-Disk -Number $NewVMDisk.DiskNumber -PartitionStyle GPT
Get-Disk -Number $NewVMDisk.Number|Get-Partition|Remove-Partition -Confirm:$false
Die Variable $NewVMDisk enthält alle relevanten Informationen zur VDHX, so auch die Disk-Nummer ($NewVMDisk.DiskNumber). Die braucht man dann nicht extra ermitteln.

Das Partitionieren ist jetzt etwas kniffliger, da PowerShell "Diskpart" nicht zu 100% ersetzt. Deswegen erledige ich das in der PowerShell auf eine Art und Weise, die etwas komisch aussieht:

Code: Alles auswählen

$null = @"
rem ===== 0. Vorspiel
select disk $($NewVMDisk.DiskNumber)
rem ===== 1. EFI-Systempartition (ESP)
create partition efi size=100
format quick fs=fat32 label="System"
assign letter="S"
gpt attributes=0x8000000000000001
rem ===== 2. Microsoft Reserved (MSR)
create partition msr size=16
rem ===== 3. Windows Startpartition
create partition primary
shrink desired=1024
format quick fs=ntfs label="Windows"
assign letter="W"
rem === 4. Wiederherstellungspartition
create partition primary
format quick fs=ntfs label="Recovery"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
exit
"@ |
diskpart.exe
Das kann man auch alles in eine Zeile Schreiben, aber dann wird das zu unübersichtlich. Wenn bis hier hin alles geklappt hat, dann sollte die VHDX jetzt so aussehen:
Screenshot 2021-03-22 192015.jpg
Als nächstes das Image in die Startpartition (W:) entpacken, wobei es jetzt egal ist, Ob PowerShell oder DISM:

Code: Alles auswählen

Expand-WindowsImage -ImagePath D:\Install.wim -ApplyPath W:\ -Index 1 -CheckIntegrity -Verify
Jetzt bootfähig machen (Dafür kenne ich keine Lösung mit der PowerShell):

Code: Alles auswählen

bcdboot W:\Windows /l de-de /s S: /f UEFI
Die VHDX jetzt bootfähig. Ab hier kann man dann jetzt noch Updates, Treiber, Apps oder sonstige Anpassungen auf W: vornehmen.

Am Ende aufräumen:

Code: Alles auswählen

$null = @"
select disk $($NewVMDisk.DiskNumber)
select partition 1
remove
select partition 3
remove
select partition 4
remove
"@ |
diskpart.exe

Dismount-VHD -Path $NewVMDisk.Path
Dein Script da ist etwas universeller, aber wenn ich mir jetzt schon die Mühe gemacht habe, das mal schnell durchzutesten, dan poste ich das mal auch. Allerdings, da ich Hyper-V nicht verwende, weiß ich jetzt nicht, wie man meine VHDX jetzt per Script in die VM brint.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

ecerer

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von ecerer » 22.03.2021, 20:28

Ich sag mal JA, aber das scheint ziemlich ausgereift ;)
460 Zeilen brauch ich dazu nicht, muss halt jeder selber wissen.
Wo du sowas nur herzauberst... steht da ich weiß!

Benutzeravatar
DK2000
Legende
Legende
Beiträge: 5151
Registriert: 03.04.2018, 00:07
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von DK2000 » 22.03.2021, 20:34

Das stand wohl mal in der c't 20/2020. Aber sieht interessant aus der Zirpt. Der sieht universell aus. Muss ich mir mal anschauen.

Benutzeravatar
Holgi
Meister
Meister
Beiträge: 358
Registriert: 12.05.2018, 12:33
Geschlecht:

Re: Hyper-V Virtuelle Maschine per Script erstellen; mein Lösungsansatz

Beitrag von Holgi » 23.03.2021, 10:00

Es gibt von c´t übrigens noch ein Script, das nennt sich Win2VHd. Aus diesem ist Win2VM erwachsen.
Win2VHd erzeugt aus Windows-Installationspaketen bootfaehige VHD-Dateien und bindet diese in den Bootloader ein. So z.B. als 2tes Windows für Experimente.
Zur Benutzung sei dieser Artikel empfohlen:
https://goneuland.de/ct-win2vhd-windows-von-vhd-booten/
hier mal das Script:

Code: Alles auswählen

cls
@echo off
setlocal enabledelayedexpansion
color 0A

set Hinweis=Bitte lesen Sie unbedingt die Anleitung zu diesem Skript in c't 2/17!


rem --------- Optional: An die eigenen Verhaeltnisse anpassen -----------

rem Pfad zum Ordner, in dem das Skript die VHD-Datei erzeugen soll. 
rem Ohne Anpassung verwendet das Skript den Ordner, in dem es liegt.
rem Keine Leerzeichen im Pfad! Mit abschliessendem "\"!

set workdir=%~d0%~p0

rem Typ der VHD festlegen.
rem Feste Groesse=0
rem Dynamisch wachsend=1

set vhdtyp=1

rem ------------- Ende der Anpassungen -----------

set operation=*** Hilfe erwuenscht? ***
if /i %1.==/?. goto hilfe
if /i %1.==-?. goto hilfe
if /i %1.==/h. goto hilfe
if /i %1.==-h. goto hilfe
if /i %1.==--h. goto hilfe
if /i %1.==/help. goto hilfe
if /i %1.==-help. goto hilfe
if /i %1.==--help. goto hilfe


echo.
echo ****************************************************
echo ***          Willkommen bei c't-Win2VHD          ***
echo ****************************************************
echo.
echo %hinweis%
echo.

echo *** Einige Pruefungen vorab ... ***
echo.

set operation=*** Skript braucht mindestens Windows 8.1 ***
for /f "tokens=3" %%a in ('reg query ^"HKLM^\SOFTWARE^\Microsoft^\Windows NT^\CurrentVersion^" /v ^"currentversion^"') do set version=%%a
if %version% lss 6.3 goto fehler1

set operation=*** Skript muss mit Administratorrechten laufen ***
whoami /groups | find "S-1-16-12288" > nul
if errorlevel 1 goto fehler1

set operation=*** Es muss ein Installationsmedium bzw. eine ISO-, WIM- oder ESD-Datei uebergeben werden ***
if not exist %1sources\install.wim if not exist %1sources\install.esd if /i not %~x1.==.iso. if /i not %~x1.==.wim. if /i not %~x1.==.esd. goto fehler1

echo *** Keine Probleme gefunden, jetzt geht es los ***
echo.

if %~x1.==.wim. set wim=%~dpnx1 && set isiso=0 && goto wahl
if %~x1.==.esd. set wim=%~dpnx1 && set isiso=0 && goto wahl
if exist %1sources\install.wim set wim=%1sources\install.wim && set isiso=0 && goto wahl
if exist %1sources\install.esd set wim=%1sources\install.esd && set isiso=0 && goto wahl

set operation=*** ISO-Datei einbinden ***
echo %operation%
echo.
set iso=%~dpnx1
set isiso=1
powershell "mount-diskimage '%iso%'"
if errorlevel 1 goto fehler2
for /f "skip=3" %%i in ('powershell "get-diskimage '%iso%' | get-volume | select driveletter"') do set isolw=%%i
set operation=*** ISO-Datei muss WIM- oder ESD-Datei enthalten ***
if not exist %isolw%:\sources\install.esd if not exist %isolw%:\sources\install.wim goto fehler1
if exist %isolw%:\sources\install.esd set wim=%isolw%:\sources\install.esd
if exist %isolw%:\sources\install.wim set wim=%isolw%:\sources\install.wim
if errorlevel 1 goto fehler2

:wahl
set operation=*** Image auswaehlen ***
set index=1
set letztenummer=1
for /f "tokens=1,2* delims=: " %%L in ('%windir%\system32\dism /get-wiminfo /wimfile:%wim%') do (
   if "%%L"=="Index" set /a letztenummer=%%M
)
if !letztenummer! equ 1 goto weiter
%windir%\system32\dism /english /get-wiminfo /wimfile:%wim% 
if errorlevel 1 goto fehler2
echo.
set /p Index=Nummer des Images eingeben:
if errorlevel 1 goto fehler2

:weiter
for /f "tokens=1,2* delims=: " %%L in ('%windir%\system32\bcdedit /enum {current}' ) do (
   if "%%L"=="path" set efi=%%M
)
if not "%efi%"=="\Windows\system32\winload.efi" goto vhd 
for /f "tokens=1,2* delims=: " %%L in ('%windir%\system32\dism /get-wiminfo /wimfile:%wim% /index:%index%' ) do (
   if "%%L"=="Architektur" set Bit=%%M
)
if "%Bit%"=="x64" goto vhd 
echo.
echo Obacht, Sie haben ein 32-Bit-Abbild ausgewaehlt.
echo Der PC ist aktuell jedoch im UEFI-Modus gebootet, 
echo in dem 32-Bit-Installationen nicht starten koennen. 
echo Daher erzeugt das Skript in diesem Modus
echo nur 64-Bit-VHD-Installationen.
echo.
:aufraeumen
set operation=*** Aufraeumen ***
echo %operation%
echo.
if %isiso%==1 powershell "dismount-diskimage '%iso%'"
echo *** fertig! ***
pause
goto :eof

:vhd
set operation=*** Laufwerksbuchstabe fuer VHD suchen ***
echo %operation%
echo.
for %%l in (P Q R S T U V W X Y Z D E F G H I J K L M N O) do (  
  set vhdlw=%%l
  mountvol %%l: /L >nul
  if errorlevel 1 (
    subst | findstr /B "%%l:" >nul
    if errorlevel 1 (
      net use %%l: >nul 2>&1
      if errorlevel 1 goto weiter2
    )
  )
)

:weiter2
echo *** Verwende %vhdlw% ***

set operation=*** VHD erzeugen ***
echo %operation%
echo.
echo Bitte geben Sie den Namen der VHD-Datei an. 
echo Bitte nur Buchstaben und Ziffern verwenden, 
echo keine Umlaute, keine Satzzeichen! 
echo Dateiendung wird automatisch angefuegt.
set /p vhdname=Name:
:groesse
echo.
echo Groesse der VHD eingeben (in MByte)
set /p vhdsize=Groesse:
if %vhdsize% lss 20000 echo. && echo Die Mindestgroesse beträgt 20.000! && echo. && goto :groesse
if %vhdtyp%==1 (set typ=expandable) else set typ=fixed
echo create vdisk file=%workdir%%vhdname%.vhd maximum=%vhdsize% type=%typ% > %workdir%diskpart1.txt
echo attach vdisk >> %workdir%diskpart1.txt
echo create partition primary >> %workdir%diskpart1.txt
echo active >> %workdir%diskpart1.txt
echo format fs=ntfs quick label="%vhdname%" >> %workdir%diskpart1.txt
echo assign letter=%vhdlw% >> %workdir%diskpart1.txt
echo exit >> %workdir%diskpart1.txt
diskpart /s %workdir%diskpart1.txt
if errorlevel 1 goto fehler2

set operation=*** Image in VHD kopieren ***
echo %operation%
echo.
dism /apply-image /imagefile=%wim% /index:%index% /applydir=%vhdlw%:
if errorlevel 1 goto fehler2

set operation=*** Eintrag im Bootloader ergaenzen ***
echo %operation%
echo.
bcdboot /d %vhdlw%:\windows /addlast /l de-de
if errorlevel 1 goto fehler2

set operation=*** Entfernen von "MountedDevices" aus der Registry ***
echo.
reg load HKLM\VHD %vhdlw%:\windows\system32\config\system >nul 2>nul
if errorlevel 1 goto fehler2
reg query HKLM\VHD\MountedDevices >nul 2>nul
if errorlevel 1 goto unload
echo *** Registry-Schluessel "MountedDevices" in VHD gefunden ***
reg delete HKLM\VHD\MountedDevices /f >nul 2>nul
if errorlevel 1 goto fehler2
echo *** Registry-Schluessel "MountedDevices" aus VHD entfernt ***
:unload
reg unload HKLM\VHD >nul 2>nul
if errorlevel 1 goto fehler2

:aufraeumen
set operation=*** Aufraeumen ***
echo %operation%
echo.
if %isiso%==1 powershell "dismount-diskimage '%iso%'"
powershell "dismount-diskimage" %workdir%%vhdname%.vhd
del %workdir%diskpart1.txt

echo *** fertig! ***
pause
goto :eof

rem Bedingung nicht erfuellt
:fehler1
set text=Folgende Bedingung wurde nicht erfuellt: 
goto Fehlerausgabe

rem Fehler bei der Durchfuehrung
:fehler2
set text=Operation fehlgeschlagen:
goto Fehlerausgabe

:fehlerausgabe
color 0C
echo.
echo %text%
echo.
echo %operation%
echo.
echo %hinweis%
echo.
pause
goto :eof

:hilfe
echo.
echo %~nx0 erzeugt aus Windows-Installationspaketem
echo bootfaehige VHD-Dateien und bindet diese in den Bootloader ein.
echo.
echo %~nx0 muss mit Administratorrechten gestartet werden!
echo.
echo %Hinweis%
echo.
pause
goto :eof
;
REM Erstellt 2016 von Axel Vahldiek/c't
REM mailto: axv@ct.de

Antworten