sync with labv2.nix + standalone flake with toDisk app

Previous history:
- c359054 daku working!
- 8de5cff fix integer overflow in vmix network lib
- 9c25a66 daku on 25.05. with ollama
- 385a3bf vmix enables relaxed sandbox
- c363da1 restructure vmixLib into linux/windows subattrs with OS-specific customizeImage
- edd4dc2 vmix: port namespace model and module improvements from conf.nix
- 6666ecf vmix: add SPICE support, install virtio guest tools with SPICE agent
- 46f5671 vmix: add QEMU guest agent channel for Windows VMs
- e1fea34 vmix: add Win11 LTSC 2024 image, refactor VirtIO driver selection
- c27ae68 vmix: make customizeImage chroot-sandboxed by default, opt-in impure
- 305fbac virt customize needs chroot for now due to usr bin env things. could be fixed later
- 264d30f vmix: add win10 VM on desk, disable SMB signing for guest Samba access
- 9b64f51 vmix: split Windows templates into per-category files, add comprehensive debloat
- ef91bf8 vmix: fix missing parent registry keys in Windows templates
- f87f340 win10 VM on panda with AMD GPU + USB passthrough
- 38e474f vmix: split Windows build into Audit Mode install + composable templates
- a6a8db3 vmix: win11 support, remove build VNC, switch VMs to SPICE
- 6cf5a21 generalize stage sets bg color, accent color and sets visual effects to performance
- a84849f remove rdp template since it doesn't even work
- 5245263 vmix: best performance template + generalize cleanup
- ab12dd3 vmix: use CopyProfile for best performance visual effects
- bce3326 vmix: CopyProfile for best performance visual effects
- 2496107 vmix: add app templates (7zip, VLC, ImageGlass, Edge WebView, VC++ runtimes)
- 29a6123 wip: debug default associations xml
- 2a2e5f5 vmix: fix DefaultAssociations.xml cmd.exe escaping
- cc6ff9d vmix: move DefaultAssociations.xml to template only
- a4a78ec vmix: add removeWMP template to remove Windows Media Player
- 3fe56de vmix: improved Edge removal (files, shortcuts, scheduled tasks)
- a491767 vmix: fully remove Edge via post-oobe AppxPackage removal
- 6ca1619 vmix: remove Edge DevToolsClient SystemApps + AppxPackage
- 0c1ec35 vmix: sandboxie windows app template
- 628bbd2 vmix: add Sandboxie-Plus template
- f055a41 vmix: reorganize templates, add file associations, remove Paint
- 34326f4 vmix: set Thorium as default browser via PS-SFTA in post-oobe
- 86af258 vmix: Active Setup for default browser (all users, no post-oobe needed)
- 35b8cb0 remove vnc display from thorium template
- c7e0af6 vmix: fix Win11 generalize timeout + UCPD disable for URL associations
- 43a1345 vmix: add Office 2024 template + Ohook activation in generalize
- 03bbce0 vmix: updated office installation xml. more privacy options enabled
- 790a0ee vmix: thorium installation - hide SFTA window
- a0e5c18 vmix: fix office install.bat call + add privacy registry policies
- 3df38ca vmix: fix Ohook activation + suppress Office theme dialog
- df39ba3 vmix: remove sandboxie shortcut from desktop
- 50d5972 vmix: skip Sandboxie desktop shortcut via installer flag
- ee2fa0f vmix: fix win10 default browser
- 938315b vmix: windows: set accent color to automatic. remove accent color from unnecessary elements
- beceda8 vmix: allow ISO-only VMs without OS disk, add WinPE VM to panda

Flake outputs: overlays.default, nixosModules.default, lib, apps.toDisk

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Git Sagar 2026-05-23 19:16:35 -03:00
parent dd1fb16e1b
commit 94f299bb81
77 changed files with 2785 additions and 796 deletions

View file

@ -0,0 +1,32 @@
{ pkgs, lib, system, ... }:
let
windows = rec {
drivers = import ./drivers { inherit pkgs system; };
makeFilesISO = (import ./helpers/makeFilesISO.nix) { inherit pkgs; };
customizeImage = (import ./helpers/customizeImage.nix) { inherit pkgs lib; };
customizeImageFold = builtins.foldl' customizeImage;
templates = (import ./templates) { inherit pkgs lib system drivers makeFilesISO; };
makeAuditModeAutounattend = (import ./helpers/makeAuditModeAutounattend.nix) { inherit pkgs lib; };
makeWinISO = (import ./helpers/makeWinISO.nix) { inherit pkgs; };
makeImage = (import ./helpers/makeImage.nix) { inherit pkgs lib drivers makeWinISO makeAuditModeAutounattend; };
};
win10 = (import ./win10) { inherit pkgs lib system windows; };
win11 = (import ./win11) { inherit pkgs lib system windows; };
# Recursively add .generalize to every derivation leaf in the image tree
addGeneralize = val:
if val ? _vmixOsType then
val // { generalize = args:
let
templateArgs = builtins.removeAttrs args [ "vncDisplay" ];
displayArgs = lib.optionalAttrs (args ? vncDisplay) { inherit (args) vncDisplay; };
in windows.customizeImage val (windows.templates.generalize templateArgs // displayArgs);
}
else if builtins.isAttrs val then
lib.mapAttrs (_: addGeneralize) val
else val;
in windows // {
images = addGeneralize { inherit win10 win11; };
}

View file

@ -0,0 +1,5 @@
{ pkgs }:
pkgs.fetchurl {
url = "https://github.com/Matishzz/AMD-Install-Drivers/releases/download/25.3.1/25.3.1.w11-w10.zip";
sha256 = "0mrz3kkiavs0l4x00978vdbw9la1j16jar0y6lny0l8z59hqp9gq";
}

View file

@ -0,0 +1,4 @@
{ pkgs, system, ... }: {
virtio-iso = import ./virtio-iso-w10-11.nix { inherit pkgs; };
amd-gpu-zip = import ./amd-gpu-drivers.nix { inherit pkgs; };
}

View file

@ -0,0 +1,6 @@
# VirtIO drivers ISO for Windows guests (stable release from Fedora)
{ pkgs, ... }:
pkgs.fetchurl {
url = " https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.285-1/virtio-win-0.1.285.iso";
sha256 = "0cb3jyik40mkmyjwbagfj6609cnyzvysf2q7y0jykhwj8jwz4k71";
}

View file

@ -0,0 +1,113 @@
# Customize Windows images via offline registry merge and/or Audit Mode script execution.
#
# Templates can provide:
# windowsRegistry — merged offline via virt-win-reg (fast, no boot needed)
# auditScript — injected into image and run in Audit Mode via QEMU boot
# cdroms — ISO files to attach as CDs when booting for auditScript
#
# Both can be combined: registry is applied first (offline), then the script runs (online).
{ pkgs, lib, ... }:
originalImage: {
name ? "",
diskSize ? "",
impure ? true,
# Offline: merge .reg file into registry via virt-win-reg
windowsRegistry ? "",
# Online: boot into Audit Mode and run this script
auditScript ? "",
# CD-ROMs to attach when booting for auditScript (e.g. VirtIO ISO)
cdroms ? [],
# Files to upload into the image before running auditScript
# List of { source = <drv or path>; dest = "/Windows/path"; }
uploads ? [],
# QEMU settings for auditScript boot
vncDisplay ? null,
smp ? 4,
memSize ? 4096,
}:
let
originalImageName = lib.strings.removeSuffix "-vmix" (lib.strings.removeSuffix ".qcow2" originalImage.name);
customImageName = (if name != "" then name else "custom") + "-${originalImageName}-vmix.qcow2";
resultImg = "./disk.qcow2";
hasRegistry = windowsRegistry != "";
hasAuditScript = auditScript != "";
# Offline registry merge
windowsRegFile = pkgs.writeText "${name}-registry.reg" windowsRegistry;
virtWinRegMerge = lib.optionalString hasRegistry ''
echo "=== vmix: merging registry entries (${name}) ==="
virt-win-reg --merge ${resultImg} ${windowsRegFile}
'';
# Audit Mode script injection + QEMU boot
auditScriptFile = pkgs.writeText "${name}-audit.cmd" auditScript;
wrapperScript = pkgs.writeText "${name}-audit-wrapper.cmd" ''
@echo off
echo === vmix audit: ${name} ===
call C:\vmix-audit-script.cmd
echo === vmix audit: ${name} complete ===
del /q C:\vmix-audit-script.cmd 2>nul
shutdown /s /t 5 /c "vmix: ${name} complete" 2>nul
del /q C:\vmix-audit-wrapper.cmd 2>nul
'';
runOnceReg = pkgs.writeText "${name}-runonce.reg" (lib.concatStringsSep "\n" [
"Windows Registry Editor Version 5.00"
""
''[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce]''
''"vmixAudit"="C:\\vmix-audit-wrapper.cmd"''
""
]);
cdromArgs = lib.concatMapStringsSep " \\\n " (cd: "-drive file=${cd},media=cdrom,readonly=on") cdroms;
auditBootCommands = lib.optionalString hasAuditScript ''
echo "=== vmix: injecting audit script (${name}) ==="
virt-customize -a ${resultImg} \
--upload ${auditScriptFile}:/vmix-audit-script.cmd \
--upload ${wrapperScript}:/vmix-audit-wrapper.cmd \
${lib.concatMapStringsSep " \\\n " (u: let dir = builtins.dirOf u.dest; in "${lib.optionalString (dir != "/") "--mkdir ${dir}"} --upload ${u.source}:${u.dest}") uploads}
echo "=== vmix: adding RunOnce entry ==="
virt-win-reg --merge ${resultImg} ${runOnceReg}
# Boot into Audit Mode to run the script
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd vars.fd
chmod +w vars.fd
echo "=== vmix: booting Audit Mode for ${name} (VNC: ${if vncDisplay != null then vncDisplay else "disabled"}) ==="
timeout 1800 qemu-system-x86_64 \
${if vncDisplay != null then "-vnc ${vncDisplay}" else "-nographic"} \
-accel kvm \
-m ${toString memSize} \
-smp ${toString smp} \
-cpu host \
-machine type=q35 \
-drive if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.fd}/FV/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=vars.fd \
-rtc base=localtime,clock=host \
-device qemu-xhci -device usb-tablet \
-global ICH9-LMB.disable_s3=1 -global ICH9-LMB.disable_s4=1 \
-drive file=${resultImg},format=qcow2,if=virtio \
${cdromArgs} \
-nic user,model=virtio-net-pci
echo "=== vmix: audit script ${name} complete ==="
'';
builderCommand = ''
# create resulting image backed by original image
qemu-img create -f qcow2 -b ${originalImage} -F qcow2 ${resultImg}
[ -n "${diskSize}" ] && qemu-img resize ${resultImg} ${diskSize}
${virtWinRegMerge}
${auditBootCommands}
mv ${resultImg} $out
'';
builtImage = pkgs.runCommand customImageName ({
nativeBuildInputs = with pkgs; [ qemu perl guestfs-tools ];
requiredSystemFeatures = [ "kvm" ];
} // lib.optionalAttrs impure { __noChroot = true; }) builderCommand;
in
builtImage // { _vmixOsType = "windows"; }

View file

@ -0,0 +1,174 @@
# Autounattend.xml for unattended Windows installation into Audit Mode.
# Minimal — only what's needed to install Windows and enter Audit Mode.
# All customization (hostname, timezone, telemetry, UAC, etc.) is done via templates.
{ pkgs, lib, ... }:
{
locale ? "en-US",
productKey ? "",
diskIndex ? 0,
imageIndex ? 1,
efi ? true,
virtioDriverLetter ? "E",
bypassRequirements ? false,
windowsVersionForVirtioDrivers
}: pkgs.writeText "Autounattend.xml" ''
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<!-- windowsPE locale, product key, VirtIO drivers, disk partitioning -->
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage>
<UILanguage>${locale}</UILanguage>
</SetupUILanguage>
<InputLocale>${locale}</InputLocale>
<SystemLocale>${locale}</SystemLocale>
<UILanguage>${locale}</UILanguage>
<UserLocale>${locale}</UserLocale>
</component>
<component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DriverPaths>
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
<Path>${virtioDriverLetter}:\amd64\${windowsVersionForVirtioDrivers}</Path>
</PathAndCredentials>
</DriverPaths>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserData>
${lib.optionalString (productKey != "") ''
<ProductKey>
<Key>${productKey}</Key>
</ProductKey>
''}
<AcceptEula>true</AcceptEula>
</UserData>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/INDEX</Key>
<Value>${toString imageIndex}</Value>
</MetaData>
</InstallFrom>
<InstallTo>
<DiskID>${toString diskIndex}</DiskID>
<PartitionID>${if efi then "3" else "1"}</PartitionID>
</InstallTo>
</OSImage>
</ImageInstall>
<DiskConfiguration>
<Disk wcm:action="add">
<DiskID>${toString diskIndex}</DiskID>
<WillWipeDisk>true</WillWipeDisk>
${if efi then ''
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Size>100</Size>
<Type>EFI</Type>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Size>16</Size>
<Type>MSR</Type>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>3</Order>
<Extend>true</Extend>
<Type>Primary</Type>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Order>1</Order>
<PartitionID>1</PartitionID>
<Format>FAT32</Format>
<Label>EFI</Label>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Order>3</Order>
<PartitionID>3</PartitionID>
<Format>NTFS</Format>
<Label>Windows</Label>
</ModifyPartition>
</ModifyPartitions>
'' else ''
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Extend>true</Extend>
<Type>Primary</Type>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Order>1</Order>
<PartitionID>1</PartitionID>
<Format>NTFS</Format>
<Label>Windows</Label>
<Active>true</Active>
</ModifyPartition>
</ModifyPartitions>
''}
</Disk>
</DiskConfiguration>
${lib.optionalString bypassRequirements ''
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>3</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
</RunSynchronous>
''}
</component>
</settings>
<!-- specialize inject RunOnce to clean up cached Autounattend and shutdown -->
<settings pass="specialize">
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v vmixCleanup /t REG_SZ /d "cmd /c del /q C:\Windows\Panther\unattend.xml" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v vmixShutdown /t REG_SZ /d "shutdown /s /t 10 /c vmix-audit-ready" /f</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<!-- oobeSystem enter Audit Mode -->
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<Reseal>
<Mode>Audit</Mode>
</Reseal>
</component>
</settings>
</unattend>
''

View file

@ -0,0 +1,23 @@
# Create an ISO from a list of files. Zips are automatically extracted.
# Nix store hash prefixes are stripped from filenames.
# Usage:
# makeFilesISO { name = "my-stuff"; files = [ ./foo.exe someZip anotherFile ]; }
# makeFilesISO { name = "my-stuff"; files = [ (pkgs.fetchurl { ... }) ]; }
{ pkgs, ... }:
{ name ? "files", files }:
pkgs.runCommand "${name}.iso" {
nativeBuildInputs = with pkgs; [ unzip cdrkit file ];
} ''
mkdir -p content
${builtins.concatStringsSep "\n" (map (f: ''
if file --mime-type -b "${f}" | grep -q "application/zip"; then
unzip -q -o "${f}" -d content
else
# Strip nix store hash prefix (e.g. "abc123-foo.exe" -> "foo.exe")
fname=$(basename "${f}")
stripped="''${fname#*-}"
cp "${f}" "content/$stripped"
fi
'') files)}
genisoimage -o $out -joliet -joliet-long -rational-rock content
''

View file

@ -0,0 +1,69 @@
# Build a pre-installed Windows qcow2 image using QEMU unattended install.
# Boots into Audit Mode after install and shuts down.
# Apply templates via customizeImageFold to install software (auditScript)
# and customize registry (windowsRegistry), then generalize when done.
{ pkgs, lib, drivers, makeWinISO, makeAuditModeAutounattend, ... }:
{
name ? "windows",
upstreamISO,
productKey ? "",
imageIndex ? 1,
diskSize ? "64G",
bypassRequirements ? false,
locale ? "en-US",
efi ? true,
smp ? 4,
memSize ? 4096,
vncDisplay ? null, # e.g. ":10" to enable VNC on port 5910 for monitoring
windowsVersionForVirtioDrivers ? "w10", # "w10", "w11", "2k22", "2k19", etc.
}:
let
AutounattendedXml = makeAuditModeAutounattend {
inherit locale productKey imageIndex
efi bypassRequirements windowsVersionForVirtioDrivers;
diskIndex = 0;
virtioDriverLetter = "E";
};
iso = makeWinISO {
iso = upstreamISO;
inherit AutounattendedXml;
};
drv = pkgs.runCommand "${name}-vmix.qcow2" {
__noChroot = true;
requiredSystemFeatures = [ "kvm" ];
nativeBuildInputs = with pkgs; [ qemu ];
} ''
# create empty disk
qemu-img create -f qcow2 disk.qcow2 ${diskSize}
# writable UEFI NVRAM so boot order persists across reboots
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd vars.fd
chmod +w vars.fd
echo "=== Starting Windows unattended install (this takes 15-30 minutes) ==="
# Windows installs unattended, reboots into Audit Mode,
# deletes cached Autounattend, shuts down → QEMU exits.
timeout 3600 qemu-system-x86_64 \
${if vncDisplay != null then "-vnc ${vncDisplay}" else "-nographic"} \
-accel kvm \
-m ${toString memSize} \
-smp ${toString smp} \
-cpu host \
-machine type=q35 \
-drive if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.fd}/FV/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=vars.fd \
-rtc base=localtime,clock=host \
-device qemu-xhci -device usb-tablet \
-global ICH9-LMB.disable_s3=1 -global ICH9-LMB.disable_s4=1 \
-drive file=disk.qcow2,format=qcow2,if=virtio \
-drive file=${iso},media=cdrom,readonly=on \
-drive file=${drivers.virtio-iso},media=cdrom,readonly=on \
-nic user,model=virtio-net-pci
echo "=== Windows install complete (Audit Mode image) ==="
mv disk.qcow2 $out
'';
in drv // { _vmixOsType = "windows"; }

View file

@ -0,0 +1,40 @@
# Remaster a Windows ISO: remove boot prompt, optionally inject Autounattend.xml and scripts
{ pkgs, ... }:
{ iso, AutounattendedXml ? null, postInstallScript ? null }:
pkgs.runCommand "windows-remastered.iso" {
nativeBuildInputs = with pkgs; [ p7zip cdrkit ];
} ''
workdir=$(mktemp -d)
isopath="${iso}"
if [ -d "$isopath" ]; then
isopath="$(find "$isopath" -maxdepth 1 -name '*.iso' -type f | head -n1)"
if [ -z "$isopath" ]; then
echo "ERROR: no .iso file found in $isopath"
exit 1
fi
fi
7z x -o"$workdir" "$isopath" > /dev/null
# remove "Press any key to boot from CD/DVD" prompt
if [ -f "$workdir/efi/microsoft/boot/efisys_noprompt.bin" ]; then
cp "$workdir/efi/microsoft/boot/efisys_noprompt.bin" \
"$workdir/efi/microsoft/boot/efisys.bin"
fi
if [ -f "$workdir/efi/microsoft/boot/cdboot_noprompt.efi" ]; then
cp "$workdir/efi/microsoft/boot/cdboot_noprompt.efi" \
"$workdir/efi/microsoft/boot/cdboot.efi"
fi
rm -f "$workdir/boot/bootfix.bin"
# inject unattend and post-install script into ISO root
${if AutounattendedXml != null then ''cp ${AutounattendedXml} "$workdir/Autounattend.xml"'' else ""}
${if postInstallScript != null then ''cp ${postInstallScript} "$workdir/post-install.cmd"'' else ""}
genisoimage \
-allow-limited-size -iso-level 3 -o "$out" \
-joliet -joliet-long -rational-rock -udf \
-b boot/etfsboot.com -no-emul-boot -boot-load-size 8 -boot-info-table \
-eltorito-alt-boot -e efi/microsoft/boot/efisys.bin -no-emul-boot \
"$workdir"
rm -rf "$workdir"
''

View file

@ -0,0 +1,20 @@
# Install 7-Zip and set file associations
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://github.com/ip7z/7zip/releases/download/26.00/7z2600-x64.msi";
hash = "sha256-w4jQREhxyhGyEjcAGvFYz92tfhN4UXleW2XO5ptRhJU=";
};
assocReg = ./7zip-file-associations.reg;
in {
name = "7zip";
cdroms = [ (makeFilesISO { name = "7zip"; files = [ installer assocReg ]; }) ];
auditScript = ''
@echo off
echo Installing 7-Zip...
msiexec /i "D:\7z2600-x64.msi" /qn /norestart
echo Importing 7-Zip file associations...
regedit /s "D:\7zip-file-associations.reg"
'';
}

View file

@ -0,0 +1,18 @@
# Install Microsoft Edge WebView2 Runtime
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/7ff41be4-dbce-4efe-823f-c7d33a4e3c5e/MicrosoftEdgeWebview2Setup.exe";
hash = "sha256-Asl+XjKpfYlhY+xoo+o6sDOeV/J0NIuGiTmWOLZJsrk=";
};
in {
name = "edge-webview";
cdroms = [ (makeFilesISO { name = "edge-webview"; files = [ installer ]; }) ];
auditScript = ''
@echo off
echo Installing Edge WebView2 Runtime...
copy D:\MicrosoftEdgeWebview2Setup.exe C:\webview-setup.exe
start /wait C:\webview-setup.exe /silent /install
del /q C:\webview-setup.exe
'';
}

View file

@ -0,0 +1,26 @@
# Install ImageGlass and set file associations
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://github.com/d2phap/ImageGlass/releases/download/9.4.1.15/ImageGlass_9.4.1.15_x64.msi";
hash = "sha256-o7q+5XpGLK+P/GQxvN/Ud5w1NxPpJ24AL54HNwda32Q=";
};
assocReg = ./imageglass-file-associations.reg;
in {
name = "imageglass";
cdroms = [ (makeFilesISO { name = "imageglass"; files = [ installer assocReg ]; }) ];
auditScript = ''
@echo off
echo Installing ImageGlass...
msiexec /i "D:\ImageGlass_9.4.1.15_x64.msi" /qn /norestart ALLUSERS=1
echo Importing ImageGlass file associations...
regedit /s "D:\imageglass-file-associations.reg"
:: delete shortcut on desktop
del /q "C:\Users\Public\Desktop\ImageGlass.lnk"
:: Remove Paint Brush class registration
reg delete "HKLM\SOFTWARE\Classes\PBrush" /f 2>nul
'';
}

View file

@ -0,0 +1,29 @@
# Install Microsoft Office 2024 (Word, Excel, PowerPoint) via offline deployment
{ pkgs, makeFilesISO, ... }:
let
officeSrc = pkgs.fetchurl {
url = "https://git.sagar.ch/dotfiles/office-2024-word-excel-powerpoint/archive/4351e8d93ceb28f65de9ec4dc9c27dccbe91ff34.zip";
hash = "sha256-ulNecpkUH6O9cqYhgtmG++a1gi+c4HIR1Vvo22VygJs=";
};
in {
name = "office";
cdroms = [ (makeFilesISO { name = "office"; files = [ officeSrc ]; }) ];
auditScript = ''
@echo off
echo Installing Microsoft Office 2024...
call D:\office-2024-word-excel-powerpoint\install.bat
:: Office privacy policies (HKCU, preserved to new users via CopyProfile)
reg add "HKCU\Software\Policies\Microsoft\office\16.0\common\privacy" /v "disconnectedstate" /t REG_DWORD /d 2 /f >nul
reg add "HKCU\Software\Policies\Microsoft\office\16.0\common\privacy" /v "usercontentdisabled" /t REG_DWORD /d 2 /f >nul
reg add "HKCU\Software\Policies\Microsoft\office\16.0\common\privacy" /v "downloadcontentdisabled" /t REG_DWORD /d 2 /f >nul
reg add "HKCU\Software\Policies\Microsoft\office\16.0\common\privacy" /v "controllerconnectedservicesenabled" /t REG_DWORD /d 2 /f >nul
reg add "HKCU\Software\Policies\Microsoft\office\common\clienttelemetry" /v "sendtelemetry" /t REG_DWORD /d 3 /f >nul
:: incase of enabling connected experiences, this disables the dialog box that shows at first run
:: reg add "HKCU\SOFTWARE\Microsoft\Office\16.0\Common\Privacy\SettingsStore\Anonymous" /v "OptionalConnectedExperiencesNoticeVersion" /t REG_DWORD /d 2 /f >nul
:: supress dialogbox - Choose your theme for 365 Apps
reg add "HKCU\SOFTWARE\Microsoft\Office\16.0\Common\PromoDialog" /v "FluentWelcomeDialogShown" /t REG_DWORD /d 1 /f >nul
'';
}

View file

@ -0,0 +1,16 @@
# Install Sandboxie-Plus
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://github.com/sandboxie-plus/Sandboxie/releases/download/v1.15.6/Sandboxie-Plus-x64-v1.15.6.exe";
hash = "sha256-0VQXy9rFCJCfVyHLJYXe/s6imcwEZugsNOKMhUoLUVM=";
};
in {
name = "sandboxie";
cdroms = [ (makeFilesISO { name = "sandboxie"; files = [ installer ]; }) ];
auditScript = ''
@echo off
echo Installing Sandboxie-Plus...
start /wait D:\Sandboxie-Plus-x64-v1.15.6.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /MERGETASKS="!desktopicon"
'';
}

View file

@ -0,0 +1,40 @@
# Install Thorium browser and set as default via Active Setup (all users)
# PS-SFTA is stored in Program Files and runs at each user's first logon.
# post-oobe.cmd also runs SFTA for the initial user.
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://github.com/Alex313031/Thorium-Win/releases/download/M138.0.7204.303/thorium_AVX2_mini_installer.exe";
hash = "sha256-43daDPX4N7NbVx1UfmO6KDMKKufhmpeQMO7qTeRggqo=";
};
sfta = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/DanysysTeam/PS-SFTA/master/SFTA.ps1";
hash = "sha256-Prb23uP9jJFgQEIGC51ljwjshdP9ChR2kRnf14vDCFE=";
};
in {
name = "thorium";
cdroms = [ (makeFilesISO { name = "thorium"; files = [ installer sfta ]; }) ];
auditScript = ''
@echo off
echo Installing Thorium browser...
copy D:\thorium_AVX2_mini_installer.exe C:\thorium_installer.exe
start /wait C:\thorium_installer.exe --silent --system-level --do-not-launch-chrome
del /q C:\thorium_installer.exe
echo Waiting for setup.exe to finish...
:wait_loop
tasklist /fi "imagename eq setup.exe" 2>nul | find /i "setup.exe" >nul
if not errorlevel 1 (
timeout /t 5 /nobreak >nul
goto wait_loop
)
echo Setting up Thorium as default browser for all users...
:: Store SFTA in Program Files (survives sysprep as installed program)
mkdir "C:\Program Files\vmix" 2>nul
copy D:\SFTA.ps1 "C:\Program Files\vmix\SFTA.ps1" >nul
:: Register Active Setup: runs at first logon for every new user
reg add "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\vmix-default-browser" /v "(Default)" /t REG_SZ /d "Set default browser" /f >nul
reg add "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\vmix-default-browser" /v "StubPath" /t REG_SZ /d "powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command \". 'C:\\Program Files\\vmix\\SFTA.ps1'; Set-FTA 'ThoriumHTM' '.htm'; Set-FTA 'ThoriumHTM' '.html'; Set-PTA 'ThoriumHTM' 'http'; Set-PTA 'ThoriumHTM' 'https'\"" /f >nul
reg add "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\vmix-default-browser" /v "Version" /t REG_SZ /d "1,0,0,0" /f >nul
'';
}

View file

@ -0,0 +1,19 @@
# Install VLC and register shell handlers for video/audio formats
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://get.videolan.org/vlc/3.0.21/win64/vlc-3.0.21-win64.exe";
hash = "sha256-l0JomlDpbdwE2Azv8EayjaK+79YXvhgWb4xecV7GDFk=";
};
in {
name = "vlc";
cdroms = [ (makeFilesISO { name = "vlc"; files = [ installer ]; }) ];
auditScript = ''
@echo off
echo Installing VLC...
start /wait D:\vlc-3.0.21-win64.exe /S /L=1033
:: delete shortcut on desktop
del /q "C:\Users\Public\Desktop\VLC media player.lnk"
'';
}

View file

@ -0,0 +1,49 @@
# Set default file associations via DefaultAssociations.xml policy.
# Writes XML to C:\Program Files\vmix\ (survives sysprep as installed program).
# Sets Group Policy registry to point at the XML.
{ pkgs, lib, ... }:
{
name = "default-apps";
auditScript = ''
@echo off
set "DA=C:\Program Files\vmix\DefaultAssociations.xml"
mkdir "C:\Program Files\vmix" 2>nul
echo ^<?xml version="1.0" encoding="UTF-8"?^> > "%DA%"
echo ^<DefaultAssociations^> >> "%DA%"
echo ^<Association Identifier=".7z" ProgId="7-Zip.7z" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".zip" ProgId="7-Zip.zip" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".rar" ProgId="7-Zip.rar" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".tar" ProgId="7-Zip.tar" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".gz" ProgId="7-Zip.gz" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".xz" ProgId="7-Zip.xz" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".cab" ProgId="7-Zip.cab" ApplicationName="7-Zip"/^> >> "%DA%"
echo ^<Association Identifier=".mp4" ProgId="VLC.mp4" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".mkv" ProgId="VLC.mkv" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".avi" ProgId="VLC.avi" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".mov" ProgId="VLC.mov" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".wmv" ProgId="VLC.wmv" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".webm" ProgId="VLC.webm" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".mpg" ProgId="VLC.mpg" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".ts" ProgId="VLC.ts" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".mp3" ProgId="VLC.mp3" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".flac" ProgId="VLC.flac" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".wav" ProgId="VLC.wav" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".aac" ProgId="VLC.aac" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".ogg" ProgId="VLC.ogg" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".wma" ProgId="VLC.wma" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".m4a" ProgId="VLC.m4a" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".opus" ProgId="VLC.opus" ApplicationName="VLC"/^> >> "%DA%"
echo ^<Association Identifier=".jpg" ProgId="ImageGlass.jpg" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".jpeg" ProgId="ImageGlass.jpeg" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".png" ProgId="ImageGlass.png" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".gif" ProgId="ImageGlass.gif" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".bmp" ProgId="ImageGlass.bmp" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".webp" ProgId="ImageGlass.webp" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".tif" ProgId="ImageGlass.tif" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".ico" ProgId="ImageGlass.ico" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".svg" ProgId="ImageGlass.svg" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^<Association Identifier=".heic" ProgId="ImageGlass.heic" ApplicationName="ImageGlass"/^> >> "%DA%"
echo ^</DefaultAssociations^> >> "%DA%"
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v DefaultAssociationsConfiguration /t REG_SZ /d "C:\Program Files\vmix\DefaultAssociations.xml" /f
'';
}

View file

@ -0,0 +1,43 @@
# Windows customization templates.
# Templates can provide:
# windowsRegistry — offline registry merge (fast, no boot)
# auditScript — runs in Audit Mode via QEMU boot
# cdroms — ISOs to attach when booting for auditScript
# uploads — files to inject into the image before auditScript
{ pkgs, lib, system, drivers, makeFilesISO, ... }:
let
args = { inherit pkgs lib system drivers makeFilesISO; };
in {
# Essentials (drivers, runtimes, removals, performance)
essentials = {
virtioTools = import ./essentials/virtio-tools.nix args;
removeEdge = import ./essentials/remove-edge.nix args;
removeIE = import ./essentials/remove-ie.nix args;
removeWMP = import ./essentials/remove-wmp.nix args;
removePaint = import ./essentials/remove-paint.nix args;
amdGpuDrivers = import ./essentials/amd-gpu-drivers.nix args;
vcppRuntimes = import ./essentials/vcpp-runtimes.nix args;
bestPerformance = import ./essentials/best-performance.nix args;
clearFileAssociations = import ./essentials/clear-file-associations.nix args;
};
# Applications
apps = {
thorium = import ./apps/thorium.nix args;
edgeWebview = import ./apps/edge-webview.nix args;
sevenZip = import ./apps/7zip.nix args;
vlc = import ./apps/vlc.nix args;
imageGlass = import ./apps/imageglass.nix args;
sandboxie = import ./apps/sandboxie.nix args;
office = import ./apps/office.nix args;
};
# Default file associations policy
defaultApps = import ./default-apps.nix args;
# Generalize (sysprep + OOBE)
generalize = import ./generalize.nix args;
# Offline registry templates
reg = import ./registry args;
}

View file

@ -0,0 +1,11 @@
# Install AMD GPU drivers (silent install via INF from ISO)
{ drivers, makeFilesISO, ... }:
{
name = "amd-gpu";
cdroms = [ (makeFilesISO { name = "amd-gpu-drivers"; files = [ drivers.amd-gpu-zip ]; }) ];
auditScript = ''
@echo off
echo Installing AMD GPU drivers (INF)...
pnputil /add-driver "D:\WT6A_INF\u0413647.inf" /install /subdirs
'';
}

View file

@ -0,0 +1,46 @@
# Best Performance visual effects — set on Administrator profile in Audit Mode.
# Used with generalize's CopyProfile=true: the Administrator's profile
# (with these settings applied) becomes the default profile for new users.
# CopyProfile bypasses SystemParametersInfo defaults during profile creation.
# CopyProfile is the only approach that reliably actually works. Editing NTUSER.dat still reset some parameters
{ ... }:
{
name = "best-perf";
auditScript = ''
@echo off
echo Applying best performance to current profile...
:: Set appearance options to "custom"
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" /v VisualFXSetting /t REG_DWORD /d 3 /f
:: Animate controls, fade/slide menus, fade/slide tooltips,
:: fade out menu items, shadows under mouse, shadows under windows,
:: slide open combo boxes, smooth-scroll list boxes (disabled)
reg add "HKCU\Control Panel\Desktop" /v UserPreferencesMask /t REG_BINARY /d 9012038010000000 /f
:: Animate windows when minimizing and maximizing (disabled)
reg add "HKCU\Control Panel\Desktop\WindowMetrics" /v MinAnimate /t REG_SZ /d "0" /f
:: Animations in the taskbar (disabled)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v TaskbarAnimations /t REG_DWORD /d 0 /f
:: Enable Peek (disabled)
reg add "HKCU\Software\Microsoft\Windows\DWM" /v EnableAeroPeek /t REG_DWORD /d 0 /f
:: Save taskbar thumbnail previews (disabled)
reg add "HKCU\Software\Microsoft\Windows\DWM" /v AlwaysHibernateThumbnails /t REG_DWORD /d 0 /f
:: Show thumbnails instead of icons (disabled)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v IconsOnly /t REG_DWORD /d 1 /f
:: Show translucent selection rectangle (disabled)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v ListviewAlphaSelect /t REG_DWORD /d 0 /f
:: Show window contents while dragging (disabled)
reg add "HKCU\Control Panel\Desktop" /v DragFullWindows /t REG_SZ /d "0" /f
:: Smooth edges of screen fonts (enabled)
reg add "HKCU\Control Panel\Desktop" /v FontSmoothing /t REG_SZ /d "2" /f
reg add "HKCU\Control Panel\Desktop" /v FontSmoothingGamma /t REG_DWORD /d 0 /f
reg add "HKCU\Control Panel\Desktop" /v FontSmoothingOrientation /t REG_DWORD /d 1 /f
reg add "HKCU\Control Panel\Desktop" /v FontSmoothingType /t REG_DWORD /d 2 /f
:: Use drop shadows for icon labels on the desktop (disabled)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v ListviewShadow /t REG_DWORD /d 0 /f
:: Disable transparency effects
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v EnableTransparency /t REG_DWORD /d 0 /f
:: Disable accent color on taskbar and window borders
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v ColorPrevalence /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\DWM" /v ColorPrevalence /t REG_DWORD /d 0 /f
'';
}

View file

@ -0,0 +1,13 @@
# Clear all FileExts UserChoice entries on the Administrator profile.
# In Audit Mode these keys aren't hash-protected yet.
# With CopyProfile=true in generalize, the clean profile (without UserChoice)
# is copied to new users, so HKLM Classes become the effective defaults.
{ ... }:
{
name = "clear-assoc";
auditScript = ''
@echo off
echo Clearing FileExts UserChoice entries...
reg delete "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts" /f 2>nul
'';
}

View file

@ -0,0 +1,50 @@
# Remove Microsoft Edge (both Chromium and built-in LTSC versions)
{ ... }:
{
name = "no-edge";
auditScript = ''
@echo off
:: Remove Chromium Edge using its installer
for /f "delims=" %%i in ('dir /b /ad "C:\Program Files (x86)\Microsoft\Edge\Application" 2^>nul') do (
if exist "C:\Program Files (x86)\Microsoft\Edge\Application\%%i\Installer\setup.exe" (
"C:\Program Files (x86)\Microsoft\Edge\Application\%%i\Installer\setup.exe" --uninstall --system-level --force-uninstall
)
)
:: Remove Edge Update
if exist "C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" (
"C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" /uninstall
)
:: Remove Edge directories
rmdir /s /q "C:\Program Files (x86)\Microsoft\Edge" 2>nul
rmdir /s /q "C:\Program Files (x86)\Microsoft\EdgeUpdate" 2>nul
rmdir /s /q "C:\Program Files (x86)\Microsoft\EdgeCore" 2>nul
:: Remove Edge and DevToolsClient SystemApps
for /d %%d in ("C:\Windows\SystemApps\Microsoft.MicrosoftEdge_*") do (
takeown /f "%%d" /r /d y >nul 2>nul
icacls "%%d" /grant Administrators:F /t >nul 2>nul
rmdir /s /q "%%d" 2>nul
)
for /d %%d in ("C:\Windows\SystemApps\Microsoft.MicrosoftEdgeDevToolsClient_*") do (
takeown /f "%%d" /r /d y >nul 2>nul
icacls "%%d" /grant Administrators:F /t >nul 2>nul
rmdir /s /q "%%d" 2>nul
)
:: Remove Edge AppxPackage for all users (audit mode)
powershell -Command "Get-AppxPackage -AllUsers *MicrosoftEdge* | Remove-AppxPackage -AllUsers -EA SilentlyContinue"
:: Remove Edge shortcuts
del /q "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk" 2>nul
del /q "%PUBLIC%\Desktop\Microsoft Edge.lnk" 2>nul
del /q "%APPDATA%\Microsoft\Internet Explorer\Quick Launch\Microsoft Edge.lnk" 2>nul
del /q "%APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Microsoft Edge.lnk" 2>nul
:: Remove Edge Update scheduled tasks
schtasks /delete /tn "\MicrosoftEdgeUpdateTaskMachineCore" /f 2>nul
schtasks /delete /tn "\MicrosoftEdgeUpdateTaskMachineUA" /f 2>nul
reg add "HKLM\SOFTWARE\Microsoft\EdgeUpdate" /v DoNotUpdateToEdgeWithChromium /t REG_DWORD /d 1 /f
'';
}

View file

@ -0,0 +1,12 @@
# Remove Internet Explorer
{ ... }:
{
name = "no-ie";
auditScript = ''
@echo off
echo Removing Internet Explorer...
dism /online /Remove-Capability /CapabilityName:Browser.InternetExplorer~~~~0.0.11.0 /NoRestart 2>nul
:: Disable IE feature if still present
dism /online /Disable-Feature /FeatureName:Internet-Explorer-Optional-amd64 /NoRestart 2>nul
'';
}

View file

@ -0,0 +1,20 @@
# Remove Microsoft Paint
{ ... }:
{
name = "no-paint";
auditScript = ''
@echo off
echo Removing Microsoft Paint...
:: Take ownership and delete mspaint.exe
takeown /f "C:\Windows\System32\mspaint.exe" >nul 2>nul
icacls "C:\Windows\System32\mspaint.exe" /grant Administrators:F >nul 2>nul
del /f "C:\Windows\System32\mspaint.exe" 2>nul
:: Remove Paint optional feature
dism /online /Remove-Capability /CapabilityName:Microsoft.Windows.MSPaint~~~~0.0.1.0 /NoRestart 2>nul
:: Remove Paint shortcuts
del /q "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Accessories\Paint.lnk" 2>nul
:: Remove PBrush class registration
reg delete "HKLM\SOFTWARE\Classes\PBrush" /f 2>nul
reg delete "HKLM\SOFTWARE\Classes\pbrush" /f 2>nul
'';
}

View file

@ -0,0 +1,11 @@
# Remove Windows Media Player
{ ... }:
{
name = "no-wmp";
auditScript = ''
@echo off
echo Removing Windows Media Player...
dism /online /Disable-Feature /FeatureName:WindowsMediaPlayer /NoRestart 2>nul
dism /online /Remove-Capability /CapabilityName:Microsoft.Windows.MediaPlayer~~~~0.0.12.0 /NoRestart 2>nul
'';
}

View file

@ -0,0 +1,18 @@
# Install all Visual C++ Redistributable runtimes (2005-2022, x86+x64)
{ pkgs, makeFilesISO, ... }:
let
installer = pkgs.fetchurl {
url = "https://github.com/abbodi1406/vcredist/releases/download/v0.103.0/VisualCppRedist_AIO_x86_x64.exe";
hash = "sha256-PBiORlG8wH3yvbBtaVhRWHl7G6+5FVewkhdiFijNWyM=";
};
in {
name = "vcpp";
cdroms = [ (makeFilesISO { name = "vcpp-runtimes"; files = [ installer ]; }) ];
auditScript = ''
@echo off
echo Installing Visual C++ Redistributable runtimes...
copy D:\VisualCppRedist_AIO_x86_x64.exe C:\vcpp-setup.exe
start /wait C:\vcpp-setup.exe /ai /gm2
del /q C:\vcpp-setup.exe
'';
}

View file

@ -0,0 +1,18 @@
# Install VirtIO guest tools (QEMU agent + SPICE vdagent)
{ drivers, ... }:
{
name = "virtio";
cdroms = [ drivers.virtio-iso ];
auditScript = ''
@echo off
:: VirtIO ISO is the first (and only) CD drive letter D:
if exist D:\cert\virtio_win_cert.cer (
certutil -addstore TrustedPublisher D:\cert\virtio_win_cert.cer
)
if exist D:\virtio-win-guest-tools.exe (
D:\virtio-win-guest-tools.exe /install /passive /norestart
) else if exist D:\guest-agent\qemu-ga-x86_64.msi (
msiexec /i D:\guest-agent\qemu-ga-x86_64.msi /qn /norestart
)
'';
}

View file

@ -0,0 +1,168 @@
# Generalize image via sysprep + OOBE in two phases.
# Phase 1 (sysprep): runs sysprep /generalize /oobe /shutdown in Audit Mode
# Phase 2 (oobe): boots through OOBE, creates user, activates Windows, shuts down
# Between phases, NTUSER.DAT can be modified offline.
# Usage: (templates.generalize { username = "User"; password = ""; })
{ pkgs, lib, makeFilesISO, ... }:
let
masScript = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/massgravel/Microsoft-Activation-Scripts/97602941e5724316aa31b6ca1da5c70245d234d5/MAS/All-In-One-Version-KL/MAS_AIO.cmd";
hash = "sha256-1hl89jQf2p+RtE3ue/+cZevSoz7Ra3p3u350aE/Xy74=";
};
in
{
username ? "User",
password ? "",
autoLogon ? true,
hostname ? "WIN-VM",
locale ? "en-US",
timezone ? "UTC",
# Desktop background solid color as hex string (e.g. "8e8cd8")
bgColor ? null,
}: let
# Convert "8e8cd8" hex to "142 140 216" decimal RGB for Windows registry
hexToRgbStr = hex: let
hexChars = lib.stringToCharacters hex;
hexToDec = h: let
c = lib.toLower h;
m = { "0"=0; "1"=1; "2"=2; "3"=3; "4"=4; "5"=5; "6"=6; "7"=7; "8"=8; "9"=9; "a"=10; "b"=11; "c"=12; "d"=13; "e"=14; "f"=15; };
in m.${c};
r = hexToDec (builtins.elemAt hexChars 0) * 16 + hexToDec (builtins.elemAt hexChars 1);
g = hexToDec (builtins.elemAt hexChars 2) * 16 + hexToDec (builtins.elemAt hexChars 3);
b = hexToDec (builtins.elemAt hexChars 4) * 16 + hexToDec (builtins.elemAt hexChars 5);
in "${toString r} ${toString g} ${toString b}";
stripHash = s: lib.removePrefix "#" s;
bgRgb = if bgColor != null then hexToRgbStr (stripHash bgColor) else null;
# Post-OOBE script: runs as the created user via FirstLogonCommands.
postOobeScript = pkgs.writeText "post-oobe.cmd" ''
@echo off
${lib.optionalString (!autoLogon) ''
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /f 2>nul
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /f 2>nul
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /f 2>nul
''}
${lib.optionalString (bgColor != null) ''
:: Set solid background color
reg add "HKCU\Control Panel\Desktop" /v WallPaper /t REG_SZ /d "" /f
reg add "HKCU\Control Panel\Colors" /v Background /t REG_SZ /d "${bgRgb}" /f
reg add "HKCU\Control Panel\Desktop" /v WallpaperStyle /t REG_SZ /d "0" /f
''}
:: Remove Edge AppxPackage for current user (runs in user context during OOBE)
:: The app is already removed on one of the templates but a ghost appx entry remains that can only be deleted at the user level
powershell -Command "Get-AppxPackage *MicrosoftEdge* | Remove-AppxPackage -ErrorAction SilentlyContinue"
powershell -Command "Get-AppxPackage *MicrosoftEdgeDevToolsClient* | Remove-AppxPackage -ErrorAction SilentlyContinue"
:: Activate Windows using HWID method
if exist C:\MAS_AIO.cmd (
echo. | call C:\MAS_AIO.cmd /HWID
)
:: Activate Office using Ohook method (if Office is installed)
if exist "C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE" (
if exist C:\MAS_AIO.cmd (
echo. | call C:\MAS_AIO.cmd /Ohook
)
)
del /q C:\MAS_AIO.cmd 2>nul
:: Clean up
del /q C:\oobe-unattend.xml 2>nul
del /q C:\vmix-audit-script.cmd 2>nul
del /q C:\vmix-audit-wrapper.cmd 2>nul
shutdown /s /t 5 /c "vmix generalize complete"
del /q C:\post-oobe.cmd 2>nul
'';
oobeXml = pkgs.writeText "oobe-unattend.xml" ''
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<!-- Copy Administrator profile to default (preserves Audit Mode customizations) -->
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<CopyProfile>true</CopyProfile>
<Themes>
<WindowColor>Automatic</WindowColor>
</Themes>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<InputLocale>${locale}</InputLocale>
<SystemLocale>${locale}</SystemLocale>
<UILanguage>${locale}</UILanguage>
<UserLocale>${locale}</UserLocale>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Work</NetworkLocation>
<SkipMachineOOBE>true</SkipMachineOOBE>
<SkipUserOOBE>true</SkipUserOOBE>
<ProtectYourPC>3</ProtectYourPC>
</OOBE>
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>${password}</Value>
</Password>
<Group>Administrators</Group>
<Name>${username}</Name>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<AutoLogon>
<Password>
<Value>${password}</Value>
</Password>
<Enabled>true</Enabled>
<Username>${username}</Username>
</AutoLogon>
<ComputerName>${hostname}</ComputerName>
<TimeZone>${timezone}</TimeZone>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>C:\post-oobe.cmd</CommandLine>
<RequiresUserInput>false</RequiresUserInput>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>
'';
in {
name = "generalize";
uploads = [
{ source = oobeXml; dest = "/oobe-unattend.xml"; }
{ source = postOobeScript; dest = "/post-oobe.cmd"; }
{ source = masScript; dest = "/MAS_AIO.cmd"; }
];
# Sysprep reboots into OOBE within the same QEMU session
auditScript = ''
@echo off
C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /reboot /quiet /unattend:C:\oobe-unattend.xml
'';
}
# :: Enable RDP (sysprep resets offline registry changes)
# reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
# reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f
# netsh advfirewall firewall add rule name="RDP" dir=in protocol=tcp localport=3389 action=allow
# :: Start and enable the RDP service
# sc config TermService start= auto
# net start TermService

View file

@ -0,0 +1,10 @@
# Disable Copilot, Recall, and AI data analysis
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot]
"TurnOffWindowsCopilot"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsAI]
"AllowRecallEnablement"=dword:00000000
"DisableAIDataAnalysis"=dword:00000001
''

View file

@ -0,0 +1,50 @@
# Disable consumer features, suggested apps, push-to-install, widgets, Cortana
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent]
"DisableWindowsConsumerFeatures"=dword:00000001
"DisableTailoredExperiencesWithDiagnosticData"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall]
"DisablePushToInstall"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds]
"EnableFeeds"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Dsh]
"AllowNewsAndInterests"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search]
"AllowCortana"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer]
"DisableSearchBoxSuggestions"=dword:00000001
"HideSCAMeetNow"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR]
"AllowGameDVR"=dword:00000000
[HKEY_LOCAL_MACHINE\System\GameConfigStore]
"GameDVR_Enabled"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Maps]
"AutoDownloadAndUpdateMapData"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MapsBroker]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\XblAuthManager]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\XblGameSave]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\XboxNetApiSvc]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\WMPNetworkSvc]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\RetailDemo]
"Start"=dword:00000004
''

View file

@ -0,0 +1,63 @@
# Offline registry customization templates.
# Each file returns raw registry entries (no header).
# Templates are composed into bundles via mkReg which adds the .reg header.
{ ... }:
let
regHeader = "Windows Registry Editor Version 5.00";
mkReg = entries: ''
${regHeader}
${entries}
'';
rdpEntries = import ./rdp.nix;
telemetryEntries = import ./telemetry.nix;
errorReportingEntries = import ./error-reporting.nix;
defenderEntries = import ./defender.nix;
updatesEntries = import ./updates.nix;
smartScreenEntries = import ./smart-screen.nix;
hibernationEntries = import ./hibernation.nix;
systemRestoreEntries = import ./system-restore.nix;
networkEntries = import ./insecure-samba.nix;
privacyEntries = import ./privacy.nix;
aiEntries = import ./ai.nix;
consumerEntries = import ./consumer.nix;
performanceEntries = import ./performance.nix;
disableUcpdEntries = import ./disable-ucpd.nix;
in rec {
# === Individual templates ===
disableTelemetry = { name = "no-telemetry"; windowsRegistry = mkReg telemetryEntries; };
disableErrorReporting = { name = "no-wer"; windowsRegistry = mkReg errorReportingEntries; };
disableDefender = { name = "no-defender"; windowsRegistry = mkReg defenderEntries; };
disableUpdates = { name = "no-updates"; windowsRegistry = mkReg updatesEntries; };
disableSmartScreen = { name = "no-smartscreen"; windowsRegistry = mkReg smartScreenEntries; };
disableHibernation = { name = "no-hibernate"; windowsRegistry = mkReg hibernationEntries; };
disableSystemRestore = { name = "no-restore"; windowsRegistry = mkReg systemRestoreEntries; };
networkTweaks = { name = "network"; windowsRegistry = mkReg networkEntries; };
disablePrivacyTracking = { name = "no-tracking"; windowsRegistry = mkReg privacyEntries; };
disableAI = { name = "no-ai"; windowsRegistry = mkReg aiEntries; };
disableConsumerFeatures = { name = "no-consumer"; windowsRegistry = mkReg consumerEntries; };
performanceTweaks = { name = "performance"; windowsRegistry = mkReg performanceEntries; };
disableUCPD = { name = "no-ucpd"; windowsRegistry = mkReg disableUcpdEntries; };
# === Convenience bundles ==
# Hardened: comprehensive debloat for lab VMs
hardened = {
name = "hardened";
windowsRegistry = mkReg (
telemetryEntries
+ errorReportingEntries
+ defenderEntries
+ updatesEntries
+ smartScreenEntries
+ hibernationEntries
+ systemRestoreEntries
+ networkEntries
+ privacyEntries
+ aiEntries
+ consumerEntries
+ performanceEntries
);
};
}

View file

@ -0,0 +1,11 @@
# Disable Windows Defender
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender]
"DisableAntiSpyware"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection]
"DisableRealtimeMonitoring"=dword:00000001
''

View file

@ -0,0 +1,10 @@
# Disable User Choice Protection Driver (UCPD) on Win11
# This allows programmatic changes to file/URL associations via UserChoice
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System]
"EnableUCPD"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\UCPD]
"Start"=dword:00000004
''

View file

@ -0,0 +1,9 @@
# Disable Windows Error Reporting
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]
"Disabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\WerSvc]
"Start"=dword:00000004
''

View file

@ -0,0 +1,9 @@
# Disable hibernation and fast startup (avoids disk corruption with snapshots)
''
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Power]
"HiberbootEnabled"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Power]
"HibernateEnabled"=dword:00000000
''

View file

@ -0,0 +1,12 @@
# Suppress network discovery popup and allow insecure guest logons for SMB
''
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\NewNetworkWindowOff]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation]
"AllowInsecureGuestAuth"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\LanmanWorkstation\Parameters]
"AllowInsecureGuestAuth"=dword:00000001
"RequireSecuritySignature"=dword:00000000
''

View file

@ -0,0 +1,34 @@
# VM performance optimizations: disable power throttling, SysMain, lock screen, autorun
''
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Power]
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Power\PowerThrottling]
"PowerThrottlingOff"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control]
"SvcHostSplitThresholdInKB"=dword:00400000
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Remote Assistance]
"fAllowToGetHelp"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization]
"NoLockScreen"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer]
"NoDriveTypeAutoRun"=dword:000000ff
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\FileHistory]
"Disabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SysMain]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\RemoteRegistry]
"Start"=dword:00000004
''

View file

@ -0,0 +1,44 @@
# Disable activity tracking, advertising ID, location, and input data collection
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System]
"EnableActivityFeed"=dword:00000000
"PublishUserActivities"=dword:00000000
"UploadUserActivities"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo]
"DisabledByGroupPolicy"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Privacy]
"TailoredExperiencesWithDiagnosticDataEnabled"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors]
"DisableLocation"=dword:00000001
"DisableLocationScripting"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\lfsvc]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports]
"PreventHandwritingErrorReports"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC]
"PreventHandwritingDataSharing"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\InputPersonalization]
"RestrictImplicitTextCollection"=dword:00000001
"RestrictImplicitInkCollection"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace]
"AllowWindowsInkWorkspace"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Settings]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy]
"HasAccepted"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy]
"LetAppsRunInBackground"=dword:00000002
''

View file

@ -0,0 +1,6 @@
# Disable SmartScreen
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System]
"EnableSmartScreen"=dword:00000000
''

View file

@ -0,0 +1,8 @@
# Disable system restore
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore]
"DisableSR"=dword:00000001
''

View file

@ -0,0 +1,15 @@
# Disable telemetry, diagnostics tracking, and feedback
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection]
"AllowTelemetry"=dword:00000000
"DoNotShowFeedbackNotifications"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\DiagTrack]
"Start"=dword:00000004
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\dmwappushservice]
"Start"=dword:00000004
''

View file

@ -0,0 +1,21 @@
# Disable automatic Windows updates, driver searching, and update-related annoyances
''
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
"NoAutoUpdate"=dword:00000001
"NoAutoRebootWithLoggedOnUsers"=dword:00000001
"AUPowerManagement"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config]
"DODownloadMode"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching]
"SearchOrderConfig"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\DoSvc]
"Start"=dword:00000004
''

View file

@ -0,0 +1,12 @@
{ pkgs, lib, system, windows, ... }:
let
upstreamISOsJSON = lib.importJSON ./upstream.json;
fetchUpstream = name: src:
if (src.type or "") == "fetchgit"
then pkgs.fetchgit { inherit (src) url rev hash fetchLFS; }
else pkgs.fetchurl { inherit (src) url sha256; };
upstreamISOs = lib.mapAttrs fetchUpstream upstreamISOsJSON.${system};
images = (import ./images.nix) { inherit pkgs lib system windows upstreamISOs; };
in images

View file

@ -0,0 +1,34 @@
# Pre-built Win10 LTSC 2021 images from upstream ISO
# Pipeline: makeImage (Audit Mode) → essentials → apps → registry → generalize
{ pkgs, lib, system, windows, upstreamISOs, ... }:
with windows;
{
ltsc = rec {
upstream = makeImage {
name = "win10-ltsc-2021";
upstreamISO = upstreamISOs.win10-ltsc-2021;
productKey = "M7XTQ-FN8P6-TTKYV-9D4CC-J462D";
};
basic = customizeImageFold upstream (with templates; [
essentials.virtioTools
essentials.removeIE
essentials.removeWMP
essentials.removeEdge
essentials.vcppRuntimes
essentials.bestPerformance
reg.hardened
apps.edgeWebview
apps.thorium
]);
withApps = customizeImageFold basic (with templates; [
apps.sandboxie
apps.sevenZip
apps.vlc
apps.imageGlass
apps.office
]);
withAMDGPU = customizeImage basic templates.essentials.amdGpuDrivers;
};
}

View file

@ -0,0 +1,11 @@
{
"x86_64-linux": {
"win10-ltsc-2021": {
"type": "fetchgit",
"url": "https://git.sagar.ch/dotfiles/win10ltsc2021-official.iso.git",
"rev": "9bb55c21ceaf224504c4240677e808b3ec91a610",
"hash": "sha256-AeGnOnkToOSiD5iRblLKaRmR8qBUkCaGp8F8KkGlVIA=",
"fetchLFS": true
}
}
}

View file

@ -0,0 +1,12 @@
{ pkgs, lib, system, windows, ... }:
let
upstreamISOsJSON = lib.importJSON ./upstream.json;
fetchUpstream = name: src:
if (src.type or "") == "fetchgit"
then pkgs.fetchgit { inherit (src) url rev hash fetchLFS; }
else pkgs.fetchurl { inherit (src) url sha256; };
upstreamISOs = lib.mapAttrs fetchUpstream upstreamISOsJSON.${system};
images = (import ./images.nix) { inherit pkgs lib system windows upstreamISOs; };
in images

View file

@ -0,0 +1,38 @@
# Pre-built Win11 LTSC 2024 images from upstream ISO
# Pipeline: makeImage (Audit Mode) → essentials → apps → registry
{ pkgs, lib, system, windows, upstreamISOs, ... }:
with windows;
{
ltsc = rec {
upstream = makeImage {
name = "win11-ltsc-2024";
upstreamISO = upstreamISOs.win11-ltsc-2024;
productKey = "M7XTQ-FN8P6-TTKYV-9D4CC-J462D";
bypassRequirements = true;
windowsVersionForVirtioDrivers = "w11";
};
basic = customizeImageFold upstream (with templates; [
essentials.virtioTools
essentials.removeIE
essentials.removeWMP
essentials.removeEdge
essentials.vcppRuntimes
essentials.bestPerformance
reg.hardened
reg.disableUCPD
apps.edgeWebview
apps.thorium
]);
withApps = customizeImageFold basic (with templates; [
apps.sandboxie
apps.sevenZip
apps.vlc
apps.imageGlass
apps.office
]);
withAMDGPU = customizeImage basic templates.essentials.amdGpuDrivers;
};
}

View file

@ -0,0 +1,11 @@
{
"x86_64-linux": {
"win11-ltsc-2024": {
"type": "fetchgit",
"url": "https://git.sagar.ch/dotfiles/win11ltsc2024-official.iso.git",
"rev": "d4a749719eb593884d1ba9835b96104e1f06290b",
"hash": "sha256-AWp4SPVfpHT7jAczaq24bgrYUZy4sLByRHMhGbPFBwg=",
"fetchLFS": true
}
}
}