Microsoft have some detailed instructions on capturing a VHD
to move to Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/prepare-for-upload-vhd-image
Another way is to create a WIM
file by booting from a Windows install ISO: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/capture-and-apply-windows-using-a-single-wim?view=windows-11
You should know that Microsoft doesn't really want to make this easy, because it would also make piracy easier. Of course on Azure this is not a problem.
Personally I would boot any Linux from USB, and use dd
, gz
, and rsync
:
$ lsblk # will show the block devices
$ mount -o ro /dev/sdb2 /mnt
$ cd /mnt
$ ls # to confirm that it's the right partition / installation
$ umount /mnt
$ dd if=/dev/sdb2 | gzip -9 > image.raw.gz
$ rsync image.raw.gz my.newhost.com:/
The snag with this approach is that you'd need double the space as you're just copying a file which then still needs to be uncompressed and depending on your purpose, written to a block device, on the target:
# dd if=image.raw.gz | gunzip | dd of=/dev/sdg1
Perhaps better than dd:
$ qemu-img convert -f raw -O vhd /dev/sdb2 image.vhd
$ rsync image.vhd my.remote.host:~
Which you can run virtually on the remote host with QEMU/KVM:
$ qemu-system-x86_64 -m 2G -hda image.vhd
The benefit of this approach is that you can use any format such as qcow2
. Just substitute vhd
above for qcow2
. You can read up more about qemu
and virt-manager
in their official documentation, there are some useful GUI tools available.
Alternatively, if you're on the same LAN or don't need to be able to resume the copy - which you can do above by just running the rsync command repeatedly until the whole copy is done, and you can copy directly to the new block device on the target machine.
First allow dd
to run as root on the target machine, which would be required to write directly to a block device if you're not logging in with the root
user:
$ ssh 192.168.1.2
$ visudo
# Add:
myuser ALL = NOPASSWD: /bin/dd
# then type :w ENTER and :q ENTER
Then you can simply issue:
$ sudo dd if=/dev/sdb2 | gzip -9 - | ssh 192.168.1.2 "gunzip - | sudo dd of=/dev/sdg1"
Yet another option is this Python script that works similar to rsync, so if the copy is interrupted, it can be resumed, so best of both. It's opinionated in that it uses ssh
to the root account on the remote host, which does not allow password logins by default, so you have to add an ssh
key
. There are several ways to do this, here's one:
$ ssh my.remotehost.com "echo `~/.ssh/id_rsa.pub` | sudo tee -a /root/.ssh/id_rsa.pub" # add your user ssh key to the remote root account
Then just get the script and run it:
$ git clone https://github.com/bscp-tool/bscp-tool.github.io.git
$ bscp /dev/sda1 my.remotehost.com:/dev/sdg1