/ scripting

Syncing Virtual Machines Between Computers

Working on two different computers can be tedious when you have to keep your environment synced. Let's sync an entire virtual machine instead.

Why?

I don't use a Linux VM as much for development since WSL/Bash on Windows came out. But when I did, keeping it synced between my desktop and laptop PC made it easier to maintain. No need to sync ssh keys/config (this was before I started Using Google Cloud for its Terminal Emulator.)

Sync Medium

I sync VM's via a USB flash drive because it is much faster than an online service due to the size of virtual disk files. Many high-end flash drives can transfer files at over 300MB/s, much faster than Internet connections.

Software

I'll be using VMware for running virtual machines and Windows 10 as my host machine.

Robocopy

Robocopy is a tool that comes with all Windows machines. It's better for copying many/large files compared to PowerShell's Copy-Item command.
robocopy C:\VMware F:\VMware /MIR
This will mirror C:\VMware on my PC to F:\VMware on my flash drive. The /MIR flag is nice because it won't copy files that haven't changed and will delete files that are no longer in the source. We want an exact copy, and this accomplishes that in the most efficient way.

Lets automate it

First we need to get the drive letter of the flash drive named 'PATRIOT'.

Function Get-VMUsbRoot {
    Return (Get-WmiObject -Class Win32_logicaldisk |
        Where-Object VolumeName -eq 'PATRIOT').DeviceID
}

Next we need a command to sync the VM.

Function Move-SyncedVirtualMachine {
    Param([Parameter(Mandatory=$true)]
          [ValidateSet('USB','PC')]
          [string]$To)
    $usbRoot = Get-VMUsbRoot
    $usb = ($usbRoot+'\VMware')
    # VM's are kept in different places on each PC.
    $vmPaths = @{'Laptop'='C:\VMWare'
                 'Desktop'='V:\VMWare'}
    $syncedVMPathOnPC = $vmPaths[$env:COMPUTERNAME]
    switch($To){
        'USB'{robocopy $syncedVMPathOnPC $usb /MIR}
        'PC'{robocopy $usb $syncedVMPathOnPC /MIR}
    }
}

This is a wrapper around robocopy so I don't have to enter the full paths every time.
Using it is simple: Move-SyncedVirtualMachine PC
2017-09-02_15-31-25_powershell

VMware: Moved or copied?

When you move a virtual machine, VMware will ask if you moved or copied it. This has to do with VMware's UUIDs.

Since we are moving it and not copying, the UUID can safely stay the same. When asked, click "I moved it". VMWareCopyDialog

How do you sync your environment?

Let me know in the comments.

Syncing Virtual Machines Between Computers
Share this