<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-AU" xmlns:media="http://search.yahoo.com/mrss/">
  <id>https://david.gardiner.net.au/tags/Virtual%20Machines.xml</id>
  <title type="html">David Gardiner - Virtual Machines</title>
  <updated>2026-05-24T00:34:41.689Z</updated>
  <subtitle>Blog posts tagged with &apos;Virtual Machines&apos; - A blog of software development, .NET and other interesting things</subtitle>
  <rights>Copyright 2026 David Gardiner</rights>
  <icon>https://www.gravatar.com/avatar/37edf2567185071646d62ba28b868fab?s=64</icon>
  <logo>https://www.gravatar.com/avatar/37edf2567185071646d62ba28b868fab?s=256</logo>
  <generator uri="https://github.com/flcdrg/astrojs-atom" version="3">astrojs-atom</generator>
  <author>
    <name>David Gardiner</name>
  </author>
  <link href="https://david.gardiner.net.au/tags/Virtual%20Machines.xml" rel="self" type="application/atom+xml"/>
  <link href="https://david.gardiner.net.au/tags/Virtual%20Machines" rel="alternate" type="text/html" hreflang="en-AU"/>
  <category term="Virtual Machines"/>
  <category term="Software Development"/>
  <entry>
    <id>https://david.gardiner.net.au/2023/10/vagrant-virtualbox-hyperv</id>
    <updated>2023-10-28T13:30:00.000+10:30</updated>
    <title>Converting a Vagrant VirtualBox .box file to Hyper-V</title>
    <link href="https://david.gardiner.net.au/2023/10/vagrant-virtualbox-hyperv" rel="alternate" type="text/html" title="Converting a Vagrant VirtualBox .box file to Hyper-V"/>
    <category term="Chocolatey"/>
    <category term="Virtual Machines"/>
    <category term="Hyper-V"/>
    <published>2023-10-28T13:30:00.000+10:30</published>
    <summary type="html">How to convert a Vagrant VirtualBox .box file to work with the Windows Hyper-V hypervisor</summary>
    <content type="html">&lt;p&gt;I maintain quite a number of &lt;a href=&quot;https://community.chocolatey.org/profiles/flcdrg&quot;&gt;Chocolatey packages&lt;/a&gt;, and sometimes I need to test a new package out, or resolve an issue that has been reported with an updated version of a package. If it is for software that I use regularly, I&apos;ll likely do the testing directly on my own machine. But if otherwise a virtual machine makes much more sense, as I can dispose of it once I&apos;m done.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-logo.BOYyrMGo_Z2uaEAk.webp&quot; alt=&quot;Vagrant logo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Chocolatey even provides a semi-automated way to do this using the HashiCorp tool &lt;a href=&quot;https://developer.hashicorp.com/vagrant&quot;&gt;Vagrant&lt;/a&gt;. They have a pre-built Windows image that is identical to the one they use for their own package verification process. Have a look at the &lt;a href=&quot;https://github.com/chocolatey-community/chocolatey-test-environment&quot;&gt;https://github.com/chocolatey-community/chocolatey-test-environment&lt;/a&gt; repo to find out more.&lt;/p&gt;
&lt;p&gt;One issue I&apos;ve encountered relates to the recent upgrading of the image to version 3.0.0, which is now is based on Windows Server 2019. The previous image version (2.0.0) was built using 2012R2. Unfortunately, for some reason while the older image was provided in both VirtualBox and Hyper-V formats, the 3.0.0 image currently only has VirtualBox support. Given the choice, I&apos;d prefer to stick with Hyper-V (rather than having to install another hypervisor on my machine). The problem is if I follow the instructions and use the default Vagrantfile from the &lt;a href=&quot;https://github.com/chocolatey-community/chocolatey-test-environment&quot;&gt;Chocolatey test environment repository&lt;/a&gt;, if I only have Hyper-V installed, it will download the older 2.0.0 image. How can I use the newer one? What follows are the steps I used to create a Hyper-V compatible box file from the VirtualBox one.&lt;/p&gt;
&lt;p&gt;First off, download the 3.0.0 image that targets VirtualBox. I don&apos;t have VirtualBox installed, but you can still tell Vagrant to download that format by providing the &lt;code&gt;--provider&lt;/code&gt; parameter. e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant box add chocolatey/test-environment --provider VirtualBox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&apos;ll see the following output (it may take a few minutes as like most Windows VM images, it is quite large)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;==&amp;gt; box: Loading metadata for box &apos;chocolatey/test-environment&apos;
    box: URL: https://vagrantcloud.com/chocolatey/test-environment
==&amp;gt; box: Adding box &apos;chocolatey/test-environment&apos; (v3.0.0) for provider: VirtualBox
    box: Downloading: https://vagrantcloud.com/chocolatey/boxes/test-environment/versions/3.0.0/providers/VirtualBox/unknown/vagrant.box
    box:
    box: Calculating and comparing box checksum...
==&amp;gt; box: Successfully added box &apos;chocolatey/test-environment&apos; (v3.0.0) for &apos;VirtualBox&apos;!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The files for this image are saved under the &lt;code&gt;vagrant.d&lt;/code&gt; directory in your user profile. eg. for me they&apos;re in&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\david\.vagrant.d\boxes\chocolatey-VAGRANTSLASH-test-environment\3.0.0\VirtualBox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this directory, you can see the following files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---        15/10/2023  12:38 PM           9047   box.ovf
-a---        15/10/2023  12:38 PM     7993072640 󰋊  chocolatey-test-environment-disk001.vmdk
-a---        15/10/2023  12:38 PM             26   metadata.json
-a---        15/10/2023  12:38 PM           3700   Vagrantfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ah haa. A .VMDK file! Now we need to convert this to a VHD. There&apos;s a few different ways to do this. The most reliable I&apos;ve found is the &lt;a href=&quot;https://www.starwindsoftware.com/starwind-v2v-converter&quot;&gt;StarWind V2V Converter tool&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-01.ChZHQNMV_ZHRM1s.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select source image location, local file&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-02.BHrvliYs_Z1yVKwa.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select source image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-03.C4VEa_XD_Z293e4E.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select destination image, local file &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-04.Ctf6CHC6_ZoARJ8.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select destination image format, VHD/VHDX&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-05.t7Q4cGIB_Z2oRobx.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select VHD/VHDX image format, VHD growable&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-06.BjW5q8YZ_ZmcOcd.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Select destination image file name&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vagrant-07.b54n824U_Z2p70yW.webp&quot; alt=&quot;StarWind V2V Conversion Wizard - Conversion progress 100% complete&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we can create a temporary virtual machine. Note that we stick with a Generation 1 VM (I tried Generation 2 and it didn&apos;t work). Also, to keep file sizes down, I stuck with a .vhd file (not a .vhdx). A .vhdx file will work but they&lt;/p&gt;
&lt;p&gt;In an elevated prompt, run the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;New-VM -name &quot;test-environment2019&quot; -VHDPath C:\tmp\chocolatey-test-environment-disk001.vhd -Generation 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and you should see this output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Name                 State CPUUsage(%) MemoryAssigned(M) Uptime   Status             Version
----                 ----- ----------- ----------------- ------   ------             -------
test-environment2019 Off   0           0                 00:00:00 Operating normally 11.0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Set-VMProcessor -VMName test-environment2019 -Count 4
Set-VM -VMName test-environment2019 -AutomaticCheckpointsEnabled $false -CheckpointType Disabled -AutomaticStopAction ShutDown
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the VM and wait for it to boot. Then sign in (the password is &apos;vagrant&apos;)&lt;/p&gt;
&lt;p&gt;Go to &lt;strong&gt;Settings&lt;/strong&gt;, &lt;strong&gt;Apps&lt;/strong&gt; and click on &lt;strong&gt;Oracle VM VirtualBox Guest Additions&lt;/strong&gt;.
Click &lt;strong&gt;Uninstall&lt;/strong&gt;. Then click &lt;strong&gt;Yes&lt;/strong&gt; to confirm.
The VM will reboot.&lt;/p&gt;
&lt;p&gt;Once it has rebooted, you can shut down the VM.&lt;/p&gt;
&lt;p&gt;Run compress just for good measure&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Optimize-VHD -Path C:\tmp\chocolatey-test-environment-disk001.vhd -Mode Full
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;re now following the steps outlined in the Vagrant documentation for &lt;a href=&quot;https://developer.hashicorp.com/vagrant/docs/providers/hyperv/boxes#packaging-the-box&quot;&gt;creating a Hyper-V base box&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Export the VM&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Export-VM -VMName test-environment2019 -path c:\tmp\v3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Go to &lt;code&gt;c:\tmp\v3&lt;/code&gt; and delete the &lt;code&gt;Snapshots&lt;/code&gt; folder (it&apos;s probably empty anyway)&lt;/p&gt;
&lt;p&gt;Create a &lt;code&gt;metadata.json&lt;/code&gt; file&lt;/p&gt;
&lt;p&gt;I took a look at the same file in the 2.0.0 box, and it turns out this is all it contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;provider&quot;: &quot;hyperv&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add that to the &lt;code&gt;metadata.json&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Now we need to create a &lt;code&gt;.tar&lt;/code&gt; file (this may take a few minutes). Tar has been &lt;a href=&quot;https://techcommunity.microsoft.com/blog/containers/tar-and-curl-come-to-windows/382409&quot;&gt;included with Windows since late 2017&lt;/a&gt;, but you could also use &lt;a href=&quot;https://7-zip.org/&quot;&gt;7-Zip&lt;/a&gt; or similar.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd C:\tmp\v3\test-environment2019\

tar cvzf c:\tmp\test-environment2019.tar ./*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can add this to Vagrant using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant box add C:\tmp\test-environment2019.tar --provider hyperv --name chocolatey/test-environment
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&apos;ll see output similar to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;==&amp;gt; box: Box file was not detected as metadata. Adding it directly...
==&amp;gt; box: Adding box &apos;chocolatey/test-environment&apos; (v0) for provider: hyperv
    box: Unpacking necessary files from: file:///C:/tmp/test-environment2019.tar
    box:
==&amp;gt; box: Successfully added box &apos;chocolatey/test-environment&apos; (v0) for &apos;hyperv&apos;!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The one issue with this is that you can see the version number of this box is v0. I&apos;d much prefer to set the version 3.0.0. It turns out you can&apos;t set that directly via the command line, but there is a workaround.&lt;/p&gt;
&lt;p&gt;Create another &lt;code&gt;metadata.json&lt;/code&gt; file (in &lt;code&gt;c:\tmp&lt;/code&gt;) and add the following content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;chocolatey/test-environment&quot;,
  &quot;versions&quot;: [
    {
      &quot;version&quot;: &quot;3.0.0&quot;,
      &quot;status&quot;: &quot;active&quot;,
      &quot;providers&quot;: [
        {
          &quot;name&quot;: &quot;hyperv&quot;,
          &quot;url&quot;: &quot;file:///C:/tmp/test-environment2019.tar&quot;
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and add the new box to Vagrant using this file instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant box add .\metadata.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we see this output&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;==&amp;gt; box: Loading metadata for box &apos;.\metadata.json&apos;
    box: URL: file://C:/tmp/metadata.json
==&amp;gt; box: Adding box &apos;chocolatey/test-environment&apos; (v3.0.0) for provider: hyperv
    box: Unpacking necessary files from: file:///C:/tmp/test-environment2019.tar
    box:
==&amp;gt; box: Successfully added box &apos;chocolatey/test-environment&apos; (v3.0.0) for &apos;hyperv&apos;!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now list all the boxes Vagrant knows about:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant box list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;chocolatey/test-environment (hyperv, 0)
chocolatey/test-environment (hyperv, 2.0.0)
chocolatey/test-environment (hyperv, 3.0.0)
chocolatey/test-environment (VirtualBox, 3.0.0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I just want the &apos;hyperv 3.0.0&apos; box, so I&apos;ll remove the others&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant box remove chocolatey/test-environment --box-version 0 --provider hyperv
vagrant box remove chocolatey/test-environment --box-version 2.0.0 --provider hyperv
vagrant box remove chocolatey/test-environment --box-version 3.0.0 --provider VirtualBox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now you should be fine to run &lt;code&gt;vagrant up&lt;/code&gt; to provision a new VM using the Hyper-V provider, and it will use Windows Server 2019!&lt;/p&gt;
&lt;p&gt;Here&apos;s an example of doing this with the &lt;a href=&quot;https://github.com/chocolatey-community/chocolatey-test-environment&quot;&gt;chocolatey-test-environment&lt;/a&gt; (run from an elevated prompt):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which gives the following output (including signing in with your local username and password):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bringing machine &apos;default&apos; up with &apos;hyperv&apos; provider...
==&amp;gt; default: Verifying Hyper-V is enabled...
==&amp;gt; default: Verifying Hyper-V is accessible...
    default: Configuring the VM...
    default: Setting VM Integration Services
==&amp;gt; default: guest_service_interface is enabled
==&amp;gt; default: heartbeat is enabled
==&amp;gt; default: key_value_pair_exchange is enabled
==&amp;gt; default: shutdown is enabled
==&amp;gt; default: time_synchronization is enabled
==&amp;gt; default: vss is enabled
    default: Setting VM Enhanced session transport type to disabled/default (VMBus)

Vagrant requires administrator access for pruning SMB shares and
may request access to complete removal of stale shares.
==&amp;gt; default: Starting the machine...
==&amp;gt; default: Waiting for the machine to report its IP address...
    default: Timeout: 130 seconds
    default: IP: 172.20.15.213
==&amp;gt; default: Waiting for machine to boot. This may take a few minutes...
    default: WinRM address: 172.20.15.213:5985
    default: WinRM username: vagrant
    default: WinRM execution_time_limit: PT2H
    default: WinRM transport: negotiate
==&amp;gt; default: Machine booted and ready!
==&amp;gt; default: Preparing SMB shared folders...
    default: You will be asked for the username and password to use for the SMB
    default: folders shortly. Please use the proper username/password of your
    default: account.
    default:
    default: Username (user[@domain]): david
    default: Password (will be hidden):

Vagrant requires administrator access to create SMB shares and
may request access to complete setup of configured shares.
==&amp;gt; default: Mounting SMB shared folders...
    default: C:/dev/git/chocolatey-test-environment/packages =&amp;gt; /packages
    default: C:/dev/git/chocolatey-test-environment =&amp;gt; /vagrant
==&amp;gt; default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==&amp;gt; default: flag to force provisioning. Provisioners marked to run always will still run.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Windows Hyper-V Manager will show the new VM running:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/hyperv-manager.nWdNnbhD_Z1wYjDd.webp&quot; alt=&quot;Windows Hyper-V Manager showing chocolatey-test-environment VM running&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can also connect to the VM and sign in to confirm it is running Windows Server 2019 and working as expected:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/vm-connected.B1y59jVe_V8VGX.webp&quot; alt=&quot;Screenshot of connection to virtual machine, showing &apos;About Windows&apos; dialog with Windows Server 2019&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Vagrant error&lt;/h2&gt;
&lt;p&gt;When you run &lt;code&gt;vagrant up&lt;/code&gt;, it fails with the following error (observed with Vagrant 2.3.7):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;An error occurred executing a remote WinRM command.

Shell: Cmd
Command: hostname
Message: Digest initialization failed: initialization error
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently this problem is &lt;a href=&quot;https://github.com/hashicorp/vagrant/issues/13242&quot;&gt;solved with Vagrant version 2.3.8&lt;/a&gt;. Ensure you&apos;re you&apos;re using Vagrant 2.3.8 or newer.&lt;/p&gt;
</content>
    <media:thumbnail url="https://david.gardiner.net.au/_astro/vagrant-logo.BOYyrMGo.png" width="256" height="256"/>
    <media:content medium="image" url="https://david.gardiner.net.au/_astro/vagrant-logo.BOYyrMGo.png" width="256" height="256"/>
  </entry>
  <entry>
    <id>https://david.gardiner.net.au/2020/04/downloading-azure-vm</id>
    <updated>2020-04-03T09:45:00.000+10:30</updated>
    <title>Downloading an Azure VM</title>
    <link href="https://david.gardiner.net.au/2020/04/downloading-azure-vm" rel="alternate" type="text/html" title="Downloading an Azure VM"/>
    <category term="Azure"/>
    <category term="Virtual Machines"/>
    <published>2020-04-03T09:45:00.000+10:30</published>
    <summary type="html">Yesterday I needed to get a copy of a virtual machine onto my local workstation.</summary>
    <content type="html">&lt;p&gt;Yesterday I needed to get a copy of a virtual machine onto my local workstation. As I&apos;m now working from home, that was going to mean downloading a lot of data, but first I had to find the VM. I remembered I had exported this particular VM up into Azure at one stage to experiment with using different hardware specs to find out how that would affect performance.&lt;/p&gt;
&lt;p&gt;Lucky for me, the VM was still there (though de-allocated to reduce costs). Usually you want to migrate a VM &lt;em&gt;up&lt;/em&gt; into the cloud, but I needed to go the other way! So how do you get a copy of that VM? It turns out it isn&apos;t that tricky:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make sure the VM is shut down (mine was)&lt;/li&gt;
&lt;li&gt;Open up the VM in the Azure Portal&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Settings&lt;/strong&gt;, click on &lt;strong&gt;Disks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Click on the individual disk (if you have more than one, you&apos;ll need to repeat the next few steps)&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Settings&lt;/strong&gt;, click on &lt;strong&gt;Disk Export&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You&apos;re prompted to enter a URL expire time. The default is 3600 seconds (1 hour). If you have limited bandwidth you should make this larger, otherwise your download may fail. I set mine to 36000 (10 hours)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Generate URL&lt;/strong&gt; and a URL will be displayed
&lt;img src=&quot;https://david.gardiner.net.au/_astro/azure-disk-export.WXbnQ9ZE_Z1I2f56.webp&quot; alt=&quot;Azure virtual machine disk export&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Download the .vhd file for this disk. Mine was 80GB and it took all day. It also failed a number of times, but I was able to restart the download and it did continue on from where it left off.&lt;/li&gt;
&lt;li&gt;The download defaulted to calling the file &lt;code&gt;abcd&lt;/code&gt;, but it is a VHD file, so just rename the file to something useful.&lt;/li&gt;
&lt;/ol&gt;
</content>
  </entry>
</feed>
