Heute kam wieder eine Anfrage an, die mich veranlasst hat, nicht direkt die Antwort zu schreiben, sondern erst kurz zu recherchieren und etwas zu testen…

Die Frage: Ich habe eine VHD variabler Grüße mit 100 GB erzeugt, die jetzt physisch auf 30 GB angewachsen. Nun wollte ich die VHD in eine VHD mit fester Grüße umwandeln. Leider wird diese dann aber 100 GB groß. Aus Gründen des Platzbedarf möchte ich sie aber nur maximal 70 GB groß haben. Wie geht das?

Der Charme von VHDs mit variabler Größe ist ja, dass sie nur den Platz für die enthaltenen Daten benötigen. Je nach Plattform haben VHDs mit fester Größe aber Vorteile bei der Performance. Unter Hyper-V mit dem Server 2008 R2 hat sich die Leistungsfähigkeit der dynamischen Platten aber derart verbessert, dass dies kein Grund mehr sein sollte.

Wichtig ist aber das Szenario VHD Boot – beim Start des Rechners aus der VHD wird die VHD immer auf die maximale Größe erweitert (Sparse Files). So ist sichergestellt, dass der physische Platz nicht ausgeht, was das OS nicht erwarten würde.

Was ist also zu tun?

Mit dem Hyper-V Manager kann man zwar VHDs erweitern, aber nicht verkleinern. Das bringt uns dann zu einem zwei Jahre alten Tools, dem VHD Resizer. Er wurde damals schon im Virtual PC Blog von Ben Armstrong erwähnt…

Zur Funktionsweise: Der VHD Resizer kopiert den Inhalt der VHD blockweise in eine neue VHD. Der Vorteil hierbei ist, dass die originale VHD erst einmal erhalten bleibt. Diese Methode ist auch die einzige, die ein Verkleinern erlaubt. Prinzipiell ließe sich dieser Vorgang auch mit anderen Werkzeugen bewerkstelligen, wichtig ist nur, dass man die Inhalte und Strukturen 1:1 kopiert. Man darf nicht vergessen, dass gerade bei VHDs mit modernen Betriebssystemen auch die “Volume ID” eines Volumes nicht verändert werden sollte. Deswegen ist die blockweise Kopie des “Container Inhalt” keine schlechte Idee.

Ein Problem muss aber getrennt, ja nach Operation auch vorher, gelöst werden: Das Anpassen der Inhalte der VHD, also der Partitionen bzw. Volumes. Die VHD ist nur der Container – die Partition/Volume ist der Inhalt. Der Container kann daher nie kleiner werden als der Inhalt!

Jetzt schlägt die Stunde der Liebhaber der Kommandozeile!

Voraussetzung ist, dass die VHD in einer anderen Betriebssysteminstanz verfügbar ist. Das geht per Hyper-V oder bei Windows 7 (oder dem Server) ebenfalls von der Kommandozeile mit diskpart:

diskpart

select vdisk file=<Pfad zur VHD Datei>
attach vdisk

Sinnvoll ist es die Partition defragmentiert zu haben, sonst wird vermutlich zuviel verteilter Platz belegt. Danach verkleinern wir das Volume:

select volume <Volume Nr>
shrink [desired=<Größe in MB>]

Ohne die Angabe der Megabytes um die verkleinert werden soll, wird maximal möglich verkleinert.

Jetzt müssen wir die VHD nur noch wieder freigeben, damit sie dann per VHD Resizer verkleinert werden kann:

select vdisk file=<Pfad zur VHD Datei>
detach vdisk

exit

Eine Eigenart ist mir beim VHD Resizer aufgefallen: Die Zielgröße muss immer etwas größer als die minimale Größe sein, damit er loslegen will.

Wer eine VHD vergrößern will, muss analog im Nachgang noch Partition/Volume vergrößern. Auch dafür liefert diskpart die benötigten Befehle:

expand vdisk erweitert eine VHD
extend erweitert eine Partition oder ein Volume

Viel Erfolg!