--- - name: Enable required Windows features for WSL tags: [packages, services, wsl] ansible.windows.win_optional_feature: name: - Microsoft-Windows-Subsystem-Linux - VirtualMachinePlatform state: present include_parent: true - name: Gather Windows host version details tags: [packages] ansible.windows.win_powershell: script: | $os = Get-ComputerInfo $Ansible.Result = @{ product_name = $os.WindowsProductName version = $os.WindowsVersion build_number = [int]$os.OsBuildNumber is_windows_11 = $os.WindowsProductName -like 'Windows 11*' is_windows_10 = $os.WindowsProductName -like 'Windows 10*' } $Ansible.Changed = $false register: windows_host_version_state - name: Enable dark mode for Windows apps tags: [packages] ansible.windows.win_regedit: path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize name: AppsUseLightTheme data: 0 type: dword register: windows_apps_dark_mode_state when: windows_enable_dark_theme | default(false) - name: Enable dark mode for Windows system surfaces tags: [packages] ansible.windows.win_regedit: path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize name: SystemUsesLightTheme data: 0 type: dword register: windows_system_dark_mode_state when: windows_enable_dark_theme | default(false) - name: Hide Windows taskbar search box tags: [packages] ansible.windows.win_regedit: path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Search name: SearchboxTaskbarMode data: 0 type: dword register: windows_taskbar_search_state when: windows_hide_taskbar_search | default(false) - name: Hide Windows 11 taskbar widgets tags: [packages] ansible.windows.win_regedit: path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced name: TaskbarDa data: 0 type: dword register: windows_11_widgets_state when: - windows_hide_taskbar_widgets | default(false) - windows_host_version_state.result.is_windows_11 | default(false) - name: Hide Windows 10 news and interests taskbar widget tags: [packages] ansible.windows.win_regedit: path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Feeds name: ShellFeedsTaskbarViewMode data: 2 type: dword register: windows_10_widgets_state when: - windows_hide_taskbar_widgets | default(false) - windows_host_version_state.result.is_windows_10 | default(false) - name: Note when Windows shell settings may require sign out tags: [packages] ansible.builtin.debug: msg: >- Windows shell appearance settings changed. Sign out and back in, or restart explorer.exe, if taskbar or theme updates do not appear immediately. changed_when: false when: >- (windows_apps_dark_mode_state is changed) or (windows_system_dark_mode_state is changed) or (windows_taskbar_search_state is changed) or (windows_11_widgets_state is changed) or (windows_10_widgets_state is changed) - name: Ensure winget is available on Windows host tags: [packages] ansible.windows.win_powershell: script: | $winget = Get-Command winget.exe -ErrorAction SilentlyContinue if ($null -eq $winget) { throw 'winget.exe is not available on the Windows host. Install App Installer or rerun the bootstrap script.' } $Ansible.Changed = $false - name: Ensure WSL 2 is the default backend tags: [packages, services, wsl] ansible.windows.win_powershell: script: | $status = & wsl --status 2>$null if ($LASTEXITCODE -eq 0 -and $status -match 'Default Version:\s*2') { $Ansible.Changed = $false return } & wsl --set-default-version 2 if ($LASTEXITCODE -ne 0) { throw 'Failed to set WSL default version to 2.' } $Ansible.Changed = $true - name: Install Windows workstation applications with winget tags: [packages] ansible.windows.win_powershell: script: | $packageId = '{{ item.id }}' $packageName = '{{ item.name | default(item.id) }}' $installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) { $Ansible.Changed = $false return } & winget install --id $packageId --exact --silent --accept-package-agreements --accept-source-agreements --disable-interactivity if ($LASTEXITCODE -ne 0) { throw "Failed to install $packageName with winget" } $Ansible.Changed = $true loop: "{{ windows_winget_packages | default([]) }}" loop_control: label: "{{ item.id }}" - name: Install VS Code WSL extensions on Windows host tags: [packages, vscode] ansible.windows.win_powershell: script: | $extensionId = '{{ item }}' $code = Get-Command code.cmd -ErrorAction SilentlyContinue if ($null -eq $code) { throw 'code.cmd is not available. Ensure Visual Studio Code is installed before managing extensions.' } $installedExtensions = & $code.Source --list-extensions if ($installedExtensions -contains $extensionId) { $Ansible.Changed = $false return } & $code.Source --install-extension $extensionId --force if ($LASTEXITCODE -ne 0) { throw "Failed to install VS Code extension $extensionId" } $Ansible.Changed = $true loop: "{{ windows_vscode_extensions | default([]) }}" loop_control: label: "{{ item }}"