Create plug and play bitlocker drive from a .vhd file

I’m using etcher on macOS and was hoping to create a bitlocker usb drive that automatically fires the bitlocker password request on insertion (into a windows machine)…
When I click ‘flash from file’ in Etcher, the file dialogue does not allow me to select a .vhd file as the source… I’m wondering if this is only the case on a mac and if there’s a reason a mac couldn’t be used to execute a clone of a VHD file to a USB ?
Many thanks in advance for any help/explanation.

Etcher only supports raw images (like ISO) and Apple Disk Images (.dmg). Etcher will treat anything else as a raw image and flash it exactly as it is in the file, byte by byte. This may or may not be what you want.

yes, that’s what I want. but the dialogue won’t let me select that file type extension… any chance that restriction could be relaxed ?

You can do that by using the command line:

$ balena-etcher <path to the vhd file>

I’ve opened an issue on the repo to allow this in the UI

Thanks very much.
I also tried using etcher to write my VHD file from a url (amazon s3 link) but this too seems to fail.
I get 'Error opening image, Something went wrong … Request failed with 403.
But when I access that url directly I get a 200 and a byte stream. Is Etcher expecting something specific in the http response when writing from a url ?
The response headers for a straight GET on my url are:

HTTP/1.1 200 OK

x-amz-id-2: yWsg/M7…oEJ5LIuQ=
x-amz-request-id: 75EA…AF017E
Date: Thu, 18 Jun 2020 12:35:48 GMT
Last-Modified: Thu, 11 Jun 2020 03:13:11 GMT
ETag: "cf2122c5cde8…dd216cc94e4-129”
x-amz-server-side-encryption: AES256
x-amz-meta-content-disposition: attachment
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Content-Length: 1073742336 Server: AmazonS3

Many thanks,

Hi there,
just to be sure, does the balena-etcher <path to the vhd file>worked for you ?

Yes. Although it’s balenaEtcher rather than balena-etcher and it’s not automatically in the path for me so I needed to specify fully qualified path to the executable: (/Applications/

but it is possible to specify a vhd this way.
Anyway, given that VHD stands for Virtual Hard Drive it would seem that this extension could be added to the valid list of extensions (if there’s even a need for a list at all)

Thanks for your help

Is it possible that when I put a URL that contains parameters, these are not sent to the target ? The UX seems to accept a long url with parameters into the dialogue and shows it back this way in the list of ‘recent’ urls… but is the full URL string being used for the GET request ?

sorry for the mistake.
I’m glad it worked, however from Etcher version 1.5.94 you can also use the UI, since all extensions are accepted.
As for the parameter URLs, they are kept, the full URL string is used for the GET request and you can check this by clicking on the image name.

Great news, thanks. Any idea why I would be getting a HTTP 403 error when I input a url which responds as expected with HTTP 200 when I hit it with curl ? (I included the response headers above)…
For some reason Etcher gives me a 403 but curl or a web browser gives me a 200 and a byte stream.
Thanks again for all your help

Hi, You say ‘all extensions are accepted in the UI’… but here’s what I see on the dialogue behind the ‘flash from file’ option… I can select .dmg and .iso files but not the virtual hard drive .vhd file I want…

Just a quick check Richard, what version of Etcher are you using?

1.5.99 MacOS


Richard, apologies, the feature we had in mind, regarding all file types being available to choose in the UI, has not actually been deployed yet, sorry for the incorrect information. Thus, for the time being, you will need to use the command line in order to flash that ‘.vhd’ file type.

Hi Balena team.
I put an https proxy between Etcher and my target and I’m pretty sure that when I chose to flash from a URL, the pathnames are being stripped off. ie. Etcher isn’t sending the full url path & parameters…
I would like to flash directly from an amazon link of the form:

Using network monitoring, I don’t think Etcher is sending the full path with the url… could this be a bug ?
Many thanks.

Etcher does not transform the URL in any way.
Here is a way you can check:
Flash from this URL: (ignore the missing partition table warning).
Then check what has been written on your device: sudo head -n21 /dev/sda (supposing the device was /dev/sda).
Check the url field that has been returned by the httpbin server: "url": ""

OK I see - yes that gets past the first url check… but unfortunately I can’t head the device afterwards to check it read from the expected url (device becomes unaddressable (’operation not permitted’) after whatever got flashed to it)… So I haven’t proved whether it used the full path or not…
And so I still have a URL which works for me in a browser and with curl (no redirects, just single GET returning a bytestream) but returns a 403 when accessed through Etcher…
Is there any way to log from Etcher what happens in the check phase where it looks if it can access the url ?
How could we figure out why this doesn’t work ?
Thanks again.

device becomes unaddressable (’ operation not permitted ’)

Use sudo, if it doesn’t work try running this from a Linux computer.

Can you share the URL ?

Etcher uses axios.
You can try this:

  • npm i axios
  • node
    Then in node:
  • require('axios').get('YOUR_URL').then(console.log).catch(console.error)

OK, tried this in axios and it downloads the content just fine with a GET as above.
However, I think I found the issue. I think Etcher first issues and HTTP HEAD request when checking the validity of the URL and the content type etc. and then issues the GET only when you ask it to Flash to the drive.
My URL is a signed AWS S3 url and I believe the HTTP verb forms part of the signature algorithm… so a HEAD request to the signed url rightly generates a 403 where a GET to the same endpoint is valid and gives a OK 200.
Unless I can get AWS to ignore the HTTP verb, Etcher isn’t able to use a signed AWS s3 link as a URL source because of the need to execute the HEAD request first :frowning:
Unless there could be an option to bypass the initial URL check which uses HEAD ?

Thanks again for all your help.