We would like to enable our users to use winget configure
command to install PowerToys and configure its settings with a Winget configuration file. For example:
properties:
resources:
- resource: Microsoft.WinGet.DSC/WinGetPackage
directives:
description: Install PowerToys
allowPrerelease: true
settings:
id: PowerToys (Preview)
source: winget
- resource: PowerToysConfigure
directives:
description: Configure PowerToys
settings:
ShortcutGuide:
Enabled: false
OverlayOpacity: 1
FancyZones:
Enabled: true
FancyzonesEditorHotkey: "Shift+Ctrl+Alt+F"
configurationVersion: 0.2.0
This should install PowerToys and make PowerToysConfigure
resource available. We can use it in the same file.
PowerToysConfigure
is a class-based DSC resource. It looks up whether each setting was specified or not by checking whether it's $null
or 0
for enum
s and invokes PowerToys.Settings.exe
with the updated value like so:
PowerToys.Settings.exe set <ModuleName>.<SettingName> <SettingValue>
So for the example the config above should perform 3 following invocations:
PowerToys.Settings.exe set ShortcutGuide.Enabled false
PowerToys.Settings.exe set FancyZones.Enabled true
PowerToys.Settings.exe set FancyZones.FancyzonesEditorHotkey "Shift+Ctrl+Alt+F"
PowerToys.Settings
uses dotnet reflection capabilities to determine SettingName
type and tries to convert the supplied SettingValue
string accordingly. We use ICmdReprParsable
for custom setting types.
We use PowerToys.Settings.DSC.Schema.Generator
to generate the bulk of PowerToysConfigure.psm1
and PowerToysConfigure.psd1
files. It also uses dotnet reflection capabilities to inspect PowerToys.Settings.UI.Lib.dll
assembly and generate properties for the modules we have. The actual generation is done as a PowerToys.Settings.DSC.Schema.Generator.csproj
post-build action.
First, make sure that PowerShell 7.4+ is installed. Then make sure that you have DSC installed:
Install-Module -Name PSDesiredStateConfiguration -RequiredVersion 2.0.7
After that, start a new pwsh
session and cd
to src\dsc\Microsoft.PowerToys.Configure\Generated
directory. From there, you should execute:
$env:PSModulePath += ";$pwd"
You should have the generated Microsoft.PowerToys.Configure.psm1
and Microsoft.PowerToys.Configure.psd1
files inside the src\dsc\Microsoft.PowerToys.Configure\Generated\Microsoft.PowerToys.Configure\0.0.1\
folder.
This will allow DSC to discover our DSC Resource module. See PSModulePath for more info.
If everything works, you should see that your module is discovered by executing the following command:
Get-Module -ListAvailable | grep PowerToys
The resource itself should also be available:
Get-DSCResource | grep PowerToys
Otherwise, you can force-import the module to diagnose issues:
Import-Module .\Microsoft.PowerToys.Configure.psd1
If it's imported successfully, you could also try to invoke it directly:
Invoke-DscResource -Name PowerToysConfigure -Method Set -ModuleName Microsoft.PowerToys.Configure -Property @{ Debug = $true; Awake = @{ Enabled = $false; Mode = "TIMED"; IntervalMinutes = "10" } }
Note that we've supplied Debug
option, so a %TEMP\PowerToys.DSC.TestConfigure.txt
is created with the supplied properties, a current timestamp, and other debug output.
Finally, you can test it with winget by invoking it as such:
winget configure .\configuration.dsc.yaml --accept-configuration-agreements --disable-interactivity