I automated my entire PowerToys setup and so you can
Learn how to automate your PowerToys configuration so it’s consistent across all your devices
Last week, I had the time to play with the new PowerToys v0.95.0 release. I had to set up PowerToys on three different machines: my own computer, my work laptop, and then, when I reached the office, my colleague wanted the same thing I had.
By the time I made it to my work laptop, I was questioning all my life choices. You probably can recognize the same. PowerToys contains more than a hundred settings across its toolchain.
Going through the release notes blog of v0.95.0, I noticed a new addition:

Now, if you know me, you know that I love Microsoft DSC.
You don't see it right out of the bat, but that added support shipped a tiny executable. It promised me something I needed desperately: the ability to define my PowerToys configuration once and deploy it everywhere.
No more clicking through dozens of settings panels and no more trying to remember which toggle I switched on. If you've ever felt the same frustration, this guide is for you.
Let me show you how I went from manually configuring PowerToys every time to completely controlling the settings using the new Desired State Configuration support.
Understanding your options
Before we dive into the how-to, it's important to know that PowerToys already offered one approach to DSC. This isn't a case of one being better than the other. It simply illustrates different scenarios and workflows.
Let's dive into the first one.
PowerShell Desired State Configuration (DSC)
The first option has been available since PowerToys v0.80.0. It leverages PowerShell DSC and integrates with WinGet configuration files. If you're already using PowerShell in your environment or you want to combine PowerToys installation, this is your path.
What this option provides is a PowerShell module called Microsoft.PowerToys.Configure. This module works through PowerShell's DSC infrastructure. It's familiar to Windows administrators who've been using DSC now for years.
Microsoft Desired State Configuration (DSC)
This is the new option seen from the introduction image, which caught my eye. Microsoft DSC is the latest flagship of Microsoft. It's a single command-line utility tool that doesn't require PowerShell. This is what I ended up using as it's a cross-platform tool (though PowerToys itself is Windows only).
For me, it was simple. Even though WinGet handles module installations, I wanted to stick with the feature capabilities Microsoft DSC provides.
Which one should you choose?
Here's my honest take on it based on my experience configuring multiple machines and talking with my team members about their preferences:
| Consideration | PowerShell DSC | Microsoft DSC |
|---|---|---|
| Requirements & Dependencies | ||
| Requires PowerShell 7.2+ | ✅ | ❌ |
| Requires PSDesiredStateConfiguration module | ✅ | ❌ |
| Works with standalone executable | ❌ | ✅ |
| No runtime dependencies | ❌ | ✅ |
| Integration | ||
| Integrates with WinGet configuration files | ✅ | ✅ |
| Works with existing PowerShell DSC infrastructure | ✅ | ❌ |
| Uses modern DSC operations | ❌ | ✅ |
| Compatible with dsc.exe CLI orchestration | ✅ | ✅ |
| Configuration Management | ||
| Combined install + configure workflows | ✅ | ❌ |
| Individual resources per utility | ✅ | ✅ |
| Fine-grained control (get/test/export per utility) | ❌ | ✅ |
| Schema validation for individual resources | ⚠️ | ✅ |
| Deployment & Operations | ||
| Easy integration with existing PS scripts | ✅ | ⚠️ |
| Portable configuration files (JSON/YAML only) | ❌ | ✅ |
| Cross-platform tooling architecture | ❌ | ✅ |
| Future-proof with Microsoft's DSC v3 investment | ⚠️ | ✅ |
| Getting Started | ||
| Familiar to Windows administrators | ✅ | ❌ |
| Simpler setup (no module dependencies) | ❌ | ✅ |
| Established documentation and examples | ✅ | ⚠️ |
For my personal workflow and the heading Microsoft is taking with Microsoft DSC, you can already see the path I'm taking, which is Microsoft DSC.
That said, I've kept one thing off the table. Orchestration.
Orchestration with Microsoft DSC isn't fully there yet. If you're an organization with an already established higher-order orchestration tool, like Azure Machine Configuration, and you need that reporting, stick with PowerShell DSC for sure.
The rest of this post focuses on Microsoft DSC since that's what I chose. However, the concepts apply to both methods.
Creating your first configuration
Now here's the fun part: defining your configuration. This is where you capture all those settings you've been manually clicking through.
To get started, let's back up our existing settings, which is extremely easy using the new export command. Open up your PowerShell terminal and run the following commands:
# Get existing resource modules
$modules = PowerToys.DSC.exe modules --resource 'settings'
# Export each module
$backup = @{}
foreach ($module in $modules) {
$config = PowerToys.DSC.exe export --resource 'settings' --module $module | ConvertFrom-Json
$backup[$module] = $config
}
# Save backup
$backup | ConvertTo-Json -Depth 10 | Out-File powertoys-backup.jsonThis provides a complete snapshot of your current PowerToys configuration. Every utility, every setting, exactly as you have it configured right now. You can always restore from this backup.
The basic structure
When I opened up my powertoys-backup.json file, I noticed something important: the export command gives you the raw settings for each module:
{
"FancyZones": {
"settings": {
"properties": {
"fancyzones_shiftDrag": {
"value": true
},
// ... more settings
}
}
},
"AlwaysOnTop": {
"settings": {
"properties": {
// ... settings
}
}
}
}To use it with dsc.exe, I had to transform it into the proper DSC format with a resources array. Here's what my initial configuration looked like after the transformation:
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/config/document.json",
"resources": [
{
"name": "Enable PowerToys utilities",
"type": "Microsoft.PowerToys/App",
"properties": {
"settings": {
"properties": {
"Enabled": {
"FancyZones": true,
"AlwaysOnTop": true,
"ColorPicker": true
}
},
"name": "App",
"version": "1.0"
}
}
},
{
"name": "Configure FancyZones",
"type": "Microsoft.PowerToys/FancyZones",
"properties": {
"settings": {
"properties": {
"fancyzones_shiftDrag": true,
"fancyzones_mouseSwitch": false,
"fancyzones_overrideSnapHotkeys": false,
"fancyzones_moveWindowAcrossMonitors": false,
"fancyzones_displayOrWorkAreaChange_moveWindows": true,
"fancyzones_zoneSetChange_moveWindows": false,
"fancyzones_appLastZone_moveWindows": false,
"use_cursorpos_editor_startupscreen": true,
"fancyzones_show_on_all_monitors": false,
"fancyzones_makeDraggedWindowTransparent": false,
"fancyzones_zoneHighlightColor": "#0078D7",
"fancyzones_quickLayoutSwitch": true
},
"name": "FancyZones",
"version": "1.0"
}
}
},
{
"name": "Configure AlwaysOnTop",
"type": "Microsoft.PowerToys/AlwaysOnTop",
"properties": {
"settings": {
"properties": {
"FrameEnabled": true,
"FrameThickness": 15,
"FrameColor": "#0099cc",
"FrameOpacity": 100,
"FrameAccentColor": true,
"SoundEnabled": true,
"RoundCornersEnabled": true
},
"name": "AlwaysOnTop",
"version": "0.0.1"
}
}
},
// more settings
]
}
I started with just five utilities because they're the ones I use the most. The beauty of this approach is that you can start small and configure just the utilities you need. You can continually expand it later.
Understanding the structure
Each resource in the configuration has three key parts:
- name – A descriptive name for what this resource does.
- type – The specific PowerToys utility (e.g.
Microsoft.PowerToys/FancyZones). - properties – All the settings for that utility.
The schema at the top ($schema) enables validation and IntelliSense in editors like VS Code when it becomes available, making it easier to catch mistakes before you apply the configuration.
Here's where the confusion part is. When you just saw the exported backup file, the format didn't match what I'd transformed into a valid Microsoft DSC configuration example. So why's that?
The PowerToys.DSC.exe acts as a translator between the two worlds. On one side, PowerToys internal settings format the output to JSON. When you ran the export command, these internal settings are grabbed and output exactly as PowerToys has them stored.
But Microsoft DSC has its own specification for how configuration documents should look. That's what the $schema reference points to at https://aka.ms/dsc/schemas/v3/bundled/config/document.json. This schema defines a standardized format: a resources array where each resource has a type and properties.
It's also why the export gives you the "raw" format while Microsoft DSC needs the "wrapped" format including the type. The export shows you precisely what PowerToys stores internally:
{
"FancyZones": {
"settings": {
"properties": {
"fancyzones_shiftDrag": {"value": true}
}
}
}
}Microsoft DSC needs it in the standardized resource format:
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/config/document.json",
"resources": [
{
"name": "Configure FancyZones",
"type": "Microsoft.PowerToys/FancyZones",
"properties": {
"fancyzones_shiftDrag": true
}
}
]
}That still leaves us with one piece, the type name. If you had installed PowerToys through winget and the location is discoverable by the PATH environment variable, the fully qualified type name was discovered:

DSC Resources are found through a resource manifest. Each resource should use the following syntax:
`<owner>[.<group>][.<area>]/<name>`The schema connection
The PowerToys.DSC.exe CLI is incredible useful to discover you the exact property names and types that DSC expects. Or is it? Here's a small caveat hat I learned while working with the CLI.
See, Microsoft DSC expects a strong contract. That contract states the expected input and outputs. To illustrate this example, you can run the following command to list out the schema for the FancyZones module resource:
$json = powerToys.DSC.exe schema --resource 'settings' --module FancyZones |
ConvertFrom-Json
$json.required
What you don't see here are the actual settings. It expects an object, which brings in difficulty to know what are the actual property settings you can use.
That's why I took the initiative to open up a pull request and document all of them.
Applying your configuration
Once you've created your configuration document file, applying it is straightforward. If you haven't installed Microsoft DSC, you can run the following command in a PowerShell terminal session:
Install-PSResource -Name PSDSC -Scope CurrentUsers -Repository PSGallery
# Install `dsc.exe`
Install-DscExeThen, if you've the configuration document saved, you can run:
dsc.exe config set --file powertoys-config.dsc.jsonThe first time I ran this command on my work laptop, I was amazed how fast it applied the settings. All my PowerToys utilities were configured exactly as I specified on my first computer.
But here's were the power lays within configuration management tooling. The test operation. Before you apply any configuration, you can check what would change:
dsc config test --file powertoys-config.dsc.jsonThis compares your desired configuration against the current state and reports any drift. It allows you to validate that your configuration matches across the systems or machines you want to apply it against. And when you need to see your current configuration, you can switch it to get:
dsc config get --file powertoys-config.dsc.jsonNow my colleague's machine was easy to do. I simply led him clone the repository and executed dsc.exe. Just a single command and we were synchronized.
Conclusion
What started as a frustration, let me into a small rabbit hole in documenting all the PowerToys settings for Micorsoft DSC. Despite that, it allowed me to easily copy settings to version control and apply it across the machines not only I was working on, but also the one from my colleague.
I now have:
- Repeatability: Every machine can get an exact configuration I have
- Time: It only takes a couple of seconds to configure multiple PowerToys utilities
- Drift detection: Running the
testoperation shows me if a drift occurred - Version control: I can easily store all my settings in version control
If you're interested in diving deeper, check out the official pull request for Microsoft Learn already. You can also check out the documentation around Microsoft DSC.