Napkin Notes: Conversion of Teradata Express VMware image for Hyper-V use

  1. Download and extract the latest Teradata Express package
  2. Download and install Microsoft Virtual Machine Converter
  3. Download and extract dsfok. You can use a similar tool (e.g. dd) but the instructions are aligned with dsfok.
  4. Start downloading latest openSUSE Recovery CD image
  5. Dump each disk's header (dsfo.exe "TDExpress16.20_Sles11-disk1.vmdk" 512 1024 descriptor1.txt, etc.)
  6. Edit each descriptor, commenting out the ddb.toolsInstallType property with a #
  7. Save each descriptor back into its respective vmdk file (dsfi.exe "TDExpress16.20_Sles11-disk1.vmdk" 512 1024 descriptor1.txt, etc.)
  8. Convert all disks (ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath path\to\TDExpress16.20_Sles11-disk1.vmdk -VhdType DynamicHardDisk -VhdFormat Vhdx -DestinationLiteralPath path\to\disk1.vhdx, etc)
  9. Create an older Hyper-V Generation 1 machine. Attach disks 1 and 2 to IDE Channel 0, and disk 3 to IDE Channel 1. Give the machine at least 8GB of RAM and a few processors. Attach openSUSE Recovery CD image to remaining IDE Channel 1 slot.
  10. Boot from Recovery CD
  11. Edit /etc/sysconfig/kernel and clean out old vmware modules (i.e. change to read INITRD_MODULES="mptspi ata_piix ata_generic hv_vmbus hv_netvsc hv_storvsc hv_blkvsc)
  12. Build a new initial ramdisk using the steps below.
  13. mount --bind /dev /run/media/linux/ROOT-BE1/dev
  14. mount --bind /sys /run/media/linux/ROOT-BE1/sys
  15. mount --bind /mnt /run/media/linux/ROOT-BE1/mnt
  16. chroot /run/media/linux/ROOT-BE1
  17. (chrooted) mkinitrd -k /boot/vmlinux-3.0.101-0.166.TDC.1.R.0-default.gz -i /boot/initrd-3.0.101-0.166.TDC.1.R.0-default
  18. Reboot. X will fail to start.
  19. SSH into the machine (or reboot and enter single user mode).
  20. Stash the old X configuration mv /etc/X11/xorg.conf /etc/X11/xorg.conf.vmware
  21. Run SaX2 to redetect the correct hardware (sax2 -r) and confirm everything looks okay in the Hyper-V Console window.
  22. Reboot. Teradata Express UI should appear.
  23. Optional: Use YaST to enable remote administration (VNC).

Using Remote Desktop Services in Containers

Remote Desktop Services (RDS) is not officially supported in Windows Containers. Nano Server-based containers, for example, don’t contain the required bits on disk. On the flip side, Windows Server Core-based containers do but the feature is deactivated for a few technical and political reasons. In these containers, you can reactivate those bits with an easy registry value.


The value to twiddle is HKLM\System\CurrentControlSet\Control\Terminal Server\TemporaryALiC. (ALiC => Allow Listeners in Container.) Set this REG_DWORD to 1 sometime before TermService startup and you’re all set. RDS defaults will kick in and spin up a RDP-Tcp transport for you to connect to as normal.

Quick and dirty Dockerfile:

FROM microsoft/windowsservercore:1709_KB4074588
RUN net user /add Rafael
RUN net user Rafael !QAZ2wsx
RUN net localgroup "Remote Desktop Users" Rafael /add
RUN net localgroup "Administrators" Rafael /add
RUN cmd /k reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v TemporaryALiC /t REG_DWORD /d 1

⚠ Warnings ⚠

  • Only tested with Windows Server containers (silos).
  • May interfere with the host machine's listener. Jiggling of the TermService on the host machine before/after container startup may be required.
  • Remote Applications Integrated Locally (RAIL) scenarios will require additional configuration (future blog post)

Booting ARM64 builds of Windows 10 in QEMU

QEMU boot Windows 10... on ARM(64)

As you may know, the venerable Quick Emulator (QEMU) supports emulation of the AArch64/ARM64 architecture. With some fiddling over the weekend, I was able to boot and install arm64 builds of Windows 10.

QEMU actually running Windows 10... on ARM(64)

Here's how I did it (feedback welcome):

  1. Warning: This is slow as dirt on an Intel Core i7 4770K

  2. Warning: I have not yet compiled the VirtIO drivers for network and other ancillary devices. That means these machines don't support networking.

  3. Download and install QEMU for Windows

  4. Download the Windows 10 (arm64) ESDs from adguard's whizzbang download page and glue them together using UUPtoISO (patched for arm64) to create a usable ISO

  5. Download my hand-crafted UEFI firmware and recompiled/signed arm64 storage drivers

  6. Create a system.vhdx that's around 23GB or larger (fixed size, not expanding, initialized using GPT partitioning scheme)

  7. Generally glue all the above together in a folder somewhere and create a windows.cmd with the following contents:

  8. Run the script.

  9. During setup, you will need to provide VirtIO drivers (browse to the mounted disk).

  10. Complete setup as usual. (This will take a long time.)

For those curious, here's the break down of the QEMU arguments, in order of appearance:

I encourage you to read the QEMU documentation for additional options.


  • Add --accel tcg,thread=multi for additional per-core performance gains (Thanks @never_released!)
  • The Windows guest may panic at device detection. Click skip when given the option and you should slowly get through.
  • The Windows guest may intermittently panic with a Kernel Security Check Failure.
  • At first boot, the Windows guest's Compatibility Telemetry runner process will spin up and eat all your CPU cores. Kill the process and performance should greatly increase.

Adding Acrylic Blur to your Windows 10 (Redstone 4) desktop apps

Back in July 2015, I provided a code sample for turning on what, at the time, I called "Aero Glass" for Windows 10 desktop apps. (Since then, its name was revealed to be Acrylic Blur.) This code was circulated to the far corners of the Internet and even made it into a shipping product at a very large company.

That's pretty cool.

But the underlying undocumented API has now changed and the sample code I provided early no longer functions correctly on late Redstone 4 builds.

Let's talk about what changed.

First, the AccentState enumeration changed, gaining a new constant specifically designed for Acrylic Blur use.

Second, the Accent Policy GradientColor member is now expected to be non-zero. Despite its unfortunate name (pulled straight from Windows symbols), this member controls the blur background and must be set to an RGBA value stored in little-endian word order (ABGR).

With some minor tweaks to the original sample, Acrylic Blur is back. You can find an updated sample app on GitHub.


Reminder: This API is not supported and can change at any time.

(02/02/2018: Thanks @StartIsBack for hitting me over the head and clarifying a revision of this post that initially discussed a two-word GradientColor.)

What's that gobbledygook in my Package Family Name?

Appx applications have a notion of a "package family" in which all the individual packages belong to. For example, the Windows Photos app may ship on x86, x64, ARM32, ARM64, and IA64 platforms and each package belongs to the overall "Microsoft.Windows.Photos_8wekyb3d8bbwe" family.

A package family name consists of two parts, separated by an underscore: A Name (e.g. Microsoft.Windows.Photos) and a Publisher ID (e.g. 8wekyb3d8bbwe).

The Name is typically derived from a common Package Name (specified in the Appx Manifest) or specified manually by a developer.

The Publisher ID is a Crockford Base32-encoded representation of the first 8 bytes of the SHA-256 hash of the Publisher UTF-32 encoded string. Phew.

For example:

  • Publisher: CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
  • SHA-256 hash: 471D3F2C6D42D7C7FACEEF1ADD20881817082D593D8B7B3E229B3617E4CD2A18
  • ... first 8 bytes: 47 1D 3F 2C 6D 42 D7 C7
  • Crockford Base32 encoded (no padding bytes): 8wekyb3d8bbwe

Using the Base3264-UrlEncoder package available on Nuget (Eric Lau, Mhano Harkness), you can write a few lines of code to calculate this yourself.

Windows Container App Compat: Access host COM ports from a Windows Server container

I field many questions from folks trying to containerize messy legacy apps. Some of the more interesting apps have been line-of-business apps with arcane licensing requirements (e.g. physical dongle) and radio communication apps (e.g. those requiring a GPS).

Windows Server does not ship in a configuration that allows for Windows Server containers to access host COM ports.

But you can change that.

Unlike Hyper-V containers, which rely on a special virtual machine for kernel-level isolation, Windows Server containers simply use Windows Server Silos to isolate processes from the host machine. Windows Server ships with a default silo configuration that aligns it with container mantras around container ephemerality, immutability, scability, etc. You can tweak that configuration to meet your needs.

For example, here's a step-by-step to bring in a COM port:

  1. Take ownership of \Windows\System32\Containers\wsc.def and give yourself write access. (Make a backup copy!)

  2. Open up wsc.def with your favorite text editor.

  3. COM port symlinks typically live in the Global?? object directory, so add the appropriate symlink under <objdir name="GLOBAL??" ...>. (For example, using WinObj, I determined my COM1 is a symlink to \Device\Serial0 and added <symlink name="COM1" path="\Device\Serial0" scope="Global" />.)

  4. Add the appropriate symlink for the device under <objdir name="Device" ...>. (Continuing the example above, I added <symlink name="VCP0" path="\Device\VCP0" scope="Global" />)

  5. Save the file and relaunch your container. (The vmcompute process reads the rules at container startup.)

  6. Type mode at the command prompt to verify your COM port is now visible.

  7. Brace yourself for disappointment when updates come down from WU in the far future and blow away your changes.

As you've probably figured out by now, you can expose way more than just COM ports -- almost anything can be exposed to containers. Be careful.

I did some limited testing on my end with a FTDI serial cable connected to a radio. Shoot me an email if this worked (or failed) for you.

KRACK: Impacted devices I use

More of a TODO list than a blog post, but wanted to document what I use, that is potentially affected by KRACK, and its associated patch status. In other words, I'm doomed.

Last updated: 10/31/2017 10:12AM PST

  • ✔️ Xbox One - Assumed Fixed.

  • ❌ Nintendo Switch - Awaiting vendor response

  • ❌ Nintendo 3DS - Awaiting vendor response

  • ❌ Sony PlayStation 3 and 4 - Awaiting vendor response

  • ❌ Amazon Echo - Awaiting vendor response

  • ❌ Amazon Kindle - Awaiting vendor response

  • ❌ Samsung Galaxy S8 - Awaiting vendor/mobile operator (T-Mobile) response. Struck out with technical support; emailed Samsung PR at 10/16 2:20PM PST. Also ref# 1135145703.

  • ✔️ iPhone 8 - Fixed

  • ✔️ Windows PCs - Fixed.

  • 〰️ Surface devices - Windows 10 is patched, however it's not immediately clear if wireless chipset drivers (for Modern Standby use) are safe.

  • ✔️ macOS PCs - Fixed

  • ❌ Samsung K-series TV - Awaiting vendor response. Struck out with technical support; emailed PR at 10/16 2:20PM PST.

  • ❌ Brother Printer - Awaiting vendor response. Stuck out with technical support; left voicemail for legal department at 10/16 1:50PM PST.

  • ❌ Netgear Nighthawk R7000 - Confirmed affected. Awaiting firmware.

  • ❌ Synology NAS - [Confirmed affected] ( Awaiting update.

Windows Container App Compat: opencv-python on Windows Server Core

When attempting to install and load the opencv-python package, you may run into the following error on Windows Server Core images (e.g. python:2.7-windowsservercore):

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python\lib\site-packages\cv2\", line 9, in <module>
    from .cv2 import *
ImportError: DLL load failed: The specified module could not be found.

This error pops up because opencv relies on ancient Video for Windows, Microsoft AVI, and Microsoft ACM Audio components, none of which ship with the Windows Server Core base image.

If you need to use parts of opencv that don't rely on these components, copy the following libraries from your container host into the container's \System32 folder (assuming 64-bit usage here, adjust accordingly).

  • msacm32.dll
  • avifil32.dll
  • avicap32.dll
  • msvfw32.dll