Posts für Suchanfrage hyper-v werden nach Relevanz sortiert angezeigt. Nach Datum sortieren Alle Posts anzeigen
Posts für Suchanfrage hyper-v werden nach Relevanz sortiert angezeigt. Nach Datum sortieren Alle Posts anzeigen

Samstag, 28. Oktober 2017

Hyper-V in in Arbeitsgruppen remote verwalten

Ich habe mal wieder etwas mit Virtualisierungsumgebungen gespielt. Hyper-V 2016 gibt es ja als freie Version ohne GUI. Damit man mit diesem Server arbeiten kann braucht man schon irgendwie den Hyper-V Manager auf einer Remotestation (Windows 10).
Nur leider so einfach geht das nicht. Die Microsoft Dokumentation beschreibt zwar viel, aber nicht alles. Ich habe hier eine Beschreibung gefunden die funktioniert, allerdings waren mir ein paar Dinge nicht ganz klar. Deswegen habe ich das Ganze nochmal aufgearbeitet.

Integrierte Firewall

Beide Maschinen sollten mit privaten Netzwerken verbunden sein. Im Netzwerk und Freigabecenter kann man das überprüfen. Ansonsten greifen die voreingestellten Firewall Regeln nicht.

Namensauflösung

Der Remote Computer muss vom Steuernden Computer per Hostnamen erreichbar sein! IP Adressen und DNS Namen sind zwar prinzipiell verwendbar, aber auch nur der Hostname muss aufgelöst werden. Notfalls muss die Maschine einfach in der Datei c:\windows\system32\drivers\etc\hosts eingetragen werden.

Einrichtung für Windows 10 Pro -> Hyper-V Server 2016

Man öffnet am Besten auf beiden Stationen eine Powershell als Administrator.

Auf dem Hyper-V Server 2016 muss Remote Management und der Credential Security Support Provider aktiviert werden.
Enable-PSRemoting
Enable-WSManCredSSP -Role server

Auf Windows 10 (bzw. steuernder Computer) muss der Hyper-V Manager und die Tools installiert werden und Remote Management  aktiviert werden.
Ersteres muss man leider per Hand in der GUI tun (Die Powershell macht es nur komplett):
  • Im Punkt Windows-Features aktivieren müssen die Hyper-V Verwaltungstools ausgewählt werden. 
Remote Management  kann man auch per PowerShell Befehl aktivieren.
Enable-PSRemoting

Ergänzung: Neues Notebook und der Eintrag fehlt in Windows-Features? Dann hat man nur Windows 10 Home gekauft? Auf vielen Seiten findet man, wie man Windows Home "aufrüsten" kann (Beispiel). Ich habe mal eine Powershell Variante gebaut, die man so per c&p in die Kommandozeile werfen kann und die die Anzahl der Dateien ausgibt. 
$arr=(gci $env:systemroot\servicing\Packages\*Hyper-V*.mum -name)
$i=$arr.Count
foreach ($datei in $arr) {
dism /online /norestart /add-package:$env:systemroot\servicing\Packages\$datei
$i--
Write-Output "noch $i Dateien zu installieren"
}
dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL

Ergänzung: für Windows 11

Der obige "Hack" läuft auch unter Windows 11. Leider wird ab Version 24H2 bei einigen Updates der Verwaltungsdienst für virtuelle Computer gestoppt und auf manuellen Start gesetzt. Abhilfe:

Set-Service vmms -StartupType Automatic -PassThru|Start-Service
Um in einer Workgroup eine andere Maschine zu Verwalten muss das Konto der Maschine und ein Admin Konto der zu steuernden Maschine eingetragen werden.
Dazu ein kurzes Script
$server = "<Hostname der zu steuernden Maschine>"
$user = "<lokaler user auf der zu steuerenden Maschine>"
Set-Item WSMan:\localhost\Client\TrustedHosts -Value $server -force
Enable-WSManCredSSP -Role client -DelegateComputer $server -force
cmdkey /add:$server /user:$user /pass
Nach interaktiver Eingabe des Passwortes ist die Konfiguration abgeschlossen.
Nun kann einfach nur der Computername im Hyper-V Manager eingetragen werden und die Verbindung wird hergestellt. Sollte ein Fehler auftreten in Richtung Host wird nicht gefunden oder WinRM Client kann nicht zugreifen, dann bitte die IP Adresse und den Hostnamen in die hosts Datei eingetragen. Warum das so ist weiß ich leider nicht.

Zusätzliche Informationen

Hyper-V Feature installieren

Bei der freien Version Hyper-V Server 2016 sind natürlich alle notwendigen Features installiert. Auf allen anderen Windows und Server Versionen kann man die Installation entweder über Programme und Features oder mit Powershell erfolgen.
Mit Get-<> kann man die möglichen Features ermitteln (3 Varianten):
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V*
Get-WindowsOptionalFeature -Online | ? featurename -match 'Microsoft-Hyper-V*'
Get-WindowsOptionalFeature -FeatureName "Microsoft-Hyper-V*" -online | Format-Table 
Mit Enable-<> oder Disable-<> kann man die Features installieren oder entfernen.
Enable-WindowsOptionalFeature -Online -FeatureName <>
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Tools-All
Leider funktioniert das nicht so wie es in der Doku steht. Ist noch kein Feature von Hyper-V installiert lässt sich keines der Einzelnen Sub-Features mit Powershell installieren. Der übergeordnete Schlüssel wird in der Registry nicht gefunden. Sobald ein Feature installiert ist, können weitere Features auch per PS installiert werden.

Zwischen den Versionen

Die Remote Administration von Hyper-V funktioniert nur einwandfrei untereinander bei gleichen Windows Versionen (Windows 10 und Server 2016). Von Windows 10 einen Hyper-V auf Server 2012 R2 funktioniert nicht. Ob man mit den separaten RSAT Versionen noch etwas erreichen kann habe ich nicht probiert.

Tools, Alternativen und Tipps

Mit cmdkey kann man Anmeldeinformation für Netzwerkobjekte speichern und bearbeiten. Oder man geht in die Systemsteuerung und dort dann:
Systemsteuerung / Benutzerkonten / Anmeldeinformationsverwaltung
Als Dateimanager kann man recht einfach den FreeCommander portabel nachrüsten.

Wird auf der steuernden Maschine selbst ein Hyper-V Host ausgeführt, erzeugt Enable-PSRemoting eine Fehlermeldung. Am Ende funktioniert es trotzdem. Allerdings lässt sich auf einer solchen Station offenbar wegen dem Virtuellen Switch die Netzwerkverbindung (private public) nicht mehr ändern. Die Maske öffnet sich einfach nicht. (Windows 10 pro 1703/Netzwerk und Interneteinstellungen/Status/Verbindungseigenschaften ändern)

Will man nested Hyper-V betreiben, muss man das pro VM aktivieren (Doku):
Set-VMProcessor -VMName <Name der VM> -ExposeVirtualizationExtensions $true

Montag, 27. August 2018

Hyper-V Server verwenden

Der Plan: Hyper-V Server 2016 (download) als Grundlage für einen kleinen Server verwenden und darauf u.a. einen bisherigen Windows Server 2012R als virtuelle Maschine zu betreiben. Nebenbei sollen dann eventuell noch andere kleinere System laufen.
  • Hardware Unabhängigkeit (es gibt einige Hardwaretreiber nicht als Serverversion, auch von namhaften Herstellern wie Intel) 
  • Kein Leistungsverlust
  • Headless Betrieb, komplett von Windows 10 remote administrierbar
Ich hatte dazu schon einmal einen Artikel, den will ich hiermit konkretisieren.

Installation und Einrichtung des Servers


  • Ganz klassisch mit USB Stick, Monitor und Tastatur. Standardeinstellungen, die System Partition auf der SSD soll später verkleinert werden. 
  • System english aber Spracheinstellung deutsch, Zeitzone Berlin. 
  • Beim ersten Boot vom USB Stick auf UEFI oder BIOS Modus achten!

Mit dem Programm sconfig (nach der Anmeldung im Vordergrund und jederzeit wieder mit sconfig aufrufbar) wird folgendes eingestellt:

2) Computer Name
4) Configure Remote Man. (4-3)Enabled + ...Response to Ping
7) Remote Desktop (7-e-2)     Enabled (all Clients) ...less secure

Für den Computer Namen will er neu starten, deswegen kann man den Punkt zuletzt machen und anschließen braucht man die lokale Anmeldung nicht  mehr. Es geht alles über RDP.

Die weiteren Einstellungen erfolgen in Powershell, dazu kann man einfach das cmd Fenster hinter dem sconfig Fenster in den Vordergrund holen und Start Powershell starten.

Remote Desktop

Funktioniert sofort nach der obigen Grundkonfiguration, aber eben nur wenn nicht die Option 1) more secure eingestellt wurde. Das liegt offenbar an einem, nach der Installation noch nicht vorhandenem Patch des CredSSP. Nach dem Windows Update des Systems funktioniert auch die Option 1).

Netzwerk und Firewall

Windows typisch befindet sich das Netzwerk zunächst in der Category Public. Damit sind aber viele Firewall Regeln schärfer und viele Zugriff nicht zugelassen. Das ist im internen Netzwerk nicht sinnvoll, also ändern auf private. Der erste Befehl liefert uns die Informationen zum Netzwerk:
Get-NetConnectionProfile


Name             : Network
InterfaceAlias   : Ethernet
InterfaceIndex   : 3
NetworkCategory  : Public
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic
Der folgende Befehl setzt den Anschluss auf Private:
Set-NetConnectionProfile -InterfaceIndex 3 -NetworkCategory Private
Den Erfolg kann man leicht mit dem vorhergehenden Befehl überprüfen.
Die IP Adresse sollte fest sein, der DHCP Server und wenn vorhanden der DNS Server sollten so konfiguriert werden, dass der die IP Adresse fest zugeordnet ist und der Computer Name als FQDN aufgelöst werden kann.

Remote Management

Dafür sind Powershell Remoting und der Credential Security Support Provider zu aktivieren.
Enable-PSRemoting
Enable-WSManCredSSP -Role server
Damit ist die Server Konfiguration abgeschlossen

Einrichtung am Client Windows 10

Das Netzwerk und die Firewall sind zunächst auch so einzurichten, dass die NetworkCategory  : Private ist (siehe oben).
Der Computer Name des Hyper-V Servers muss als FQDN auflösbar sein, bitte so prüfen.
nslookup name.domain
Funktioniert das nicht, kann/muss ein Eintrag in der Datei C:\Windows\System32\drivers\etc\hosts gemacht werden.

Hyper-V-Verwaltungstools

Man kann sich anzeigen lassen, welche Hyper-V Features schon installiert sind
Get-WindowsOptionalFeature -Online -FeatureName *hyper-v*  | where state -eq enabled| select DisplayName, FeatureName
Will man nur die Management Tools installieren, geht prinzipiell mit Powershell, ist jedoch noch nichts von Hyper-V installiert kommt leider ein Fehler. Es funktioniert nur im Dialog so wie gewünscht.
Windows Features aktivieren oder deaktivieren (nicht Apps & Features und nicht optionale Features)
Eine Krücke mit Powershell wäre: Alles installieren und die Hyper-V-Plattform wieder deinstallieren.
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell -all
disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V
Allerdings ist dafür wegen der Installation von Hyper-V-Plattform ein Neustart fällig.

Vertrauen in einer Workgroup 

Eigentlich ist die Empfehlung von Microsoft auf dem Client als Erstes ebenfalls den Befehl Enable-PSRemoting auszuführen. Allerdings aktiviert das primär auch die Remote Verwaltung des Clients.
Es geht auch etwas sparsamer:

$server = "name.domain"
$user = "administrator"
Start-Service -Name winrm
Set-Item WSMan:\localhost\Client\TrustedHosts -Value $server
Stop-Service -Name winrm
cmdkey /add:$server /user:$user /pass

Jetzt öffnet man den Hyper-V Manager und fügt unter dem Punkt "Verbindung mit Server herstellen" den Server mit dem Namen "name.domain" (also exakt so wie bisher verwendet) ohne Angabe eines Benutzers hinzu.

Danke, dass ich dafür diesen Artikel lesen durfte.

Remote Shutdown für den Server einrichten

Die Konfiguration wird auf dem Hyper-V Server in der Powershellkonsole durchgeführt.

Benutzer anlegen

Das Passwort wird abgefragt.
New-LocalUser "UserShutdown"

Will man verhindern, dass das Passwort altert:
Set-LocalUser -Name "UserShutdown" -PasswordNeverExpires 1

Benutzerrechte festlegen

Dazu muss zunächst ein PS Script Modul heruntergeladen und eingebunden werden.
$url = "https://gallery.technet.microsoft.com/scriptcenter/Grant-Revoke-Query-user-26e259b0/file/198800/1/UserRights.psm1"
$output = "UserRights.psm1"
# $start_time = Get-Date
Invoke-WebRequest -Uri $url -OutFile $output
# Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
Import-Module .\UserRights.psm1

User Rechte erteilen 
Grant-UserRight -Account "UserShutdown" -Right SeRemoteShutdownPrivilege

Firewall

Regeln für "File and Print" aktivieren, entweder mit dem netsh Tool, was mit dem dargestellten Syntax nur auf einem englischen System funktioniert.
netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes
Oder mit dem Powershell cmdlet und der "codierten" Variante, die sprachunabhängig funktioniert.
Enable-NetFirewallRule -Group "@FirewallAPI.dll,-28502"

Volume verkleinern

Ich würde gern noch das Volume C auf dem Hyper-V Server minimieren. 48 GB sollten dafür ausreichen, derzeit ist das Volume 127 GB groß. Die Aufgabe erledigt man einfach mit:
diskpart

Am Prompt von diskpart lässt man sich die Plattenkonfiguration zeigen, wählt die gewünschte Partition und verkleinert sie um den Betrag 80000 MB. (1024 MB = 1 GB)
list disk
sel disk 0
list part
sel part 4
shrink desired=80000
exit

Probleme

Scheinbar ziemlich aktuell taucht ein Problem auf, wenn die CredSSP der beiden Maschinen einen unterschiedlichen Patchlevel haben. Ich konnte mich zwar mit dem Hyper-V Manager zu meinem Hyper-V Server verbinden und kann den komplett administrieren, eine Verbindung zu den Virtuellen Gastmaschinen schlug aber wieder mit der Meldung "CredSSP ... Oracle ... Remediation ... linkid=866660" fehl.
Abhilfe schafft in dem Fall auf die Schnelle:
gpedit (Editor für Lokale Gruppenrichtlinien) -> Computerkonfiguration -> Administrative Vorlagen -> System -> Delegieren von Anmeldeinformationen
Dann diese Einstellung am Client
Letzendlich wird damit dieser Schlüssel in der Registry gesetzt:
REG_DWORD
AllowEncryptionOracle : 2
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP
Original existiert dieser Wert nicht und entspricht damit 0

Quelle1
Quelle2

Dies und das

Firewall aus und einschalten
NetSh Advfirewall set allprofiles state off
NetSh Advfirewall set allprofiles state on

Firewall Rules abfragen
Get-NetFirewallRule -name *

Sonntag, 16. Februar 2020

Windows Server 2012 Foundation - Hyper-V Treiber installieren

Microsoft hat irgendwie umfangreich verhindert, dass man Windows Server 2012 Foundation in Hyper-V virtualisieren kann. Blöd wenn man eine produktiven Server hat, mit dem man ein paar Untersuchungen anstellen will. Virtualisierung / Hyper-V ist dafür nun mal eine Super Sache.
Es gibt einen guten Artikel, der mir sehr weiter geholfen hat.
Da die Situation nach einer Virtualisierung erstmal dramatisch ist, habe ich eine Weg gesucht und gefunden, es zu vereinfachen.
Das Hauptproblem ist die fehlende Installation der Hyper-V Treiber.

Das notwendige Paket windows6.2-hypervintegrationservices-x64.cab kann man bei Microsoft herunterladen. Die ursprüngliche existierende vmguest.iso wird nicht mehr ausgeliefert.
Für den Rest habe ich ein paar Powershell Scripts erstellt.
Zunächst brauchen wir die entpackten Dateien in einem temporären Pfad.
# cab Datei entpacken und in allen inf Dateien eine Zeile ergaenzen
$cabFile="E:\support\amd64\Windows6.2-HyperVIntegrationServices-x64.cab"
# Zielpfad frisch machen
$DestDir = (split-path $cabFile -leaf) -replace '.cab'
if (Test-Path -Path $DestDir) {rm $DestDir}
md $DestDir
# cab datei auspacken
cmd.exe /c "C:\Windows\System32\expand.exe -F:* $cabFile $DestDir"
Damit die Treiber später installiert werden können, muss die inf Datei um die eine Zeile ($rString) ergänzt werden. Zusätzlich muss "neben" der inf Datei die Datei update.cat liegen.
# replace in den inf Dateien
$fString=[regex]::Escape('[Version]') # escapen wegen der Klammer []
$rString="$&`nCatalogFile=update.cat" # Der String der gefunden wurde + NL + Text
gci -Recurse $DestDir |where {$_.name -like "*.inf"}|% {(Get-Content $_.fullname) -replace $fString, $rString| Set-Content $_.fullname;copy-item "$DestDir\update.cat"  (split-path $_.fullname)}
Die mit Windows Server 2012 Foundation vorbereitete virtuelle Disk (VHD Datei) kann man per Doppelklick einfach einbinden. Die Treiber werden dann ins Offline Image integriert.
# Treiber in offline Image integrieren
$offDir="F:"
$driverDir="\\omv1\Shares\Software\vmguest"
Add-WindowsDriver -Path $offDir -Driver $driverDir -Recurse -ForceUnsigned
Sollte was schiefgegangen sein, kann man auch alles wieder entfernen, oder sich nur vergewissern das die Treiber vorhanden sind.
# Alle Treiber wieder entfernen 
$dArray=gci -Recurse $driverDir |where {$_.name -like "*.inf"}|% {$_.name}
Get-WindowsDriver -path $offDir|% {if ($dArray -match (split-path $_.OriginalFileName -leaf)){Remove-WindowsDriver -path $offDir -Driver $_.driver}}
Zum Abschluss die VHD Datei auswerfen und die virtuelle Maschine starten. Es sind keine weiteren Arbeiten erforderlich.

Für die Virtualisierung einer produktiven Server 2012 Foundation Maschine hat man damit folgenden simplen Weg:
  1. Image ziehen, entweder offline mit dem USB Stick von hier, oder online mit disk2vhd.
  2. Das Image auf eine neue VHD anwenden, oder die VHD Datei von disk2vhd verwenden.
  3. VHD Datei als Laufwerk mounten und die Hyper-V Treiber integrieren. 
  4. VHD Datei Auswerfen und in Hyper-V verwenden.
Damit funktioniert:
  • Gen 2 Virtuelle Maschine
  • EFI Boot
  • SCSI Disk, Netzkarte usw.

Was leider bleibt:
  • Die Hyper-V Dienste (vmic...) laufen nicht. 
 

Mittwoch, 5. Februar 2020

Windows Core Server verwalten

Eigentlich gibt es ein simples Dokument vom Hersteller, aber das hat so viele Lücken und Fehler, ich schreibe einfach mal auf wie es kurz und knapp geht.

Verwaltung eines Core Servers (Hyper-V 2019) ohne Domäne

Um ohne lokale Konsole arbeiten zu können braucht man RDP. Das aktiviert man schnell:
  • entweder im Dialog der blauen Box von %windir%\System32\sconfig.cmd (bzw. %windir%\System32\%language%\sconfig.vbs) 
    • Dialog: 7 e 1
  • oder über ein vorhandenes Script:
cscript %WinDir%\System32\Scregedit.wsf /ar 0
REM Dieser Befehl noch für alte RDP Clients
Cscript %WinDir%\System32\Scregedit.wsf /cs 0
Man sollte den Server noch umbenennen, entweder im Dialog (2) oder
netdom renamecomputer %computername% /force /NewName:ComputerName
Danach muss man den Server neu starten!

Ab hier geht es auch Remote

Das "Netzwerkprofile" steht per default auf public, das stellt man um auf private und ermöglicht die Reaktion auf Ping. Dazu eine Powershell im "schwarzen Fenster" starten:
start Powershell
Ping funktioniert mit dem Regelset -DisplayGroup "File and Printer Sharing" (Sprachabhängig: "Datei- und Druckerfreigabe") oder "codiert" in Group.
Set-NetConnectionProfile -InterfaceIndex (Get-NetConnectionProfile).InterfaceIndex -NetworkCategory Private
Enable-NetFirewallRule -Group "@FirewallAPI.dll,-28502"

Am Client

Eine "Remote Verwaltung" funktioniert nur mit etwas Vorbereitung.

  • Der Zielcomputer muss als TrustedHost eingetragen und 
  • das Konto vom Zielcomputer muss hinterlegt werden. 

Verwirrend: Für den Hyper-V Manager muss der TrustedHost mit FQDN hinterlegt werden! Man kann sich entscheiden oder beides hinterlegen.
$server = "ComputerName"
$user = "administrator"
$pwd = Read-Host "Enter Password"
$fqdn=[System.Net.Dns]::GetHostByName($server).Hostname
Start-Service -Name winrm
Set-Item WSMan:\localhost\Client\TrustedHosts -Concatenate -Value $server
Set-Item WSMan:\localhost\Client\TrustedHosts -Concatenate -Value $fqdn
Stop-Service -Name winrm
cmdkey /add:$server /user:$user /pass:$pwd
cmdkey /add:$fqdn /user:$user /pass:$pwd

Ist alles ordentlich eingerichtet kann man eine Powershell Remotesitzung aufbauen.
Enter-PSSession -ComputerName $server

Neben Powershell und dem Hyper-V Manager funktionieren auch andere "lokale" Snap-Ins in der mmc, mir ist aber noch nicht klar nach welchem Schema was funktioniert und was nicht.
Die Hyper-V Verwaltungstools kann man besser über die grafische Schnittstelle installieren, die Powershell Schnittstelle funktioniert nur Hyper-V komplett oder gar nicht.
Mann sollte dafür die RSat Tools verwenden, oder eben alles über RDP und Powershell machen.

Informationen

Es gibt ein Tool für die Kommandozeile, welches knapp und übersichtlich die System Informationen darstellt:
systeminfo.exe
Auf dem Windows Server ist PSRemoting von Haus aus aktiviert, auf anderen Ziel Systemen kann man sie mit Enable-PSRemoting aktivieren. Ob aktiviert oder nicht lässt sich leicht von jeder Maschine aus testen:
Test-WSMan -ComputerName ComputerName
Die schon existierenden Zielsysteme kann man abfragen
Start-Service -Name winrm
(Get-Item WSMan:\localhost\Client\TrustedHosts).value
Stop-Service -Name winrm
Die existierenden Konten kann man anzeigen lassen
cmdkey /list

Auf dem Server kann man sich Profil und die aktivierten Firewall Regeln anschauen:
Get-NetConnectionProfile
Get-NetFirewallRule -DisplayGroup "Windows Remote Management"|select Name,enabled
Get-NetFirewallRule -Group "@FirewallAPI.dll,-28502"|select name,enabled
Mit der Tastenkombination Ctrl+Alt+Ende öffnet sich ein Fenster von wo aus man z.B. den Taskmanager starten kann.

ToDo Ist da noch was?
Code Block
System Volume nach der Installation auf 60GB schrumpfen und den Rest als Volume V einrichten.
$disk=Get-Partition -DriveLetter C
Resize-Partition -DiskNumber $disk.DiskNumber -PartitionNumber $disk.PartitionNumber -Size 60GB
New-Partition -DiskNumber $disk.DiskNumber -UseMaximumSize -DriveLetter v|Format-Volume

Weiteres

Insgesamt zu diesem Thema gibt es auch schon ein paar Artikel hier im Blog
Link

Sonntag, 16. September 2018

Virtuelle Maschinen erzeugen und administrieren mit Powershell

Kennt Ihr das? Hilfe Texte stimmen nicht, Beschreibungen funktionieren nicht? Das Thema Powershell und VM ist auch damit ganz schlimm gebeutelt.

VM anlegen

Man kann eine leere VM anlegen, das ergibt ein relativ mageres Ergebnis:
1GB RAM, Generation 1, keine Disk.
New-VM –Name 'Test1'
Will man in etwa das Ergebnis, was der Hyper-V Manager Wizard nur mit der Eingabe "Name" erzeugt, muss man es so machen:
$vm = 'Test2'
New-VM –Name $vm –NewVHDPath "$vm.vhdx" -NewVHDSizeBytes 127GB
Bisher haben wir VMs der Generation 1 erzeugt.
Viel mehr als im nächsten Befehl, kann man bei New-VM gar nicht angeben.
$vm = 'Test3'
New-VM –Name $vm -Generation 2 –MemoryStartupBytes 4GB –NewVHDPath "$vm.vhdx" -NewVHDSizeBytes 32GB
Alles weitere muss man mit Set-VM* Befehlen machen.

Startmedien - DVD Laufwerk

Das wichtigste dabei (und nicht ganz einfach wie man denkt) wäre ja die Angabe von Start- bzw. Installationsmedien. Kaum noch existieren wirklich optische Laufwerke, das Handling am Hyper-V Server wäre extrem unpraktisch. Man kann ohne weiteres ISO oder VHD Images einbinden, aber nur wenn sie lokal auf dem Hyper-V Server liegen. Microsoft hat eine sehr eigenartige Sicherheit eingebaut, wenn es um den Zugriff auf ein Image geht, welches auf einem Server liegt.
Auch die hier beschriebenen Wege funktionieren bei mir nur in der manuellen Art für VMs der Generation 1!

Mein Resumé: Startmedien gehen nur lokal

Mag sein es funktioniert in AD Umgebungen, ich habe es in einer Workgroup versucht, und wirklich viel experimentiert, ich bekomme es nicht hin! Man kann auf dem Hyper-V Host ein Image mounten und sich einen Überblick von den Laufwerksbuchstaben ausgeben lassen.
Mount-DiskImage -ImagePath \\omv1\shares\ISO\de_windows_7_All_with_sp1_x64_.iso
Get-Volume|? DriveType -eq CD-ROM

Für VMs der Generation 1 kann man nun im Hyper-V Manager das physische Laufwerk auswählen und zuweisen. (Mit Set-VMDvdDrive kann man nur echte DVD Laufwerke zuweisen)

Bei VMs der Generation 2 kann man nur mit lokalen ISO Images arbeiten!
Mann muss zunächst ein DVD Laufwerk hinzufügen.
Add-VMDvdDrive -VMName $vm -Path D:\ISO\Name.iso
Mit Set-VMDvdDrive kann man lokale ISO Images zuweisen und ändern.

Konfiguration Netzwerk, Bootreihenfolge und Prozessor

Damit der Startvorgang nicht am PXE Boot "verhungert" sollte man noch die Boot Reihenfolge festlegen
$VMDVD=Get-VMDvdDrive -VMName $vm
Set-VMFirmware -VMName $vm -FirstBootDevice $VMDVD
Oder man legt die Reihenfolge neu fest, die neue vhdx Datei kann sowieso nicht booten, er sollte in dem Fall beim ersten Mal von der DVD starten
$VMHDD=Get-VMHardDiskDrive -VMName $vm
Set-VMFirmware -VMName $vm -BootOrder $VMHDD, $VMDVD
Der Start von linux Systemen erfordert (derzeit noch), dass Secure Boot ausgeschaltet wird.
Set-VMFirmware -VMName $vm -EnableSecureBoot Off
Will man den (einzigen) Netzwerk Adapter noch mit dem (einzigen) virtuellen, externen Switch verbinden, kann man das so machen
Connect-VMNetworkAdapter -VMName $vm -SwitchName (Get-VMSwitch|? Switchtype -eq External).Name
Während wir den mindest RAM bei der Einrichtung festgelegt haben, hat die VM bisher nur einen Prozessor. Man kann so alle verfügbaren Prozessoren zuweisen
Set-VMProcessor -VMName $vm -Count (Get-VMHost).LogicalProcessorCount
Will man Virtualisierung in der Virtualisierung testen, muss man dieses Feature separat aktivieren.
Set-VMProcessor -VMName $vm -ExposeVirtualizationExtensions $true

Zusammenfassung

Hier ein Template/Script für eine neue VM, Der VM Name kann als Parameter übergeben werden oder wird abgefragt (Mandatory=$true).
In der ersten und zweiten Zeile werden alle Parameter gesetzt. Ich habe deshalb auf übermäßig viele Variablen verzichtet.
<#
.SYNOPSIS 
    Das Script erstellt eine neue virtuelle Maschine
.DESCRIPTION 
    Das Script erstellt eine neue virtuelle Maschine
.EXAMPLE 
    CreateVM Name 
.NOTES 
    Generation 2, 32 GB HDD, 4 GB RAM, alle Prozessoren
#>
#region Params
param(
    [Parameter(Position=0, Mandatory=$true,HelpMessage="Name der VM",ValueFromPipeline=$false)]
    [System.String]
    $vm=""
)
#endregion 

New-VM –Name $vm -Generation 2 –MemoryStartupBytes 4GB –NewVHDPath "$vm.vhdx" -NewVHDSizeBytes 32GB
Add-VMDvdDrive -VMName $vm 
$VMDVD=Get-VMDvdDrive -VMName $vm
$VMHDD=Get-VMHardDiskDrive -VMName $vm
Set-VMFirmware -VMName $vm -BootOrder $VMHDD, $VMDVD
Connect-VMNetworkAdapter -VMName $vm -SwitchName (Get-VMSwitch|? Switchtype -eq External).Name
Set-VMProcessor -VMName $vm -Count (Get-VMHost).LogicalProcessorCount

Für die DVD habe ich mal noch einen "Würgaround" gefunden.
Dieser Mehrzeiler schaut nach, ob die ISO Datei im lokalen Pfad schon existiert und kopiert diese ansonsten dahin.
$DVD = "name.iso"
$Ziel = 'D:\ISO\'
$Quelle = '\\omv1\shares\iso\'
$Diff = Compare-Object -ReferenceObject (gci -Path $Ziel) -DifferenceObject (gci -Path $Quelle)
Copy-Item -Path (($Diff|? InputObject -like $DVD).InputObject).FullName -Destination $Ziel
# DVD einlegen
Set-VMDvdDrive -VMName $vm -Path $Ziel$DVD

Damit das lokale Verzeichnis nicht vermüllt, kann man ja von Zeit zu Zeit die ISOs entfernen, die nicht mehr eingebunden sind.
$Ziel = 'D:\ISO\'
$InUse = (Get-VMDvdDrive -VMName *|? Path -like $Ziel*).Path
$Exist = (gci -Path $Ziel).Fullname
$Diff = Compare-Object -ReferenceObject $Exist -DifferenceObject $InUse
Remove-Item ($Diff|? SideIndicator -eq '<=').InputObject -confirm

Aufräumen

Dieser Einzeiler löscht alle VMs und deren virtuelle HDDs, deren Name mit Test beginnt.
Jeder Löschvorgang verlangt nach Bestätigung! Bitte genau hinschauen, ich übernehme keine Verantwortung!
Ich hoffe, dass ich in einem Jahr noch weiß, wie dieser Einzeiler funktioniert.
% ist das Kürzel für ForEach, $_ Ist das aktuelle Element der Schleife
-process enthält den Ausführungsteil(, beide Befehlsteile werden in getrennten Schleifen abgearbeitet.)
-InputObject die Eingabe
% -process {Remove-Item (Get-VMHardDiskDrive -VMName $_.name).Path -Confirm ; Remove-VM -VMName $_.name} -inputobject (Get-VM -VMName Test*)

Informationen

Man kann sich relativ schnell einen Überblick über die Cmdlets verschaffen und detaillierte Hilfe abrufen. (Leider stimmt auch in den Hilfetexten nicht alles)
Get-Help Hyper-V
Get-Help Set-VM*

Montag, 30. November 2020

WSL - ein paar Notizen zur Verwendung

Es gibt eine Menge im Netz zum WSL, aber vieles ist nicht klar mit Versionshinweisen beschrieben. Ich habe etwas mit WSL herum gespielt und hier meine Notizen dazu.

Versionen

Windows Server 2019: unterstützt nur V1, Tools: wsl.exe, wslconfig.exe, keine Store - nur manuelle Installation der (älteren) Distributionen.

Windows 10: unterstützt V1 und V2, Tools: wsl.exe mit erweitertem Umfang

Version 1: keine virtuelle Netzwerkkarte, verwendet direkt das Hostnetzwerk

Version 2: eine virtuelle Netzwerkkarte (bei jedem Neustart neue IP Adresse, Bereich 172.x.x.x) für alle Distributionen, besserer Kernel

Hier der offizielle Vergleich von MS.

Zugriff mit der virtuellen Maschine

wsl.exe öffnet quasi das "Terminal" ssh braucht man für die "Bedienung" nicht. 

Im Zusammenhang mit dem Thema "Kommandozeile" lohnt sich ein Blick auf Windows Terminal, dies ist seit kurzem über Windows Store installierbar.

Alle Datenträger vom Host sind direkt erreichbar (/mnt/c/...)

Die Ports aus der virtuellen Maschine werden an den Host durchgereicht, man kann über localhost:port oder 127.0.0.1:port zugreifen. Will man aus dem Netzwerk über den Host auf Ports in der virtuellen Maschine zugreifen, ist das Vorgehen bei V1 und V2 unterschiedlich. Die virtuelle IP ist aus dem Netzwerk nicht direkt erreichbar (NAT). 

Die Ports kann man mit ss -lntu innerhalb WSL V2 anzeigen, netstat und lsof sind nicht installiert (und funktionieren wohl nicht?). In WSL V1 habe ich keine Port Ausgabe hinbekommen, die Meldung klingt so, als ob im Kernel V1 etwas nicht implementiert ist.

Interessant: 

  • Aus dem ubuntu Subsystem heraus kann man direkt Windows Programme starten.
  • Mit einer kleinen Vorbereitung geht das auch umgekehrt, siehe diese Beschreibung.
  • In Windows kann man mit bash -c "Kommando" auch direkt Linux Befehle ausführen.

Die Distributionen (Ubuntu, debian) in WSL haben offenbar generell kein init System (wie systemd) aber eventuell kann man darauf auch verzichten. Mann kann den WSL und Prozesse darin direkt über die Windows Aufgabenplanung (Taskscheduler) starten.

Eine Kommando in Windows mit wsl.exe an WSL übergeben liefert die Ausgabe an Windows zurück. Die Ermittlung der IP Adresse gibt uns dafür ein paar Beispiele.  

Die einfachste Variante, funktioniert in CMD und Powershell - hat allerdings ein Leerzeichen am Ende. Dies kann man in PS einfach abschneiden (Befehl liefert String).trim()
wsl hostname -I

Ich habe die anderen Varianten mal zur Dokumentation und als Beispiel stehen lassen:

cmd Variante (fragt die wsl Umgebung ab, funktioniert aber nicht in powershell. Anmerkung: ^ ist ein Escape Zeichen der batch Umgebung)

WSL -d debian -- ip addr show eth0 ^| grep -oP '(?^<=inet\s)\d+(\.\d+){3}'

Powershell Variante Anmerkung: ` ist das Escape Zeichen in Powershell. Der Code braucht eine zweite Zeile!

(wsl -- ip addr show eth0 `| grep 'inet ') -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
$matches[0]


Installation und Konfiguration

Das Root Dateisystem jeder Linux Distribution wird in einer dynamischen 256GB VHDX Datei installiert. Den Speicherort kann man sich in Powershell so ausgeben lassen:

& cmd "/c dir %LOCALAPPDATA%\Packages\$((Get-AppxPackage -Name "*debian*").PackageFamilyName)\LocalState"

Statt über die interaktive Installation über den Store kann man die Pakete auch manuell herunterladen. Achtung: Das praktische Ergebnis (November 2020) ist anders, als die über den MS Store. Die Versionen sind viel älter!

Und offenbar teilweise sogar unvollständig:

  • In einer Variante fehlte wget und gnupg 
  • Die öffentlichen Zertifikaten waren alt oder nicht vorhanden! Ein apt install ca-certificates behebt das Problem.

Mit der kurzen url von dieser Seite geht das auch mit Powershell. 

Get-AppxPackage *Ubuntu*|Remove-AppxPackage
Get-AppxPackage *debian*|Remove-AppxPackage
Invoke-WebRequest -Uri https://aka.ms/wsl-debian-gnulinux -OutFile Debian.appx -UseBasicParsing
Add-AppxPackage .\Debian.appx

Man kann in WSL V2 auch komplette Distributionen exportieren (einpacken) und wieder importieren.

Der Windows Server hat keinen Store, die Installation funktioniert nur so wie hier beschrieben

Der Server 2019 Version kennt anstatt Enable-WindowsOptionalFeature.

Install-WindowsFeature -Name Microsoft-Windows-Subsystem-Linux

Die Hyper-V Umgebung

Ob Hyper-V schon aktiv ist kann man mit diesem Powershell Einzeiler testen:

(gcim Win32_ComputerSystem).HypervisorPresent

Ob die Hardware Hyper-V und damit auch WSL unterstützt kann man mit einem Powershell Einzeiler testen:

$list=@('Name', 'SecondLevelAddressTranslationExtensions', 'VirtualizationFirmwareEnabled', 'VMMonitorModeExtensions');Get-CimInstance -ClassName win32_processor -Property $list|Format-List $list

Ich habe diesen Test in einer virtuellen Maschine (Hyper-V) durchgeführt. Hier muss man auf dem Hyper-V Host die Virtualisierung an die Maschine "weiterreichen":

$vm=Get-Vm -Name <MaschineName>
Stop-Vm $vm
Set-VMProcessor $vm -ExposeVirtualizationExtensions $true
Start-Vm $vm


Die Ports

Achtung: Das Verhalten der Portweiterleitung ist unmittelbar nach der Einrichtung und nach einem Neustart unter Umständen komplett anders! 

Irgendwie gelingt es relativ leicht, dass man sich das Portmapping aus WSL heraus auf 127.0.0.1 zerschießt - ein netsh interface portproxy reset bewirkt dies zuverlässig. 

Hat man einmal einen Portproxy eingerichtet, funktioniert das Ganze nach einem Neustart nicht mehr. Man muss alles löschen und neu einrichten. Will man portproxy Einträge wieder löschen, kann man dies auch einzeln mit delete v4tov4 listenport=8083 tun! Dabei bleibt offenbar das (nicht sichtbare?) default Mapping erhalten. Löscht man den Eintrag für portproxy, stellt ein Neustart die ursprüngliche Funktion wieder her. 

Die Lösung für meine beobachteten Probleme liegt darin, den portproxy nicht auf localhost einzurichten (obwohl dies zunächst funktioniert) sondern auf die WSL eth0 Adresse. Hier ein Beispiele, die ich im Weiteren auch verwendet habe: 

  1. Artikel WSL Port forwarding 
  2. Artikel auf superuser

Mit tasklist | findstr wslhost kann man nachschauen auf welcher PID wsl arbeitet, mit netstat -aon | findstr <Suchstring> kann man den Prozess oder das Port darstellen. Die Prozesse innerhalb von wsl werden aber separat geführt. Mir ist es noch nicht die gesamte Prozesskette darzustellen.

Die wsl Kommanozeile

Es gibt einen Unterschied in der Verarbeitung zwischen dem Parameter -e und -- 

  • Bei -- kann man mehrere Befehle übergeben, getrennt mit Semikolon Befehl1;Befehl2,
  • das funktioniert offenbar bei -e nicht!
  • Gibt man den Linux Account mit:  -u username - funktioniert die Übergabe mehrere Befehle aber nicht mehr.

Empfehlung: Einfach eine Scriptdatei machen, das funktioniert viel einfacher als sich mit escapen und Variablenauflösung herumzuschlagen. Das Konstrukt wsl -e bash Script.sh funktioniert in gleicher Art in CMD, Powershell.


Dienstag, 4. September 2018

Partitionen und virtuelle Disk

In Hyper-V per default eine neue virtuelle Platte (VHDX) erstellt - und dann...

  • stellt man fest, dass Platten mit dynamischer Größe mit der Zeit viel langsamer sind als virtuelle Platten mit fester Größe. 
  • Das virtuelle Platten auf einer SSD viel schneller sind als auf einer herkömmlichen HDD
  • Das es jetzt ziemlich verschwenderisch ist, 127 GB auf der knappen SSD zu belegen, um eine virtuelle Platte zu hosten, die mit weniger als der Hälfte üppig ausgestattet wäre.

Dafür ein kurzes HowTo, wie man von dieser Ausgangssituation zum gewünschten Ziel kommt. Für einen Trockentest, kann man so eine virtuelle Disk zum Test anlegen. Die verwendeten Größen sind nur als Beispiel zu sehen.

Test Datei erstellen

Die typische System Platte sieht in etwa so aus.
PartitionNumber  DriveLetter Offset                                        Size Type
---------------  ----------- ------                                        ---- ----
1                            1048576                                     450 MB Recovery
2                            472907776                                    99 MB System
3                            576716800                                    16 MB Reserved
4                C           593494016                                126.45 GB Basic
Die folgende Zeilen erstellen eine vhdx Datei mit genau dieser Struktur. Das Windows Upgrade baut manchmal noch eine Partition hinten dran.
Dummerweise gibt es die x-VHD Powershell-Cmdlets nur, wenn die Hyper-V Rolle komplett installiert ist. Alternativ kann man dafür diskpart verwenden.
$VDisk = "D:\VHD\TestBase.vhdx"
New-VHD -Path $VDisk -SizeBytes 127GB
$Disk = Mount-VHD -Path $VDisk -Passthru|Get-Disk
$Disk
$Disk|Initialize-Disk -Passthru|Remove-Partition -PartitionNumber 1
$Disk|New-Partition -Size 450MB -GptType '{de94bba4-06d1-4d40-a16a-bfd50179d6ac}'
$Disk|New-Partition -Size 99MB -GptType '{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}'
$Disk|New-Partition -Size 16MB -GptType '{e3c9e316-0b5c-4db8-817d-f92df00215ae}'
$Disk|New-Partition -Size ((get-disk $Disk.Number).LargestFreeExtent-450MB) -AssignDriveLetter|Format-Volume
$Disk|New-Partition -UseMaximumSize -GptType '{de94bba4-06d1-4d40-a16a-bfd50179d6ac}'
$DriveLetter = ($Disk|Get-Partition|Get-Volume|? Driveletter -ne $null).DriveLetter
$path = ($DriveLetter+":\Test.tmp");$file = [io.file]::Create($path);$file.SetLength(10GB);$file.Close()
Dismount-VHD -Path $VDisk
Initialize-Disk erzeugt per default eine "reserved" Partition. Da ich die Original Struktur haben wollte, wird diese zunächst gelöscht und an dritter Stelle wieder erzeugt. Für diese Test vhdx ist das unerheblich, im produktiven Umfeld würde ich das nicht machen.
Die vorletzte Zeile enthält keine Pipe sondern mehrere Befehle um einfach einen große Datei in dem Volume zu erzeugen.

Minimierung der Ausgangsdatei

Die folgende Befehlsfolge reduziert die Partition in der Datei auf ein Minimum und reduziert die vhdx Datei auf ein Minimum. Zunächst mounten wir die vhdx Datei und erhalten als Ausgabe die Tabelle der Volumes.
Mount-VHD -Path $VDisk -Passthru| Get-Disk | Get-Partition | Get-Volume
Die folgende Aktion kann eine Partition auf minimale Größe bringen. Den richtigen Laufwerksbuchstaben einsetzen:
$DriveLetter = "E"
$size = Get-PartitionSupportedSize -DriveLetter $DriveLetter
Resize-Partition -DriveLetter $DriveLetter -Size $size.sizeMin
Manchmal baut Windows Update an das Ende der Systemplatte eine Wiederherstellungspartition, diese ist eigentlich unnütz und verhindert die Verkleinerung der gesamten Disk.
So kann man Partitionen entfernen. Vorsicht! Dieser Befehl löscht Daten, fragt aber vorher nach. Bitte genau lesen! 
Der zweite Befehl listet uns den Inhalt, im dritten Befehl muss die richtige PartitionNumber nn gesetzt werden.
$Disk = Get-Disk (Get-Partition -DriveLetter $DriveLetter).DiskNumber|Get-Partition
$Disk
$Disk |? PartitionNumber -eq nn|Remove-Partition
Hat man die letzte Partition verkleinert, kann man auch die gesamte Disk verkleinern:
Dismount-VHD -Path $VDisk
Resize-VHD -path $VDisk -ToMinimumSize
Zum Schluss kann man noch die Dateigröße der vhdx Datei verringern.
Optimize-VHD -path $VDisk -mode full
Jetzt befindet sich die vhdx in minimaler Größe und kann z.B. schneller kopiert werden.

In Form bringen

Anschließend soll die Datei wieder in eine produktive Form gebracht werden. Zunächst die komplette Disk auf die gewünschte Größe bringen.
Resize-VHD -path $VDisk -SizeBytes 500MB
Danach Mounten und die Struktur anschauen, das letzte Volume kann vergrößert werden.
In der zweiten Zeile den richtigen Laufwerksbuchstaben einsetzen!
Mount-VHD -Path $VDisk -Passthru| Get-Disk | Get-Partition | Get-Volume
$DriveLetter = "E"
$size = Get-PartitionSupportedSize -DriveLetter $DriveLetter
Resize-Partition -DriveLetter $DriveLetter -Size $size.sizeMax
Jetzt noch die virtuelle Disk vom dynamischen in ein festes Format wandeln. Dabei wird eine neue Datei erzeugt.
Dismount-VHD -Path $VDisk
Convert-VHD -path $VDisk –DestinationPath V:\NeuerName.vhdx –VHDType Fixed

Nützlich

Zwischen den einzelnen Schritten, kann immer mal der momentane Zustand der vhdx Datei und der Partition überprüft werden.
Get-VHD $VDisk
Get-PartitionSupportedSize -DriveLetter $DriveLetter
So ermittelt man die Werte für Disk und Partition.
Get-Disk
$dn=8
Get-Partition -DiskNumber $dn
$pn=2
$size = (Get-PartitionSupportedSize -DiskNumber $dn -PartitionNumber $pn)
# Partition auf Maxmimale Größe bringen
Resize-Partition -DiskNumber $dn -PartitionNumber $pn -Size $size.SizeMax
Die x-VHD Powershell Cmdlets lassen sich etwas umständlicher durch diskpart Befehle ersetzen
create vdisk file="c:\ttt\testBase.vhdx" maximum=1024
sel vdisk file="c:\ttt\testBase.vhdx"
attach vdisk
detach vdisk
expand vdisk maximum=20000
Anbinden und auswerfen der vhdx Datei geht auch mit dem Windows Explorer.
Die Konvertierung kann man auch mit dem Hyper-V Manager durch Import der vhdx Datei bewerkstelligen.

Will man mehr als die Standardausgabe von einem Cmdlet sehen, hilft das Format-List Cmdlet. Es gibt alle Elemente in einzelnen Zeilen aus.
Get-Disk |Format-List -Property *
Dadurch erhält man z.B. die Information über Elemente nach denen man auch Filtern kann.
Get-Disk |Where-Object {$_.Bustype -Eq "USB"}|

Ist die Zielfestplatte beim Konvertieren in den Type Fixed zu klein, ist die Fehlermeldung ziemlich unspezifisch:
Convert-VHD : Fehler beim Konvertieren des virtuellen Datenträgers.
Fehler beim Konvertieren von "d:\vhd\hyper-v-2016.vhdx".
In Zeile:1 Zeichen:1
+ Convert-VHD -path $VDisk –DestinationPath V:\Hyper-V2016-C.vhdx –VHDT ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Convert-VHD], VirtualizationException
    + FullyQualifiedErrorId : OperationFailed,Microsoft.Vhd.PowerShell.Cmdlets.ConvertVhd

Dienstag, 2. April 2024

USB Geräte in Windows WSL nutzen - oder Virtualisierung tief verschachtelt

 Da hab ich ein "neues" Projekt gefunden (gibt es offenbar schon 2 Jahre) womit es nun möglich ist USB Geräte in WSL 2 zu verwenden. Ich probiere solche Dinge gerne in einer virtuellen Maschine - damit geht die Odyssee der Stolpersteine los ...

Manchmal entdeckt man dabei Dinge die man schon immer wissen wollte, die habe ich jetzt einfach mit aufgeschrieben. Das Ergebnis diese Artikels ist ein WSL/Linux auf einem Windows/Hyper-V welches auf Linux/KVM auf einer physischen CPU läuft! In dem WSL könnte man noch Docker installieren!

Montag, 12. April 2021

Windows To Go

- auch zum mitnehmen 😂 -

Es gab mal eine spezielle Live Version für Windows mit gleicher Bezeichnung, diese Variation wurde aber wieder eingestellt.

mobiles Windows - auf einem Stick

Als Werkzeugkasten - es ist relativ unkompliziert und einfach zu erstellen: Wer sich nicht weiter mit Internas beschäftigen will, nimmt das Tool Rufus, das macht einen guten Job! Es kopiert quasi das Windows ISO Image auf einen USB Stick. Entweder hat man das schon oder es wird vom Tool herunterladen. Die Bedienung ist aus meiner Sicht eindeutig.

Dienstag, 25. Mai 2021

Linux Image in Hyper-V starten

Bekommt man ein x86-64 Linux Image direkt in Windows Hyper-V aktiviert?  (OpenWrt gibt es als .img.gz zum Download)

Ja das geht: mit einem Tool, und einem Powershell Script. (Quelle)

  1. openwrt.xx.xx.x-x86-64-combined-ext4.img.gz herunterladen.
  2. gzip auspacken
  3. Mit qemu-img das img nach vhdx konvertieren.
  4. Virtuelle Maschine definieren und die vorhandene vhdx Datei einbinden.

Montag, 15. Oktober 2018

Powershell und Windows Update

Der Hyper-V Server hat ein Management Interface welches aus mehreren Scripts besteht:
Auszug

  • sconfig.cmd
    • sconfig.vbs
    • WUA_SearchDownloadInstall.vbs
    • ...
Die VBS-Scripts liegen %systemroot%\system32\en-us\ (bzw. anderen Sprachen).
Gesteuert wird das Windows Update über die Windows Update API. Die Doku ist schwerer Stoff, ich habe mir von verschiedenen Seiten und aus dem oben erwähnten Script ein paar Dinge zusammen gelesen und will es hier kurz notieren.
Meine Scripts in dem Artikel sind alle nicht perfekt, sondern eher als Lösungsansatz gedacht. Damit kann man z.B. beim Hyper-V Server etwas mehr tun als nur mit der sconfig "Oberfläche".

Die Schritte etwas im Detail

Zuerst muss man festlegen welche Updates man suchen will (ein paar Details):
$Criteria = "IsInstalled=0 and Type='Software'"
$Criteria = "IsInstalled=0 and Type='Driver'"
Dann werden verschiedene Com Objecte eingerichtet und z.B. die Titel der verfügbaren Updates angezeigt.
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$SearchResult = $Searcher.Search($Criteria).Updates
# Titel anzeigen
$SearchResult|select Title
Powershell bietet an der Stelle etwas mehr Komfort zur Suche und Auswahl als die eigentliche API. Deshalb füge ich hier bewusst den Neubau der Update Collection ein. Eigentlich ist diese jetzt schon in $SearchResult enthalten.
$updatesToDownload = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResult|%{ if($_.Title -match "KB2267602") {$updatesToDownload.Add($_)}}
$updatesToDownload|select Title
Danach werden die gewünschten Updates heruntergeladen.
$Session = New-Object -ComObject Microsoft.Update.Session
$Downloader = $Session.CreateUpdateDownloader()
$Downloader.Updates = $updatesToDownload
$Downloader.Download()
Um es ganz korrekt zu machen, kann man noch eine Collection der wirklich heruntergeladenen Updates erstellen ...
$updatesToInstall = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResult|%{ if($_.isDownloaded) {$updatesToInstall.Add($_)}}
... um dann die Updates zu installieren.
$Installer = New-Object -ComObject Microsoft.Update.Installer
$Installer.Updates = $updatesToInstall
$Result = $Installer.Install()
Als Abschluss wird bei Bedarf ein Neustart ausgeführt.
If ($Result.rebootRequired) { shutdown.exe /t 0 /r }

Komplett in einem Script

Das Ganze als ein Script mit zwei Parametern am Anfang:
Den Type entweder weglassen (Alle suchen) oder auf Software oder Driver setzen.
Bei $compare kann man entweder nur einen "*" für "Alles" setzen oder wie im Beispiel den Begriff mit Wildcards für ein bestimmtes Update.
# Parameter
$Criteria = "IsInstalled=0 and Type='Software'"
$compare= "*" # "*KB2267602*"
# Suche notwendige Updates 
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$SearchResult = $Searcher.Search($Criteria).Updates
# Zusammenstellung Download Collection
$updatesToDownload = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResult|%{ if( $_.Title -like $compare ) {$updatesToDownload.Add($_)}}
#$updatesToDownload|select Title
#$updatesToDownload.Count
# Download Updates 
$Session = New-Object -ComObject Microsoft.Update.Session
$Downloader = $Session.CreateUpdateDownloader()
$Downloader.Updates = $updatesToDownload
if ($updatesToDownload.Count -gt 0) {$Downloader.Download()}
# Zusammenstellung Install Collection
$updatesToInstall = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResult|%{ if($_.isDownloaded) {$updatesToInstall.Add($_)}}
# Install Updates 
$Installer = New-Object -ComObject Microsoft.Update.Installer
$Installer.Updates = $updatesToInstall
$Result = $Installer.Install()
# Neustart wenn gefordert
If ($Result.rebootRequired) { shutdown.exe /t 0 /r }

Was lief bisher?

Man kann sich auch die gesamte Historie anzeigen lassen:
Wann wurde welches Update installiert? Die Zeiten werden in UTC angezeigt!
# Historie abfragen
$session = new-object -comobject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
$history = $searcher.QueryHistory(0, $searcher.GetTotalHistoryCount())
$history |select Date,Title |more
Leider liefert das Ergebnis am Ende immer viele Leerzeilen.

Mehr Komfort

Die Powershell Gallery halt ein umfangreiches Scriptmodul "PSWindowsUpdate" bereit mit dem der Windows Update Service wohl sehr komfortabel behandelt werden kann. Ich habe mir das zunächst nur kurz angeschaut. Um das Script aus der PSGallery zuinstallieren muss man ein paar Vorbereitungen treffen, das ist hier ganz gut beschrieben.

Noch ein Special

In $SearchResult stehen auf den zweiten Blick noch mehr Informationen!
So erzeugt man eine Liste mit Detailinformationen, z.B. mit der UpdateID oder dem Download Link.
#$Criteria = "IsInstalled=0 and Type='Software'"
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$SearchResult = $Searcher.Search($Criteria).Updates

foreach ($update in $SearchResult) {
  $title = $update.Title
  $guid = $update.Identity.UpdateId
  $title
  $guid
  $bundles = $update.BundledUpdates
     foreach($bundledUpdate in $bundles) {
        foreach($content in $bundledUpdate.DownloadContents) {
           if (!$content.IsDeltaCompressedContent) {
              $url = $content.DownloadUrl
              $url
            }
        }
    }
}

Mit der so ermittelten UpdateID wäre es auch möglich die Suche nach speziellen Paketen auszuführen:
$Criteria = "IsInstalled=0 and UpdateID='a3fafd03-b687-49e6-9df9-3963057ce376'"

Es gibt mit CIM und "PowerShell remoting session" auch einen Ansatz die VMs zentral zu patchen.
Ich habe hier ein Infos z.B. zu den resultcodes gefunden.

Montag, 10. Oktober 2022

WSL und Docker Desktop - Neuigkeiten

Mit Windows 11 Build 22000 habe ich mal die Neuigkeiten bei der Installation von Windows-Subsystem für Linux und die Installation von Docker Desktop getestet. Die sind am Ende relativ umfangreich - gemessen an meinen früheren Versuchen.

Mittwoch, 30. Januar 2019

VHD - was geht, was nicht?

VHD erzeugen und verwenden

VHDs sind Container Dateien, die ein Festplattenimage enthalten. Ich setze sie der neben Virtualisierung gerne ein, um alte Datenpartitionen zu erhalten oder separate Festplatten zu simulieren. Um sie schnell mal zu erzeugen und auch für "normale" Benutzer bereitzustellen, gibt es verschiedenen Möglichkeiten.

In jedem aktuellen Windows System vorhanden:
Explorer: Man kann VHD Dateien mounten/dismounten - einfach per Doppelklick oder rechter Maustaste. Das funktioniert auch mit normalen Benutzerrechten.
Alle anderen Möglichkeiten brauchen Adminrechte.
diskpart/Datenträgerverwaltung: Mit beiden Tools kann man VHD Dateien erzeugen und mounten/dismounten.
Die Powershell kennt zwei Sets an Cmdlets.
(Dismount, Get, Mount)-DiskImage
Diese Cmdlets sind wahrscheinlich in jeder Windows Version vorhanden. Sie funktionieren mit VHD und ISO Dateien. Für die Verwendung von VHD Dateien braucht man Administrator Rechte.
*-VHD, *-VHDSet, *-VHDSnapshot
Ein neues, umfangreiches Set an Cmdlets welches erst mit der Hyper-V Rolle installiert wird. Mit denen kann man VHDs auch erstellen und umfangreich manipulieren. Doku.

Automatische Bereitstellung.

Zur Laufzeit kann man VHD Dateien leicht interaktiv einbinden und auswerfen, aber kann man VHD Dateien als HDD Ersatz auch beim Systemstart bereitstellen?
Das geht per Taskplaner und diskpart Script.

Praktisches Beispiel

Schritt für Schritt entsteht so eine dynamische VHD Datei mit 10 GB und einer Partition.
Achtung: Die Powershellversion funktioniert nur auf einem Hyper-V "aktiviertem" System:
$VDisk = "D:\VHD\TestPS.vhdx"
New-VHD -Path $VDisk -Dynamic -SizeBytes 10GB
$Disk = Mount-VHD -Path $VDisk -Passthru|Get-Disk
$Disk|Initialize-Disk 
$Disk|New-Partition -UseMaximumSize -AssignDriveLetter|Format-Volume -NewFileSystemLabel "Meine VHD"
Dismount-VHD -Path $VDisk
Schritt für Schritt in diskpart
create vdisk file=D:\VHD\TestDP.vhdx type=expandable maximum=10240
select vdisk file=D:\VHD\TestDP.vhdx 
attach vdisk
create partition primary
format FS=NTFS LABEL="MEINE VHD" QUICK
assign
detach vdisk
Alle diskpart Befehle kann man in eine Textdatei packen, und diese dann als Parameter übergeben.
diskpart /s Scriptdatei
Für die automatische Bereitstellung braucht man nun bloß noch ein paar Befehle. Für Powershell ist das Script ein Einzeiler
Mount-VHD -Path "D:\VHD\TestPS.vhdx"
# Oder so
Mount-DiskImage "D:\VHD\TestPS.vhdx"
Um es mit diskpart automatisch zu erledigen, braucht man wieder ein kurzes Script. Dieses startet man dann wie oben.
select vdisk file="D:\VHD\TestDP.vhdx"
attach vdisk
exit

Das Vorgehen bis hierher hat eventuell ein Problem: Die Zuweisung eines Laufwerkbuchstabens. Das passiert im Zweifelsfall einfach nicht. Wenn dem System die VHD nicht bekannt ist, wird sie eventuell ohne Laufwerksbuchstaben bereitgestellt. Bei dem Diskpart Script kann man das einbauen, der Mount-VHD Befehl kennt nur die Option -NoDriveLetter, bei Mount-DiskImage hat man gar keine Option.

Im Taskplaner (Aufgabenplanung) kann man eine Task für den Systemstart einrichten, damit steht die VHD nach dem Start für alle Benutzer zur Verfügung. So geht es:
Registerkarte Allgemein
Wichtig: Benutzer SYSTEM verwenden und den "Mit höchsten Privilegien" Haken setzen.
Registerkarte Trigger
"beim Start" auswählen.
Registerkarte Aktion
Hier in zwei getrennten Boxen den Programmnamen und die Argumente eintragen:
powershell
# entweder als Befehlsblock
-Command Mount-DiskImage "D:\VHD\TestPS.vhdx"
# alternativ als Scriptfile
-ExecutionPolicy Bypass -File "C:\Tools\Scripts\mountvhd.ps1"

diskpart
/s "C:\Tools\Scripts\mountvhd.txt"
Mit "Ausführen" sollte man die Aufgabe nach dem Erstellen direkt testen!

Um den Laufwerksbuchstaben der gemounteten VHD Datei zu ermitteln, muss man eine Kette von Cmdlets bemühen (Doku):
(Get-DiskImage -ImagePath $VDisk |Get-Disk|Get-Partition|Get-Volume).DriveLetter

Mittwoch, 5. September 2018

Storage Pool auf dem Hyper-V Server verwalten

Wie bekommt man einen gespiegeltes HDD System, welches unter Windows Server 2012 als Storage Pool eingerichtet war, wieder online?

Ein paar Befehle für die  Analyse des Storage mit Powershell 

So bekommt man ein Bild der vorhandenen Disks:
get-disk

Number Friendly Name Serial Number                    HealthStatus         OperationalStatus      Total Size Partition
                                                                                                             Style
------ ------------- -------------                    ------------         -----------------      ---------- ----------
1      Samsung SS... S1DBNSAF878015M                  Healthy              Online                  232.89 GB GPT
0      Samsung SS... S21PNSAG155972R                  Healthy              Online                  232.89 GB GPT
6      VD1           {05bf1a4e-44d2-11e5-80d3-7824... Healthy              Offline                   1.82 TB GPT
5      VD2           {dcdf1498-41bd-11e5-80cf-7824... Healthy              Offline                    930 GB GPT
7      TOSHIBA Ex...            92N5P3KXT             Healthy              Online                  931.51 GB MBR
Zwei Platten sind Offline, die Disks 2,3 und 4 "fehlen".

Die Abfrage der Virtuellen Disk ergibt folgendes Bild:
get-virtualdisk

FriendlyName ResiliencySettingName OperationalStatus HealthStatus IsManualAttach    Size
------------ --------------------- ----------------- ------------ --------------    ----
VD1          Mirror                OK                Healthy      False          1.82 TB
VD2          Simple                OK                Healthy      False           930 GB
Obwohl die eigentlichen Laufwerke im Storage Pool ausgeblendet werden, kann man sich die echten Laufwerke anzeigen lassen:
Get-physicaldisk

FriendlyName              SerialNumber    CanPool OperationalStatus HealthStatus Usage            Size
------------              ------------    ------- ----------------- ------------ -----            ----
Samsung SSD 840 EVO 250GB S1DBNSAF878015M True    OK                Healthy      Auto-Select 232.89 GB
WDC WD2003FYPS-27Y2B0     WD-WCAVY7115101 False   OK                Healthy      Auto-Select   1.82 TB
TOSHIBA External USB 3.0  92N5P3KXT       False   OK                Healthy      Auto-Select 931.51 GB
Samsung SSD 850 EVO 250GB S21PNSAG155972R False   OK                Healthy      Auto-Select 232.89 GB
ST31000333AS              9TE24JDS        False   OK                Healthy      Auto-Select  931.5 GB
WDC WD2003FYPS-27Y2B0     WD-WCAVY5334150 False   OK                Healthy      Auto-Select   1.82 TB

Get-PhysicalDisk kann aber mehr, mit Hilfe von Format-List habe ich mal eine Ausgabe der Zuordnung zu den Hardware Ports gebastelt
Get-PhysicalDisk| Select-Object -Property DeviceId,PhysicalLocation,BusType,MediaType,FriendlyName,SerialNumber| Sort-Object -Property DeviceId |Format-Table

DeviceId PhysicalLocation                BusType MediaType   FriendlyName              SerialNumber
-------- ----------------                ------- ---------   ------------              ------------
0        Integrated : Adapter 0 : Port 1 SATA    SSD         Samsung SSD 850 EVO 250GB S21PNSAG155972R
1        Integrated : Adapter 1 : Port 0 SATA    SSD         Samsung SSD 840 EVO 250GB S1DBNSAF878015M
2        Integrated : Adapter 1 : Port 1 SATA    HDD         ST31000333AS              9TE24JDS
3        Integrated : Adapter 1 : Port 4 SATA    HDD         WDC WD2003FYPS-27Y2B0     WD-WCAVY5334150
4        Integrated : Adapter 1 : Port 5 SATA    HDD         WDC WD2003FYPS-27Y2B0     WD-WCAVY7115101
6        Integrated : Adapter 0 : Port 0 USB     Unspecified TOSHIBA External USB 3.0  92N5P3KXT

Den Zusammenhang zwischen Storage Pool, VirtualDisk und PhysicalDisk kann man auch anzeigen lassen. Dazu braucht man zunächst ein Object auf den Storage Pool
$stpool = (Get-StoragePool -FriendlyName "SP1")
Get-VirtualDisk -StoragePool $stpool

FriendlyName ResiliencySettingName OperationalStatus HealthStatus IsManualAttach    Size
------------ --------------------- ----------------- ------------ --------------    ----
VD1          Mirror                Degraded          Warning      False          1.82 TB

Get-PhysicalDisk -StoragePool $stpool

FriendlyName          SerialNumber    CanPool OperationalStatus HealthStatus Usage          Size
------------          ------------    ------- ----------------- ------------ -----          ----
WDC WD2003FYPS-27Y2B0 WD-WCAVY7115101 False   OK                Healthy      Retired     1.82 TB
WDC WD2003FYPS-27Y2B0 WD-WCAVY5334150 False   OK                Healthy      Auto-Select 1.82 TB
Für die Information auf welcher Disk das Volume des Systemlaufwerkes ist, habe ich diese Befehlskette gefunden.
Get-Disk (Get-Partition | ? isboot).DiskNumber

Storage Pool Disk wieder aktivieren

Ich möchte das VD1 wieder online ist, dies wird nämlich nicht automatisch getan, wenn der Storagepool an einen andere Maschine gehangen wird. Da VD1 eine (virtuelle) Disk ist, geht das mit dem set-disk Cmdlet
Set-Disk -Number 6 -IsOffline $False
Es gab bei mir die Situation, dass eine Disk nach dem Import von einer Physical Disk in eine vhdx Datei mit dem Hyper-V Manager sowohl offline als auch readonly war. Auch readonly lässt sich mit Set-Disk beheben.
Set-Disk -Number 5 -IsReadonly $False

Storage Pool Disk Fehler behandeln

Es gibt hier eine detaillierte Beschreibung wie man Fehler im Storage Pool behandeln kann. Hinbekommen habe ich das so aber noch nicht.
Versucht man in einem StoragePool, der 2 HDD enthält und darin eine Mirror VirtualDisk - eine HDD geordnet zu entfernen und diese danach durch eine Andere zu ersetzen, funktioniert das praktisch nicht. Obwohl man eine Platte als Retired markiert, lässt sie sich nicht entfernen. Man muss erst einen neue HDD zum StoragePool hinzufügen. Aber selbst das ist mir nicht richtig gelungen.
Dies habe ich versucht:
Set-PhysicalDisk -FriendlyName "WDC WD2003FYPS-27Y2B0" -SerialNumber WD-WCAVY7115101 -Usage Retired
Repair-VirtualDisk -FriendlyName "VD1"
# Zwei Varianten um das Objekt der richtigen PhysicalDisk zu bekommen
$PDToRemove = Get-PhysicalDisk | Where-Object { $_.Usage -eq 'Retired'}
$PDToRemove = Get-PhysicalDisk -FriendlyName "WDC WD2003FYPS-27Y2B0" -SerialNumber WD-WCAVY7115101
Remove-PhysicalDisk -PhysicalDisks $PDToRemove -StoragePoolFriendlyName "SP1"
Aber diese Aktion endet mit einem Fehler:
StorageWMI 48011,Remove-PhysicalDisk

Storage Pool entfernen

Erkenntnis: Storage Pool sieht gut aus, ist mir aber so undurchsichtig! Nach der kompletten Sicherung der Daten, habe ich einfach alles entfernt:
Set-Disk -Number 6 -IsOffline $true
Remove-VirtualDisk -FriendlyName "VD1"
Remove-StoragePool -FriendlyName "SP1"
Jetzt tauchen die Platten 3 + 4 wieder normal in der Ansicht auf (get-disk) und können normal verwendet werden. Um sie völlig leer zu machen verwendet man Clear-Disk
Clear-Disk -Number 3
Clear-Disk -Number 4
Get-Disk |Where-Object PartitionStyle –Eq "RAW" |Initialize-Disk 

Um eine neue Partition anzulegen, einen bestimmten Laufwerksbuchstaben zu vergeben und es gleich zu formatieren, kann man so vorgehen.
New-Partition -DiskNumber 3 -UseMaximumSize -DriveLetter S |Format-Volume

Dienstag, 2. August 2022

UEFI Start manipulieren

Mal eben von einem externen Laufwerk ein anderes System starten: USB Laufwerk einstecken, Restart ausführen - Mist - wie war die Taste für das Bootmenü? Ach ja: F7 - Mist zu langsam gedrückt - neuer Versuch.

Dieses Vorgehen ist doch echt nervig!? 

Es geht eventuell auch anders: Mit BCDEdit (Windows) und efibootmgr (Linux) hat man Tools um per Kommandozeile den (nächsten) Start des Rechners zu beeinflussen. Also neuer Versuch: USB Laufwerk einstecken, Script für den Restart ausführen und entspannt zuschauen wie präzise das gewünschte System ausgeführt wird. So könnte es gehen - mal schauen wie weit ich komme. Das wird erstmal ein Arbeitsdokument.

Samstag, 23. Dezember 2023

libvirt - Hardware direkt zum Gast verbinden

Ein großer Vorteil der Linux QEMU/KVM gegenüber Windows Hyper-V ist meiner Meinung nach die Möglichkeit physische Hardware mit dem Gast System zu verbinden. Ich will kurz die Möglichkeiten aufzeigen einen USB Speicherstick einzubinden.

Sonntag, 18. November 2018

Windows Image

Die Windows Installation (so wie ist) auf eine neue Festplatte ziehen - geht auch mit Boardmitteln.

Achtung! Diese Anleitung enthält Befehle, die bei falscher Anwendung Daten löschen können! Bitte unbedingt zwischen Copy & Paste auch den Kopf verwenden! Dism /capture-image nur innerhalb Windows PE anwenden!

Was wird benötigt?
  • Ein Startmedium mit Windows PE: USB Stick oder CD (ISO)
  • Einen genügend großen Zwischenspeicher: USB Festplatte oder Netzlaufwerk,
  • ein paar Tools von Windows und
  • gewusst wie.
Am Ende dieses Artikels stehen ein paar Links mit wichtigen Quellen!

Ablauf

  1. Den Computer mit Windows PE starten (Man kann Quell und Ziel Laufwerk anschließen)
  2. Die Quell Laufwerk mit dism in ein image "aufzeichnen".
  3. Optional: Umbauen und wieder mit WinPE starten.
  4. Das Ziel Laufwerk partitionieren.
  5. Das Image auf das Ziel Laufwerk "anwenden".
  6. Startsystem wieder herstellen
Es ist also ziemlich simpel, die Befehle und Schritte sind im Prinzip im zweiten Link beschrieben. Ich will dies hier aber mit etwas Erfahrungen und Tipps ausbauen.

Windows PE

Es gibt Windows PE in 32 und 64 bit Version. Obwohl WinPE mit einem einfachen CMD Fenster startet, kann man von dort die meisten (portablen) Programme und Tools einfach starten. Aber - die 64 bit Version hat kein 32 bit Subsystem, man kann also immer nur Programme der gleichen Architektur starten!
Ich habe darauf verzichtet WinPE aufwendig anzupassen. Ich habe einfach ein paar Scripte erstellt, einen Teil habe ich auf dem USB Stick bereitgestellt und Andere einfach auf einem zentralen Netzwerklaufwerk abgelegt.
Es genügt ein kleiner USB2 Stick, WinPE ist nicht groß (ca. 300 MB ohne Anpassung, ca 450 MB mit Powershell) und die Ladezeiten sind nicht sehr lang.
An meinem System lagen die Zeiten zwischen 25 und 30 sec, der Unterschied USB2 und USB3 sowie Powershell ging quasi in der "Nachdenkzeit" des Reset und BIOS unter.

Damit man mit der Tastatur klar kommt braucht man ein Startscript.
wpeutil SetKeyboardLayout 0407:00000407
start cmd
Die Tastatur ist sonst mit englischem Layout und die Änderung mit SetKeyboardLayout wirkt erst im neuen Fenster.
Um eine Netzwerkverbindung herzustellen ist dies sinnvoll. Dieses Zeile enthält auch einen Trick:
Hat man ein Linux SMB Share, welches mit anonymen Zugriff konfiguriert ist, kann sich WinPE nicht ohne Konto verbinden (anonymer Zugriff ist auch in Windows seit Version 10 1709 abgeschaltet).
Bei WinPE hilft es einfach einen Benutzer anzugeben den es nicht gibt: net use ist zufrieden und Linux ignoriert es.
net use * \\server1\Shares /user:willi password 
net use * \\server1\Sicherung  
Natürlich kann man die paar Zeilen auch in ein CMD Script packen und auf dem USB Stick bereitstellen.
Die beiden net use Befehle erzeugen ein Laufwerk z: und y: - das Laufwerk x: ist das Systemlaufwerk von WinPE.

Image aufzeichnen

Zunächst  muss man ermitteln, welche Laufwerksbuchstaben WinPE für die eingehängten Festplatten vergeben hat. Dazu gibt es viele Möglichkeiten, ziemlich eindeutig und gezielt funktioniert es mit diskpart. Am Prompt: DISKPART> gibt man folgende Reihenfolge ein:
list disk
sel disk 0
detail disk
Der erste Befehl zeigt alle eingebauten Festplatten.
Der zweite Befehl selektiert die Quellfestplatte, die Ziffer ist also entsprechend anzupassen.
Der dritte Befehl zeigt alle Details der gewählten Disk inklusive der dort enthaltenen Volumes und Laufwerks Buchstaben.
Tipp: Auch gleich die Nummer für das Zielaufwerk merken, die wird im nächsten Abschnitt benötigt.
Für Fortgeschrittene: Man kann die Befehle für Diskpart auch direkt in der Kommandozeile "pipen".
echo list volume|diskpart
(echo sel disk 0 & echo list part)|diskpart
(echo sel disk 0 & echo sel part 2 & echo detail part)|diskpart
Ein Beispiel zum Aufzeichnen des Images von Laufwerk C
dism /capture-image /imagefile:y:\wim\backup.wim /capturedir:c:\ /name:C-WinOS
Man kann recht einfach ein Beispielscript im Laufwerk z: vorbereiten und mit notepad (läuft unter WinPE) anpassen und dann ausführen. So spart man sich viel Tipparbeit. Die meiste Zeit wird die Bandbreite zum Ziellaufwerk sehr gut genutzt, die Geschwindigkeit für die Aufzeichnung hängt also vom Umfang, Geschwindigkeit Quelle und Netzlaufwerk (oder USB Laufwerk) ab.

Ziel Laufwerk partitionieren

Hinweis: Hat man einen neuen PC mit gleichem Windows OS gekauft, kann man jetzt auch einfach die Windows Partition formatieren, diesen Schritt überspringen und das Image anwenden!

Ein leeres Ziellaufwerk muss man neu partitionieren und kann dabei auch völlig neu strukturiert werden! 
Beispiel: War das Quellsystem eine MBR Partition kann die Ziel Platte ein GPT System werden (falls der PC UEFI unterstützt).
Achtung! Wird jetzt die falsche Disk verwendet, werden ohne Nachfrage Daten gelöscht!
Die Empfehlung von Microsoft (man findet Unterschiedliche) für eine GPT Partitionsstruktur aus meinem zweiten Link sieht als diskpart Script wie folgt aus:
rem == CreatePartitions-UEFI.txt ==
rem == These commands are used with DiskPart to
rem    create four partitions
rem    for a UEFI/GPT-based PC.
rem    Adjust the partition sizes to fill the drive
rem    as necessary. ==
select disk 0
clean
convert gpt
rem == 1. System partition =========================
create partition efi size=100
rem    ** NOTE: For Advanced Format 4Kn drives,
rem               change this value to size = 260 ** 
format quick fs=fat32 label="System"
assign letter="S"
rem == 2. Microsoft Reserved (MSR) partition =======
create partition msr size=16
rem == 3. Windows partition ========================
rem ==    a. Create the Windows partition ==========
create partition primary 
rem ==    b. Create space for the recovery tools ===
shrink minimum=500
rem       ** NOTE: Update this size to match the
rem                size of the recovery tools 
rem                (winre.wim)                    **
rem ==    c. Prepare the Windows partition ========= 
format quick fs=ntfs label="Windows"
assign letter="W"
rem === 4. Recovery tools partition ================
create partition primary
format quick fs=ntfs label="Recovery tools"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
list volume
exit
Bevor jetzt das Script mit dieser Befehlszeile angewendet wird, ist wie im vorherigen Abschnitt bitte genau zu prüfen auf welche Disk mit welcher Nummer das Ziel geschrieben werden soll! Das Script kann man einfach mit Notepad ändern und speichern.
DiskPart /s Z:\Scripts\CreatePartitions-UEFI.txt

Image anwenden

Für den jetzigen Schritt sind eigentlich alle Vorbereitungen getroffen und man kann direkt loslegen. Ich habe hier das Script zur Anwendung mal etwas vor dem "Doppelklick" entschärft.
@if "%1" == "" goto usage 
dism /Apply-Image /ImageFile:%1 /Index:1 /ApplyDir:%2
goto end
:usage
@echo Nichts passiert: Parameter fehlen, bitte so verwenden
@echo apply y:\wim\backup.wim W:\
:end

Startsystem erzeugen

Jetzt muss man mindestens noch die neue Platte "start-fähig" machen. Dazu genügt in der Regel ein Befehl. Wieder als ungefährliches Script:
@if "%1" == "" goto usage 
bcdboot %1 /s %2
goto end
:usage
@echo Nichts passiert: Parameter fehlen, bitte so verwenden
@echo makeboot W:\Windows S:
:end
Jetzt kann man mit dem Befehl
wpeutil shutdown
das System herunterfahren, den USB Stick und die Quellplatte entfernen und das System sollte sich mit der neuen Platte einfach starten lassen.

Recovery System erzeugen

Eigentlich fehlt noch etwas, das Recovery System. Vielleicht war es auf der Quellplatte schon nicht vorhanden, aber bei einer Windows Installation gehört es dazu. Solange die Laufwerke aus Schritt 4 noch vorhanden sind, sollte dieses Script das Recovery System einrichten.
@if "%1" == "" goto usage 
md %1
copy %2\System32\Recovery\winre.wim %1\winre.wim
%2\System32\reagentc /setreimage /path %1 /target %2
goto end
:usage
@echo MakeRecovery R:\Recovery\WindowsRE W:\Windows
:end
Anmerkung:

  • Man kann das Recovery System auch später im laufenden System einrichten, aber dann muss man noch einmal einen Laufwerksbuchstaben zuweisen und wieder entfernen.
  • Der Befehl reagentc erzeugt unter WinPE keinerlei Ausgabe, d.h. /info hat keine Wirkung.
  • Es kann erforderlich sein unter dem fertigen Windows noch einmal den Schalter /enable anzuwenden! Die obige Aktion richtet das Recovery Image zwar ein, aktiviert es aber nicht.

Windows PE bekommen

Windows PE kann man aus unterschiedlichsten Quellen verwenden und "bauen". Ich habe einfach das aktuelle Windows ADK heruntergeladen, man braucht die Deployment Tools und das Windows PE AddOn (Details im 1. Link, aktuelles ADK im 4. Link))
Das "Kommandocenter" für die Umgebung öffnet man nach der Installation mit "Windows + Bereit (tippen)" + rechte Maustaste "Als Administrator ausführen".
Hier braucht man nur zwei Befehle, Laufwerk mit 600-800 MB freiem Platz und einen freien USB Stick. Die Laufwerksbuchstaben und Pfade müssen angepasst  werden.
Achtung, der USB Stick wird (nach Nachfrage) neu formatiert!
copype amd64 D:\WinPE_amd64
MakeWinPEMedia /UFD D:\WinPE_amd64 Q:
Man kann natürlich auch ein ISO File erstellen, z.B. für Test in Hyper-V.
MakeWinPEMedia /ISO D:\WinPE_amd64 D:\ISO\WinPE_amd64.iso
Relativ simpel kann man das Start Script von WinPE erweitern:
Dism /Mount-Image /ImageFile:"C:\WinPE_amd64\media\sources\boot.wim" /index:1 /MountDir:"C:\WinPE_amd64\mount"
# an der Stelle das Script editieren C:\WinPE_amd64\mount\Windows\System32\Startnet.cmd
Dism /Unmount-Image /MountDir:"C:\WinPE_amd64\mount" /commit

Anmerkung für Dual Boot x86 und amd64:
Ich hatte hier schon mal einen dualen Windows Setup Stick gebaut. Ob die Anleitung mit aktuellem ADK funktioniert habe ich nicht getestet.

Probleme lösen

Ich hatte unklare, nicht reproduzierbare Probleme mit der 32 bit Version von WinPE und dism /Capture-Image. Ich habe daraufhin konsequent alles mit der 64 bit Version getestet. Ob die 32 bit Version ein generelles Problem hat kann ich nicht sagen.
Abbruch von dism
Beim Prozess "Aufzeichnen" hatte ich neben zu wenig Platz auf dem Netzlaufwerk Probleme die mit spartanischen Fehlermeldungen von dism abgebrochen wurden. dism schreibt aber normal eine Logdatei nach \Windows\Logs\DISM.
War der Vorgang erfolgreich sollte man die übrigens löschen, sonst ist sie beim nächsten Mal und einer Fehlersuche unnötig groß.
Durch die Hinweise im Log konnte ich die Fälle lösen.
  • chkdsk /f half beim Fehler mit dem Volumebit auf dem Laufwerk.
  • Löschen einer Datei im User Ordner \OneDrive half, weil dism offenbar eine "kaputte" Datei erst aus der Cloud komplett synchronisieren wollte.
  • Ein kleine verdächtige Datei im Browsercache des Users wurde vom Virenscanner erkannt. Ich hatte zu dem Zeitpunkt nicht WinPE gestartet sondern das normale System laufen und die Platte zusätzlich angesteckt.
Ich war durchaus froh über diese "Fehler" die sonst mit auf die neue Platte gewandert wären.
Der Virenscanner im laufenden System wird den Aufzeichnungsprozess verlangsamen! Aber man sollte durchaus erstmal das System auf der originalen Platte gründlich scannen!

Neue Platte startet nicht
Trotz identischem Vorgehen, hatte ich ein UEFI System, welches zunächst nicht starten wollte. Nachdem ich etwas konfus probiert und untersucht habe, war die Lösung ziemlich einfach:
  • Einfach solange in den Fehler starten (3 mal) bis Windows von sich aus in die Startoptionen startet. 
  • Dort einmal die Option: "Abgesichert mit Kommando Fenster" auswählen, anmelden und dann neu starten. Windows repariert so offenbar sein Startsystem automatisch.

Recovery System funktioniert nicht
Die obigen Befehle funktionieren scheinbar alle einwandfrei, aber im fertigen System meldet der Befehl
reagentc /info
das Recovery System als nicht verfügbar.
Der Befehl zum Aktivieren bringt eine Fehlermeldung
reagentc /enable
REAGENTC.EXE: Startkonfigurationsdaten können nicht aktualisiert werden.
Nach langer erfolgloser Suche habe ich einfach das probiert:
del c:\Windows\System32\Recovery\ReAgent.xml
Danach funktionierte /enable einwandfrei.

Zum Schluss

Ich bin oft für spartanische Lösungen, mit dem was gerade da ist. Windows hat seit langem schon alles an Board um eine Systeminstallation (die Systempartition) zu sichern und auf eine neue Festplatte zu bringen. Man braucht keine "bunten" Tools, die im Zweifelsfall auch bloß Dinge machen die man nicht versteht und die Fehlerhaft sein können.
Was ich hier aufgeschrieben habe funktioniert Schritt für Schritt "zu Fuß" und wenn man will mit Batch- oder Powershellscripts. Die c't hat vor Jahren schon mal ein Script für dism & Co vorgestellt welches noch weiter geht. Es erstellt eine Sicherung, die sich mit Setup wieder installieren lässt. (WIMage)
Diese Methode hat gegenüber dem üblicherweise verwendeten sektorbasiertem 1:1 Image durchaus Vorteile:
  • Dateisystem wird quasi auf Fehler überprüft
  • Quell und Zielsystem können unterschiedlich sein:
    • BIOS / UEFI
    • Partitionsgröße - man muss z.B. nicht vorher zeitaufwendig defragmentieren und verkleinern um ein System von einer großen Partition auf eine kleiner SSD zu migrieren
    • Partitionsanordnung
  • man könnte Ordner aus dem Aufzeichnungsprozess ausschließen (WimScript.ini - [ExclusionList])
  • unterschiedliches Dateisystem - muss ich noch untersuchen?
  • Zielsystem ist anschließend erstmal defragmentiert.

Nützliche Tools für WinPE

Die Anleitung zur Integration von Powershell findet man im dritten Link. Die Startzeit vergrößert sich dadurch etwas. 
Ein aktueller OpenSource Dateimanager mit 32 und 64 bit: DoubleCommander  
Ansonsten laufen relativ viele OpenSource Programme ohne Probleme.

Wichtige Quellen


  1. Microsoft: Boot to Windows PE
  2. Microsoft Aufzeichnen und Anwenden von wim Images
  3. Microsoft WinPE mit Powershell
  4. Microsoft: Aktuelles ADK