318 lines
10 KiB
Markdown
318 lines
10 KiB
Markdown
I really love my nixos config. I install it on all my linux boxes and it makes it dead simple to configure them exactly how I want them. I want a taste of that experience for my windows boxes. I am trying to evaluate different approaches. Can you help me evaluate a few different approaches?
|
|
|
|
- I do not like python so ansible sounds not great but I would like to know what all features they have configured out of the box
|
|
- I really like typescript and projects like sst and pulumi. They seem to have a lot of overlap with what I want to do, given they have a `diff` and `apply` command.
|
|
|
|
I cloned my nixos-config to docs\nixos-config
|
|
|
|
and I cloned several of the tools I am evaluating to docs\cloned-repos-as-docs
|
|
|
|
I think it would be very useful for you to grep through all of that and get an understanding of what each tool can do what.
|
|
|
|
The main things I want:
|
|
|
|
- Be able to declare what programs are installed on the box
|
|
- Declare that wsl2 be enabled
|
|
- Declare that there should be a specific wsl distro installed.
|
|
- Declare the `"C:\Users\ethan\.wslconfig"` settings
|
|
- Declare the windows theme (dark)
|
|
- Have the system be modular so I can enable/disable some programs for different hosts.
|
|
|
|
# WinOS Config
|
|
|
|
A declarative configuration system for Windows 11, inspired by NixOS. The goal is to describe the complete state of a Windows machine in version-controlled configuration files.
|
|
|
|
## Project Goals
|
|
|
|
- **Declarative**: Define _what_ the system should look like, not _how_ to get there
|
|
- **Reproducible**: Apply the same config to multiple machines with identical results
|
|
- **Version controlled**: Track all configuration changes in git
|
|
- **Modular**: Compose configurations for different hosts (gaming-pc, work-laptop, htpc)
|
|
|
|
## Current Status: Research & Planning
|
|
|
|
This project is in the early research phase. We are evaluating technologies and documenting what is/isn't possible on Windows.
|
|
|
|
---
|
|
|
|
## Technology Options Under Consideration
|
|
|
|
### 1. DSC v3 (Microsoft Desired State Configuration)
|
|
|
|
**Pros:**
|
|
- Actively maintained (v3.1.2 released Nov 2025, v3.2.0-preview.8 in progress)
|
|
- Complete rewrite in Rust - no PowerShell dependency
|
|
- Cross-platform (Windows, macOS, Linux)
|
|
- JSON/YAML configuration files
|
|
- JSON Schema available for validation/type generation
|
|
- Resources can be written in any language
|
|
- Adapters for legacy PowerShell DSC resources
|
|
- WinGet integration via `microsoft/winget-dsc`
|
|
|
|
**Cons:**
|
|
- No official TypeScript/Python/Go SDKs or language bindings
|
|
- Configuration is YAML/JSON (not a real programming language)
|
|
- **Does NOT auto-uninstall packages when removed from config**
|
|
- Limited built-in resources - most functionality requires adapters
|
|
- No native WSL configuration resource
|
|
- No Start Menu/taskbar pin configuration
|
|
|
|
**Resources:**
|
|
- Repo: https://github.com/PowerShell/DSC
|
|
- Docs: https://learn.microsoft.com/en-us/powershell/dsc/overview
|
|
- Schemas: https://github.com/PowerShell/DSC/tree/main/schemas
|
|
- WinGet DSC: https://github.com/microsoft/winget-dsc
|
|
- Samples: https://aka.ms/dsc.yaml
|
|
|
|
### 2. Ansible
|
|
|
|
**Pros:**
|
|
- Mature ecosystem with large community
|
|
- YAML-based with inventory system for multi-host
|
|
- Idempotent task execution
|
|
- Good Windows support via WinRM
|
|
|
|
**Cons:**
|
|
- Requires control node (Linux/WSL) to run FROM
|
|
- YAML configuration (not a real language)
|
|
- **Does NOT auto-uninstall packages when removed from config** - requires explicit `state: absent`
|
|
- Windows modules less mature than Linux
|
|
|
|
### 3. PowerShell DSC v2 (Legacy)
|
|
|
|
**Pros:**
|
|
- Full PowerShell language features
|
|
- Native Windows integration
|
|
- Can compose configurations programmatically
|
|
|
|
**Cons:**
|
|
- Being superseded by DSC v3
|
|
- MOF-based, more complex
|
|
- **Does NOT auto-uninstall when removed from config**
|
|
|
|
### 4. Custom TypeScript Tooling
|
|
|
|
**Pros:**
|
|
- Full language features (types, functions, loops, conditionals)
|
|
- Can generate DSC v3 YAML from TypeScript
|
|
- Type safety via JSON Schema → TypeScript generation
|
|
- Familiar tooling (Bun, npm ecosystem)
|
|
|
|
**Cons:**
|
|
- Must build/maintain the tooling ourselves
|
|
- Thin wrapper around DSC v3 CLI
|
|
|
|
### 5. WinGet Configuration (standalone)
|
|
|
|
**Pros:**
|
|
- Native Windows, simple YAML
|
|
- Built on DSC v3 under the hood
|
|
- `winget configure` command
|
|
|
|
**Cons:**
|
|
- Single file per configuration (limited modularity)
|
|
- **Does NOT auto-uninstall when removed from config**
|
|
|
|
---
|
|
|
|
## The Uninstall Problem
|
|
|
|
### NixOS Behavior (What We Want)
|
|
In NixOS, removing a package from `configuration.nix` and running `nixos-rebuild switch` will:
|
|
1. Build a new system profile without that package
|
|
2. Switch to the new profile
|
|
3. The package is no longer available
|
|
|
|
### Windows Reality (What We Get)
|
|
**No Windows configuration tool provides true "remove on deletion" behavior.**
|
|
|
|
| Tool | Behavior When Package Removed From Config |
|
|
|------|-------------------------------------------|
|
|
| DSC v3 | Stops managing it - package remains installed |
|
|
| Ansible | Nothing happens - requires explicit `state: absent` |
|
|
| WinGet Config | Nothing happens - package remains installed |
|
|
| Chocolatey DSC | Nothing happens - package remains installed |
|
|
|
|
### Workarounds
|
|
|
|
1. **Explicit "absent" lists**: Maintain a separate list of packages that should NOT be present
|
|
```yaml
|
|
packages_present:
|
|
- Google.Chrome
|
|
- Git.Git
|
|
|
|
packages_absent:
|
|
- Microsoft.Edge # Explicitly remove
|
|
```
|
|
|
|
2. **State diffing**: Build tooling that compares current state vs desired state and generates removal tasks
|
|
|
|
3. **Full reset approach**: Periodically wipe and reapply (not practical for daily use)
|
|
|
|
---
|
|
|
|
## What Can Be Configured
|
|
|
|
### Fully Supported
|
|
|
|
| Category | Method | Notes |
|
|
|----------|--------|-------|
|
|
| **Package Installation** | WinGet DSC | Searches winget-pkgs repository |
|
|
| **Registry Settings** | `Microsoft.Windows/Registry` | Theme, Explorer options, etc. |
|
|
| **Environment Variables** | PSDscResources adapter | System and user variables |
|
|
| **Windows Services** | PSDscResources adapter | Start/stop, startup type |
|
|
| **Windows Features** | PSDscResources adapter | Enable/disable optional features |
|
|
|
|
### Partially Supported
|
|
|
|
| Category | Method | Limitations |
|
|
|----------|--------|-------------|
|
|
| **WSL Enable** | WindowsOptionalFeature | Works via adapter |
|
|
| **WSL Distro Install** | WinGet | Install only, no config |
|
|
| **File Creation** | Script resource | Not declarative, imperative script |
|
|
|
|
### Not Supported (Manual/Script Required)
|
|
|
|
| Category | Why |
|
|
|----------|-----|
|
|
| **`.wslconfig` file** | No file content resource in DSC v3 |
|
|
| **Start Menu Layout** | Complex binary format, export/import only |
|
|
| **Taskbar Pinned Apps** | Complex, no resource exists |
|
|
| **Default Browser** | Requires user interaction |
|
|
| **File Associations** | Registry-based but complex |
|
|
| **Microsoft Account Sync** | Cloud-based, not local config |
|
|
|
|
---
|
|
|
|
## Package Availability (WinGet Repository)
|
|
|
|
WinGet uses the community-maintained [winget-pkgs](https://github.com/microsoft/winget-pkgs) repository. You can search at https://winget.run
|
|
|
|
### Common Developer Tools
|
|
| App | WinGet ID | Available |
|
|
|-----|-----------|-----------|
|
|
| Chrome | `Google.Chrome` | Yes |
|
|
| Firefox | `Mozilla.Firefox` | Yes |
|
|
| Cursor | `Anysphere.Cursor` | Yes |
|
|
| VS Code | `Microsoft.VisualStudioCode` | Yes |
|
|
| Git | `Git.Git` | Yes |
|
|
| Bun | `Oven-sh.Bun` | Yes |
|
|
| Node.js | `OpenJS.NodeJS` | Yes |
|
|
| Python | `Python.Python.3.12` | Yes |
|
|
| Rust | `Rustlang.Rust.MSVC` | Yes |
|
|
|
|
### Entertainment
|
|
| App | WinGet ID | Available |
|
|
|-----|-----------|-----------|
|
|
| Spotify | `Spotify.Spotify` | Yes |
|
|
| Discord | `Discord.Discord` | Yes |
|
|
| Steam | `Valve.Steam` | Yes |
|
|
| Epic Games | `EpicGames.EpicGamesLauncher` | Yes |
|
|
|
|
### Utilities
|
|
| App | WinGet ID | Available |
|
|
|-----|-----------|-----------|
|
|
| 7-Zip | `7zip.7zip` | Yes |
|
|
| PowerToys | `Microsoft.PowerToys` | Yes |
|
|
| Windows Terminal | `Microsoft.WindowsTerminal` | Yes |
|
|
| WinRAR | `RARLab.WinRAR` | Yes |
|
|
|
|
---
|
|
|
|
## Registry Paths for Common Settings
|
|
|
|
### Theme & Appearance
|
|
```
|
|
# Dark mode (apps)
|
|
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize
|
|
AppsUseLightTheme = 0 (dark) | 1 (light)
|
|
|
|
# Dark mode (system)
|
|
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize
|
|
SystemUsesLightTheme = 0 (dark) | 1 (light)
|
|
|
|
# Taskbar alignment (Windows 11)
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
|
|
TaskbarAl = 0 (left) | 1 (center)
|
|
|
|
# Accent color on title bars
|
|
HKCU\SOFTWARE\Microsoft\Windows\DWM
|
|
ColorPrevalence = 0 (off) | 1 (on)
|
|
```
|
|
|
|
### Explorer Settings
|
|
```
|
|
# Show file extensions
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
|
|
HideFileExt = 0 (show) | 1 (hide)
|
|
|
|
# Show hidden files
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
|
|
Hidden = 1 (show) | 2 (hide)
|
|
|
|
# Show full path in title bar
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
|
|
FullPath = 1 (show) | 0 (hide)
|
|
```
|
|
|
|
### Privacy & Telemetry
|
|
```
|
|
# Disable Cortana
|
|
HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search
|
|
AllowCortana = 0 (disabled) | 1 (enabled)
|
|
|
|
# Telemetry level (requires admin)
|
|
HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection
|
|
AllowTelemetry = 0 (security) | 1 (basic) | 2 (enhanced) | 3 (full)
|
|
```
|
|
|
|
---
|
|
|
|
## DSC v3 JSON Schema (For TypeScript Generation)
|
|
|
|
DSC v3 publishes JSON schemas that can be used to generate TypeScript types:
|
|
|
|
```bash
|
|
# Download bundled schema
|
|
curl -o schemas/dsc-config.schema.json \
|
|
https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/config/document.json
|
|
|
|
# Generate TypeScript types
|
|
bunx json-schema-to-typescript schemas/dsc-config.schema.json > src/types/dsc-config.d.ts
|
|
```
|
|
|
|
---
|
|
|
|
---
|
|
|
|
## What This Project Will NOT Track
|
|
|
|
Some things are better left out of declarative config:
|
|
|
|
| Category | Reason |
|
|
|----------|--------|
|
|
| **User documents/files** | Use cloud sync (OneDrive, git) |
|
|
| **Browser bookmarks/extensions** | Use browser sync |
|
|
| **Application-specific settings** | Often stored in AppData, use app's sync |
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. [ ] Decide on primary technology (DSC v3 vs custom TypeScript wrapper)
|
|
2. [ ] Set up JSON schema → TypeScript type generation
|
|
3. [ ] Create base configuration module
|
|
4. [ ] Create first host configuration (gaming-pc)
|
|
5. [ ] Document the "absent packages" pattern for uninstalls
|
|
6. [ ] Test on fresh Windows 11 VM
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [NixOS Config (inspiration)](https://github.com/ethan/nixos-config)
|
|
- [DSC v3 Repository](https://github.com/PowerShell/DSC)
|
|
- [WinGet DSC Resources](https://github.com/microsoft/winget-dsc)
|
|
- [WinGet Package Search](https://winget.run)
|
|
- [DSC v3 Documentation](https://learn.microsoft.com/en-us/powershell/dsc/overview)
|