Skip to content

Instantly share code, notes, and snippets.

@manics
Last active September 23, 2021 08:41
Show Gist options
  • Save manics/e2923e8c3342e42cefc57d253d4b07f1 to your computer and use it in GitHub Desktop.
Save manics/e2923e8c3342e42cefc57d253d4b07f1 to your computer and use it in GitHub Desktop.
Create a windows 10 image with virt-install

Setup a Windows 10 VM with virt-install for AWS AMI

Based on https://gist.github.com/ilude/a083934402ee761c402b7ab3ae9bcda7 and https://docs.aws.amazon.com/vm-import/latest/userguide/vmie_prereqs.html

ISO_DIR=~/Downloads/packer
IMAGE_DIR=/var/lib/libvirt/images

WINDOWS_ISO=$ISO_DIR/19043.928.210409-1212.21h1_release_svc_refresh_CLIENTENTERPRISEEVAL_OEMRET_x64FRE_en-us.iso
VIRTIO_ISO=$ISO_DIR/virtio-win.iso
IMAGE_PREFIX=$IMAGE_DIR/win10

sudo qemu-img create -f qcow2 $IMAGE_DIR/win10.qcow2 20G

sudo virt-install --name Win10 --description 'Windows 10' --ram 4096 --vcpus 2 --disk path=${IMAGE_PREFIX}.qcow2,size=20,bus=virtio --disk path=$VIRTIO_ISO,device=cdrom,perms=ro --os-type windows --os-variant win2k8 --network network=default,model=virtio --graphics vnc,listen=127.0.0.1,port=5901 --cdrom $WINDOWS_ISO
  • During installation install drivers from CDROM D:\amd\w10 to get the storage to appear
  • Create user: setup, password setup, answer setup to 3 security questions

Post install Install all drivers from cdrom E:\virtio-win-gt-x64.exe

Start a powershell prompt as Administrator, then clone and run some setup scripts

Invoke-WebRequest -Uri https://github.com/StefanScherer/packer-windows/archive/refs/tags/2021.08.23.zip -OutFile packer-windows-2021.08.23.zip
Expand-Archive -Path packer-windows-2021.08.23.zip -DestinationPath packer-windows

cd ./packer-windows/packer-windows-2021.08.23/scripts/

Allow execution of scripts

Set-ExecutionPolicy RemoteSigned

Edit win-updates.ps1, replace a:\enable-winrm.ps1 with .\enable-winrm.ps1 Edit microsoft-updates.bat, replace A:\temp.vbs with .\temp.vbs

Run the following scripts

.\fixnetwork.ps1
.\microsoft-updates.bat
.\disable-screensaver.ps1
.\win-updates.ps1

.\enable-rdp.bat
.\set-powerplan.ps1
.\compile-dotnet-assemblies.bat
.\set-winrm-automatic.bat
.\scripts/uac-enable.bat
.\dis-updates.bat

Install AWS CLI

Invoke-WebRequest -Uri https://awscli.amazonaws.com/AWSCLIV2.msi -OutFile AWSCLIV2.msi

msiexec.exe /i AWSCLIV2.msi /qn doesn't work so run the installer manually instead

Install AWS Elastic Network Adapter (ENA)

Invoke-WebRequest -Uri https://s3.amazonaws.com/ec2-windows-drivers-downloads/ENA/Latest/AwsEnaNetworkDriver.zip -OutFile AwsEnaNetworkDriver.zip
Expand-Archive -Path AwsEnaNetworkDriver.zip -DestinationPath AwsEnaNetworkDriver
cd AwsEnaNetworkDriver
.\install.ps1

Install AWS SSM agent

Invoke-WebRequest -Uri https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe -OutFile AmazonSSMAgentSetup.exe
SSMAgent_latest.exe /S

Eject D:\ and E:\ drives in Windows Explorer.

Configure universal time

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f

Run Sysprep

c:\windows\system32\sysprep\sysprep.exe /generalize /oobe /quit

Set an Administrator password

net user administrator /active:yes
net user administrator <password>

Convert to raw disk format (qemu-img can create VMDKs but it AWS EC2 rejects it)

sudo qemu-img convert ${IMAGE_PREFIX}.qcow2 ${IMAGE_PREFIX}.raw

Upload the raw disk file to an S3 bucket. Make the object public (a pre-signed URL is meant to work but it didn't for me). Note the bucket must not have a top-level block on public access:

aws cp win10.raw s3://example-bucket/prefix/win10.raw
aws s3api put-object-acl --bucket example-bucket --key prefix/win10.raw --acl public-read

Create a JSON file containing the S3 bucket, prefix, and disk description:

containers.json
[
  {
    "Description": "Windows 10 test",
    "Format": "raw",
    "UserBucket": {
      "S3Bucket": "example-bucket",
      "S3Key": "prefix/win10.raw"
    }
  }
]

Import the disk to an AMI:

aws ec2 import-image --description "Windows 10 test" --disk-containers file://containers.json

This should output an ImportTaskId. Use this to monitor the progress of the import:

aws ec2 describe-import-image-tasks --import-task-ids <ImportTaskId>

When it shows completed there should be an ImageId which is the AMI ID.

#sysprep /generalize /oobe /shutdown /unattend:c:\windows\system32\sysprep\unattend.xml
Invoke-WebRequest -Uri https://github.com/StefanScherer/packer-windows/archive/refs/tags/2021.08.23.zip -OutFile packer-windows-2021.08.23.zip
Expand-Archive -Path packer-windows-2021.08.23.zip -DestinationPath packer-windows
cd ./packer-windows/packer-windows-2021.08.23/scripts/
"./scripts/fixnetwork.ps1",
"./scripts/disable-screensaver.ps1",
"./scripts/disable-winrm.ps1",
"./scripts/enable-winrm.ps1",
"./scripts/microsoft-updates.bat",
"./scripts/win-updates.ps1"
"./scripts/enable-rdp.bat"
"./scripts/vm-guest-tools.ps1",
"./scripts/debloat-windows.ps1"
"./scripts/set-powerplan.ps1",
"./scripts/docker/disable-windows-defender.ps1"
"./scripts/pin-powershell.bat",
"./scripts/compile-dotnet-assemblies.bat",
"./scripts/set-winrm-automatic.bat",
"./scripts/uac-enable.bat",
"./scripts/dis-updates.bat",
"./scripts/compact.bat"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment