├── .github └── workflows │ └── psscriptanalyzer.yml ├── README.md ├── SampleEvent.json ├── SampleScript.ps1 ├── experimental ├── ChangeEdgeBackgroundDefault.ps1 ├── ChangeMicrosoftEdgeTheme.ps1 ├── README.md └── SyncVirtualDesktops.ps1 ├── other ├── DisableJpegCompression.reg ├── DisableStartupDelay.reg ├── EnableJpegCompression.reg ├── EnableStartupDelay.reg ├── InstallStartupTask.ps1 ├── README.md └── UninstallStartupTask.ps1 └── stable ├── ChangeDisplayBrightness.ps1 ├── ChangeWindowsAppTheme.ps1 ├── ChangeWindowsSystemTheme.ps1 ├── ChangeWindowsTerminalBackground.ps1 └── README.md /.github/workflows/psscriptanalyzer.yml: -------------------------------------------------------------------------------- 1 | name: PSScriptAnalyzer 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | paths: 7 | - '**.ps1' 8 | pull_request: 9 | branches: [ master ] 10 | paths: 11 | - '**.ps1' 12 | 13 | jobs: 14 | analyze: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: microsoft/psscriptanalyzer-action@v1.1 21 | with: 22 | recurse: true 23 | 24 | - uses: github/codeql-action/upload-sarif@v2 25 | with: 26 | sarif_file: results.sarif 27 | category: psscriptanalyzer 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WDD-scripts 2 | PowerShell scripts that add features to [WinDynamicDesktop](https://github.com/t1m0thyj/WinDynamicDesktop) 3 | 4 | **Note:** Scripts are a new feature in WinDynamicDesktop 4.0. Click [here](https://github.com/t1m0thyj/WinDynamicDesktop/wiki/Installing-scripts) for instructions on how to install them. 5 | 6 | ## Browse Existing Scripts 7 | 8 | Select a category of scripts to browse: 9 | 10 | * [Stable](/stable#readme) 11 | * [Experimental](/experimental#readme) 12 | * [Other scripts](/other#readme) 13 | 14 | ## Create New Scripts 15 | 16 | PowerShell scripts are run by WinDynamicDesktop when the wallpaper image is updated. They are invoked with a JSON object that contains the following parameters: 17 | 18 | * `daySegment2` - 0 = Day, 1 = Night 19 | * `daySegment4` - -1 = N/A, 0 = Sunrise, 1 = Day, 2 = Sunset, 3 = Night 20 | * `themeMode` - 0 = Automatic, 1 = Light Mode, 2 = Dark Mode 21 | * `imagePaths` - List of paths to current wallpaper image for each display 22 | 23 | To read the values of these parameters, add the line below to the top of your script and access them like this: `$params.daySegment2` 24 | 25 | ```powershell 26 | $params = $Input | ConvertFrom-Json 27 | ``` 28 | 29 | A sample script that uses parameters can be found [here](./SampleScript.ps1). When the sample script is installed and gets run by WinDynamicDesktop, it will display the values of all the parameters. 30 | 31 | If you create a script and would like to share it with other users of the app, pull requests in this repository are welcome. 32 | -------------------------------------------------------------------------------- /SampleEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "daySegment2": 0, 3 | "daySegment4": 1, 4 | "themeMode": 0, 5 | "imagePaths": [ 6 | "C:\\Windows\\Web\\Wallpaper\\Windows\\img0.jpg" 7 | ] 8 | } -------------------------------------------------------------------------------- /SampleScript.ps1: -------------------------------------------------------------------------------- 1 | # To test with sample event, run: cat SampleEvent.json | .\SampleScript.ps1 2 | $params = $Input | ConvertFrom-Json 3 | 4 | Add-Type -AssemblyName PresentationCore,PresentationFramework 5 | [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 6 | [System.Windows.MessageBox]::Show(($params | Format-List | Out-String), "WinDynamicDesktop") 7 | -------------------------------------------------------------------------------- /experimental/ChangeEdgeBackgroundDefault.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | If ($params.imagePaths -And (Test-Path "~\AppData\Local\Microsoft\Edge\User Data\Default")) { 4 | Copy-Item $params.imagePaths[0] "~\AppData\Local\Microsoft\Edge\User Data\Default\edge_background.jpg" 5 | } 6 | -------------------------------------------------------------------------------- /experimental/ChangeMicrosoftEdgeTheme.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | $registryPath = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Main" 4 | $dwordValue = If ($params.themeMode -Eq 0) {$params.daySegment2} Else {$params.themeMode - 1} 5 | 6 | if (Test-Path $registryPath) 7 | { 8 | New-ItemProperty -Path $registryPath -Name "Theme" -Value $dwordValue -PropertyType DWORD -Force | Out-Null 9 | } 10 | -------------------------------------------------------------------------------- /experimental/README.md: -------------------------------------------------------------------------------- 1 | # Experimental PowerShell scripts 2 | 3 | **Note:** Scripts are a new feature in WinDynamicDesktop 4.0. Click [here](https://github.com/t1m0thyj/WinDynamicDesktop/wiki/Installing-scripts) for instructions on how to install them. 4 | 5 | ## Table of Contents 6 | 7 | - [Change Microsoft Edge Theme](#change-microsoft-edge-theme) 8 | - [Change Microsoft Edge Background Image (Default profile)](#change-microsoft-edge-background-image-default-profile) 9 | - [Synchronize Virtual Desktops](#synchronize-virtual-desktops) 10 | 11 | --- 12 | 13 | ## Change Microsoft Edge Theme 14 | 15 | Changes Microsoft Edge theme based on the time of day. 16 | 17 | **Author:** @t1m0thyj 18 | 19 | **Requirements:** 20 | - Windows 10 and up 21 | - Desktop version of WDD (doesn't work in Microsoft Store app) 22 | 23 | ⚠️ Changing the theme does not update it in Edge immediately. Restarting the browser is required for the change to take effect. 24 | 25 | [Download](/experimental/ChangeMicrosoftEdgeTheme.ps1?raw=true) 26 | 27 | --- 28 | 29 | ## Change Microsoft Edge Background Image (Default profile) 30 | 31 | Changes Microsoft Edge background image based on the time of day. 32 | 33 | **Author:** @khuongduybui 34 | 35 | **Requirements:** 36 | - Windows 10 and up 37 | - Desktop version of WDD (doesn't work in Microsoft Store app) 38 | 39 | ⚠️ This only changes the background for the default profile. Please edit the script on your computer to include other profiles. 40 | 41 | [Download](/experimental/ChangeEdgeBackgroundDefault.ps1?raw=true) 42 | 43 | --- 44 | 45 | ## Synchronize Virtual Desktops 46 | 47 | Synchronizes the same wallpaper across multiple virtual desktops. 48 | 49 | **Author:** @t1m0thyj 50 | 51 | **Requirements:** 52 | - Windows 11 53 | - Single wallpaper is set across all monitors 54 | 55 | ⚠️ This script uses an unofficial API that is not supported by Microsoft and may break in future versions of Windows. 56 | 57 | [Download](/experimental/SyncVirtualDesktops.ps1?raw=true) 58 | -------------------------------------------------------------------------------- /experimental/SyncVirtualDesktops.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | If (-Not $params.imagePaths) { 4 | Break 5 | } 6 | 7 | $currentWinVer = (Get-CimInstance Win32_OperatingSystem).version 8 | $settingsFile = "$((Get-Item $PSCommandPath).BaseName).dat" 9 | $settingsUpdated = $false 10 | if (-Not (Get-Module -ListAvailable -Name VirtualDesktop)) { 11 | if (-Not (Get-PackageProvider -ListAvailable | Where-Object { $_.Name -eq "NuGet" })) { 12 | Install-PackageProvider -Name NuGet -Force -Scope CurrentUser 13 | } 14 | Install-Module -Name VirtualDesktop -AllowClobber -Force -Scope CurrentUser 15 | $settingsUpdated = $true 16 | } elseif (-Not (Test-Path -Path $settingsFile -PathType Leaf) -Or ($currentWinVer -Ne (Import-Clixml -Path $settingsFile))) { 17 | Update-Module -Name VirtualDesktop -Force 18 | $settingsUpdated = $true 19 | } 20 | 21 | Get-DesktopList | ForEach-Object { 22 | if (-Not (Test-CurrentDesktop -Desktop $_.Number)) { 23 | Set-DesktopWallpaper -Desktop $_.Number -Path $params.imagePaths[0] 24 | } 25 | } 26 | 27 | if ($settingsUpdated) { 28 | $currentWinVer | Export-Clixml -Path $settingsFile 29 | } 30 | -------------------------------------------------------------------------------- /other/DisableJpegCompression.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_CURRENT_USER\Control Panel\Desktop] 4 | "JPEGImportQuality"=dword:00000064 5 | -------------------------------------------------------------------------------- /other/DisableStartupDelay.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize] 4 | "StartupDelayInMSec"=dword:00000000 5 | -------------------------------------------------------------------------------- /other/EnableJpegCompression.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_CURRENT_USER\Control Panel\Desktop] 4 | "JPEGImportQuality"=- 5 | -------------------------------------------------------------------------------- /other/EnableStartupDelay.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize] 4 | "StartupDelayInMSec"=- 5 | -------------------------------------------------------------------------------- /other/InstallStartupTask.ps1: -------------------------------------------------------------------------------- 1 | if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 2 | Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$PSCommandPath`"" -Verb RunAs 3 | exit 4 | } 5 | 6 | $exePath = (Get-Process -Name WinDynamicDesktop).Path 7 | if (!$exePath) { 8 | Add-Type -AssemblyName PresentationCore,PresentationFramework 9 | [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 10 | [System.Windows.MessageBox]::Show("WinDynamicDesktop must be running in order to use this script.", "Error") 11 | exit 12 | } 13 | 14 | $taskAction = New-ScheduledTaskAction -Execute $exePath 15 | $taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries 16 | $taskTrigger = New-ScheduledTaskTrigger -AtLogOn 17 | Register-ScheduledTask -TaskName WinDynamicDesktop -Action $taskAction -Description "Start WinDynamicDesktop at logon" -Settings $taskSettings -Trigger $taskTrigger 18 | 19 | Add-Type -AssemblyName PresentationCore,PresentationFramework 20 | [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 21 | [System.Windows.MessageBox]::Show("Scheduled task created successfully.", "WinDynamicDesktop") 22 | -------------------------------------------------------------------------------- /other/README.md: -------------------------------------------------------------------------------- 1 | # Other miscellaneous scripts 2 | 3 | **Note:** These scripts are standalone and can be run on your PC to tweak Windows settings. They cannot be installed into WinDynamicDesktop. 4 | 5 | ## Table of Contents 6 | 7 | - [Disable/Enable JPEG Compression](#disableenable-jpeg-compression) 8 | - [Disable/Enable Startup Delay](#disableenable-startup-delay) 9 | - [Install/Uninstall Startup Task](#installuninstall-startup-task) 10 | 11 | --- 12 | 13 | ## Disable/Enable JPEG Compression 14 | 15 | Toggles the default behavior of Windows to compress desktop wallpapers that are in JPEG format ([read more](https://www.windowscentral.com/how-disable-image-compression-desktop-wallpapers-windows-10)). 16 | 17 | **Author:** @t1m0thyj 18 | 19 | **Downloads:** [Disable](/other/DisableJpegCompression.reg?raw=true) | [Enable](/other/EnableJpegCompression.reg?raw=true) 20 | 21 | --- 22 | 23 | ## Disable/Enable Startup Delay 24 | 25 | Toggles the default behavior of Windows to wait 10 seconds after startup before loading third party programs like WDD ([read more](https://www.howtogeek.com/403162/how-to-disable-the-windows-10-startup-delay/)). 26 | 27 | **Author:** @t1m0thyj 28 | 29 | **Downloads:** [Disable](/other/DisableStartupDelay.reg?raw=true) | [Enable](/other/EnableStartupDelay.reg?raw=true) 30 | 31 | --- 32 | 33 | ## Install/Uninstall Startup Task 34 | 35 | Adds or removes a task in Windows Task Scheduler to start WinDynamicDesktop at logon ([read more](https://www.sevenforums.com/tutorials/67503-task-create-run-program-startup-log.html)). 36 | 37 | **Author:** @t1m0thyj 38 | 39 | **Requirements:** 40 | - Desktop version of WDD (doesn't work in Microsoft Store app) 41 | - Administrator permissions 42 | 43 | **Downloads:** [Install](/other/InstallStartupTask.ps1?raw=true) | [Uninstall](/other/UninstallStartupTask.ps1?raw=true) 44 | -------------------------------------------------------------------------------- /other/UninstallStartupTask.ps1: -------------------------------------------------------------------------------- 1 | if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 2 | Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$PSCommandPath`"" -Verb RunAs 3 | exit 4 | } 5 | 6 | Unregister-ScheduledTask -TaskName WinDynamicDesktop -Confirm:$false 7 | 8 | Add-Type -AssemblyName PresentationCore,PresentationFramework 9 | [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 10 | [System.Windows.MessageBox]::Show("Scheduled task deleted successfully.", "WinDynamicDesktop") 11 | -------------------------------------------------------------------------------- /stable/ChangeDisplayBrightness.ps1: -------------------------------------------------------------------------------- 1 | # NOTE: Requires hardware that supports DDC/CI (the ability to change display brightness in Windows) 2 | $params = $Input | ConvertFrom-Json 3 | 4 | # Edit these values to be a valid screen brightness percent between 0 and 100 5 | $sunriseBrightness = 40 6 | $dayBrightness = 80 7 | $sunsetBrightness = 30 8 | $nightBrightness = 20 9 | 10 | if ($params.daySegment4 -Eq -1) { 11 | $params.daySegment4 = $params.daySegment2 * 2 + 1 12 | } 13 | 14 | $brightnessPercent = switch ($params.daySegment4) 15 | { 16 | 0 { $sunriseBrightness } 17 | 1 { $dayBrightness } 18 | 2 { $sunsetBrightness } 19 | 3 { $nightBrightness } 20 | } 21 | 22 | $display = Get-WmiObject -Namespace "root\WMI" -Class "WmiMonitorBrightnessMethods" 23 | $display.WmiSetBrightness(0, $brightnessPercent) 24 | -------------------------------------------------------------------------------- /stable/ChangeWindowsAppTheme.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | $registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" 4 | $dwordValue = 1 - $(If ($params.themeMode -Eq 0) {$params.daySegment2} Else {$params.themeMode - 1}) 5 | 6 | if (Test-Path $registryPath) 7 | { 8 | New-ItemProperty -Path $registryPath -Name "AppsUseLightTheme" -Value $dwordValue -PropertyType DWORD -Force | Out-Null 9 | } 10 | 11 | if ([System.Environment]::OSVersion.Version.Build -ge 22000) 12 | { 13 | # Call Windows theme refresh 14 | Add-Type -TypeDefinition @" 15 | using System; 16 | using System.Runtime.InteropServices; 17 | 18 | public class Win32Utils { 19 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 20 | public static extern int SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, int fuFlags, int uTimeout, out IntPtr lpdwResult); 21 | } 22 | "@ -PassThru 23 | 24 | $HWND_BROADCAST = [IntPtr]0xFFFF 25 | $WM_SETTINGCHANGE = 0x1A 26 | $SMTO_ABORTIFHUNG = 0x2 27 | [Win32Utils]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, 5000, [ref]([IntPtr]::Zero)) 28 | } 29 | -------------------------------------------------------------------------------- /stable/ChangeWindowsSystemTheme.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | $registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" 4 | $dwordValue = 1 - $(If ($params.themeMode -Eq 0) {$params.daySegment2} Else {$params.themeMode - 1}) 5 | 6 | if (Test-Path $registryPath) 7 | { 8 | New-ItemProperty -Path $registryPath -Name "SystemUsesLightTheme" -Value $dwordValue -PropertyType DWORD -Force | Out-Null 9 | } 10 | 11 | if ([System.Environment]::OSVersion.Version.Build -ge 22000) 12 | { 13 | # Call Windows theme refresh 14 | Add-Type -TypeDefinition @" 15 | using System; 16 | using System.Runtime.InteropServices; 17 | 18 | public class Win32Utils { 19 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 20 | public static extern int SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, int fuFlags, int uTimeout, out IntPtr lpdwResult); 21 | } 22 | "@ -PassThru 23 | 24 | $HWND_BROADCAST = [IntPtr]0xFFFF 25 | $WM_SETTINGCHANGE = 0x1A 26 | $SMTO_ABORTIFHUNG = 0x2 27 | [Win32Utils]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, 5000, [ref]([IntPtr]::Zero)) 28 | } 29 | -------------------------------------------------------------------------------- /stable/ChangeWindowsTerminalBackground.ps1: -------------------------------------------------------------------------------- 1 | $params = $Input | ConvertFrom-Json 2 | 3 | If (-Not $params.imagePaths) { 4 | Break 5 | } 6 | 7 | $jsonFilePath = "$Env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" 8 | $jsonDataOld = Get-Content -Path $jsonFilePath 9 | $imagePath = $params.imagePaths[0].Replace('\', '\\') 10 | 11 | If ($jsonDataOld -match '(?