You are on page 1of 400

Microsoft Windows

Powershell Desired State


Configuration

6/12/17
This manual is taken directly from the Microsoft website. I take no credit or responsibility for its content.

This is intended as an offline means to access this great resource on configuring and managing a Desired
State Configuration (DSC) platform.

Collected by Les Lewis


Table of Contents
Windows PowerShell Desired State Configuration Overview ........................................................................... 21
Key Concepts ........................................................................................................................................... 21
See Also ................................................................................................................................................... 22
Desired State Configuration Overview for Decision Makers ............................................................................. 23
What Is Desired State Configuration? ...................................................................................................... 23
Benefits of Using Desired State Configuration......................................................................................... 23
Desired State Configuration and DevOps ................................................................................................ 24
Desired State Configuration On- and Off-Premises ................................................................................. 24
DSC and Compatibility ............................................................................................................................. 24
Desired State Configuration Overview for Engineers ....................................................................................... 25
Benefits of Desired State Configuration ................................................................................................... 25
"I have PowerShell, why do I need Desired State Configuration?" ........................................................... 25
Separating Environment from Structure .................................................................................................. 27
See Also ................................................................................................................................................... 28
Desired State Configuration Quick Start ......................................................................................................... 29
Requirements ........................................................................................................................................... 29
Write and place the index.htm file ........................................................................................................... 29
Write the configuration ............................................................................................................................ 29
Compile the configuration ....................................................................................................................... 30
Apply the configuration ........................................................................................................................... 31
Test the configuration .............................................................................................................................. 32
Next steps ................................................................................................................................................ 32
DSC Configurations ....................................................................................................................................... 33
Configuration syntax ................................................................................................................................ 33
Compiling the configuration .................................................................................................................... 34
Using DependsOn .................................................................................................................................... 36
Using new resources in Your configuration ............................................................................................. 36
See Also ................................................................................................................................................... 37
Enacting configurations ................................................................................................................................. 38
Push mode ............................................................................................................................................... 38
Pull mode ................................................................................................................................................. 38
Separating configuration and environment data............................................................................................. 40
What is configuration data? ..................................................................................................................... 40
A simple example ..................................................................................................................................... 40
Using configuration data to define development and production environments ................................... 42
Configuration data file ........................................................................................................................ 42
Configuration script file ...................................................................................................................... 43
Using non-node data ............................................................................................................................... 46
See Also ................................................................................................................................................... 47
Using resources with multiple versions ........................................................................................................... 48
Installing multiple resource versions side-by-side ................................................................................... 48
Specifying a resource version in a configuration ..................................................................................... 49
See also .................................................................................................................................................... 50
Running DSC with user credentials ................................................................................................................. 51
Specifying cross-node dependencies ............................................................................................................. 53
Using WaitForXXXX resources ................................................................................................................. 53
See Also ................................................................................................................................................... 54
Using configuration data in DSC .................................................................................................................... 56
The ConfigurationData common parameter ............................................................................................ 56
Defining the ConfigurationData hashtable .............................................................................................. 59
Compiling a configuration with configuration data ................................................................................. 59
Compiling a configuration with configuration data using a variable ................................................ 60
Compiling a configuration with configuration data using a data file ............................................... 60
Using ConfigurationData variables in a configuration ............................................................................. 60
Using non-node data ............................................................................................................................... 60
See Also ................................................................................................................................................... 61
Credentials Options in Configuration Data ..................................................................................................... 62
Plain Text Passwords and Domain Users.................................................................................................. 62
Handling Credentials in DSC .................................................................................................................... 64
Example: The Group resource Credential property .................................................................................. 66
Example Configuration ............................................................................................................................ 66
PsDscAllowPlainTextPassword ................................................................................................................. 67
Domain Credentials ................................................................................................................................. 68
PSDscAllowDomainUser........................................................................................................................... 69
Nesting DSC configurations ........................................................................................................................... 70
See Also ................................................................................................................................................... 71
Securing the MOF File ................................................................................................................................... 72
Prerequisites ............................................................................................................................................ 72
Overall process ........................................................................................................................................ 72
Certificate Requirements.......................................................................................................................... 73
Certificate creation ................................................................................................................................... 73
Creating the Certificate on the Target Node ...................................................................................... 74
Creating the Certificate on the Authoring Node ................................................................................ 75
Configuration data ................................................................................................................................... 77
Configuration script ................................................................................................................................. 79
Setting up decryption .............................................................................................................................. 79
Running the configuration ....................................................................................................................... 80
Credential Encryption Module Example ................................................................................................... 81
PowerShell Desired State Configuration partial configurations ........................................................................ 85
Partial configurations in push mode ........................................................................................................ 85
Configuring the LCM for push-mode partial configurations ............................................................. 85
Publishing and starting push-mode partial configurations ............................................................... 86
Partial configurations in pull mode .......................................................................................................... 88
Configuring the LCM for pull node configurations ............................................................................ 88
Naming and placing the configuration documents on the pull server (ConfigurationNames) ........ 91
Naming and placing the configuration documents on the pull server (ConfigurationID) ............... 92
Running partial configurations from a pull server ............................................................................. 92
Partial configurations in mixed push and pull modes .............................................................................. 92
Mixed push and pull modes using ConfigurationNames................................................................... 93
Mixed push and pull modes using ConfigurationID .......................................................................... 94
Example ServiceAccountConfig Partial Configuration.............................................................................. 95
Example SharePointConfig Partial Configuration ..................................................................................... 96
See Also ................................................................................................................................................... 96
Writing help for DSC configurations ............................................................................................................... 97
Viewing configuration help ...................................................................................................................... 98
See Also ................................................................................................................................................... 99
Configure a virtual machines at initial boot-up by using DSC ........................................................................ 100
Requirements ......................................................................................................................................... 100
Inject a configuration MOF document into a VHD ................................................................................ 100
To inject the configuration MOF document on the VHD ................................................................. 101
Inject a DSC metaconfiguration into a VHD ........................................................................................... 102
To inject the metaconfiguration MOF document on the VHD ........................................................ 103
Disable DSC at boot time ....................................................................................................................... 104
See Also ................................................................................................................................................. 105
DSCAutomationHostEnabled registry key ..................................................................................................... 106
See Also ................................................................................................................................................. 106
DSC Resources ............................................................................................................................................ 107
Built-In Windows PowerShell Desired State Configuration Resources ............................................................ 108
DSC Archive Resource ................................................................................................................................. 109
Syntax .................................................................................................................................................... 109
Properties ............................................................................................................................................... 109
Example ................................................................................................................................................. 110
DSC Environment Resource ......................................................................................................................... 111
Syntax .................................................................................................................................................... 111
Properties ............................................................................................................................................... 111
Example ................................................................................................................................................. 112
DSC File Resource ....................................................................................................................................... 113
Syntax .................................................................................................................................................... 113
Properties ............................................................................................................................................... 113
Example ................................................................................................................................................. 114
DSC Group Resource .................................................................................................................................. 116
Syntax .................................................................................................................................................... 116
Properties ............................................................................................................................................... 116
Example 1............................................................................................................................................... 117
Example 2............................................................................................................................................... 117
Example 3............................................................................................................................................... 118
DSC GroupSet Resource .............................................................................................................................. 120
Syntax## ................................................................................................................................................ 120
Properties ............................................................................................................................................... 120
Example 1............................................................................................................................................... 121
DSC Log Resource ...................................................................................................................................... 123
Properties ............................................................................................................................................... 123
Example ................................................................................................................................................. 123
DSC Package Resource ............................................................................................................................... 125
Syntax .................................................................................................................................................... 125
Properties ............................................................................................................................................... 125
Example ................................................................................................................................................. 126
DSC WindowsProcess Resource ................................................................................................................... 127
Syntax .................................................................................................................................................... 127
Properties ............................................................................................................................................... 127
DSC Registry Resource ................................................................................................................................ 129
Syntax .................................................................................................................................................... 129
Properties ............................................................................................................................................... 129
Example ................................................................................................................................................. 130
DSC Script Resource .................................................................................................................................... 132
Syntax .................................................................................................................................................... 132
Properties ............................................................................................................................................... 133
Example 1............................................................................................................................................... 133
Example 2............................................................................................................................................... 134
DSC Service Resource ................................................................................................................................. 136
Syntax .................................................................................................................................................... 136
Properties ............................................................................................................................................... 136
Example ................................................................................................................................................. 137
DSC ServiceSet Resource ............................................................................................................................. 138
Syntax .................................................................................................................................................... 138
Properties ............................................................................................................................................... 138
Example ................................................................................................................................................. 139
SC User Resource#...................................................................................................................................... 140
Syntax## ................................................................................................................................................ 140
Properties ............................................................................................................................................... 140
Example ................................................................................................................................................. 141
DSC WaitForAll Resource............................................................................................................................. 142
Syntax .................................................................................................................................................... 142
Properties ............................................................................................................................................... 142
Example ................................................................................................................................................. 143
DSC WaitForAny Resource .......................................................................................................................... 144
Syntax .................................................................................................................................................... 144
Properties ............................................................................................................................................... 144
Example ................................................................................................................................................. 145
DSC WaitForSome Resource ........................................................................................................................ 146
Syntax .................................................................................................................................................... 146
Properties ............................................................................................................................................... 146
Example ................................................................................................................................................. 147
DSC WindowsFeature Resource ................................................................................................................... 148
Syntax .................................................................................................................................................... 148
Properties ............................................................................................................................................... 148
Example ................................................................................................................................................. 149
DSC WindowsFeatureSet Resource .............................................................................................................. 150
Syntax .................................................................................................................................................... 150
Properties ............................................................................................................................................... 150
Example ................................................................................................................................................. 151
DSC WindowsOptionalFeature Resource ...................................................................................................... 152
Syntax .................................................................................................................................................... 152
Properties ............................................................................................................................................... 152
DSC WindowsOptionalFeatureSet Resource ................................................................................................. 154
Syntax .................................................................................................................................................... 154
Properties ............................................................................................................................................... 154
DSC WindowsPackageCab Resource............................................................................................................ 156
Syntax .................................................................................................................................................... 156
Properties ............................................................................................................................................... 156
Example ................................................................................................................................................. 157
DSC WindowsProcess Resource ................................................................................................................... 159
Syntax .................................................................................................................................................... 159
Properties ............................................................................................................................................... 159
Build Custom Windows PowerShell Desired State Configuration Resources ................................................... 161
DSC resource components..................................................................................................................... 161
Writing a custom DSC resource with MOF ................................................................................................... 162
Creating the MOF schema ..................................................................................................................... 162
Folder structure for a MOF resource .................................................................................................. 162
The contents of the MOF file .............................................................................................................. 162
Writing the resource script ................................................................................................................. 163
Creating the module manifest ............................................................................................................ 168
Supporting PsDscRunAsCredential ........................................................................................................ 169

Authoring a DSC resource in C # ................................................................................................................ 171

Writing a cmdlet-based resource........................................................................................................... 171


Writing the MOF schema ................................................................................................................... 171
Setting up the Visual Studio project................................................................................................... 171
Writing the cmdlet code .................................................................................................................... 172
Deploying the resource ...................................................................................................................... 177
See Also.............................................................................................................................................. 177
Writing a custom DSC resource with PowerShell classes ............................................................................... 179
Folder structure for a class resource ...................................................................................................... 179
Create the class ...................................................................................................................................... 180
Declare properties .............................................................................................................................. 180
Implementing the methods................................................................................................................ 181
The complete file ................................................................................................................................ 184
Create a manifest ................................................................................................................................... 188
Test the resource ................................................................................................................................... 189
Supporting PsDscRunAsCredential ........................................................................................................ 190
Require or disallow PsDscRunAsCredential for your resource............................................................ 190
Access the user context ...................................................................................................................... 191
See Also ................................................................................................................................................. 191
Concepts ............................................................................................................................................ 191
Composite resources: Using a DSC configuration as a resource .................................................................... 192
Creating the composite resource ........................................................................................................... 192
Saving the configuration as a composite resource ............................................................................ 195
Using the composite resource ............................................................................................................... 195
Supporting PsDscRunAsCredential ........................................................................................................ 196
See Also ................................................................................................................................................. 197
Concepts ............................................................................................................................................ 197
Writing a single-instance DSC resource (best practice) ................................................................................. 198
Resource authoring checklist ....................................................................................................................... 204
Resource module contains .psd1 file and schema.mof for every resource ............................................ 204
Resource and schema are correct## ...................................................................................................... 204
Resource loads without errors ............................................................................................................... 205
Resource is idempotent in the positive case .......................................................................................... 206
Test user modification scenario ............................................................................................................. 206
Call Get/Set/Test-TargetResource functions directly ............................................................................ 207
Verify End to End using Start-DscConfiguration .................................................................................... 207
Test compatability on all DSC supported platforms .............................................................................. 207
Verify on Windows Client (if applicable) ................................................................................................ 208
Get-DSCResource lists the resource....................................................................................................... 208
Resource module contains examples ..................................................................................................... 208
Error messages are easy to understand and help users solve problems ................................................ 210
Log messages are easy to understand and informative (including verbose, debug and ETW logs) ... 210
Resource implementation does not contain hardcoded paths .............................................................. 211
Resource implementation does not contain user information............................................................... 212
Resource was tested with valid/invalid credentials ................................................................................ 212
Resource does not require interactive input .......................................................................................... 212
Resource functionality was thoroughly tested ....................................................................................... 212
Best practice: Resource module contains Tests folder with ResourceDesignerTests.ps1 script ............. 213
Best practice: Resource folder contains resource designer script for generating schema## ................. 213
Best practice: Resource supports -whatif ............................................................................................... 214
Debugging DSC resources........................................................................................................................... 216
Enabling DSC debugging ....................................................................................................................... 216
Starting a configuration with debug enabled ........................................................................................ 216
Debugging the resource script .............................................................................................................. 218
Disabling DSC debugging ...................................................................................................................... 218
See Also ................................................................................................................................................. 218
Calling DSC resource methods directly......................................................................................................... 220
Ensure a file is present ........................................................................................................................... 220
Test that a file is present ........................................................................................................................ 220
Get the contents of file .......................................................................................................................... 221
See Also ................................................................................................................................................. 221
Configuring the Local Configuration Manager .............................................................................................. 222
Writing and enacting an LCM configuration .......................................................................................... 222
Basic settings ......................................................................................................................................... 223
Pull servers ............................................................................................................................................. 225
Configuration server blocks ................................................................................................................... 226
Resource server blocks........................................................................................................................... 226
Report server blocks .............................................................................................................................. 227
Partial configurations ............................................................................................................................. 228
See Also ................................................................................................................................................. 229
Concepts ............................................................................................................................................ 229
Other Resources ................................................................................................................................. 229
Windows PowerShell 4.0 Desired State Configuration Local Configuration Manager (LCM) ............................ 230
Local Configuration Manager properties ............................................................................................... 230
Example of updating Local Configuration Manager settings ............................................................. 231
Setting up a DSC web pull server ................................................................................................................. 233
Using the xDSCWebService resource ..................................................................................................... 233
Registration Key ..................................................................................................................................... 235
Placing configurations and resources .................................................................................................... 237
DSC resource module package format............................................................................................... 237
Configuration MOF format ................................................................................................................. 238
Tooling ................................................................................................................................................... 238
Pull client configuration ......................................................................................................................... 238
See also .................................................................................................................................................. 239
Setting up a DSC SMB pull server ................................................................................................................ 240
Using the xSmbShare resource to create an SMB file share .................................................................. 240
Install the xSmbShare resource .......................................................................................................... 240
Create the directory and file share ..................................................................................................... 240
Give file system access to the pull client ............................................................................................ 241
Placing configurations and resources .................................................................................................... 243
Creating the MOF checksum.................................................................................................................. 243
Setting up a pull client for SMB ............................................................................................................. 244
Acknowledgements ............................................................................................................................... 245
See also .................................................................................................................................................. 246
Setting up a DSC pull client ......................................................................................................................... 247
Setting up a pull client using configuration names ........................................................................................ 248
Resource and report servers .................................................................................................................. 249
See Also ................................................................................................................................................. 251
Setting up a pull client using configuration ID .............................................................................................. 252
Configuration ID .................................................................................................................................... 253
SMB pull server ...................................................................................................................................... 253
Resource and report servers .................................................................................................................. 254
See Also ................................................................................................................................................. 256
Using a DSC report server ........................................................................................................................... 257
Configuring a node to send reports ...................................................................................................... 257
Getting report data ................................................................................................................................ 259
Viewing report data ............................................................................................................................... 260
See Also ................................................................................................................................................. 263
Pull server best practices ............................................................................................................................. 265
Abstract .................................................................................................................................................. 265
Versions of the Windows Management Framework........................................................................... 266
Windows PowerShell Desired State Configuration ............................................................................. 266
Pull server role .................................................................................................................................... 266
Configuration planning .......................................................................................................................... 266
Software requirements ....................................................................................................................... 267
Software downloads ........................................................................................................................... 267
WMF ................................................................................................................................................... 267
DSC resource ...................................................................................................................................... 268
Hardware requirements...................................................................................................................... 268
Accounts ............................................................................................................................................ 269
DNS records ....................................................................................................................................... 269
Public Key Infrastructure .................................................................................................................... 270
Choosing an architecture ................................................................................................................... 271
Staging configurations and modules on the pull server .................................................................... 272
Installation Guide ................................................................................................................................... 275
Prerequisites ....................................................................................................................................... 275
Installation and configuration scripts ................................................................................................. 276
Basic configuration for Windows Server 2012 .................................................................................... 276
Advanced configuration for Windows Server 2012 R2 ....................................................................... 277
Verify pull server functionality ............................................................................................................ 281
Configure clients ................................................................................................................................ 282
Additional references, snippets, and examples ...................................................................................... 282
Appendix - Understanding ODATA service data file types .................................................................... 283
DSC examples ............................................................................................................................................. 284
Building a Continuous Integration and Continuous Deplyoment pipeline with DSC ........................................ 285
Prerequisites .......................................................................................................................................... 285
What you will need ................................................................................................................................ 285
Client .................................................................................................................................................. 285
TFSSrv1 ............................................................................................................................................... 286
BuildAgent.......................................................................................................................................... 286
TestAgent1 ......................................................................................................................................... 286
TestAgent2 ......................................................................................................................................... 286
Add the code to TFS .............................................................................................................................. 286
Understanding the code ........................................................................................................................ 287
The DSC configuration ....................................................................................................................... 287
Configuration data ............................................................................................................................. 289
The psake build script ........................................................................................................................ 290
The psake deploy script...................................................................................................................... 292
Test scripts ......................................................................................................................................... 293
Define the build ..................................................................................................................................... 294
PowerShell Script................................................................................................................................ 294
Publish Test Results ............................................................................................................................ 294
Copy Files ........................................................................................................................................... 295
Publish Artifact ................................................................................................................................... 295
Enable continuous integration ............................................................................................................... 295
Create the release definition .................................................................................................................. 296
PowerShell Script................................................................................................................................ 296
First Publish Test Results .................................................................................................................... 296
Second Publish Test Results ............................................................................................................... 296
Verify your results .................................................................................................................................. 297
Next steps .............................................................................................................................................. 297
Separating configuration and environment data........................................................................................... 298
What is configuration data? ................................................................................................................... 298
A simple example ................................................................................................................................... 298
Using configuration data to define development and production environments ................................. 300
Configuration data file ....................................................................................................................... 300
Configuration script file ...................................................................................................................... 301
Using non-node data ............................................................................................................................. 304
See Also ................................................................................................................................................. 305
Troubleshooting DSC .................................................................................................................................. 306
WinRM Dependency .............................................................................................................................. 306
Using Get-DscConfigurationStatus ........................................................................................................ 306
Example ................................................................................................................................................. 307
My script wont run: Using DSC logs to diagnose script errors .............................................................. 308
Where are DSC event logs?.................................................................................................................... 308
What do DSC logs contain? ................................................................................................................... 309
Gathering events from a single DSC operation ...................................................................................... 309
1: Operations failures ......................................................................................................................... 311
2: Details of operations run in the last half hour ................................................................................ 312
3: Messages from the latest operation ............................................................................................... 312
4: Error messages logged for recent failed operations ....................................................................... 313
5: All events generated for a particular job ID. ................................................................................... 313
Using xDscDiagnostics to analyze DSC logs .......................................................................................... 314
Getting details of DSC operations ...................................................................................................... 314
Getting details of DSC events ............................................................................................................. 315
Getting events for a remote computer ............................................................................................... 319
My resources wont update: How to reset the cache ............................................................................. 321
Using DebugMode ................................................................................................................................. 322
See Also ................................................................................................................................................. 326
Reference ........................................................................................................................................... 326
Concepts ............................................................................................................................................ 326
Other Resources ................................................................................................................................. 326
Using DSC on Nano Server .......................................................................................................................... 327
DSC features available on Nano Server ................................................................................................. 327
DSC features not available on Nano Server ........................................................................................... 329
Using custom DSC resources on Nano Server ....................................................................................... 329
See Also ................................................................................................................................................. 330
Get started with Desired State Configuration (DSC) for Linux ........................................................................ 331
Supported Linux operation system versions .......................................................................................... 331
Installing DSC for Linux .......................................................................................................................... 332
Installing OMI ..................................................................................................................................... 332
Installing DSC ..................................................................................................................................... 332
Using DSC for Linux ............................................................................................................................... 333
Creating a configuration MOF document .......................................................................................... 333
Push the configuration to the Linux computer ................................................................................... 334
Distribute the configuration with a pull server ................................................................................... 335
Working with configurations locally ................................................................................................... 335
PowerShell Desired State Configuration for Linux Log Files .................................................................. 336
Built-In Desired State Configuration Resources for Linux ............................................................................... 337
Built-in resources ................................................................................................................................... 337
DSC for Linux nxArchive Resource ............................................................................................................... 338
Syntax .................................................................................................................................................... 338
Properties ............................................................................................................................................... 338
Example ................................................................................................................................................. 339
DSC for Linux nxEnvironment Resource........................................................................................................ 340
Syntax .................................................................................................................................................... 340
Properties ............................................................................................................................................... 340
Additional Information........................................................................................................................... 341
Example ................................................................................................................................................. 341
DSC for Linux nxFile Resource...................................................................................................................... 341
Syntax .................................................................................................................................................... 341
Properties ............................................................................................................................................... 342
Additional Information........................................................................................................................... 343
Example ................................................................................................................................................. 345
DSC for Linux nxFileLine Resource ............................................................................................................... 346
Syntax .................................................................................................................................................... 346
Properties ............................................................................................................................................... 346
Example ................................................................................................................................................. 346
DSC for Linux nxGroup Resource ................................................................................................................. 348
Syntax .................................................................................................................................................... 348
Properties ............................................................................................................................................... 348
Example ................................................................................................................................................. 349
DSC for Linux nxPackage Resource .............................................................................................................. 350
Syntax .................................................................................................................................................... 350
Properties ............................................................................................................................................... 350
Example ................................................................................................................................................. 351
DSC for Linux nxService Resource ................................................................................................................ 352
Syntax .................................................................................................................................................... 352
Properties ............................................................................................................................................... 352
Additional Information........................................................................................................................... 353
Example ................................................................................................................................................. 353
DSC for Linux nxSshAuthorizedKeys Resource .............................................................................................. 354
Syntax .................................................................................................................................................... 354
Properties ............................................................................................................................................... 354
Example ................................................................................................................................................. 355
DSC for Linux nxUser Resource .................................................................................................................... 356
Syntax .................................................................................................................................................... 356
Properties ............................................................................................................................................... 356
Example ................................................................................................................................................. 357
Using DSC on Microsoft Azure .................................................................................................................... 359
Azure Desired State Configuration extension handler ........................................................................... 359
Azure Automation DSC .......................................................................................................................... 359
MSFT_DSCLocalConfigurationManager class ................................................................................................ 360
Syntax .................................................................................................................................................... 360
Members ................................................................................................................................................ 360
Methods ............................................................................................................................................. 360
Requirements ......................................................................................................................................... 362
ApplyConfiguration method of the MSFT_DSCLocalConfigurationManager class ........................................... 363
Syntax .................................................................................................................................................... 363
Parameters ............................................................................................................................................. 363
Return value ........................................................................................................................................... 363
Remarks ................................................................................................................................................. 363
Requirements ......................................................................................................................................... 363
See also .................................................................................................................................................. 364
DisableDebugConfiguration method of the MSFT_DSCLocalConfigurationManager class .............................. 365
Syntax .................................................................................................................................................... 365
Parameters ............................................................................................................................................. 365
Return value ........................................................................................................................................... 365
Remarks ................................................................................................................................................. 365
Requirements ......................................................................................................................................... 365
See also .................................................................................................................................................. 365
EnableDebugConfiguration method of the MSFT_DSCLocalConfigurationManager class ............................... 367
Syntax .................................................................................................................................................... 367
Parameters ............................................................................................................................................. 367
Return value ........................................................................................................................................... 367
Remarks ................................................................................................................................................. 367
Requirements ......................................................................................................................................... 367
See also .................................................................................................................................................. 368
GetConfiguration method of the MSFT_DSCLocalConfigurationManager class .............................................. 369
Syntax .................................................................................................................................................... 369
Parameters ............................................................................................................................................. 369
Return value ........................................................................................................................................... 369
Remarks ................................................................................................................................................. 369
Requirements ......................................................................................................................................... 369
See also .................................................................................................................................................. 370
GetConfigurationResultOutput method of the MSFT_DSCLocalConfigurationManager class .......................... 371
Syntax .................................................................................................................................................... 371
Parameters ............................................................................................................................................. 371
Return value ........................................................................................................................................... 371
Remarks ................................................................................................................................................. 371
Requirements ......................................................................................................................................... 372
See also .................................................................................................................................................. 372
GetConfigurationStatus method of the MSFT_DSCLocalConfigurationManager class ..................................... 373
Syntax .................................................................................................................................................... 373
Parameters ............................................................................................................................................. 373
Return value ........................................................................................................................................... 373
Remarks ................................................................................................................................................. 373
Requirements ......................................................................................................................................... 374
See also .................................................................................................................................................. 374
GetMetaConfiguration method of the MSFT_DSCLocalConfigurationManager class....................................... 375
Syntax .................................................................................................................................................... 375
Parameters ............................................................................................................................................. 375
Return value ........................................................................................................................................... 375
Remarks ................................................................................................................................................. 375
Requirements ......................................................................................................................................... 375
See also .................................................................................................................................................. 376
PerformRequiredConfigurationChecks method of the MSFT_DSCLocalConfigurationManager class ............... 377
Syntax .................................................................................................................................................... 377
Parameters ............................................................................................................................................. 377
Return value ........................................................................................................................................... 377
Remarks ................................................................................................................................................. 378
Requirements ......................................................................................................................................... 378
See also .................................................................................................................................................. 378
RemoveConfiguration method of the MSFT_DSCLocalConfigurationManager class ....................................... 379
Syntax .................................................................................................................................................... 379
Parameters ............................................................................................................................................. 379
Return value ........................................................................................................................................... 379
Remarks ................................................................................................................................................. 380
Requirements ......................................................................................................................................... 380
See also .................................................................................................................................................. 380
ResourceGet method of the MSFT_DSCLocalConfigurationManager class ..................................................... 381
Syntax .................................................................................................................................................... 381
Parameters ............................................................................................................................................. 381
Return value ........................................................................................................................................... 381
Remarks ................................................................................................................................................. 382
Requirements ......................................................................................................................................... 382
See also .................................................................................................................................................. 382
ResourceSet method of the MSFT_DSCLocalConfigurationManager class ...................................................... 383
Syntax .................................................................................................................................................... 383
Parameters ............................................................................................................................................. 383
Return value ........................................................................................................................................... 383
Remarks ................................................................................................................................................. 384
Requirements ......................................................................................................................................... 384
See also .................................................................................................................................................. 384
ResourceTest method of the MSFT_DSCLocalConfigurationManager class .................................................... 385
Syntax .................................................................................................................................................... 385
Parameters ............................................................................................................................................. 385
Return value ........................................................................................................................................... 385
Remarks ................................................................................................................................................. 386
Requirements ......................................................................................................................................... 386
See also .................................................................................................................................................. 386
RollBack method of the MSFT_DSCLocalConfigurationManager class ............................................................ 387
Syntax .................................................................................................................................................... 387
Parameters ............................................................................................................................................. 387
Return value ........................................................................................................................................... 387
Remarks ................................................................................................................................................. 387
Requirements ......................................................................................................................................... 387
See also .................................................................................................................................................. 388
SendConfiguration method of the MSFT_DSCLocalConfigurationManager class ............................................ 389
Syntax .................................................................................................................................................... 389
Parameters ............................................................................................................................................. 389
Return value ........................................................................................................................................... 389
Remarks ................................................................................................................................................. 389
Requirements ......................................................................................................................................... 389
See also .................................................................................................................................................. 390
SendConfigurationApply method of the MSFT_DSCLocalConfigurationManager class ................................... 391
Syntax .................................................................................................................................................... 391
Parameters ............................................................................................................................................. 391
Return value ........................................................................................................................................... 391
Remarks ................................................................................................................................................. 391
Requirements ......................................................................................................................................... 391
See also .................................................................................................................................................. 392
SendConfigurationApplyAsync method of the MSFT_DSCLocalConfigurationManager class .......................... 393
Syntax .................................................................................................................................................... 393
Parameters ............................................................................................................................................. 393
Return value ........................................................................................................................................... 393
Remarks ................................................................................................................................................. 393
Requirements ......................................................................................................................................... 394
See also .................................................................................................................................................. 394
SendMetaConfigurationApply method of the MSFT_DSCLocalConfigurationManager class............................ 395
Syntax .................................................................................................................................................... 395
Parameters ............................................................................................................................................. 395
Return value ........................................................................................................................................... 395
Remarks ................................................................................................................................................. 395
Requirements ......................................................................................................................................... 395
See also .................................................................................................................................................. 396
StopConfiguration method of the MSFT_DSCLocalConfigurationManager class ............................................. 397
Syntax .................................................................................................................................................... 397
Parameters ............................................................................................................................................. 397
Return value ........................................................................................................................................... 397
Remarks ................................................................................................................................................. 397
Requirements ......................................................................................................................................... 397
See also .................................................................................................................................................. 398
TestConfiguration method of the MSFT_DSCLocalConfigurationManager class ............................................. 399
Syntax .................................................................................................................................................... 399
Parameters ............................................................................................................................................. 399
Return value ........................................................................................................................................... 400
Remarks ................................................................................................................................................. 400
Requirements ......................................................................................................................................... 400
See also .................................................................................................................................................. 400
Windows PowerShell Desired State
Configuration Overview
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

DSC is a management platform in PowerShell that enables you to manage your IT and
development infrastructure with configuration as code.

For an overview of the business benefits of using DSC, see Desired State
Configuration Overview for Decision Makers.
For an overview of the engineering benefits of using DSC, see Desired State
Configuration Overview for Engineers.
To start using DSC quickly, see DSC quick start.

Key Concepts
DSC is a declarative platform used for configuration, deployment, and management of
systems. It consists of three primary components:

Configurations are declarative PowerShell scripts which define and configure


instances of resources. Upon running the configuration, DSC (and the resources
being called by the configuration) will simply make it so, ensuring that the
system exists in the state laid out by the configuration. DSC configurations are also
idempotent: the Local Configuration Manager (LCM) will continue to ensure that
machines are configured in whatever state the configuration declares.
Resources are the "make it so" part of DSC. They contain the code that put and
keep the target of a configuration in the specified state. Resources reside in
PowerShell modules and can be written to model something as generic as a file or
a Windows process, or as specific as an IIS server or a VM running in Azure.
The Local Configuration Manager (LCM) is the engine by which DSC facilitates the
interaction between resources and configurations. The LCM regularly polls the
system using the control flow implemented by resources to ensure that the state
defined by a configuration is maintained. If the system is out of state, the LCM
makes calls to the code in resources to make it so according to the configuration.
+

See Also
DSC Configurations
DSC Resources
Configuring The Local Configuration Manager
Desired State Configuration Overview for
Decision Makers
Document describes the business benefits of using PowerShell Desired State
Configuration (DSC). It is not a technical guide.

What Is Desired State Configuration?


Windows PowerShell Desired State Configuration (DSC) is a configuration management
platform built into Windows that is based on open standards. DSC is flexible enough to
function reliably and consistently in each stage of the deployment lifecycle
(development, test, pre-production, production), as well as during scale-out.

DSC centers around "configurations". A configuration is an easy-to-read document that


describes an environment made up of computers ("nodes") with specific characteristics.
These characteristics can be as simple as ensuring a specific Windows feature is enabled
or as complex as deploying SharePoint.

DSC also has monitoring and reporting built in. If a system is no longer compliant, DSC
can raise an alert and act to correct the system.

Benefits of Using Desired State Configuration


Configurations are designed to be easily read, stored, and updated. Configurations
declare the state target devices should be in, instead of writing instructions for how to
put them in that state. This makes it much less costly to learn, adopt, implement, and
maintain configuration through DSC.

Creating configurations means that complex deployment steps are captured as a "single
source of truth" in a single location. This makes repeated deployments of a specific set
of machines much less error-prone. In turn, this makes deployments faster and more
reliable. This enables quick turnaround on complex deployments.

Configurations are also shareable via the PowerShell Gallery. This means common
scenarios and best practices might already exist for the work you need done.
Desired State Configuration and DevOps
DevOps is a combination of people, technologies, and culture that allow for rapid
deployment and iteration. DSC was designed with DevOps in mind. Having a single
configuration define an environment means that developers can encode their
requirements into a configuration, check that configuration into source control, and
operations teams can easily deploy code without having to go through error-prone
manual processes.

Configurations are also data-driven, which makes it easier for ops teams to identify and
change environments without developer intervention.

Desired State Configuration On- and Off-Premises


DSC can be used to manage both on-premises and off-premises deployments. For on-
premises solutions, DSC has a pull server that can be used to centralize management of
machines and report on their status. For cloud solutions, DSC is usable wherever
Windows is usable. There are also specific offerings from Azure built on Desired State
Configuration, such as Azure Automation, which centralizes reporting of DSC.

DSC and Compatibility


Although DSC was introduced in Windows Server 2012 R2, it is available for downlevel
operating systems via the Windows Management Framework (WMF) package. More
information about the WMF can be found on the PowerShell homepage.

DSC can also be used to manage Linux. For more information, see Getting Started with
DSC for Linux.
Desired State Configuration Overview for
Engineers
This document is intended for developer and operations teams to understand the
benefits of PowerShell Desired State Configuration (DSC). For a higher level view of the
value DSC provides, please see Desired State Configuration Overview for Decision
Makers

Benefits of Desired State Configuration


DSC exists to:

Decrease the complexity of scripting in Windows


Increase the speed of iteration

The concept of "continuous deployment" is becoming more important. Continuous


deployment means the ability to deploy frequently, potentially many times per day. The
purpose of these deployments are not to fix something but to get something published
quickly. By getting new features through development into operation as smoothly and
reliably as possible, you reduce time-to-value of new business logic.

There are two trends at play which exacerbate this need to move quickly. The move
towards cloud computing implies rapid change, at scale, with a constant threat of
failure. These implications force automation in order to keep up. The creation of the
"DevOps" mentality is a response to these changes.

DSC is a platform that provides declarative, autonomous and idempotent (repeatable)


deployment, configuration and conformance. The DSC platform enables you to ensure
that the components of your data center have the correct configuration, which avoids
errors and prevents costly deployment failures. By treating DSC configurations as part of
application code, DSC enables continuous deployment. The DSC configuration should
be updated as a part of the application, ensuring that the knowledge needed to deploy
the application is always up-to-date and ready to be used.

"I have PowerShell, why do I need Desired State


Configuration?"
DSC configurations separate intent, or "what I want to do", from execution, or "how I
want to do it." This means the logic of execution is contained within the resources. Users
do not have to know how to implement or deploy a feature when a DSC resource for
that feature is available. This allows the user to focus on the structure of their
deployment.

As an example, PowerShell scripts should look like this:


PowerShellCopy

# Create a share in Windows Server 8


New-SmbShare -Name MyShare -Path C:\Demo\Temp -FullAccess Alice -ReadAccess Bob

This script is simple, comprehensible, and straightforward. However, if you try putting
that script into production, you will run into several issues. What happens if that script is
run twice in a row? What happens if Bob previously had Full Access to the share?

To compensate for these issues, a "real" version of the script will look closer to
something like:
PowerShellCopy

# But actually creating a share in an idempotent way would be

$shareExists = $false
$smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue
if($smbShare -ne $null)
{
Write-Verbose -Message "Share with name $Name exists"
$shareExists = $true
}

if ($shareExists -eq $false)


{
Write-Verbose "Creating share $Name to ensure it is Present"
New-SmbShare @psboundparameters
}
else
{
# Need to call either Set-SmbShare or *ShareAccess cmdlets
if ($psboundparameters.ContainsKey("ChangeAccess"))
{
#...etc, etc, etc
}
}

This script is more complex, with plenty of logic and error handling. The script is more
complex because you are no longer stating what you want done, but how to do it.

DSC allows you to say what you want done, and the underlying logic is abstracted away.
PowerShellCopy

# A configuration is a special kind of PowerShell function


Configuration Sample_Share
{
Import-DscResource -Module xSmbShare
# Nodes are the endpoint we wish to configure
# A Configuration block can have zero or more Node blocks
Node $NodeName
{
# Next, specify one or more resource blocks
# Resources are simply PowerShell modules that
# implement the logic of "how" to execute a task
xSmbShare MySMBShare
{
Ensure = "Present"
Name = "MyShare"
Path = "C:\Demo\Temp"
ReadAccess = "Alice"
FullAccess = "Bob"
Description = "This is an updated description for this share"
}
}
}
#Run the function to compile the configuration
Sample_Share
#Pass the configuration to the nodes we defined and configure them
Start-DscConfiguration Sample_Share

This script is cleanly formatted and straightforward to read. The logic paths and error
handling are still present in the resource implementation, but invisible to the script
author.

Separating Environment from Structure


A common pattern in DevOps is to have multiple environments for deployment. For
example, there might be a "dev" environment used to quickly prototype new code. The
code from the "dev" environment goes into a "test" environment, where other people
verify the new functionality. Finally, the code goes into "prod", or the live site production
environment.

DSC configurations accomodate this dev-test-prod pipeline through the use


of configuration data. This further abstracts the difference between the structure of the
configuration from the nodes that are managed. For example, you can define a
configuration that requires a SQL server, an IIS server, and a middle-tier server.
Regardless of what nodes receive the different pieces of this configuration, those three
elements will always be present. You can use configuration data to point all three
elements towards the same machine for a dev environment, separate out the three
elements to three different machines for a test environment, and finally towards all your
production servers for the prod environment. To deploy to the different environments,
you can invoke Start-DscConfiguration with the correct configuration data for the
environment you want to target.

See Also
Configurations

Configuration Data

Resources
Desired State Configuration Quick Start
This exercise walks through creating and applying a Desired State Configuration (DSC)
configuration from start to finish. The example we'll use ensures that a server has
the Web-Server (IIS) feature enabled, and that the content for a simple "Hello World"
website is present in the intetpub\wwwroot directory of that server.

For an overview of what DSC is and how it works, see Desired State Configuration
Overview for Decision Makers.

Requirements
To run this example, you will need a computer running Windows Server 2012 or later
and PowerShell 4.0 or later.

Write and place the index.htm file


First, we'll create the HTML file that we will use as the website content.

In your root folder, create a folder named test .

In a text editor, type the following text:


htmlCopy

<head></head>
<body>
<p>Hello World!</p>
</body>

Save this as index.htm in the test folder you created earlier.

Write the configuration


A DSC configuration is a special PowerShell function that defines how you want to
configure one or more target computers (nodes).
In the PowerShell ISE, type the following:
PowerShellCopy

Configuration WebsiteTest {

# Import the module that contains the resources we're using.


Import-DscResource -ModuleName PsDesiredStateConfiguration

# The Node statement specifies which targets this configuration will be applied
to.
Node 'localhost' {

# The first resource block ensures that the Web-Server (IIS) feature is
enabled.
WindowsFeature WebServer {
Ensure = "Present"
Name = "Web-Server"
}

# The second resource block ensures that the website content copied to the
website root folder.
File WebsiteContent {
Ensure = 'Present'
SourcePath = 'c:\test\index.htm'
DestinationPath = 'c:\inetpub\wwwroot'
}
}
}

Save the file as WebsiteTest.ps1 .

You can see that it looks like a PowerShell function, with the addition of the
keyword Configuration used before the name of the function.

The Node block specifies the target node to be configured, in this case localhost .

The configuration calls two resources, WindowsFeature and File. Resources do the work
of ensuring that the target node is in the state defined by the configuration.

Compile the configuration


For a DSC configuration to be applied to a node, it must first be compiled into a MOF
file. To do this, you run the configuration like a function. In a PowerShell console,
navigate to the same folder where you saved your configuration and run the following
commands to compile the configuration into a MOF file:
PowerShellCopy

. .\WebsiteTest.ps1
WebsiteTest

This generates the following output:


Copy

Directory: C:\ConfigurationTest\WebsiteTest

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 3/13/2017 5:20 PM 2746 localhost.mof

The first line makes the configuration function available in the console. The second line
runs the configuration. The result is that a new folder, named WebsiteTest is created as
a subfolder of the current folder. The WebsiteTest folder contains a file
named localhost.mof . It is this file that can then be applied to the target node.

Apply the configuration


Now that you have the compiled MOF, you can apply the configuration to the target
node (in this case, the local computer) by calling the Start-DscConfiguration cmdlet.

The Start-DscConfiguration cmdlet tells the Local Configuration Manager (LCM), which
is the engine of DSC, to apply the configuration. The LCM does the work of calling the
DSC resources to apply the configuration.

In a PowerShell console, navigate to the same folder where you saved your
configuration and run the following command:
PowerShellCopy

Start-DscConfiguration .\WebsiteTest
Test the configuration
You can call the Get-DscConfigurationStatus cmdlet to see whether the configuration
succeeded.

You can also test the results directly, in this case by browsing to http://localhost/ in a
web browser. You should see the "Hello World" HTML page you created as the first step
in this example.

Next steps
Find out more about DSC configurations at DSC configurations.
See what DSC resources are available, and how to create custom DSC resources
at DSC resources.
Find DSC configurations and resources in the PowerShell Gallery.
DSC Configurations
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

DSC configurations are PowerShell scripts that define a special type of function. To
define a configuration, you use the PowerShell keyword Configuration.
PowerShellCopy

Configuration MyDscConfiguration {

Node "TEST-PC1" {
WindowsFeature MyFeatureInstance {
Ensure = "Present"
Name = "RSAT"
}
WindowsFeature My2ndFeatureInstance {
Ensure = "Present"
Name = "Bitlocker"
}
}
}

MyDscConfiguration

Save the script as a .ps1 file.

Configuration syntax
A configuration script consists of the following parts:

The Configuration block. This is the outermost script block. You define it by using
the Configuration keyword and providing a name. In this case, the name of the
configuration is "MyDscConfiguration".
One or more Node blocks. These define the nodes (computers or VMs) that you
are configuring. In the above configuration, there is one Node block that targets a
computer named "TEST-PC1".
One or more resource blocks. This is where the configuration sets the properties
for the resources that it is configuring. In this case, there are two resource blocks,
each of which call the "WindowsFeature" resource.
Within a Configuration block, you can do anything that you normally could in a
PowerShell function. For example, in the previous example, if you didn't want to hard
code the name of the target computer in the configuration, you could add a parameter
for the node name:
PowerShellCopy

Configuration MyDscConfiguration {

param(
[string[]]$ComputerName="localhost"
)
Node $ComputerName {
WindowsFeature MyFeatureInstance {
Ensure = "Present"
Name = "RSAT"
}
WindowsFeature My2ndFeatureInstance {
Ensure = "Present"
Name = "Bitlocker"
}
}
}

MyDscConfiguration

In this example, you specify the name of the node by passing it as


the ComputerName parameter when you compile the configuraton. The name defaults
to "localhost".

Compiling the configuration


Before you can enact a configuration, you have to compile it into a MOF document. You
do this by calling the configuration like you would a PowerShell function.
The last line of the example containing only the name of the configuration, calls the
configuration.

Note: To call a configuration, the function must be in global scope (as with any other
PowerShell function). You can make this happen either by "dot-sourcing" the script, or
by running the configuration script by using F5 or clicking on the Run Script button in
the ISE. To dot-source the script, run the command .
.\myConfig.ps1 where myConfig.ps1 is the name of the script file that contains your
configuration.

When you call the configuration, it:

Resolves all variables


Creates a folder in the current directory with the same name as the configuration.
Creates a file named NodeName.mof in the new directory, where NodeName is the
name of the target node of the configuration. If there are more than one nodes, a
MOF file will be created for each node.

Note: The MOF file contains all of the configuration information for the target node.
Because of this, its important to keep it secure. For more information, see Securing the
MOF file.

Compiling the first configuration above results in the following folder structure:
PowerShellCopy

. .\MyDscConfiguration.ps1
MyDscConfiguration

Copy

Directory: C:\users\default\Documents\DSC Configurations\MyDscConfiguration


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/23/2015 4:32 PM 2842 TEST-PC1.mof

If the configuration takes a parameter, as in the second example, that has to be


provided at compile time. Here's how that would look:
PowerShellCopy

. .\MyDscConfiguration.ps1
MyDscConfiguration -ComputerName 'MyTestNode'

Copy

Directory: C:\users\default\Documents\DSC Configurations\MyDscConfiguration


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/23/2015 4:32 PM 2842 MyTestNode.mof
Using DependsOn
A useful DSC keyword is DependsOn. Typically (though not necessarily always), DSC
applies the resources in the order that they appear within the configuration.
However, DependsOn specifies which resources depend on other resources, and the
LCM ensures that they are applied in the correct order, regardless of the order in which
resource instances are defined. For example, a configuration might specify that an
instance of the User resource depends on the existence of a Group instance:
PowerShellCopy

Configuration DependsOnExample {
Node Test-PC1 {
Group GroupExample {
Ensure = "Present"
GroupName = "TestGroup"
}

User UserExample {
Ensure = "Present"
UserName = "TestUser"
FullName = "TestUser"
DependsOn = "[Group]GroupExample"
}
}
}

DependsOnExample

Using new resources in Your configuration


If you ran the previous examples, you might have noticed that you were warned that
you were using a resource without explicitly importing it. Today, DSC ships with 12
resources as part of the PSDesiredStateConfiguration module. Other resources in
external modules must be placed in $env:PSModulePath in order to be recognized by the
LCM. A new cmdlet, Get-DscResource, can be used to determine what resources are
installed on the system and available for use by the LCM. Once these modules have
been placed in $env:PSModulePath and are properly recognized by Get-DscResource,
they still need to be loaded within your configuration. Import-DscResource is a
dynamic keyword that can only be recognized within a Configuration block (i.e. it is not
a cmdlet). Import-DscResource supports two parameters:
ModuleName is the recommended way of using Import-DscResource. It accepts
the name of the module that contains the resources to be imported (as well as a
string array of module names).
Name is the name of the resource to import. This is not the friendly name returned
as "Name" by Get-DscResource, but the class name used when defining the
resource schema (returned as ResourceType by Get-DscResource).

See Also
Windows PowerShell Desired State Configuration Overview
DSC Resources
Configuring The Local Configuration Manager
Enacting configurations
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

There are two ways to enact PowerShell Desired State Configuration (DSC)
configurations: push mode and pull mode.

Push mode

Push mode refers to a user actively applying a configuration to a target node by calling
the Start-DscConfiguration cmdlet.

After creating and compiling a configuration, you can enact it in push mode by calling
the Start-DscConfiguration cmdlet, setting the -Path parameter of the cmdlet to the
path where the configuration MOF is located. For example, if the configuration MOF is
located at C:\DSC\Configurations\localhost.mof , you would apply it to the local
machine with the following command: Start-DscConfiguration -Path
'C:\DSC\Configurations'

Note: By default, DSC runs a configuration as a background job. To run the


configuration interactively, call the Start-DscConfiguration with the -Wait parameter.

Pull mode

In pull mode, pull clients are configured to get their desired state configurations from a
remote pull server. Likewise, the pull server has been set up to host the DSC service, and
has been provisioned with the configurations and resources that are required by the pull
clients. Each one of the pull clients has a scheduled task that performs a periodic
compliance check on the configuration of the node. When the event is triggered the first
time, the Local Configuration Manager (LCM) on the pull client makes a request to the
pull server to get the configuration specified in the LCM. If that configuration exists on
the pull server, and it passes initial validation checks, the configuration is transmitted to
the pull client, where it is then executed by the LCM.
The LCM checks that the client is in compliance with the configuration at regular
intervals specified by the ConfigurationModeFrequencyMinsproperty of the LCM. The
LCM checks for updated configurations on the pull server at regular intervals specified
by the RefreshModeFrequencyproperty of the LCM. For information about configuring
the LCM, see Configuring the Local Configuration Manager.

For more information on setting up a DSC Pull Server, see Setting up a DSC web pull
server.

If you would prefer to take advantage of an online service to host Pull Server
functionality, see the Azure Automation DSC service.

The following topics explain how to set up pull servers and clients:

Setting up a web pull server


Setting up an SMB pull server
Configuring a pull client
Separating configuration and environment
data
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

It can be useful to separate the data used in a DSC configuration from the configuration
itself by using configuration data. By doing this, you can use a single configuration for
multiple environments.

For example, if you are developing an application, you can use one configuration for
both development and production environments, and use configuration data to specify
data for each environment.

What is configuration data?


Configuration data is data that is defined in a hashtable and passed to a DSC
configuration when you compile that configuration.

For a detailed description of the ConfigurationData hashtable, see Using configuration


data.

A simple example
Let's look at a very simple example to see how this works. We'll create a single
configuration that ensures that IIS is present on some nodes, and that Hyper-V is
present on others:
PowerShellCopy

Configuration MyDscConfiguration {

Node $AllNodes.Where{$_.Role -eq "WebServer"}.NodeName


{
WindowsFeature IISInstall {
Ensure = 'Present'
Name = 'Web-Server'
}

}
Node $AllNodes.Where{$_.Role -eq "VMHost"}.NodeName
{
WindowsFeature HyperVInstall {
Ensure = 'Present'
Name = 'Hyper-V'
}
}
}

$MyData =
@{
AllNodes =
@(
@{
NodeName = 'VM-1'
Role = 'WebServer'
},

@{
NodeName = 'VM-2'
Role = 'VMHost'
}
)
}

MyDscConfiguration -ConfigurationData $MyData

The last line in this script compiles the configuration, passing $MyData as the
value ConfigurationData parameter.

The result is that two MOF files are created:


Copy

Directory: C:\DscTests\MyDscConfiguration

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 3/31/2017 5:09 PM 1968 VM-1.mof
-a---- 3/31/2017 5:09 PM 1970 VM-2.mof
$MyData specifies two different nodes, each with its own NodeName and Role . The
configuration dynamically creates Node blocks by taking the collection of nodes it gets
from $MyData (specifically, $AllNodes ) and filters that collection against
the Role property..

Using configuration data to define development and


production environments
Let's look at a complete example that uses a single configuration to set up both
development and production environments of a website. In the development
environment, both IIS and SQL Server are installed on a single nodes. In the production
environment, IIS and SQL Server are installed on separate nodes. We'll use a
configuration data .psd1 file to specify the data for the two different environments.

Configuration data file

We'll define the development and production environment data in a file


namd DevProdEnvData.psd1 as follows:
PowerShellCopy

@{

AllNodes = @(

@{
NodeName = "*"
SQLServerName = "MySQLServer"
SqlSource = "C:\Software\Sql"
DotNetSrc = "C:\Software\sxs"
},

@{
NodeName = "Prod-SQL"
Role = "MSSQL"
},

@{
NodeName = "Prod-IIS"
Role = "Web"
SiteContents = "C:\Website\Prod\SiteContents\"
SitePath = "\\Prod-IIS\Website\"
},

@{
NodeName = "Dev"
Role = "MSSQL", "Web"
SiteContents = "C:\Website\Dev\SiteContents\"
SitePath = "\\Dev\Website\"
}
)
}

Configuration script file

Now, in the configuration, which is defined in a .ps1 file, we filter the nodes we defined
in DevProdEnvData.psd1 by their role ( MSSQL , Dev , or both), and configure them
accordingly. The development environment has both the SQL Server and IIS on one
node, while the production environment has them on two different nodes. The site
contents is also different, as specified by the SiteContents properties.

At the end of the configuration script, we call the configuration (compile it into a MOF
document), passing DevProdEnvData.psd1 as the $ConfigurationData parameter.

Note: This configuration requires the modules xSqlPs and xWebAdministration to be


installed on the target node.

Let's define the configuration in a file named MyWebApp.ps1 :


PowerShellCopy

Configuration MyWebApp
{
Import-DscResource -Module PSDesiredStateConfiguration
Import-DscResource -Module xSqlPs
Import-DscResource -Module xWebAdministration

Node $AllNodes.Where{$_.Role -contains "MSSQL"}.Nodename


{
# Install prerequisites
WindowsFeature installdotNet35
{
Ensure = "Present"
Name = "Net-Framework-Core"
Source = "c:\software\sxs"
}

# Install SQL Server


xSqlServerInstall InstallSqlServer
{
InstanceName = $Node.SQLServerName
SourcePath = $Node.SqlSource
Features = "SQLEngine,SSMS"
DependsOn = "[WindowsFeature]installdotNet35"

}
}

Node $AllNodes.Where{$_.Role -contains "Web"}.NodeName


{
# Install the IIS role
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}

# Install the ASP .NET 4.5 role


WindowsFeature AspNet45
{
Ensure = 'Present'
Name = 'Web-Asp-Net45'

# Stop the default website


xWebsite DefaultSite
{
Ensure = 'Present'
Name = 'Default Web Site'
State = 'Stopped'
PhysicalPath = 'C:\inetpub\wwwroot'
DependsOn = '[WindowsFeature]IIS'

# Copy the website content


File WebContent
{
Ensure = 'Present'
SourcePath = $Node.SiteContents
DestinationPath = $Node.SitePath
Recurse = $true
Type = 'Directory'
DependsOn = '[WindowsFeature]AspNet45'

# Create the new Website

xWebsite NewWebsite

Ensure = 'Present'
Name = $WebSiteName
State = 'Started'
PhysicalPath = $Node.SitePath
DependsOn = '[File]WebContent'
}

MyWebApp -ConfigurationData DevProdEnvData.psd1

When you run this configuration, three MOF files are created (one for each named entry
in the AllNodes array):
Copy

Directory: C:\DscTests\MyWebApp

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 3/31/2017 5:47 PM 2944 Prod-SQL.mof
-a---- 3/31/2017 5:47 PM 6994 Dev.mof
-a---- 3/31/2017 5:47 PM 5338 Prod-IIS.mof

Using non-node data


You can add additional keys to the ConfigurationData hashtable for data that is not
specific to a node. The following configuration ensures the presence of two websites.
Data for each website are defined in the AllNodes array. The file Config.xml is used for
both websites, so we define it in an additional key with the name NonNodeData . Note
that you can have as many additional keys as you want, and you can name them
anything you want. NonNodeData is not a reserved word, it is just what we decided to
name the additional key.

You access additional keys by using the special variable $ConfigurationData. In this
example, ConfigFileContents is accessed with the line:
PowerShellCopy

Contents = $ConfigurationData.NonNodeData.ConfigFileContents

in the File resource block.


PowerShellCopy

$MyData =
@{
AllNodes =
@(
@{
NodeName = *
LogPath = C:\Logs
},

@{
NodeName = VM-1
SiteContents = C:\Site1
SiteName = Website1
},

@{
NodeName = VM-2;
SiteContents = C:\Site2
SiteName = Website2
}
);

NonNodeData =
@{
ConfigFileContents = (Get-Content C:\Template\Config.xml)
}
}

configuration WebsiteConfig
{
Import-DscResource -ModuleName xWebAdministration -Name MSFT_xWebsite

node $AllNodes.NodeName
{
xWebsite Site
{
Name = $Node.SiteName
PhysicalPath = $Node.SiteContents
Ensure = Present
}

File ConfigFile
{
DestinationPath = $Node.SiteContents + \\config.xml
Contents = $ConfigurationData.NonNodeData.ConfigFileContents
}
}
}

See Also
Using configuration data
Credentials Options in Configuration Data
DSC Configurations
Using resources with multiple versions
Applies To: Windows PowerShell 5.0

In PowerShell 5.0, DSC resources can have multiple versions, and versions can be
installed on a computer side-by-side. This is implemented by having multiple versions of
a resource module that are contained in the same module folder.

Installing multiple resource versions side-by-side


You can use the MinimumVersion, MaximumVersion,
and RequiredVersion parameters of the Install-Module cmdlet to specify which version
of a module to install. Calling Install-Module without specifying a version installs the
most recent version.

For example, there are multiple versions of the xFailOverCluster module, each of which
contains an xCluster resouce. The result of calling Install-Module without specifying
the version number is as follows:
PowerShellCopy

C:\Program Files\WindowsPowerShell\Modules\xFailOverCluster> Install-Module


xFailOverCluster
C:\Program Files\WindowsPowerShell\Modules\xFailOverCluster> Get-DscResource xCluster

ImplementedAs Name ModuleName Version


Properties
------------- ---- ---------- ------- -
---------
PowerShell xCluster xFailOverCluster 1.2.0.0
{DomainAdministratorCredential, ...

Now, if you call Install-Module again, but specify a RequiredVersion of 1.1.0.0, it


results in the following:
PowerShellCopy

C:\Program Files\WindowsPowerShell\Modules\xFailOverCluster> Install-Module


xFailOverCluster -RequiredVersion 1.1
C:\Program Files\WindowsPowerShell\Modules\xFailOverCluster> Get-DscResource xCluster
ImplementedAs Name ModuleName Version
Properties
------------- ---- ---------- ------- -
---------
PowerShell xCluster xFailOverCluster 1.1
{DomainAdministratorCredential, Name, ...
PowerShell xCluster xFailOverCluster 1.2.0.0
{DomainAdministratorCredential, Name, ...

Specifying a resource version in a configuration


If you have multiple resources installed on a computer, you must specify the version of
that resource when you use it in a configuration. You do this by specifying
the ModuleVersion parameter of the Import-DscResource keyword. If you fail to
specify the version of a resource module of a resource of which you have more than one
version installed, the configuration generates an error.

The following configuration shows how to specify the version of the resource to call:
PowerShellCopy

configuration VersionTest
{
Import-DscResource -ModuleName xFailOverCluster -ModuleVersion 1.1

Node 'localhost'
{
xCluster ClusterTest
{
Name = 'TestCluster'
StaticIPAddress = '10.0.0.3'
DomainAdministratorCredential = Get-Credential
}
}
}

Note: The ModuleVersion parameter of Import-DscResource is not available in


PowerShell 4.0. In PowerShell 4.0, you can specify a module version by passing a module
specification object to the ModuleName parameter of Import-DscResource. A module
specification object is a hash table that contains ModuleName and RequiredVersion
keys. For example:
PowerShellCopy

configuration VersionTest
{
Import-DscResource -ModuleName (@{ModuleName='xFailOverCluster';
RequiredVersion='1.1'} )

Node 'localhost'
{
xCluster ClusterTest
{
Name = 'TestCluster'
StaticIPAddress = '10.0.0.3'
DomainAdministratorCredential = Get-Credential
}
}
}

This will also work in PowerShell 5.0, but it is recommended that you use
the ModuleVersion parameter.

See also
DSC Configurations
DSC Resources
Running DSC with user credentials
Applies To: Windows PowerShell 5.0, Windows PowerShell 5.1

You can run a DSC resource under a specified set of credentials by using the
automatic PsDscRunAsCredential property in the configuration. By default, DSC runs
each resource as the system account. There are times when running as a user is
necessary, such as installing MSI packages in a specific user context, setting a user's
registry keys, accessing a user's specific local directory, or accessing a network share.

Every DSC resource has a PsDscRunAsCredential property that can be set to any user
credentials (a PSCredential object). The credential can be hard-coded as the value of the
property in the configuration, or you can set the value to Get-Credential, which will
prompt the user for a credential when the configuration is compiled (for information
about compiling configurations, see Configurations.

Note: In PowerShell 5.0, using the PsDscRunAsCredential property in configurations


calling composite resources was not supported. In PowerShell 5.1,
the PsDscRunAsCredential property is supported in configurations calling composite
resources.

Note: The PsDscRunAsCredential property is not available in PowerShell 4.0.

In the following example, Get-Credential is used to prompt the user for credentials.
The Registry resource is used to change the registry key that specifies the background
color for the Windows command prompt window.
PowerShellCopy

Configuration ChangeCmdBackGroundColor
{
Import-DscResource -ModuleName PSDesiredStateConfiguration

Node $AllNodes.NodeName
{
Registry CmdPath
{
Key = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command
Processor'
ValueName = 'DefaultColor'
ValueData = '1F'
ValueType = 'DWORD'
Ensure = 'Present'
Force = $true
Hex = $true
PsDscRunAsCredential = Get-Credential
}
}
}

$configData = @{
AllNodes = @(
@{
NodeName = 'localhost';
PSDscAllowDomainUser = $true
CertificateFile = 'C:\publicKeys\targetNode.cer'
Thumbprint = '7ee7f09d-4be0-41aa-a47f-96b9e3bdec25'
}
)
}

ChangeCmdBackGroundColor -ConfigurationData $configData

Note: This example assumes that you have a valid certificate


at C:\publicKeys\targetNode.cer , and that the thumbprint of that certificate is the value
shown. For information about encrypting credentials in DSC configuration MOF files,
see Securing the MOF file.
Specifying cross-node dependencies
Applies To: Windows PowerShell 5.0

DSC provides special resources, WaitForAll, WaitForAny, and WaitForSome that can
be used in configurations to specify dependencies on configurations on other nodes.
The behavior of these resources is as follows:

WaitForAll: Succeeds if the specified resource is in the desired state on all target
nodes defined in the NodeName property.
WaitForAny: Succeeds if the specified resource is in the desired state on at least
one of the target nodes defined in the NodeNameproperty.
WaitForSome: Specifies a NodeCount property in addition to
a NodeName property. The resource succeeds if the resource is in the desired
state on a minimum number of nodes (specified by NodeCount) defined by
the NodeName property.

Using WaitForXXXX resources


To use the WaitForXXXX resources, you create a resource block of that resource type
that specifies the DSC resource and node(s) to wait for. You then use
the DependsOn property in any other resource blocks in your configuration to wait for
the conditions specified in the WaitForXXXXnode to succeed.

For example, in the following configuration, the target node is waiting for
the xADDomain resource to finish on the MyDC node with maximum number of 30
retries, at 15-second intervals, before the target node can join the domain.
PowerShellCopy

Configuration JoinDomain

{
Import-DscResource -Module xComputerManagement, xActiveDirectory

Node myDC
{
WindowsFeature InstallAD
{
Ensure = 'Present'
Name = 'AD-Domain-Services'
}

xADDomain NewDomain
{
DomainName = 'Contoso.com'
DomainAdministratorCredential = (Get-Credential)
SafemodeAdministratorPassword = (Get-Credential)
DatabasePath = "C:\Windows\NTDS"
LogPath = "C:\Windows\NTDS"
SysvolPath = "C:\Windows\Sysvol"
}

Node myDomainJoinedServer
{

WaitForAll DC
{
ResourceName = '[xADDomain]NewDomain'
NodeName = 'MyDC'
RetryIntervalSec = 15
RetryCount = 30
}

xComputer JoinDomain
{
Name = 'myPC'
DomainName = 'Contoso.com'
Credential = (Get-Credential)
DependsOn ='[WaitForAll]DC'
}
}
}

Note: By default the WaitForXXX resources try one time and then fail. Although it is not
required, you will typically want to specify a retry interval and count.

See Also
DSC Configurations
DSC Resources
Configuring The Local Configuration Manager
Using configuration data in DSC
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

By using the built-in DSC ConfigurationData parameter, you can define data that can
be used within a configuration. This allows you to create a single configuration that can
be used for multiple nodes or for different environments. For example, if you are
developing an application, you can use one configuration for both development and
production environments, and use configuration data to specify data for each
environment.

This topic describes the structure of the ConfigurationData hashtable. For examples of
how to use configuration data, see Separating configuration and environment data.

The ConfigurationData common parameter


A DSC configuration takes a common parameter, ConfigurationData, that you specify
when you compile the configuration. For information about compiling configurations,
see DSC configurations.

The ConfigurationData parameter is a hasthtable that must have at least one key
named AllNodes. It can also have one or more other keys.

Note: The examples in this topic use a single additional key (other than the
named AllNodes key) named NonNodeData , but you can include any number of
additional keys, and name them whatever you want.
PowerShellCopy

$MyData =
@{
AllNodes = @()
NonNodeData = ""
}

The value of the AllNodes key is an array. Each element of this array is also a hash table
that must have at least one key named NodeName:
PowerShellCopy
$MyData =
@{
AllNodes =
@(
@{
NodeName = "VM-1"
},

@{
NodeName = "VM-2"
},

@{
NodeName = "VM-3"
}
);

NonNodeData = ""
}

You can add other keys to each hash table as well:


PowerShellCopy

$MyData =
@{
AllNodes =
@(
@{
NodeName = "VM-1"
Role = "WebServer"
},

@{
NodeName = "VM-2"
Role = "SQLServer"
},

@{
NodeName = "VM-3"
Role = "WebServer"
}
);

NonNodeData = ""
}

To apply a property to all nodes, you can create a member of the AllNodes array that
has a NodeName of * . For example, to give every node a LogPath property, you could
do this:
PowerShellCopy

$MyData =
@{
AllNodes =
@(
@{
NodeName = "*"
LogPath = "C:\Logs"
},

@{
NodeName = "VM-1"
Role = "WebServer"
SiteContents = "C:\Site1"
SiteName = "Website1"
},

@{
NodeName = "VM-2"
Role = "SQLServer"
},

@{
NodeName = "VM-3"
Role = "WebServer"
SiteContents = "C:\Site2"
SiteName = "Website3"
}
);
}

This is the equivalent of adding a property with a name of LogPath with a value
of "C:\Logs" to each of the other blocks ( VM-1 , VM-2 , and VM-3 ).

Defining the ConfigurationData hashtable


You can define ConfigurationData either as a variable within the same script file as a
configuration (as in our previous examples) or in a separate .psd1 file. To
define ConfigurationData in a .psd1 file, create a file that contains only the hashtable
that represents the configuration data.

For example, you could create a file named MyData.psd1 with the following contents:
PowerShellCopy

@{
AllNodes =
@(
@{
NodeName = 'VM-1'
FeatureName = 'Web-Server'
},

@{
NodeName = 'VM-2'
FeatureName = 'Hyper-V'
}
)
}

Compiling a configuration with configuration data


To compile a configuration for which you have defined configuration data, you pass the
cofiguration data as the value of the ConfigurationDataparameter.

This will create a MOF file for each entry in the AllNodes array. Each MOF file will be
named with the NodeName property of the corresponding array entry.
For example, if you define configuration data as in the MyData.psd1 file above, compiling
a configuration would create both VM-1.mof and VM-2.mof files.

Compiling a configuration with configuration data using a variable

To use configuration data that is defined as a variable in the same .ps1 file as the
configuration, you pass the variable name as the value of
the ConfigurationData parameter when compiling the configuration:
PowerShellCopy

MyDscConfiguration -ConfigurationData $MyData

Compiling a configuration with configuration data using a data file

To use configuration data that is defined in a .psd1 file, you pass the path and name of
that file as the value of the ConfigurationData parameter when compiling the
configuration:
PowerShellCopy

MyDscConfiguration -ConfigurationData .\MyData.psd1

Using ConfigurationData variables in a configuration


DSC provides three special variables that can be used in a configuration
script: $AllNodes, $Node, and $ConfigurationData.

$AllNodes refers to the entire collection of nodes defined in ConfigurationData. You can filter
the AllNodes collection by using .Where()and .ForEach().
Node refers to a particular entry in the AllNodes collection after it is filtered by
using .Where() or .ForEach().
ConfigurationData refers to the entire hash table that is passed as the parameter when compiling
a configuration.

Using non-node data


As we've seen in previous examples, the ConfigurationData hashtable can have one or
more keys in addition to the required AllNodes key. In the examples in this topic, we
have used only a single addiontal node, and named it NonNodeData . However, you can
define any number of addiontal keys, and name them anything you want.

For an example of using non-node data, see Separating configuration and environment
data.

See Also
Credentials Options in Configuration Data
DSC Configurations
Credentials Options in Configuration Data
Applies To: Windows PowerShell 5.0

Plain Text Passwords and Domain Users


DSC configurations containing a credential without encryption will generate an error
messages about plain text passwords. Also, DSC will generate a warning when using
domain credentials. To suppress these error and warning messages use the DSC
configuration data keywords:

PsDscAllowPlainTextPassword
PsDscAllowDomainUser

Note: Using plaintext passwords is not secure. Securing credentials by using the
techniques covered later in this topic is recommended.

The following is an example of passing plain text credentials:


PowerShellCopy

#Prompt user for their credentials


#credentials will be unencrypted in the MOF
$promptedCreds = get-credential -Message "Please enter your credentials to generate a
DSC MOF:"

# Store passwords in plaintext, in the document itself


# will also be stored in plaintext in the mof
$password = "ThisIsAPlaintextPassword" | ConvertTo-SecureString -asPlainText -Force
$username = "User1"
[PSCredential] $credential = New-Object
System.Management.Automation.PSCredential($username,$password)

# DSC requires explicit confirmation before storing passwords insecurely


$ConfigurationData = @{
AllNodes = @(
@{
# The "*" means "all nodes named in ConfigData" so we don't have to
repeat ourselves
NodeName="*"
PSDscAllowPlainTextPassword = $true
},
#however, each node still needs to be explicitly defined for "*" to have
meaning
@{
NodeName = "TestMachine1"
},
#we can also use a property to define node-specific passwords, although this
is no more secure
@{
NodeName = "TestMachine2";
UserName = "User2"
LocalPassword = "ThisIsYetAnotherPlaintextPassword"
}
)
}
configuration unencryptedPasswordDemo
{
Node "TestMachine1"
{
# We use the plaintext password to generate a new account
User User1
{
UserName = $username
Password = $credential
Description = "local account"
Ensure = "Present"
Disabled = $false
PasswordNeverExpires = $true
PasswordChangeRequired = $false
}
# We use the prompted password to add this account to the local admins group
Group addToAdmin
{
# Ensure the user exists before we add the user to a group
DependsOn = "[User]User1"
Credential = $promptedCreds
GroupName = "Administrators"
Ensure = "Present"
MembersToInclude = "User1"
}
}

Node "TestMachine2"
{
# Now we'll use a node-specific password to this machine
$password = $Node.LocalPass | ConvertTo-SecureString -asPlainText -Force
$username = $node.UserName
[PSCredential] $nodeCred = New-Object
System.Management.Automation.PSCredential($username,$password)

User User2
{
UserName = $username
Password = $nodeCred
Description = "local account"
Ensure = "Present"
Disabled = $false
PasswordNeverExpires = $true
PasswordChangeRequired = $false
}

Group addToAdmin
{
Credential = $domain
GroupName = "Administrators"
DependsOn = "[User]User2"
Ensure = "Present"
MembersToInclude = "User2"
}
}

}
# We declared the ConfigurationData in a local variable, but we need to pass it in to
our configuration function
# We need to invoke the configuration function we created to generate a MOF
unencryptedPasswordDemo -ConfigurationData $ConfigurationData
# We need to pass the MOF to the machines we named.
#-wait: doesn't use jobs so we get blocked at the prompt until the configuration is
done
#-verbose: so we can see what's going on and catch any errors
#-force: for testing purposes, I run start-dscconfiguration frequently + want to make
sure i'm
# not blocked by previous configurations that are still running
Start-DscConfiguration ./unencryptedPasswordDemo -verbose -wait -force

Handling Credentials in DSC


DSC configuration resources run as Local System by default. However, some resources
need a credential, for example when the Package resource needs to install software
under a specific user account.

Earlier resources used a hard-coded Credential property name to handle this. WMF 5.0
added an automatic PsDscRunAsCredential property for all resources. For information
about using PsDscRunAsCredential , see Running DSC with user credentials. Newer
resources and custom resources can use this automatic property instead of creating
their own property for credentials.

Note that the design of some resources are to use multiple credentials for a specific
reason, and they will have their own credential properties.

To find the available credential properties on a resource use either Get-DscResource -


Name ResourceName -Syntax or the Intellisense in the ISE ( CTRL+SPACE ).
PowerShellCopy

PS C:\> Get-DscResource -Name Group -Syntax


Group [String] #ResourceName
{
GroupName = [string]
[Credential = [PSCredential]]
[DependsOn = [string[]]]
[Description = [string]]
[Ensure = [string]{ Absent | Present }]
[Members = [string[]]]
[MembersToExclude = [string[]]]
[MembersToInclude = [string[]]]
[PsDscRunAsCredential = [PSCredential]]
}

This example uses a Group resource from the PSDesiredStateConfiguration built-in DSC
resource module. It can create local groups and add or remove members. It accepts
both the Credential property and the automatic PsDscRunAsCredential property.
However, the resource only uses the Credential property.

For more information about the PsDscRunAsCredential property, see Running DSC with
user credentials.
Example: The Group resource Credential property
DSC runs under Local System , so it already has permissions to change local users and
groups. If the member added is a local account, then no credential is necessary. If
the Group resource adds a domain account to the local group, then a credential is
necessary.

Anonymous queries to Active Directory are not allowed. The Credential property of
the Group resource is the domain account used to query Active Directory. For most
purposes this could be a generic user account, because by default users can read most
of the objects in Active Directory.

Example Configuration
The following example code uses DSC to populate a local group with a domain user:
PowerShellCopy

Configuration DomainCredentialExample
{
param
(
[PSCredential] $DomainCredential
)
Import-DscResource -ModuleName PSDesiredStateConfiguration

node localhost
{
Group DomainUserToLocalGroup
{
GroupName = 'ApplicationAdmins'
MembersToInclude = 'contoso\alice'
Credential = $DomainCredential
}
}
}

$cred = Get-Credential -UserName contoso\genericuser -Message "Password please"


DomainCredentialExample -DomainCredential $cred

This code generates both an error and warning message:


Copy

ConvertTo-MOFInstance : System.InvalidOperationException error processing


property 'Credential' OF TYPE 'Group': Converting and storing encrypted
passwords as plain text is not recommended. For more information on securing
credentials in MOF file, please refer to MSDN blog:
http://go.microsoft.com/fwlink/?LinkId=393729

At line:11 char:9
+ Group
At line:297 char:16
+ $aliasId = ConvertTo-MOFInstance $keywordName $canonicalizedValue
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Write-Error],
InvalidOperationException
+ FullyQualifiedErrorId : FailToProcessProperty,ConvertTo-MOFInstance

WARNING: It is not recommended to use domain credential for node 'localhost'.


In order to suppress the warning, you can add a property named
'PSDscAllowDomainUser' with a value of $true to your DSC configuration data
for node 'localhost'.

This example has two issues:

1. An error explains that plain text passwords are not recommended


2. A warning advises against using a domain credential

PsDscAllowPlainTextPassword
The first error message has a URL with documentation. This link explains how to encrypt
passwords using a ConfigurationData structure and a certificate. For more information
on certificates and DSC read this post.

To force a plain text password, the resource requires


the PsDscAllowPlainTextPassword keyword in the configuration data section as follows:
PowerShellCopy

Configuration DomainCredentialExample
{
param
(
[PSCredential] $DomainCredential
)
Import-DscResource -ModuleName PSDesiredStateConfiguration

node localhost
{
Group DomainUserToLocalGroup
{
GroupName = 'ApplicationAdmins'
MembersToInclude = 'contoso\alice'
Credential = $DomainCredential
}
}
}

$cd = @{
AllNodes = @(
@{
NodeName = 'localhost'
PSDscAllowPlainTextPassword = $true
}
)
}

$cred = Get-Credential -UserName contoso\genericuser -Message "Password please"


DomainCredentialExample -DomainCredential $cred -ConfigurationData $cd

Note that NodeName cannot equal asterisk, a specific node name is mandatory.

Microsoft advises to avoid plain text passwords due to the significant security
risk.

Domain Credentials
Running the example configuration script again (with or without encryption), still
generates the warning that using a domain account for a credential is not
recommended. Using a local account eliminates potential exposure of domain
credentials that could be used on other servers.

When using credentials with DSC resources, prefer a local account over a domain
account when possible.
If there is a '\' or '@' in the Username property of the credential, then DSC will treat it as
a domain account. There is an exception for "localhost", "127.0.0.1", and "::1" in the
domain portion of the user name.

PSDscAllowDomainUser
In the DSC Group resource example above, querying an Active Directory
domain requires a domain account. In this case add the PSDscAllowDomainUser property
to the ConfigurationData block as follows:
PowerShellCopy

$cd = @{
AllNodes = @(
@{
NodeName = 'localhost'
PSDscAllowDomainUser = $true
# PSDscAllowPlainTextPassword = $true
CertificateFile = "C:\PublicKeys\server1.cer"
}
)
}

Now the configuration script will generate the MOF file with no errors or warnings.
Nesting DSC configurations
A nested configuration (also called composite configuration) is a configuration that is
called within another configuration as if it were a resource. Both configurations must be
defined in the same file.

Let's look at a simple example:


PowerShellCopy

Configuration FileConfig
{
param (
[Parameter(Mandatory = $true)]
[String] $CopyFrom,

[Parameter(Mandatory = $true)]
[String] $CopyTo
)

Import-DscResource -ModuleName PSDesiredStateConfiguration

File FileTest
{
SourcePath = $CopyFrom
DestinationPath = $CopyTo
Ensure = 'Present'
}

Configuration NestedFileConfig
{
Node localhost
{
FileConfig NestedConfig
{
CopyFrom = 'C:\Test\TestFile.txt'
CopyTo = 'C:\Test2'
}
}
}
In this example, FileConfig takes two mandatory parameters, CopyFrom and CopyTo,
which are used as the values for the SourcePath and DestinationPath properties in
the File resource block. The NestedConfig configuration calls FileConfig as if it were a
resource. The properties in the NestedConfig resource block (CopyFrom and CopyTo)
are the parameters of the FileConfig configuration.

See Also
Composite resources--Using a DSC configuration as a resource
Securing the MOF File
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

DSC tells the target nodes what configuration they should have by sending a MOF file
with that information to each node, where the Local Configuration Manager (LCM)
implements the desired configuration. Because this file contains the details of the
configuration, its important to keep it secure. To do this, you can set the LCM to check
the credentials of a user. This topic describes how to transmit those credentials securely
to the target node by encrypting them with certificates.

Note: This topic discusses certificates used for encryption. For encryption, a self-signed
certificate is sufficient, because the private key is always kept secret and encryption does
not imply trust of the document. Self-signed certificates should not be used for
authentication purposes. You should use a certificate from a trusted Certification
Authority (CA) for any authentication purposes.

Prerequisites
To successfully encrypt the credentials used to secure a DSC configuration, make sure
you have the following:

Some means of issuing and distributing certificates. This topic and its examples assume you
are using Active Directory Certification Authority. For more background information on Active
Directory Certificate Services, see Active Directory Certificate Services Overview andActive Directory
Certificate Services in Windows Server 2008.
Administrative access to the target node or nodes.
Each target node has an encryption-capable certificate saved its Personal Store. In Windows
PowerShell, the path to the store is Cert:\LocalMachine\My. The examples in this topic use the
workstation authentication template, which you can find (along with other certificate templates)
at Default Certificate Templates.
If you will be running this configuration on a computer other than the target node, export the
public key of the certificate, and then import it to the computer you will run the configuration
from. Make sure that you export only the public key; keep the private key secure.

Overall process
1. Set up the certificates, keys, and thumbprints, making sure that each target node has copies of the
certificate and the configuration computer has the public key and thumbprint.
2. Create a configuration data block that contains the path and thumbprint of the public key.
3. Create a configuration script that defines your desired configuration for the target node and sets
up decryption on the target nodes by commanding the Local Configuration manager to decrypt the
configuration data using the certificate and its thumbprint.
4. Run the configuration, which will set the Local Configuration Manager settings and start the DSC
configuration.

Certificate Requirements
To enact credential encryption, a public key certificate must be available on the Target
Node that is trusted by the computer being used to author the DSC configuration. This
public key certificate has specific requirements for it to be used for DSC credential
encryption:

1. Key Usage:
Must contain: 'KeyEncipherment' and 'DataEncipherment'.
Should not contain: 'Digital Signature'.
2. Enhanced Key Usage:
Must contain: Document Encryption (1.3.6.1.4.1.311.80.1).
Should not contain: Client Authentication (1.3.6.1.5.5.7.3.2) and Server Authentication
(1.3.6.1.5.5.7.3.1).
3. The Private Key for the certificate is available on the *Target Node_.
4. The Provider for the certificate must be "Microsoft RSA SChannel Cryptographic Provider".

Recommended Best Practice: Although you can use a certificate with containing a
Key Usage of 'Digital Signature' or one of the Authentication EKU's, this will enable the
encryption key to be more easily misused and vulnerable to attack. So it is best practice
to use a certificate created specifically for the purpose of securing DSC credentials that
omits these Key Usage and EKUs.

Any existing certificate on the Target Node that meets these criteria can be used to
secure DSC credentials.

Certificate creation
There are two approaches you can take to create and use the required Encryption
Certificate (public-private key pair).

1. Create it on the Target Node and export just the public key to the Authoring Node
2. Create it on the Authoring Node and export the entire key pair to the Target Node
Method 1 is recommended because the private key used to decrypt credentials in the
MOF stays on the Target Node at all times.

Creating the Certificate on the Target Node

The private key must be kept secret, because is used to decrypt the MOF on the Target
Node The easiest way to do that is to create the private key certificate on the Target
Node, and copy the public key certificate to the computer being used to author the
DSC configuration into a MOF file. The following example:

1. creates a certificate on the Target node


2. exports the public key certificate on the Target node.
3. imports the public key certificate into the my certificate store on the Authoring node.

On the Target Node: create and export the certificate

Authoring Node: Windows Server 2016 and Windows 10


PowerShellCopy

# note: These steps need to be performed in an Administrator PowerShell session


$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName
'DscEncryptionCert' -HashAlgorithm SHA256
# export the public key certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force

Once exported, the DscPublicKey.cer would need to be copied to the Authoring Node.

Authoring Node: Windows Server 2012 R2/Windows 8.1 and earlier

Because the New-SelfSignedCertificate cmdlet on Windows Operating Systems prior to


Windows 10 and Windows Server 2016 do not support the Type parameter, an alternate
method of creating this certificate is required on these operating systems. In this case
you can use makecert.exe or certutil.exe to create the certificate.

An alternate method is to download the New-SelfSignedCertificateEx.ps1 script from


Microsoft Script Center and use it to create the certificate instead:
PowerShellCopy

# note: These steps need to be performed in an Administrator PowerShell session


# and in the folder that contains New-SelfSignedCertificateEx.ps1
. .\New-SelfSignedCertificateEx.ps1
New-SelfsignedCertificateEx `
-Subject "CN=${ENV:ComputerName}" `
-EKU 'Document Encryption' `
-KeyUsage 'KeyEncipherment, DataEncipherment' `
-SAN ${ENV:ComputerName} `
-FriendlyName 'DSC Credential Encryption certificate' `
-Exportable `
-StoreLocation 'LocalMachine' `
-StoreName 'My' `
-KeyLength 2048 `
-ProviderName 'Microsoft Enhanced Cryptographic Provider v1.0' `
-AlgorithmName 'RSA' `
-SignatureAlgorithm 'SHA256'
# Locate the newly created certificate
$Cert = Get-ChildItem -Path cert:\LocalMachine\My `
| Where-Object {
($_.FriendlyName -eq 'DSC Credential Encryption certificate') `
-and ($_.Subject -eq "CN=${ENV:ComputerName}")
} | Select-Object -First 1
# export the public key certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force

Once exported, the DscPublicKey.cer would need to be copied to the Authoring Node.

On the Authoring Node: import the certs public key


PowerShellCopy

# Import to the my store


Import-Certificate -FilePath "$env:temp\DscPublicKey.cer" -CertStoreLocation
Cert:\LocalMachine\My

Creating the Certificate on the Authoring Node

Alternately, the encryption certificate can be created on the Authoring Node, exported
with the private key as a PFX file and then imported on the Target Node. This is the
current method for implementing DSC credential encryption on Nano Server. Although
the PFX is secured with a password it should be kept secure during transit. The following
example:
1. creates a certificate on the Authoring node.
2. exports the certificate including the private key on the Authoring node.
3. removes the private key from the Authoring node, but keeps the public key certificate in
the my store.
4. imports the private key certificate into the root certificate store on the Target node.
it must be added to the root store so that it will be trusted by the Target node.

On the Authoring Node: create and export the certificate

Target Node: Windows Server 2016 and Windows 10


PowerShellCopy

# note: These steps need to be performed in an Administrator PowerShell session


$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName
'DscEncryptionCert' -HashAlgorithm SHA256
# export the private key certificate
$mypwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWD" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath "$env:temp\DscPrivateKey.pfx" -Password
$mypwd -Force
# remove the private key certificate from the node but keep the public key
certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force
$cert | Remove-Item -Force
Import-Certificate -FilePath "$env:temp\DscPublicKey.cer" -CertStoreLocation
Cert:\LocalMachine\My

Once exported, the DscPrivateKey.cer would need to be copied to the Target Node.

Target Node: Windows Server 2012 R2/Windows 8.1 and earlier

Because the New-SelfSignedCertificate cmdlet on Windows Operating Systems prior to


Windows 10 and Windows Server 2016 do not support the Type parameter, an alternate
method of creating this certificate is required on these operating systems. In this case
you can use makecert.exe or certutil.exe to create the certificate.

An alternate method is to download the New-SelfSignedCertificateEx.ps1 script from


Microsoft Script Center and use it to create the certificate instead:
PowerShellCopy

# note: These steps need to be performed in an Administrator PowerShell session


# and in the folder that contains New-SelfSignedCertificateEx.ps1
. .\New-SelfSignedCertificateEx.ps1
New-SelfsignedCertificateEx `
-Subject "CN=${ENV:ComputerName}" `
-EKU 'Document Encryption' `
-KeyUsage 'KeyEncipherment, DataEncipherment' `
-SAN ${ENV:ComputerName} `
-FriendlyName 'DSC Credential Encryption certificate' `
-Exportable `
-StoreLocation 'LocalMachine' `
-KeyLength 2048 `
-ProviderName 'Microsoft Enhanced Cryptographic Provider v1.0' `
-AlgorithmName 'RSA' `
-SignatureAlgorithm 'SHA256'
# Locate the newly created certificate
$Cert = Get-ChildItem -Path cert:\LocalMachine\My `
| Where-Object {
($_.FriendlyName -eq 'DSC Credential Encryption certificate') `
-and ($_.Subject -eq "CN=${ENV:ComputerName}")
} | Select-Object -First 1
# export the public key certificate
$mypwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWD" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath "$env:temp\DscPrivateKey.pfx" -Password
$mypwd -Force
# remove the private key certificate from the node but keep the public key
certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force
$cert | Remove-Item -Force
Import-Certificate -FilePath "$env:temp\DscPublicKey.cer" -CertStoreLocation
Cert:\LocalMachine\My

On the Target Node: import the certs private key as a trusted root
PowerShellCopy

# Import to the root store so that it is trusted


$mypwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWD" -Force -AsPlainText
Import-PfxCertificate -FilePath "$env:temp\DscPrivateKey.pfx" -CertStoreLocation
Cert:\LocalMachine\Root -Password $mypwd > $null

Configuration data
The configuration data block defines which target nodes to operate on, whether or not
to encrypt the credentials, the means of encryption, and other information. For more
information on the configuration data block, see Separating Configuration and
Environment Data.

The elements that can be configured for each node that are related to credential
encryption are:

NodeName - the name of the target node that the credential encryption is being configured for.
PsDscAllowPlainTextPassword - whether unencrypted credentials will be allowed to be passed
to this node. This is not recommended.
Thumbprint - the thumbprint of the certificate that will be used to decrypt the credentials in the
DSC Configuration on the Target Node. This certificate must exist in the Local Machine
certificate store on the Target Node.
CertificateFile - the certificate file (containing the public key only) that should be used to encrypt
the credentials for the Target Node. This must be either a DER encoded binary X.509 or Base-64
encoded X.509 format certificate file.

This example shows a configuration data block that specifies a target node to act on
named targetNode, the path to the public key certificate file (named targetNode.cer),
and the thumbprint for the public key.
PowerShellCopy

$ConfigData= @{
AllNodes = @(
@{
# The name of the node we are describing
NodeName = "targetNode"

# The path to the .cer file containing the


# public key of the Encryption Certificate
# used to encrypt credentials for this node
CertificateFile = "C:\publicKeys\targetNode.cer"

# The thumbprint of the Encryption Certificate


# used to decrypt the credentials on target node
Thumbprint = "AC23EA3A9E291A75757A556D0B71CBBF8C4F6FD8"
};
);
}
Configuration script
In the configuration script itself, use the PsCredential parameter to ensure that
credentials are stored for the shortest possible time. When you run the supplied
example, DSC will prompt you for credentials and then encrypt the MOF file using the
CertificateFile that is associated with the target node in the configuration data block.
This code example copies a file from a share that is secured to a user.
Copy

configuration CredentialEncryptionExample
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[PsCredential] $credential
)

Node $AllNodes.NodeName
{
File exampleFile
{
SourcePath = "\\Server\share\path\file.ext"
DestinationPath = "C:\destinationPath"
Credential = $credential
}
}
}

Setting up decryption
Before Start-DscConfiguration can work, you have to tell the Local Configuration
Manager on each target node which certificate to use to decrypt the credentials, using
the CertificateID resource to verify the certificates thumbprint. This example function
will find the appropriate local certificate (you might have to customize it so it will find
the exact certificate you want to use):
PowerShellCopy

# Get the certificate that works for encryption


function Get-LocalEncryptionCertificateThumbprint
{
(dir Cert:\LocalMachine\my) | %{
# Verify the certificate is for Encryption and valid
if ($_.PrivateKey.KeyExchangeAlgorithm -and $_.Verify())
{
return $_.Thumbprint
}
}
}

With the certificate identified by its thumbprint, the configuration script can be updated
to use the value:
PowerShellCopy

configuration CredentialEncryptionExample
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[PsCredential] $credential
)

Node $AllNodes.NodeName
{
File exampleFile
{
SourcePath = "\\Server\share\path\file.ext"
DestinationPath = "C:\destinationPath"
Credential = $credential
}

LocalConfigurationManager
{
CertificateId = $node.Thumbprint
}
}
}

Running the configuration


At this point, you can run the configuration, which will output two files:

A *.meta.mof file that configures the Local Configuration Manager to decrypt the credentials using
the certificate that is stored on the local machine store and identified by its thumbprint. Set-
DscLocalConfigurationManager applies the *.meta.mof file.
A MOF file that actually applies the configuration. Start-DscConfiguration applies the configuration.

These commands will accomplish those steps:


PowerShellCopy

Write-Host "Generate DSC Configuration..."


CredentialEncryptionExample -ConfigurationData $ConfigData -OutputPath
.\CredentialEncryptionExample

Write-Host "Setting up LCM to decrypt credentials..."


Set-DscLocalConfigurationManager .\CredentialEncryptionExample -Verbose

Write-Host "Starting Configuration..."


Start-DscConfiguration .\CredentialEncryptionExample -wait -Verbose

This example would push the DSC configuration to the target node. The DSC
configuration can also be applied using a DSC Pull Server if one is available.

See Setting up a DSC pull client for more information on applying DSC configurations
using a DSC Pull Server.

Credential Encryption Module Example


Here is a full example that incorporates all of these steps, plus a helper cmdlet that
exports and copies the public keys:
PowerShellCopy

# A simple example of using credentials


configuration CredentialEncryptionExample
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[PsCredential] $credential
)
Node $AllNodes.NodeName
{
File exampleFile
{
SourcePath = "\\server\share\file.txt"
DestinationPath = "C:\Users\user"
Credential = $credential
}

LocalConfigurationManager
{
CertificateId = $node.Thumbprint
}
}
}

# A Helper to invoke the configuration, with the correct public key


# To encrypt the configuration credentials
function Start-CredentialEncryptionExample
{
[CmdletBinding()]
param ($computerName)

[string] $thumbprint = Get-EncryptionCertificate -computerName $computerName -


Verbose
Write-Verbose "using cert: $thumbprint"

$certificatePath = join-path -Path "$env:SystemDrive\$script:publicKeyFolder" -


childPath "$computername.EncryptionCertificate.cer"

$ConfigData= @{
AllNodes = @(
@{
# The name of the node we are describing
NodeName = "$computerName"

# The path to the .cer file containing the


# public key of the Encryption Certificate
CertificateFile = "$certificatePath"

# The thumbprint of the Encryption Certificate


# used to decrypt the credentials
Thumbprint = $thumbprint
};
);
}

Write-Verbose "Generate DSC Configuration..."


CredentialEncryptionExample -ConfigurationData $ConfigData -OutputPath
.\CredentialEncryptionExample `
-credential (Get-Credential -UserName "$env:USERDOMAIN\$env:USERNAME" -
Message "Enter credentials for configuration")

Write-Verbose "Setting up LCM to decrypt credentials..."


Set-DscLocalConfigurationManager .\CredentialEncryptionExample -Verbose

Write-Verbose "Starting Configuration..."


Start-DscConfiguration .\CredentialEncryptionExample -wait -Verbose

#region HelperFunctions

# The folder name for the exported public keys


$script:publicKeyFolder = "publicKeys"

# Get the certificate that works for encryptions


function Get-EncryptionCertificate
{
[CmdletBinding()]
param ($computerName)
$returnValue= Invoke-Command -ComputerName $computerName -ScriptBlock {
$certificates = dir Cert:\LocalMachine\my

$certificates | %{
# Verify the certificate is for Encryption and valid
if ($_.PrivateKey.KeyExchangeAlgorithm -and $_.Verify())
{
# Create the folder to hold the exported public key
$folder= Join-Path -Path $env:SystemDrive\ -ChildPath
$using:publicKeyFolder
if (! (Test-Path $folder))
{
md $folder | Out-Null
}

# Export the public key to a well known location


$certPath = Export-Certificate -Cert $_ -FilePath (Join-Path
-path $folder -childPath "EncryptionCertificate.cer")

# Return the thumbprint, and exported certificate path


return @($_.Thumbprint,$certPath);
}
}
}
Write-Verbose "Identified and exported cert..."
# Copy the exported certificate locally
$destinationPath = join-path -Path "$env:SystemDrive\$script:publicKeyFolder" -
childPath "$computername.EncryptionCertificate.cer"
Copy-Item -Path (join-path -path \\$computername -childPath
$returnValue[1].FullName.Replace(":","$")) $destinationPath | Out-Null

# Return the thumbprint


return $returnValue[0]
}

Start-CredentialEncryptionExample
PowerShell Desired State Configuration partial
configurations
Applies To: Windows PowerShell 5.0 and later.

In PowerShell 5.0, Desired State Configuration (DSC) allows configurations to be


delivered in fragments and from multiple sources. The Local Configuration Manager
(LCM) on the target node puts the fragments together before applying them as a single
configuration. This capability allows sharing control of configuration between teams or
individuals. For example, if two or more teams of developers are collaborating on a
service, they might each want to create configurations to manage their part of the
service. Each of these configurations could be pulled from different pull servers, and
they could be added at different stages of development. Partial configurations also
allow different individuals or teams to control different aspects of configuring nodes
without having to coordinate the editing of a single configuration document. For
example, one team might be responsible for deploying a VM and operating system,
while another team might deploy other applications and services on that VM. With
partial configurations, each team can create its own configuration, without either of
them being unnecessarily complicated.

You can use partial configurations in push mode, pull mode, or a combination of the
two.

Partial configurations in push mode


To use partial configurations in push mode, you configure the LCM on the target node
to receive the partial configurations. Each partial configuration must be pushed to the
target by using the Publish-DSCConfiguration cmdlet. The target node then combines
the partial configuration into a single configuration, and you can apply the configuration
by calling the Start-DscConfiguration cmdlet.

Configuring the LCM for push-mode partial configurations

To configure the LCM for partial configurations in push mode, you create
a DSCLocalConfigurationManager configuration with one PartialConfiguration block
for each partial configuration. For more information about configuring the LCM,
see Windows Configuring the Local Configuration Manager. The following example
shows an LCM configuration that expects two partial configurationsone that deploys
the OS, and one that deploys and configures SharePoint.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PartialConfigDemo
{
Node localhost
{

PartialConfiguration ServiceAccountConfig
{
Description = 'Configuration to add the SharePoint service account to the
Administrators group.'
RefreshMode = 'Push'
}
PartialConfiguration SharePointConfig
{
Description = 'Configuration for the SharePoint server'
RefreshMode = 'Push'
}
}
}
PartialConfigDemo

The RefreshMode for each partial configuration is set to "Push". The names of
the PartialConfiguration blocks (in this case, "ServiceAccountConfig" and
"SharePointConfig") must match exactly the names of the configurations that are
pushed to the target node.

Note: The named of each PartialConfiguration block must match the actual name of
the configuration as it is specified in the configuration script, not the name of the MOF
file, which should be either the name of the target node or localhost .

Publishing and starting push-mode partial configurations

You then call Publish-DSCConfiguration for each configuration, passing the folders that
contain the configuration documents as the Pathparameters. Publish-
DSCConfiguration places the configuration MOF files to the target nodes. After
publishing both configurations, you can call Start-DSCConfiguration UseExisting on the
target node.
For example, if you have compiled the following configuration MOF documents on the
authoring node:
PowerShellCopy

PS C:\PartialConfigTest> Get-ChildItem -Recurse

Directory: C:\PartialConfigTest

Mode LastWriteTime Length Name


---- ------------- ------ ----
d----- 8/11/2016 1:55 PM ServiceAccountConfig
d----- 11/17/2016 4:14 PM SharePointConfig

Directory: C:\PartialConfigTest\ServiceAccountConfig

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 8/11/2016 2:02 PM 2034 TestVM.mof

Directory: C:\DscTests\SharePointConfig

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 11/17/2016 4:14 PM 1930 TestVM.mof

You would publish and run the configurations as follows:


PowerShellCopy

PS C:\PartialConfigTest> Publish-DscConfiguration .\ServiceAccountConfig -


ComputerName 'TestVM'
PS C:\PartialConfigTest> Publish-DscConfiguration .\SharePointConfig -ComputerName
'TestVM'
PS C:\PartialConfigTest> Start-DscConfiguration -UseExisting -ComputerName 'TestVM'

Id Name PSJobTypeName State HasMoreData Location


Command
-- ---- ------------- ----- ----------- --------
-------
17 Job17 Configuratio... Running True TestVM
Start-DscConfiguration...

Note: The user running the Publish-DSCConfiguration cmdlet must have administrator
privileges on the target node.

Partial configurations in pull mode


Partial configurations can be pulled from one or more pull servers (for more information
about pull servers, see Windows PowerShell Desired State Configuration Pull Servers. To
do this, you have to configure the LCM on the target node to pull the partial
configurations, and name and locate the configuration documents properly on the pull
servers.

Configuring the LCM for pull node configurations

To configure the LCM to pull partial configurations from a pull server, you define the
pull server in either a ConfigurationRepositoryWeb (for an HTTP pull server)
or ConfigurationRepositoryShare (for an SMB pull server) block. You then
create PartialConfiguration blocks that refer to the pull server by using
the ConfigurationSource property. You also need to create a Settings block to specify
that the LCM uses pull mode, and to specify
the ConfigurationNames or ConfigurationID that the pull server and target node use
to identify the configurations. The following meta-configuration defines an HTTP pull
server named CONTOSO-PullSrv and two partial configurations that use that pull server.

For more information about configuring the LCM using ConfigurationNames,


see Setting up a pull client using configuration names. For information about
configuring the LCM using ConfigurationID, see Setting up a pull client using
configuration ID.

Configuring the LCM for pull mode configurations using configuration names
PowerShellCopy

[DscLocalConfigurationManager()]
Configuration PartialConfigDemoConfigNames
{
Settings
{
RefreshFrequencyMins = 30;
RefreshMode = "PULL";
ConfigurationMode ="ApplyAndAutocorrect";
AllowModuleOverwrite = $true;
RebootNodeIfNeeded = $true;
ConfigurationModeFrequencyMins = 60;
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = 5b41f4e6-5e6d-45f5-8102-f2227468ef38
ConfigurationNames = @("ServiceAccountConfig",
"SharePointConfig")
}

PartialConfiguration ServiceAccountConfig
{
Description = "ServiceAccountConfig"
ConfigurationSource = @("[ConfigurationRepositoryWeb]CONTOSO-
PullSrv")
}

PartialConfiguration SharePointConfig
{
Description = "SharePointConfig"
ConfigurationSource = @("[ConfigurationRepositoryWeb]CONTOSO-
PullSrv")
DependsOn =
'[PartialConfiguration]ServiceAccountConfig'
}

Configuring the LCM for pull mode configurations using ConfigurationID


PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PartialConfigDemoConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc'

PartialConfiguration ServiceAccountConfig
{
Description = 'Configuration for the Base OS'
ConfigurationSource = '[ConfigurationRepositoryWeb]CONTOSO-
PullSrv'
RefreshMode = 'Pull'
}
PartialConfiguration SharePointConfig
{
Description = 'Configuration for the Sharepoint
Server'
ConfigurationSource = '[ConfigurationRepositoryWeb]CONTOSO-
PullSrv'
DependsOn =
'[PartialConfiguration]ServiceAccountConfig'
RefreshMode = 'Pull'
}
}
}
PartialConfigDemo

You can pull partial configurations from more than one pull serveryou would just
need to define each pull server, and then refer to the appropriate pull server in
each PartialConfiguration block.
After creating the meta-configuration, you must run it to create a configuration
document (a MOF file), and then call Set-DscLocalConfigurationManager to configure
the LCM.

Naming and placing the configuration documents on the pull server


(ConfigurationNames)

The partial configuration documents must be placed in the folder specified as


the ConfigurationPath in the web.config file for the pull server (typically C:\Program
Files\WindowsPowerShell\DscService\Configuration ).

Naming configuration documents on the pull server in PowerShell 5.1

If you are pulling only one partial configuration from an individual pull server, the
configuration document can have any name. If you are pulling more than one partial
configuration from a pull server, the configuration document can be named
either <ConfigurationName>.mof , where ConfigurationName is the name of the partial
configuration, or <ConfigurationName>.<NodeName>.mof , where ConfigurationName is the
name of the partial configuration, and NodeName is the name of the target node. This
allows you to pull configurations from Azure Automation DSC pull server.

Naming configuration documents on the pull server in PowerShell 5.0

The configuration documents must be named as follows: ConfigurationName.mof ,


where ConfigurationName is the name of the partial configuration. For our example, the
configuration documents should be named as follows:
Copy

ServiceAccountConfig.mof
ServiceAccountConfig.mof.checksum
SharePointConfig.mof
SharePointConfig.mof.checksum
Naming and placing the configuration documents on the pull server
(ConfigurationID)

The partial configuration documents must be placed in the folder specified as


the ConfigurationPath in the web.config file for the pull server (typically C:\Program
Files\WindowsPowerShell\DscService\Configuration ). The configuration documents must
be named as follows: ConfigurationName. ConfigurationID .mof ,
where ConfigurationName is the name of the partial configuration
and ConfigurationID is the configuration ID defined in the LCM on the target node. For
our example, the configuration documents should be named as follows:
Copy

ServiceAccountConfig.1d545e3b-60c3-47a0-bf65-5afc05182fd0.mof
ServiceAccountConfig.1d545e3b-60c3-47a0-bf65-5afc05182fd0.mof.checksum
SharePointConfig.1d545e3b-60c3-47a0-bf65-5afc05182fd0.mof
SharePointConfig.1d545e3b-60c3-47a0-bf65-5afc05182fd0.mof.checksum

Running partial configurations from a pull server

After the LCM on the target node has been configured, and the configuration
documents have been created and properly named on the pull server, the target node
will pull the partial configurations, combine them, and apply the resulting configuration
at regular intervals as specified by the RefreshFrequencyMins property of the LCM. If
you want to force a refresh, you can call the Update-DscConfiguration cmdlet, to pull
the configurations, and then Start-DSCConfiguration UseExisting to apply them.

Partial configurations in mixed push and pull modes


You can also mix push and pull modes for partial configurations. That is, you could have
one partial configuration that is pulled from a pull server, while another partial
configuration is pushed. Specify the refresh mode for each partial configuration as
described in the previous sections. For example, the following meta-configuration
describes the same example, with the ServiceAccountConfig partial configuration in pull
mode and the SharePointConfig partial configuration in push mode.
Mixed push and pull modes using ConfigurationNames

PowerShellCopy

[DscLocalConfigurationManager()]
Configuration PartialConfigDemoConfigNames
{
Settings
{
RefreshFrequencyMins = 30;
RefreshMode = "PULL";
ConfigurationMode = "ApplyAndAutocorrect";
AllowModuleOverwrite = $true;
RebootNodeIfNeeded = $true;
ConfigurationModeFrequencyMins = 60;
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = 5b41f4e6-5e6d-45f5-8102-f2227468ef38
ConfigurationNames = @("ServiceAccountConfig",
"SharePointConfig")
}

PartialConfiguration ServiceAccountConfig
{
Description = "ServiceAccountConfig"
ConfigurationSource = @("[ConfigurationRepositoryWeb]CONTOSO-
PullSrv")
RefreshMode = 'Pull'
}

PartialConfiguration SharePointConfig
{
Description = "SharePointConfig"
DependsOn =
'[PartialConfiguration]ServiceAccountConfig'
RefreshMode = 'Push'
}

}
Mixed push and pull modes using ConfigurationID

PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PartialConfigDemo
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc'

PartialConfiguration ServiceAccountConfig
{
Description = 'Configuration for the Base OS'
ConfigurationSource = '[ConfigurationRepositoryWeb]CONTOSO-PullSrv'
RefreshMode = 'Pull'
}
PartialConfiguration SharePointConfig
{
Description = 'Configuration for the Sharepoint Server'
DependsOn = '[PartialConfiguration]ServiceAccountConfig'
RefreshMode = 'Push'
}
}
}
PartialConfigDemo

Note that the RefreshMode specified in the Settings block is "Pull", but
the RefreshMode for the SharePointConfig partial configuration is "Push".
Name and locate the configuration MOF files as described above for their respective
refresh modes. Call Publish-DSCConfiguration to publish the SharePointConfig partial
configuration, and either wait for the ServiceAccountConfig configuration to be pulled
from the pull server, or force a refresh by calling Update-DscConfiguration.

Example ServiceAccountConfig Partial Configuration


PowerShellCopy

Configuration ServiceAccountConfig
{
Param (
[Parameter(Mandatory,
HelpMessage="Domain credentials required to add
domain\sharepoint_svc to the local Administrators group.")]
[ValidateNotNullOrEmpty()]
[pscredential]$Credential
)

Import-DscResource -ModuleName PSDesiredStateConfiguration

Node localhost
{
Group LocalAdmins
{
GroupName = 'Administrators'
MembersToInclude = 'domain\sharepoint_svc',
'admins@example.domain'
Ensure = 'Present'
Credential = $Credential

WindowsFeature Telnet
{
Name = 'Telnet-Server'
Ensure = 'Absent'
}
}
}
ServiceAccountConfig
Example SharePointConfig Partial Configuration
PowerShellCopy

Configuration SharePointConfig
{
Param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[pscredential]$ProductKey
)

Import-DscResource -ModuleName xSharePoint

Node localhost
{
xSPInstall SharePointDefault
{
Ensure = 'Present'
BinaryDir = '\\FileServer\Installers\Sharepoint\'
ProductKey = $ProductKey
}
}
}
SharePointConfig

See Also
Concepts Windows PowerShell Desired State Configuration Pull Servers

Windows Configuring the Local Configuration Manager


Writing help for DSC configurations
Applies To: Windows Windows PowerShell 5.0

You can use comment-based help in DSC configurations. Users can access the help by
calling the configuration function with -? , or by using theGet-Help cmdlet. For more
information about PowerShell comment-based help, see about_Comment_Based_Help.

The following example shows a script that contains a configuration and comment-based
help for it:
PowerShellCopy

<#
.SYNOPSIS
A brief description of the function or script. This keyword can be used only once for
each configuration.

.DESCRIPTION
A detailed description of the function or script. This keyword can be used only once
for each configuration.

.PARAMETER ComputerName
The description of a parameter. Add a .PARAMETER keyword for each parameter in the
function or script syntax.

Type the parameter name on the same line as the .PARAMETER keyword. Type the
parameter description on the lines following the .PARAMETER keyword.
Windows PowerShell interprets all text between the .PARAMETER line and the next
keyword or the end of the comment block as part of the parameter description.
The description can include paragraph breaks.

The Parameter keywords can appear in any order in the comment block, but the function
or script syntax determines the order in which the parameters
(and their descriptions) appear in help topic. To change the order, change the
syntax.

.PARAMETER FilePath
Provide a PARAMETER section for each parameter that your script or function accepts.

.EXAMPLE
A sample command that uses the function or script, optionally followed by sample
output and a description. Repeat this keyword for each example. If you have multiple
examples,
there is no need to number them. PowerShell will number the examples in help text.

.EXAMPLE
This example will be labeled "EXAMPLE 2" when help is displayed to the user.
#>

configuration HelpSample1
{
param([string]$ComputerName,[string]$FilePath)
File f
{
Contents="Hello World"
DestinationPath = "c:\Destination.txt"
}
}

Viewing configuration help


To view the help for a configuration, use the Get-Help cmdlet with the name of the
function, or type the name of the function followed by -? . The following is the output
of the previous function when passed to Get-Help:
PowerShellCopy

PS C:\> Get-Help HelpSample1

NAME
HelpSample1

SYNOPSIS
A brief description of the function or script. This keyword can be used only once
for each configuration.

SYNTAX
HelpSample1 [[-InstanceName] <String>] [[-DependsOn] <String[]>] [[-OutputPath]
<String>] [[-ConfigurationData] <Hashtable>] [[-ComputerName]
<String>] [[-FilePath] <String>] [<CommonParameters>]
DESCRIPTION
A detailed description of the function or script. This keyword can be used only
once for each configuration.

RELATED LINKS

REMARKS
To see the examples, type: "get-help HelpSample1 -examples".
For more information, type: "get-help HelpSample1 -detailed".
For technical information, type: "get-help HelpSample1 -full".

See Also
DSC Configurations
Configure a virtual machines at initial boot-up
by using DSC

Requirements
To run these examples, you will need:

A bootable VHD to work with. You can download an ISO with an evaluation copy of Windows
Server 2016 at TechNet Evaluation Center. You can find instructions on how to create a VHD from
an ISO image at Creating Bootable Virtual Hard Disks.
A host computer that has Hyper-V enabled. For information, see Hyper-V overview.

By using DSC, you can automate software installation and configuration for a computer
at initial boot-up. You do this by either injecting a configuration MOF document or a
metaconfiguration into bootable media (such as a VHD) so that they are run during the
initial boot-up process. This behavior is specified by the DSCAutomationHostEnabled
registry key registry key
under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\P
olicies. By default, the value of this key is 2, which allows DSC to run at boot time.

If you do not want DSC to run at boot time, set the value of
the DSCAutomationHostEnabled registry key registry key to 0.

Inject a configuration MOF document into a VHD


Inject a DSC metaconfiguration into a VHD
Disable DSC at boot time

Note: You can inject both Pending.mof and MetaConfig.mof into a computer at the same
time. If both files are present, the settings specified in MetaConfig.mof take precedence.

Inject a configuration MOF document into a VHD


To enact a configuration at initial boot-up, you can inject a compiled configuration MOF
document into the VHD as its Pending.mof file. If
the DSCAutomationHostEnabled registry key is set to 2 (the default value), DSC will
apply the configuration defined by Pending.mof when the computer boots up for the
first time.
For this example, we will use the following configuration, which will install IIS on the new
computer:
PowerShellCopy

Configuration SampleIISInstall
{
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

node ('localhost')
{
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}
}
}

To inject the configuration MOF document on the VHD

1. Mount the VHD into which you want to inject the configuration by calling
the Mount-VHD cmdlet. For example:

PowerShellCopy

Mount-VHD -Path C:\users\public\documents\vhd\Srv16.vhd

2. On a computer running PowerShell 5.0 or later, save the above configuration


(SampleIISInstall) as a PowerShell script (.ps1) file.
3. In a PowerShell console, navigate to the folder where you saved the .ps1 file.
4. Run the following PowerShell commands to compile the MOF document (for
information about compiling DSC configurations, see DSC Configurations:

PowerShellCopy

. .\SampleIISInstall.ps1
SampleIISInstall
5. This will create a localhost.mof file in a new folder named SampleIISInstall .
Rename and move that file into the proper location on the VHD as Pending.mof by
using the Move-Item cmdlet. For example:

PowerShellCopy

Move-Item -Path C:\DSCTest\SampleIISInstall\localhost.mof -Destination


E:\Windows\Sytem32\Configuration\Pending.mof

6. Dismount the VHD by calling the Dismount-VHD cmdlet. For example:

PowerShellCopy

Dismount-VHD -Path C:\users\public\documents\vhd\Srv16.vhd

7. Create a VM by using the VHD where you installed the DSC MOF document. After
intial boot-up and operating system installation, IIS will be installed. You can verify
this by calling the Get-WindowsFeature cmdlet.

Inject a DSC metaconfiguration into a VHD


You can also configure a computer to pull a configuration at intial boot-up by injecting
a metaconfiguration (see Configuring the Local Configuration Manager (LCM)) into the
VHD as its MetaConfig.mof file. If the DSCAutomationHostEnabled registry key is set
to 2 (the default value), DSC will apply the metaconfiguration defined
by MetaConfig.mof to the LCM when the computer boots up for the first time. If the
metaconfiguration specifies that the LCM should pull configurations from a pull server,
the computer will attempt to pull a configuration from that pull server at inital boot-up.
For information about setting up a DSC pull server, see Setting up a DSC web pull
server.

For this example, we will use both the configuration described in the previous section
(SampleIISInstall), and the following metaconfiguration:
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientBootstrap
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '140a952b-b9d6-406b-b416-e0f759c9c0e4'
ConfigurationNames = @('SampleIISInstall')
}
}
}

To inject the metaconfiguration MOF document on the VHD

1. Mount the VHD into which you want to inject the metaconfiguration by calling
the Mount-VHD cmdlet. For example:

PowerShellCopy

Mount-VHD -Path C:\users\public\documents\vhd\Srv16.vhd

2. Set up a DSC web pull server, and save the SampleIISInistall configuration to the
appropriate folder.
3. On a computer running PowerShell 5.0 or later, save the above metaconfiguration
(PullClientBootstrap) as a PowerShell script (.ps1) file.
4. In a PowerShell console, navigate to the folder where you saved the .ps1 file.
5. Run the following PowerShell commands to compile the metaconfiguration MOF
document (for information about compiling DSC configurations, see DSC
Configurations:

PowerShellCopy

. .\PullClientBootstrap.ps1
PullClientBootstrap

6. This will create a localhost.meta.mof file in a new folder


named PullClientBootstrap . Rename and move that file into the proper location
on the VHD as MetaConfig.mof by using the Move-Item cmdlet.

PowerShellCopy

Move-Item -Path C:\DSCTest\PullClientBootstrap\localhost.meta.mof -Destination


E:\Windows\Sytem32\Configuration\MetaConfig.mof

7. Dismount the VHD by calling the Dismount-VHD cmdlet. For example:

PowerShellCopy

Dismount-VHD -Path C:\users\public\documents\vhd\Srv16.vhd

8. Create a VM by using the VHD where you installed the DSC MOF document. After
intial boot-up and operating system installation, DSC will pull the configuration
from the pull server, and IIS will be installed. You can verify this by calling the Get-
WindowsFeature cmdlet.

Disable DSC at boot time


By default, the value of
the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Poli
cies\DSCAutomationHostEnabledkey is set to 2, which allows a DSC configuration to
run if the computer is in pending or current state. If you do not want a configuration to
run at initial boot-up, you need so set the value of this key to 0:

1. Mount the VHD by calling the Mount-VHD cmdlet. For example:

PowerShellCopy

Mount-VHD -Path C:\users\public\documents\vhd\Srv16.vhd


2. Load the registry HKLM\Software subkey from the VHD by calling reg load .

Copy

reg load HKLM\Vhd E:\Windows\System32\Config\Software`

3. Navigate to
the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersio
n\Policies\* by using the PowerShell Registry provider.

PowerShellCopy

Set-Location HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies`

4. Change the value of DSCAutomationHostEnabled to 0.

PowerShellCopy

Set-ItemProperty -Path . -Name DSCAutomationHostEnabled -Value 0

5. Unload the registry by running the following commands:

PowerShellCopy

[gc]::Collect()
reg unload HKLM\Vhd

See Also
DSC Configurations
DSCAutomationHostEnabled registry key
Configuring the Local Configuration Manager (LCM)
Setting up a DSC web pull server
DSCAutomationHostEnabled registry key
DSC uses the DSCAutomationHostEnabled registry key
under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\P
olicies to enable configuration of the machine at initial boot-up.
DSCAutomationHostEnabled supports three modes:
DSCAutomationHostEnabled Value Description

0 Disable configuring the machine at boot-up.

1 Enable configuring the machine at boot-up.

2 Enable configuring the machine only if DSC is in pending or current st

See Also
For an example of how to use this feature to run configurations at initial boot-up,
see Configure a virtual machines at initial boot-up by using DSC.
DSC Resources
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Desired State Configuration (DSC) Resources provide the building blocks for a DSC
configuration. A resource exposes properties that can be configured (schema) and
contains the PowerShell script functions that the Local Configuration Manager (LCM)
calls to "make it so".

A resource can model something as generic as a file or as specific as an IIS server


setting. Groups of like resources are combined in to a DSC Module, which organizes all
the required files in to a structure that is portable and includes metadata to identify how
the resources are intended to be used.

The following topics describe DSC resources:

Built-In DSC resources


Build custom DSC resources
Built-In DSC resources for Linux
Built-In Windows PowerShell Desired State
Configuration Resources
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Windows PowerShell Desired State Configuration (DSC) comes with a set of built-in
configuration resources. The following table provides an alphabetical list of these
resources and links to topics that describe them in detail. If you need to create
additional resources, see Build Custom Windows PowerShell Desired State Configuration
Resources

Archive Resource
Environment Resource
File Resource
Group Resource
Log Resource
Package Resource
Registry Resource
Script Resource
Service Resource
User Resource
WindowsFeature Resource
WindowsProcess Resource
DSC Archive Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Archive resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to unpack archive (.zip) files at a specific path.

Syntax
MOFCopy

Archive [string] #ResourceName


{
Destination = [string]
Path = [string]
[ Checksum = [string] { CreatedDate | ModifiedDate | SHA-1 | SHA-256 | SHA-512 }
]
[ DependsOn = [string[]] ]
[ Ensure = [string] { Absent | Present } ]
[ Force = [bool] ]
[ Validate = [bool] ]
}

Properties
Property Description

Destination Specifies the location where you want to ensure the archive contents are extracted.

Path Specifies the source path of the archive file.

Checksum Defines the type to use when determining whether two files are the same. If Checksum is n
used for comparison. Valid values include: SHA-1, SHA-256, SHA-512, createdDate, modif
specify Checksum without Validate, the configuration will fail.

Ensure Determines whether to check if the content of the archive exists at the Destination. Set this
Set it to Absent to ensure they do not exist. The default value is Present.
Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is configur
configuration script block that you want to run first is ResourceName and its type is Resour
is DependsOn = "[ResourceType]ResourceName" .

Validate Uses the Checksum property to determine if the archive matches the signature. If you specify
will fail. If you specify Validate without Checksum, a SHA-256 checksum is used by default

Force Certain file operations (such as overwriting a file or deleting a directory that is not empty) w
overrides such errors. The default value is False.

Example
The following example shows how to use the Archive resource to ensure that the
contents of an archive file called Test.zip exist and are extracted at a given destination.
Copy

Archive ArchiveExample {
Ensure = "Present" # You can also set Ensure to "Absent"
Path = "C:\Users\Public\Documents\Test.zip"
Destination = "C:\Users\Public\Documents\ExtractionPath"
}
DSC Environment Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Environment resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to manage system environment variables.

Syntax
mofCopy

Environment [string] #ResourceName


{
Name = [string]
[ Ensure = [string] { Absent | Present } ]
[ Path = [bool] ]
[ DependsOn = [string[]] ]
[ Value = [string] ]
}

Properties
Property Description

Name Indicates the name of the environment variable for which you want to ensure a specific state.

Ensure Indicates if a variable exists. Set this property to Present to create the environment variable
matches what is provided through the Value property if the variable already exists. Set it to A

Path Defines the environment variable that is being configured. Set this property to $true if the va
to $false. The default is $false. If the variable being configured is the Path variable, the va
appended to the existing value.

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .
Property Description

Value The value to assign to the environment variable.

Example
The following example ensures that TestEnvironmentVariable is present and it has the
value TestValue. If it is not present, it creates it.
PowerShellCopy

Environment EnvironmentExample
{
Ensure = "Present" # You can also set Ensure to "Absent"
Name = "TestEnvironmentVariable"
Value = "TestValue"
}
DSC File Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The File resource in Windows PowerShell Desired State Configuration (DSC) provides a
mechanism to manage files and folders on the target node.

Note: If the MatchSource property is set to $false (which is the default value), the
contents to be copied are cached the first time the configuration is applied. Subsequent
applications of the configuration will not check for updated files and/or folders in the
path specified by SourcePath. If you want to check for updates to the files and/or
folders in SourcePath every time the configuration is applied,
set MatchSource to $true.

Syntax
Copy

File [string] #ResourceName


{
DestinationPath = [string]
[ Attributes = [string[]] { Archive | Hidden | ReadOnly | System }]
[ Checksum = [string] { CreatedDate | ModifiedDate | SHA-1 | SHA-256 | SHA-512 }
]
[ Contents = [string] ]
[ Credential = [PSCredential] ]
[ Ensure = [string] { Absent | Present } ]
[ Force = [bool] ]
[ Recurse = [bool] ]
[ DependsOn = [string[]] ]
[ SourcePath = [string] ]
[ Type = [string] { Directory | File } ]
[ MatchSource = [bool] ]
}

Properties
Property Description

DestinationPath Indicates the location where you want to ensure the state for a file or directory.

Attributes Specifies the desired state of the attributes for the targeted file or directory.

Checksum Indicates the checksum type to use when determining whether two files are the same. If C
directory name is used for comparison. Valid values include: SHA-1, SHA-256, SHA-51

Contents Specifies the contents of a file, such as a particular string.

Credential Indicates the credentials that are required to access resources, such as source files, if such

Ensure Indicates if the file or directory exists. Set this property to "Absent" to ensure that the file
ensure that the file or directory does exist. The default is "Present".

Force Certain file operations (such as overwriting a file or deleting a directory that is not empty
overrides such errors. The default value is $false.

Recurse Indicates if subdirectories are included. Set this property to $true to indicate that you wa
is $false. Note: This property is only valid when the Type property is set to Directory.

DependsOn Indicates that the configuration of another resource must run before this resource is confi
configuration script block that you want to run first is ResourceName and its type is R
is DependsOn = "[ResourceType]ResourceName" .

SourcePath Indicates the path from which to copy the file or folder resource.

Type Indicates if the resource being configured is a directory or a file. Set this property to "Dir
Set it to "File" to indicate that the resource is a file. The default value is File.

MatchSource If set to the default value of $false, then any files on the source (say, files A, B, and C) w
configuration is applied. If a new file (D) is added to the source, it will not be added to th
applied later. If the value is $true, then each time the configuration is applied, new files s
in this example) are added to the destination. The default value is $false.

Example
The following example shows how to use the File resource to ensure that a directory
with the path C:\Users\Public\Documents\DSCDemo\DemoSource on a source computer (such
as the pull server) is also present (along with all subdirectories) on the target node. It
also writes a confirmatory message to the log when complete and includes a statement
to ensure that the file-checking operation runs prior to the logging operation.
PowerShellCopy

Configuration FileResourceDemo
{
Node "localhost"
{
File DirectoryCopy
{
Ensure = "Present" # You can also set Ensure to "Absent"
Type = "Directory" # Default is "File".
Recurse = $true # Ensure presence of subdirectories, too
SourcePath = "C:\Users\Public\Documents\DSCDemo\DemoSource"
DestinationPath = "C:\Users\Public\Documents\DSCDemo\DemoDestination"
}

Log AfterDirectoryCopy
{
# The message below gets written to the Microsoft-Windows-Desired State
Configuration/Analytic log
Message = "Finished running the file resource with ID DirectoryCopy"
DependsOn = "[File]DirectoryCopy" # This means run "DirectoryCopy" first.
}
}
}
DSC Group Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Group resource in Windows PowerShell Desired State Configuration (DSC) provides
a mechanism to manage local groups on the target node.

Syntax
Copy

Group [string] #ResourceName


{
GroupName = [string]
[ Credential = [PSCredential] ]
[ Description = [string[]] ]
[ Ensure = [string] { Absent | Present } ]
[ Members = [string[]] ]
[ MembersToExclude = [string[]] ]
[ MembersToInclude = [string[]] ]
[ DependsOn = [string[]] ]
}

Properties
Property Description

GroupName The name of the group for which you want to ensure a specific state.

Credential The credentials required to access remote resources. Note: This account must have t
add all non-local accounts to the group; otherwise, an error occurs when the configur

Description The description of the group.

Ensure Indicates if the group exists. Set this property to "Absent" to ensure that the group do
value) ensures that the group exists.
Property Description

Members Use this property to replace the current group membership with the specified membe
of the form Domain\UserName. If you set this property in a configuration, do not use
the MembersToExclude or MembersToIncludeproperty. Doing so generates an

MembersToExclude Use this property to remove members from the existing membership of the group. Th
the form Domain\UserName. If you set this property in a configuration, do not use th
error.

MembersToInclude Use this property to add members to the existing membership of the group. The value
form Domain\UserName. If you set this property in a configuration, do not use the M
error.

DependsOn Indicates that the configuration of another resource must run before this resource is c
configuration script block that you want to run first is ResourceName and its type
property is `DependsOn = "[ResourceType]ResourceName"``.

Example 1
The following example shows how to ensure that a group called "TestGroup" is absent.
PowerShellCopy

Group GroupExample
{
# This removes TestGroup, if present
# To create a new group, set Ensure to "Present
Ensure = "Absent"
GroupName = "TestGroup"
}

Example 2
The following example shows how to add an Active Directory User to the local
administrators group as part of a Multi-Machine Lab build where you are already using
a PSCredential for the Local Adminstrator account. As this is also used for the Domain
Admin Account (after Domain promotion) we then need to convert this existing
PSCredential to a Domain Friendly credential to enable us to add a Domain User to the
Local Administrators Group on the Member server.
PowerShellCopy

@{
AllNodes = @(
@{
NodeName = '*';
DomainName = 'SubTest.contoso.com';
}
@{
NodeName = 'Box2';
AdminAccount = 'Admin-Dave_Alexanderson'
}
)
}

$domain = $node.DomainName.split('.')[0]
$DCredential = New-Object -TypeName System.Management.Automation.PSCredential -
ArgumentList ("$domain\$($credential.Username)", $Credential.Password)

Group AddADUserToLocalAdminGroup
{
GroupName='Administrators'
Ensure= 'Present'
MembersToInclude= "$domain\$($Node.AdminAccount)"
Credential = $dCredential
PsDscRunAsCredential = $DCredential
}

Example 3
The following example shows how to ensure a local group, TigerTeamAdmins, on the
server TigerTeamSource.Contoso.Com does not contain a particular domain account,
Contoso\JerryG.
PowerShellCopy

Configuration SecureTigerTeamSrouce
{
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
Node TigerTeamSource.Contoso.Com {
Group TigerTeamAdmins
{
GroupName = 'TigerTeamAdmins'
Ensure = 'Absent'
MembersToInclude = "Contoso\JerryG"
}
}
}
DSC GroupSet Resource
Applies To: Windows Windows PowerShell 5.0

The GroupSet resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to manage local groups on the target node. This resource is
a composite resource that calls the Group resource for each group specified in
the GroupName parameter.

Use this resource when you want to add and/or remove the same list of members to
more than one group, remove more than one group, or add more than one group with
the same list of members.

Syntax##
Copy

Group [string] #ResourceName


{
GroupName = [string[]]
[ Ensure = [string] { Absent | Present } ]
[ MembersToInclude = [string[]] ]
[ MembersToExclude = [string[]] ]
[ Credential = [PSCredential] ]
[ DependsOn = [string[]] ]
}

Properties
Property Description

GroupName The names of the groups for which you want to ensure a specific state.

MembersToExclude Use this property to remove members from the existing membership of the groups. T
the form Domain\UserName. If you set this property in a configuration, do not use th
error.
Property Description

Credential The credentials required to access remote resources. Note: This account must have t
add all non-local accounts to the group; otherwise, an error will occur.

Ensure Indicates whether the groups exist. Set this property to "Absent" to ensure that the gr
default value) ensures that the groups exist.

Members Use this property to replace the current group membership with the specified membe
of the form Domain\UserName. If you set this property in a configuration, do not use
the MembersToExclude or MembersToIncludeproperty. Doing so will generat

MembersToInclude Use this property to add members to the existing membership of the group. The value
form Domain\UserName. If you set this property in a configuration, do not use the M
error.

DependsOn Indicates that the configuration of another resource must run before this resource is c
configuration script block that you want to run first is ResourceName and its type
property is `DependsOn = "[ResourceType]ResourceName"``.

Example 1
The following example shows how to ensure that two groups called "myGroup" and
"myOtherGroup" are present.
PowerShellCopy

configuration GroupSetTest
{
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node localhost
{
GroupSet GroupSetTest
{
GroupName = @("myGroup", "myOtherGroup")
Ensure = "Present"
MembersToInclude = @("contoso\alice", "contoso\bob")
MembersToExclude = $("contoso\john")
Credential = Get-Credential
}
}
}
$cd = @{
AllNodes = @(
@{
NodeName = 'localhost'
PSDscAllowPlainTextPassword = $true
PSDscAllowDomainUser = $true
}
)
}

GroupSetTest -ConfigurationData $cd

Note: This example uses plaintext credentials for simplicity. For information about how
to encrypt credentials in the configuration MOF file, seeSecuring the MOF File.
DSC Log Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Log resource in Windows PowerShell Desired State Configuration (DSC) provides a
mechanism to write messages to the Microsoft-Windows-Desired State
Configuration/Analytic event log.
Copy

Syntax

Log [string] #ResourceName


{
Message = [string]
[ DependsOn = [string[]] ]
}

NOTE: By default only the Operational logs for DSC are enabled. Before the Analytic log
will be available or visible, it must be enabled. See the following article.

Where are DSC Event Logs?

Properties
Property Description

Message Indicates the message you want to write to the Microsoft-Windows-Desired State Configurati

DependsOn Indicates that the configuration of another resource must run before this log message gets wri
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .

Example
The following example shows how to include a message in the Microsoft-Windows-
Desired State Configuration/Analytic event log.
Note: if you run Test-DscConfiguration with this resource configured, it will always
return $false.

PowerShellCopy

Configuration logResourceTest
{
Import-DscResource -ModuleName PSDesiredStateConfiguration

Node localhost

{
Log LogExample
{
Message = "This message will appear in the Microsoft-Windows-Desired
State Configuration/Analytic event log."
}
}
}
DSC Package Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Package resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to install or uninstall packages, such as Windows Installer and
setup.exe packages, on a target node.

Syntax
Copy

Package [string] #ResourceName


{
Name = [string]
Path = [string]
ProductId = [string]
[ Arguments = [string] ]
[ Credential = [PSCredential] ]
[ Ensure = [string] { Absent | Present } ]
[ LogPath = [string] ]
[ DependsOn = [string[]] ]
[ ReturnCode = [UInt32[]] ]
}

Properties
Property Description

Name Indicates the name of the package for which you want to ensure a specific state.

Path Indicates the path where the package resides.

ProductId Indicates the product ID that uniquely identifies the package.

Arguments Lists a string of arguments that will be passed to the package exactly as provided.
Property Description

Credential Provides access to the package on a remote source. This property is not used to install the pac
system.

Ensure Indicates if the package is installed. Set this property to "Absent" to ensure the package is not
installed). Set it to "Present" (the default value) to ensure the package is installed.

LogPath Indicates the full path where you want the provider to save a log file to install or uninstall the

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
`DependsOn = "[ResourceType]ResourceName"``.

ReturnCode Indicates the expected return code. If the actual return code does not match the expected valu
error.

Example
This example runs the .msi installer that is located at the specified path and has the
specified product ID.
PowerShellCopy

Configuration PackageTest
{
Package PackageExample
{
Ensure = "Present" # You can also set Ensure to "Absent"
Path = "$Env:SystemDrive\TestFolder\TestProject.msi"
Name = "TestPackage"
ProductId = "ACDDCDAF-80C6-41E6-A1B9-8ABD8A05027E"
}
}
DSC WindowsProcess Resource
Applies To: Windows PowerShell 5.0

The ProcessSet resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to configure processes on a target node. This resource is
a composite resource that calls the WindowsProcess resource for each group specified
in the GroupName parameter.

Syntax
Copy

WindowsProcess [string] #ResourceName


{
Arguments = [string]
Path = [string]
[ Credential = [PSCredential] ]
[ Ensure = [string] { Absent | Present } ]
[ StandardOutputPath = [string] ]
[ StandardErrorPath = [string] ]
[ StandardInputPath = [string] ]
[ WorkingDirectory = [string] ]
[ DependsOn = [string[]] ]
}

Properties
Property Description

Arguments A string that contains arguments to pass to the process as-is. If you need to pass seve

Path The paths to the process executables. If these are the names of the executable files (n
search the environment Path variable ( $env:Path ) to find the files. If the values of t
not use the Path environment variable to find the files, and will throw an error if any
allowed.

Credential Indicates the credentials for starting the process.


Property Description

Ensure Specifies whether the processes exists. Set this property to "Present" to ensure that th
default is "Present".

StandardErrorPath The path to which the processes write standard error. Any existing file there will be o

StandardInputPath The stream from which the process receives standard input.

StandardOutputPath The path of the file to which the processes write standard output. Any existing file th

WorkingDirectory The location used as the current working directory for the processes.

DependsOn Indicates that the configuration of another resource must run before this resource is c
configuration script block that you want to run first is ResourceName and its type
property is `DependsOn = "[ResourceType]ResourceName"`` .
DSC Registry Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Registry resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to manage registry keys and values on a target node.

Syntax
Copy

Registry [string] #ResourceName


{
Key = [string]
ValueName = [string]
[ Ensure = [string] { Enable | Disable } ]
[ Force = [bool] ]
[ Hex = [bool] ]
[ DependsOn = [string[]] ]
[ ValueData = [string[]] ]
[ ValueType = [string] { Binary | Dword | ExpandString | MultiString | Qword |
String } ]
}

Properties
Property Description

Key Indicates the path of the registry key for which you want to ensure a specific state. This path m

ValueName Indicates the name of the registry value. To add or remove a registry key, specify this propert
ValueType or ValueData. To modify or remove the default value of a registry key, specify th
specifying ValueType or ValueData.

Ensure Indicates if the key and value exist. To ensure that they do, set this property to "Present". To e
"Absent". The default value is "Present".

Force If the specified registry key is present, Force overwrites it with the new value. If deleting a r
Property Description

Hex Indicates if data will be expressed in hexadecimal format. If specified, the DWORD/QWORD
Not valid for other types. The default value is $false.

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .

ValueData The data for the registry value.

ValueType Indicates the type of the value. The supported types are:

String (REG_SZ)
Binary (REG-BINARY)
Dword 32-bit (REG_DWORD)
Qword 64-bit (REG_QWORD)
Multi-string (REG_MULTI_SZ)
Expandable string (REG_EXPAND_SZ)

Example
This example ensures that a key named "ExampleKey" is present in
the HKEY_LOCAL_MACHINE hive.
PowerShellCopy

Configuration RegistryTest
{
Registry RegistryExample
{
Ensure = "Present" # You can also set Ensure to "Absent"
Key = "HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey"
ValueName = "TestValue"
ValueData = "TestData"
}
}

Note: Changing a registry setting in the HKEY_CURRENT_USER hive requires that the
configuration runs with user credentials, rather than as the system. You can use
the PsDscRunAsCredential property to specify user credentials for the configuration.
For an example, see Running DSC with user credentials
DSC Script Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Script resource in Windows PowerShell Desired State Configuration (DSC) provides
a mechanism to run Windows PowerShell script blocks on target nodes.
The Script resource has GetScript , SetScript , and TestScript properties. These
properties should be set to script blocks that will run on each target node.

The GetScript script block should return a hashtable representing the state of the
current node. The hashtable must only contain one key Result and the value must be of
type String . It is not required to return anything. DSC doesn't do anything with the
output of this script block.

The TestScript script block should determine if the current node needs to be modified.
It should return $true if the node is up-to-date. It should return $false if the node's
configuration is out-of-date and should be updated by the SetScript script block.
The TestScript script block is called by DSC.

The SetScript script block should modify the node. It is called by DSC if
the TestScript block return $false .

If you need to use variables from your configuration script in the GetScript , TestScript ,
or SetScript script blocks, use the $using: scope (see below for an example).

Syntax
Copy

Script [string] #ResourceName


{
GetScript = [string]
SetScript = [string]
TestScript = [string]
[ Credential = [PSCredential] ]
[ DependsOn = [string[]] ]
}
Properties
Property Description

GetScript Provides a block of Windows PowerShell script that runs when you invoke the Get-DscConfi
hashtable. The hashtable must only contain one key Result and the value must be of type St

SetScript Provides a block of Windows PowerShell script. When you invoke the Start-DscConfiguratio
the TestScriptblock returns $false, the SetScript block will run. If the TestScript block

TestScript Provides a block of Windows PowerShell script. When you invoke the Start-DscConfiguratio
SetScript block will run. If it returns $true, the SetScript block will not run. The TestScript
DscConfiguration cmdlet. However, in this case, the SetScript block will not run, no matter
The TestScript block must return True if the actual configuration matches the current desire
match. (The current desired state configuration is the last configuration enacted on the node th

Credential Indicates the credentials to use for running this script, if credentials are required.

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .

Example 1
PowerShellCopy

$version = Get-Content 'version.txt'

Configuration ScriptTest
{
Import-DscResource ModuleName 'PSDesiredStateConfiguration'

Script ScriptExample
{
SetScript =
{
$sw = New-Object System.IO.StreamWriter("C:\TempFolder\TestFile.txt")
$sw.WriteLine("Some sample string")
$sw.Close()
}
TestScript = { Test-Path "C:\TempFolder\TestFile.txt" }
GetScript = { @{ Result = (Get-Content C:\TempFolder\TestFile.txt) } }
}
}

Example 2
PowerShellCopy

$version = Get-Content 'version.txt'

Configuration ScriptTest
{
Import-DscResource ModuleName 'PSDesiredStateConfiguration'

Script UpdateConfigurationVersion
{
GetScript = {
$currentVersion = Get-Content (Join-Path -Path $env:SYSTEMDRIVE -
ChildPath 'version.txt')
return @{ 'Version' = "$currentVersion" }
}
TestScript = {
$state = $GetScript
if( $state['Version'] -eq $using:version )
{
Write-Verbose -Message ('{0} -eq {1}' -f
$state['Version'],$using:version)
return $true
}
Write-Verbose -Message ('Version up-to-date: {0}' -f $using:version)
return $false
}
SetScript = {
$using:version | Set-Content -Path (Join-Path -Path $env:SYSTEMDRIVE -
ChildPath 'version.txt')
}
}
}

This resource is writing the configuration's version to a text file. This version is available
on the client computer, but isn't on any of the nodes, so it has to be passed to each of
the Script resource's script blocks with PowerShell's using scope. When generating
the node's MOF file, the value of the $version variable is read from a text file on the
client computer. DSC replaces the $using:version variables in each script block with the
value of the $version variable.
DSC Service Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The Service resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to manage services on the target node.

Syntax
Copy

Service [string] #ResourceName


{
Name = [string]
[ BuiltInAccount = [string] { LocalService | LocalSystem | NetworkService } ]
[ Credential = [PSCredential] ]
[ DependsOn = [string[]] ]
[ StartupType = [string] { Automatic | Disabled | Manual } ]
[ State = [string] { Running | Stopped } ]
[ Description = [string] ]
[ DisplayName = [string] ]
[ Ensure = [string] { Absent | Present } ]
[ Path = [string] ]
}

Properties
Property Description

Name Indicates the service name. Note that sometimes this is different from the display name. Y
state with the Get-Service cmdlet.

BuiltInAccount Indicates the sign-in account to use for the service. The values that are allowed for this pr
and NetworkService.

Credential Indicates credentials for the account that the service will run under. This property and the
together.
Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is config
configuration script block that you want to run first is ResourceName and its type is Re
is DependsOn = "[ResourceType]ResourceName" .

StartupType Indicates the startup type for the service. The values that are allowed for this property are

State Indicates the state you want to ensure for the service.

Description Indicates the description of the target service.

DisplayName Indicates the display name of the target service.

Ensure Indicates whether the target service exists on the system. Set this property to Absent to e
it to Present (the default value) ensures that target service exists.

Path Indicates the path to the binary file for a new service.

Example
PowerShellCopy

configuration ServiceTest
{
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node localhost
{

Service ServiceExample
{
Name = "TermService"
StartupType = "Manual"
State = "Running"
}
}
}
DSC ServiceSet Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The ServiceSet resource in Windows PowerShell Desired State Configuration (DSC)


provides a mechanism to manage services on the target node. This resource is
a composite resource that calls the Service resource for each service specified in
the Name property.

Use this resource when you want to configure a number of services to the same state.

Syntax
Copy

Service [string] #ResourceName


{
Name = [string[]]
[ StartupType = [string] { Automatic | Disabled | Manual } ]
[ BuiltInAccount = [string] { LocalService | LocalSystem | NetworkService } ]
[ State = [string] { Running | Stopped } ]
[ Ensure = [string] { Absent | Present } ]
[ Credential = [PSCredential] ]
[ DependsOn = [string[]] ]

Properties
Property Description

Name Indicates the service names. Note that sometimes this is different from the display names.
state with the Get-Service cmdlet.

StartupType Indicates the startup type for the service. The values that are allowed for this property are

BuiltInAccount Indicates the sign-in account to use for the services. The values that are allowed for this p
and NetworkService.
Property Description

State Indicates the state you want to ensure for the services: Stopped or Running.

Ensure Indicates whether the services exist on the system. Set this property to Absent to ensure
to Present (the default value) ensures that target services exist.

Credential Indicates credentials for the account that the service resource will run under. This property
used together.

DependsOn Indicates that the configuration of another resource must run before this resource is config
configuration script block that you want to run first is ResourceName and its type is Resou
is DependsOn = "[ResourceType]ResourceName" .

Example
The following configuration starts the "Windows Audio" and "Remote Desktop Services"
services.
PowerShellCopy

configuration ServiceSetTest
{
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node localhost
{

ServiceSet ServiceSetExample
{
Name = @("TermService", "Audiosrv")
StartupType = "Manual"
State = "Running"
}
}
}
SC User Resource#
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The User resource in Windows PowerShell Desired State Configuration (DSC) provides a
mechanism to manage local user accounts on the target node.

Syntax##
Copy

User [string] #ResourceName


{
UserName = [string]
[ Description = [string] ]
[ Disabled = [bool] ]
[ Ensure = [string] { Absent | Present } ]
[ FullName = [string] ]
[ Password = [PSCredential] ]
[ PasswordChangeNotAllowed = [bool] ]
[ PasswordChangeRequired = [bool] ]
[ PasswordNeverExpires = [bool] ]
[ DependsOn = [string[]] ]
}

Properties
Property Description

UserName Indicates the account name for which you want to ensure a specific state.

Description Indicates the description you want to use for the user account.

Disabled Indicates if the account is enabled. Set this property to $true to ensure that
ensure that it is enabled.

Ensure Indicates if the account exists. Set this property to "Present" to ensure that th
that the account does not exist.
Property Description

FullName Represents a string with the full name you want to use for the user account.

Password Indicates the password you want to use for this account.

PasswordChangeNotAllowed Indicates if the user can change the password. Set this property to $true to
and set it to $false to allow the user to change the password. The default va

PasswordChangeRequired Indicates if the user must change the password at the next sign in. Set this p
password. The default value is $true.

PasswordNeverExpires Indicates if the password will expire. To ensure that the password for this ac
to $true, and set it to $false if the password will expire. The default value

DependsOn Indicates that the configuration of another resource must run before this res
resource configuration script block that you want to run first is ResourceN
for using this property is DependsOn = "[ResourceType]ResourceName" .

Example
PowerShellCopy

User UserExample
{
Ensure = "Present" # To ensure the user account does not exist, set Ensure to
"Absent"
UserName = "SomeName"
Password = $passwordCred # This needs to be a credential object
DependsOn = "[Group]GroupExample" # Configures GroupExample first
}
DSC WaitForAll Resource
Applies To: Windows PowerShell 5.0 and later

The WaitForAll Desired State Configuration (DSC) resource can be used within a node
block in a DSC configuration to specify dependencies on configurations on other nodes.

This resource succeeds if if the resource specified by the ResourceName property is in


the desired state on all target nodes defined in the NodeName property.

Syntax
Copy

WaitForAll [string] #ResourceName


{
ResourceName = [string]
NodeName = [string]
[ RetryIntervalSec = [Uint64] ]
[ RetryCount = [Uint32] ]
[ ThrottleLimit = [Uint32]]
[ DependsOn = [string[]] ]
}

Properties
Property Description

ResourceName The resource name to depend on.

NodeName The target nodes of the resource to depend on.

RetryIntervalSec The number of seconds before retrying. Minimum is 1.

RetryCount The maximum number of times to retry.

ThrottleLimit Number of machines to connect simultaneously. Default is new-cimsession default.


Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is conf
configuration script block that you want to run first is ResourceName and its type is R
property is DependsOn = "[ResourceType]ResourceName" .

Example
For an example of how to use this resource, see Specifying cross-node dependencies
DSC WaitForAny Resource
Applies To: Windows PowerShell 5.1 and later

The WaitForSome Desired State Configuration (DSC) resource can be used within a
node block in a DSC configuration to specify dependencies on configurations on other
nodes.

This resource succeeds if if the resource specified by the ResourceName property is in


the desired state on any target nodes defined in the NodeName property.

Syntax
Copy

WaitForAny [string] #ResourceName


{
ResourceName = [string]
NodeName = [string]
[ RetryIntervalSec = [Uint64] ]
[ RetryCount = [Uint32] ]
[ ThrottleLimit = [Uint32]]
[ DependsOn = [string[]] ]
}

Properties
Property Description

ResourceName The resource name to depend on.

NodeName The target nodes of the resource to depend on.

RetryIntervalSec The number of seconds before retrying. Minimum is 1.

RetryCount The maximum number of times to retry.


Property Description

ThrottleLimit Number of machines to connect simultaneously. Default is new-cimsession default.

DependsOn Indicates that the configuration of another resource must run before this resource is conf
configuration script block that you want to run first is ResourceName and its type is R
property is DependsOn = "[ResourceType]ResourceName" .

Example
For an example of how to use this resource, see Specifying cross-node dependencies
DSC WaitForSome Resource
Applies To: Windows PowerShell 5.0 and later

The WaitForAny Desired State Configuration (DSC) resource can be used within a node
block in a DSC configuration to specify dependencies on configurations on other nodes.

This resource succeeds if if the resource specified by the ResourceName property is in


the desired state on a minimum number of nodes (specified by NodeCount) defined by
the NodeName property.

Syntax
Copy

WaitForAll [string] #ResourceName


{
ResourceName = [string]
NodeName = [string]
NodeCount = [Uint32]
[ RetryIntervalSec = [Uint64] ]
[ RetryCount = [Uint32] ]
[ ThrottleLimit = [Uint32]]
[ DependsOn = [string[]] ]
}

Properties
Property Description

ResourceName The resource name to depend on.

NodeName The target nodes of the resource to depend on.

NodeCount The minimum number of nodes that must be in the desired state for this resource to succ

RetryIntervalSec The number of seconds before retrying. Minimum is 1.


Property Description

RetryCount The maximum number of times to retry.

ThrottleLimit Number of machines to connect simultaneously. Default is new-cimsession default.

DependsOn Indicates that the configuration of another resource must run before this resource is conf
configuration script block that you want to run first is ResourceName and its type is R
property is DependsOn = "[ResourceType]ResourceName" .

Example
For an example of how to use this resource, see Specifying cross-node dependencies
DSC WindowsFeature Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The WindowsFeature resource in Windows PowerShell Desired State Configuration


(DSC) provides a mechanism to ensure that roles and features are added or removed on
a target node.

Syntax
Copy

WindowsFeature [string] #ResourceName


{
Name = [string]
[ Credential = [PSCredential] ]
[ Ensure = [string] { Absent | Present } ]
[ IncludeAllSubFeature = [bool] ]
[ LogPath = [string] ]
[ DependsOn = [string[]] ]
[ Source = [string] ]
}

Properties
Property Description

Name Indicates the name of the role or feature that you want to ensure is added or remove
the Get-WindowsFeature cmdlet, and not the display name of the role or feature.

Credential Indicates the credentials to use to add or remove the role or feature.

Ensure Indicates if the role or feature is added. To ensure that the role or feature is added, s
role or feature is removed, set the property to "Absent".

IncludeAllSubFeature Set this property to $true to ensure the state of all required subfeatures with the sta
the Name property.
Property Description

LogPath Indicates the path to a log file where you want the resource provider to log the oper

DependsOn Indicates that the configuration of another resource must run before this resource is
configuration script block that you want to run first is ResourceName and its typ
property is DependsOn = "[ResourceType]ResourceName" .

Source Indicates the location of the source file to use for installation, if necessary.

Example
PowerShellCopy

WindowsFeature RoleExample
{
Ensure = "Present"
# Alternatively, to ensure the role is uninstalled, set Ensure to "Absent"
Name = "Web-Server" # Use the Name property from Get-WindowsFeature
}
DSC WindowsFeatureSet Resource
Applies To: Windows PowerShell 5.0

The WindowsFeatureSet resource in Windows PowerShell Desired State Configuration


(DSC) provides a mechanism to ensure that roles and features are added or removed on
a target node. This resource is a composite resource that calls the WindowsFeature
resource for each feature specified in the Name property.

Use this resource when you want to configure a number of Windows Features to the
same state.

Syntax
Copy

WindowsFeatureSet [string] #ResourceName


{
Name = [string[]]
[ Ensure = [string] { Absent | Present } ]
[ Source = [string] ]
[ IncludeAllSubFeature = [bool] ]
[ Credential = [PSCredential] ]
[ LogPath = [string] ]
[ DependsOn = [string[]] ]

Properties
Property Description

Name The names of the roles or features that you want to ensure are added or removed. T
WindowsFeature cmdlet, and not the display name of the roles or features.

Credential The credentials to use to add or remove the roles or features.


Property Description

Ensure Indicates whether the roles or features are added. To ensure that the roles or feature
ensure that the roles or features are removed, set the property to "Absent".

IncludeAllSubFeature Set this property to $true to include all required subfeatures with of the features yo

LogPath The path to a log file where you want the resource provider to log the operation.

DependsOn Indicates that the configuration of another resource must run before this resource is
configuration script block that you want to run first is ResourceName and its typ
property is DependsOn = "[ResourceType]ResourceName" .

Source Indicates the location of the source file to use for installation, if necessary.

Example
The following configuration ensures that the Web-Server (IIS) and SMTP
Server features, and all subfeatures of each, are installed.
PowerShellCopy

configuration FeatureSetTest
{
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node localhost
{

WindowsFeatureSet WindowsFeatureSetExample
{
Name = @("SMTP-Server", "Web-Server")
Ensure = 'Present'
IncludeAllSubFeature = $true
}
}
}
DSC WindowsOptionalFeature Resource
Applies To: Windows PowerShell 5.0

The WindowsOptionalFeature resource in Windows PowerShell Desired State


Configuration (DSC) provides a mechanism to ensure that optional features are enabled
on a target node.

Syntax
Copy

WindowsOptionalFeature [string] #ResourceName


{
Name = [string]
[ Ensure = [string] { Enable | Disable } ]
[ Source = [string] ]
[ NoWindowsUpdateCheck = [bool] ]
[ RemoveFilesOnDisable = [bool] ]
[ LogLevel = [string] { ErrorsOnly | ErrorsAndWarning |
ErrorsAndWarningAndInformation } ]
[ LogPath = [string] ]
[ DependsOn = [string[]] ]

Properties
Property Description

Name Indicates the name of the feature that you want to ensure is enabled or disabled

Ensure Specifies whether the feature is enabled. To ensure that the feature is enabled, s
feature is disabled, set the property to "Disable".

Source Not implemented.


Property Description

NoWindowsUpdateCheck Specifies whether DISM contacts Windows Update (WU) when searching for t
does not contact WU.

RemoveFilesOnDisable Set to $true to remove all files associated with the feature when it is disabled (

LogLevel The maximum output level shown in the logs. The accepted values are: "Errors
"ErrorsAndWarning" (errors and warnings are logged), and "ErrorsAndWarnin
information are logged).

LogPath The path to a log file where you want the resource provider to log the operation

DependsOn Specifies that the configuration of another resource must run before this resour
resource configuration script block that you want to run first is ResourceNam
using this property is DependsOn = "[ResourceType]ResourceName" .
DSC WindowsOptionalFeatureSet Resource
Applies To: Windows PowerShell 5.0

The WindowsOptionalFeatureSet resource in Windows PowerShell Desired State


Configuration (DSC) provides a mechanism to ensure that optional features are enabled
on a target node. This resource is a composite resource that calls
the WindowsOptionalFeature resource for each feature specified in the Name property.

Use this resource when you want to configure a number of Windows optional features
to the same state.

Syntax
Copy

WindowsOptionalFeature [string] #ResourceName


{
Name = [string[]]
[ Ensure = [string] { Enable | Disable } ]
[ Source = [string] ]
[ RemoveFilesOnDisable = [bool] ]
[ LogPath = [string] ]
[ NoWindowsUpdateCheck = [bool] ]
[ LogLevel = [string] { ErrorsOnly | ErrorsAndWarning |
ErrorsAndWarningAndInformation } ]
[ DependsOn = [string[]] ]

Properties
Property Description

Name Indicates the name of the features that you want to ensure are enabled or disabl

Ensure Specifies whether the features are enabled. To ensure that the features are enab
the features are disabled, set the property to "Disable".
Property Description

Source Not implemented.

NoWindowsUpdateCheck Specifies whether DISM contacts Windows Update (WU) when searching for t
does not contact WU.

RemoveFilesOnDisable Set to $true to remove all files associated with the features when they are disab

LogLevel The maximum output level shown in the logs. The accepted values are: "Errors
"ErrorsAndWarning" (errors and warnings are logged), and "ErrorsAndWarnin
information are logged).

LogPath The path to a log file where you want the resource provider to log the operation

DependsOn Specifies that the configuration of another resource must run before this resour
resource configuration script block that you want to run first is ResourceNam
using this property is DependsOn = "[ResourceType]ResourceName" .
DSC WindowsPackageCab Resource
Applies To: Windows PowerShell 5.1 and later

The WindowsPackageCab resource in Windows PowerShell Desired State


Configuration (DSC) provides a mechanism to install or uninstall Windows cabinet (.cab)
packages on a target node.

The target node must have the DISM PowerShell module installed. For information,
see Use DISM in Windows PowerShell.

Syntax
Copy

{
Name = [string]
Ensure = [string] { Absent | Present }
SourcePath = [string]
[ LogPath = [string] ]
[ DependsOn = [string[]] ]
}

Properties
Property Description

Name Indicates the name of the package for you want to ensure a specific state.

Ensure Indicates if the package is installed. Set this property to "Absent" to ensure the package is not
installed). Set it to "Present" (the default value) to ensure the package is installed.

Path Indicates the path where the package resides.

LogPath Indicates the full path where you want the provider to save a log file to install or uninstall the
Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
`DependsOn = "[ResourceType]ResourceName"``.

Example
The following example configuration takes input parameters, and ensures that the .cab
file specified by the $Name parameter is installed.
PowerShellCopy

Configuration Sample_WindowsPackageCab
{
param
(
[Parameter (Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name,

[Parameter (Mandatory = $true)]


[ValidateNotNullOrEmpty()]
[String]
$SourcePath,

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$LogPath
)

Import-DscResource -ModuleName 'PSDscResources'

WindowsPackageCab WindowsPackageCab1
{
Name = $Name
Ensure = 'Present'
SourcePath = $SourcePath
LogPath = $LogPath
}
}
DSC WindowsProcess Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

The WindowsProcess resource in Windows PowerShell Desired State Configuration


(DSC) provides a mechanism to configure processes on a target node.

Syntax
Copy

WindowsProcess [string] #ResourceName


{
Arguments = [string]
Path = [string]
[ Credential = [PSCredential] ]
[ Ensure = [string] { Absent | Present } ]
[ DependsOn = [string[]] ]
[ StandardErrorPath = [string] ]
[ StandardInputPath = [string] ]
[ StandardOutputPath = [string] ]
[ WorkingDirectory = [string] ]
}

Properties
Property Description

Arguments Indicates a string of arguments to pass to the process as-is. If you need to pass severa

Path The path to the process executable. If this the file name of the executable (not the ful
the environment Path variable ( $env:Path ) to find the executable file. If the value o
not use the Path environment variable to find the file, and will throw an error if the p

Credential Indicates the credentials for starting the process.

Ensure Indicates if the process exists. Set this property to "Present" to ensure that the process
is "Present".
Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is c
configuration script block that you want to run first is ResourceName and its type
property is `DependsOn = "[ResourceType]ResourceName"`` .

StandardErrorPath Indicates the directory path to write the standard error. Any existing file there will be

StandardInputPath Indicates the standard input location.

StandardOutputPath Indicates the location to write the standard output. Any existing file there will be ove

WorkingDirectory Indicates the location that will be used as the current working directory for the proces
Build Custom Windows PowerShell Desired
State Configuration Resources
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Windows PowerShell Desired State Configuration (DSC) has built-in resources that you
can use to configure your environment. (For more information, see Built-In Windows
PowerShell Desired State Configuration Resources.) This topic provides an overview of
developing resources and links to topics with specific information and examples.

DSC resource components


A DSC resource is a Windows PowerShell module. The module contains both the
schema (the definition of the configurable properties) and the implementation (the code
that does the actual work specified by a configuration) for the resource. A DSC resource
schema can be defined in a MOF file, and the implementation is performed by a script
module. Beginning with the support of PowerShell classes in version 5, the schema and
implementation can both be defined in a class. The following topics describe in more
detail how to create DSC resources.

Writing a custom DSC resource with MOF


Implementing a DSC resource in C#
Writing a custom DSC resource with PowerShell classes
Composite resources: Using a DSC configuration as a resource
Using the Resource Designer tool
Writing a custom DSC resource with MOF
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

In this topic, we will define the schema for a Windows PowerShell Desired State
Configuration (DSC) custom resource in a MOF file, and implement the resource in a
Windows PowerShell script file. This custom resource is for creating and maintaining a
web site.

Creating the MOF schema


The schema defines the properties of your resource that can be configured by a DSC
configuration script.

Folder structure for a MOF resource

To implement a DSC custom resource with a MOF schema, create the following folder
structure. The MOF schema is defined in the file Demo_IISWebsite.schema.mof, and the
resource script is defined in Demo_IISWebsite.psm1. Optionally, you can create a
module manifest (psd1) file.
Copy

$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResources (folder)
|- DSCResources (folder)
|- Demo_IISWebsite (folder)
|- Demo_IISWebsite.psd1 (file, optional)
|- Demo_IISWebsite.psm1 (file, required)
|- Demo_IISWebsite.schema.mof (file, required)

Note that it is necessary to create a folder named DSCResources under the top-level
folder, and that the folder for each resource must have the same name as the resource.

The contents of the MOF file

Following is an example MOF file that can be used for a custom website resource. To
follow this example, save this schema to a file, and call the
file Demo_IISWebsite.schema.mof.
Copy

[ClassVersion("1.0.0"), FriendlyName("Website")]
class Demo_IISWebsite : OMI_BaseResource
{
[Key] string Name;
[Required] string PhysicalPath;
[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure;
[write,ValueMap{"Started","Stopped"},Values{"Started", "Stopped"}] string State;
[write] string Protocol[];
[write] string BindingInfo[];
[write] string ApplicationPool;
[read] string ID;
};

Note the following about the previous code:

FriendlyName defines the name you can use to refer to this custom resource in DSC
configuration scripts. In this example, Website is equivalent to the friendly name Archive for
the built-in Archive resource.
The class you define for your custom resource must derive from OMI_BaseResource .
The type qualifier, [Key] , on a property indicates that this property will uniquely identify the
resource instance. At least one [Key] property is required.
The [Required] qualifier indicates that the property is required (a value must be specified in any
configuration script that uses this resource).
The [write] qualifier indicates that this property is optional when using the custom resource in a
configuration script. The [read] qualifier indicates that a property cannot be set by a
configuration, and is for reporting purposes only.
Values restricts the values that can be assigned to the property to the list of values defined
in ValueMap . For more information, see ValueMap and Value Qualifiers.
Including a property called Ensure with values Present and Absent in your resource is
recommended as a way to maintain a consistent style with built-in DSC resources.
Name the schema file for your custom resource as follows: classname.schema.mof ,
where classname is the identifier that follows the class keyword in your schema definition.

Writing the resource script

The resource script implements the logic of the resource. In this module, you must
include three functions called Get-TargetResource, Set-TargetResource, and Test-
TargetResource. All three functions must take a parameter set that is identical to the
set of properties defined in the MOF schema that you created for your resource. In this
document, this set of properties is referred to as the resource properties. Store these
three functions in a file called .psm1. In the following example, the functions are stored
in a file called Demo_IISWebsite.psm1.

Note: When you run the same configuration script on your resource more than once,
you should receive no errors and the resource should remain in the same state as
running the script once. To accomplish this, ensure that your Get-
TargetResource and Test-TargetResourcefunctions leave the resource unchanged,
and that invoking the Set-TargetResource function more than once in a sequence with
the same parameter values is always equivalent to invoking it once.

In the Get-TargetResource function implementation, use the key resource property


values that are provided as parameters to check the status of the specified resource
instance. This function must return a hash table that lists all the resource properties as
keys and the actual values of these properties as the corresponding values. The
following code provides an example.
PowerShellCopy

# DSC uses the Get-TargetResource function to fetch the status of the resource
instance specified in the parameters for the target machine
function Get-TargetResource
{
param
(
[ValidateSet("Present", "Absent")]
[string]$Ensure = "Present",

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$Name,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$PhysicalPath,

[ValidateSet("Started", "Stopped")]
[string]$State = "Started",

[string]$ApplicationPool,

[string[]]$BindingInfo,
[string[]]$Protocol
)

$getTargetResourceResult = $null;

<# Insert logic that uses the mandatory parameter values to get the website
and assign it to a variable called $Website #>
<# Set $ensureResult to "Present" if the requested website exists and to
"Absent" otherwise #>

# Add all Website properties to the hash table


# This simple example assumes that $Website is not null
$getTargetResourceResult = @{
Name = $Website.Name;
Ensure = $ensureResult;
PhysicalPath = $Website.physicalPath;
State = $Website.state;
ID = $Website.id;
ApplicationPool = $Website.applicationPool;
Protocol =
$Website.bindings.Collection.protocol;
Binding =
$Website.bindings.Collection.bindingInformation;
}

$getTargetResourceResult;
}

Depending on the values that are specified for the resource properties in the
configuration script, the Set-TargetResource must do one of the following:

Create a new website


Update an existing website
Delete an existing website

The following example illustrates this.


PowerShellCopy

# The Set-TargetResource function is used to create, delete or configure a website on


the target machine.
function Set-TargetResource
{
[CmdletBinding(SupportsShouldProcess=$true)]
param
(
[ValidateSet("Present", "Absent")]
[string]$Ensure = "Present",

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$Name,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$PhysicalPath,

[ValidateSet("Started", "Stopped")]
[string]$State = "Started",

[string]$ApplicationPool,

[string[]]$BindingInfo,

[string[]]$Protocol
)

<# If Ensure is set to "Present" and the website specified in the mandatory input
parameters does not exist, then create it using the specified parameter values #>
<# Else, if Ensure is set to "Present" and the website does exist, then update
its properties to match the values provided in the non-mandatory parameter values #>
<# Else, if Ensure is set to "Absent" and the website does not exist, then do
nothing #>
<# Else, if Ensure is set to "Absent" and the website does exist, then delete the
website #>
}

Finally, the Test-TargetResource function must take the same parameter set as Get-
TargetResource and Set-TargetResource. In your implementation of Test-
TargetResource, check the status of the resource instance that is specified in the key
parameters. If the actual status of the resource instance does not match the values
specified in the parameter set, return $false. Otherwise, return $true.

The following code implements the Test-TargetResource function.


PowerShellCopy

function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[ValidateSet("Present","Absent")]
[System.String]
$Ensure,

[parameter(Mandatory = $true)]
[System.String]
$Name,

[parameter(Mandatory = $true)]
[System.String]
$PhysicalPath,

[ValidateSet("Started","Stopped")]
[System.String]
$State,

[System.String[]]
$Protocol,

[System.String[]]
$BindingData,

[System.String]
$ApplicationPool
)

#Write-Verbose "Use this cmdlet to deliver information about command processing."

#Write-Debug "Use this cmdlet to write debug information while troubleshooting."

#Include logic to
$result = [System.Boolean]
#Add logic to test whether the website is present and its status mathes the supplied
parameter values. If it does, return true. If it does not, return false.
$result
}

Note: For easier debugging, use the Write-Verbose cmdlet in your implementation of
the previous three functions.
This cmdlet writes text to the verbose message stream. By default, the verbose message
stream is not displayed, but you can display it by changing the value of
the $VerbosePreference variable or by using the Verbose parameter in the DSC
cmdlets = new.

Creating the module manifest

Finally, use the New-ModuleManifest cmdlet to define a .psd1 file for your custom
resource module. When you invoke this cmdlet, reference the script module (.psm1) file
described in the previous section. Include Get-TargetResource, Set-TargetResource,
and Test-TargetResource in the list of functions to export. Following is an example
manifest file.
PowerShellCopy

# Module manifest for module 'Demo.IIS.Website'


#
# Generated on: 1/10/2013
#

@{

# Script module or binary module file associated with this manifest.


# RootModule = ''

# Version number of this module.


ModuleVersion = '1.0'

# ID used to uniquely identify this module


GUID = '6AB5ED33-E923-41d8-A3A4-5ADDA2B301DE'

# Author of this module


Author = 'Contoso'

# Company or vendor of this module


CompanyName = 'Contoso'

# Copyright statement for this module


Copyright = 'Contoso. All rights reserved.'

# Description of the functionality provided by this module


Description = 'This Module is used to support the creation and configuration of IIS
Websites through Get, Set and Test API on the DSC managed nodes.'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '4.0'

# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = '4.0'

# Modules that must be imported into the global environment prior to importing this
module
RequiredModules = @("WebAdministration")

# Modules to import as nested modules of the module specified in


RootModule/ModuleToProcess
NestedModules = @("Demo_IISWebsite.psm1")

# Functions to export from this module


FunctionsToExport = @("Get-TargetResource", "Set-TargetResource", "Test-
TargetResource")

# Cmdlets to export from this module


#CmdletsToExport = '*'

# HelpInfo URI of this module


# HelpInfoURI = ''
}

Supporting PsDscRunAsCredential
Note: PsDscRunAsCredential is supported in PowerShell 5.0 and later.

The PsDscRunAsCredential property can be used in DSC configurations resource


block to specify that the resource should be run under a specified set of credentials. For
more information, see Running DSC with user credentials.

To access the user context from within a custom resource, you can use the automatic
variable $PsDscContext .

For example the following code would write the user context under which the resource
is running to the verbose output stream:
PowerShellCopy

if (PsDscContext.RunAsUser) {
Write-Verbose "User: $PsDscContext.RunAsUser";
}
Authoring a DSC resource in C #
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Typically, a Windows PowerShell Desired State Configuration (DSC) custom resource is


implemented in a PowerShell script. However, you can also implement the functionality
of a DSC custom resource by writing cmdlets in C#. For an introduction on writing
cmdlets in C#, see Writing a Windows PowerShell Cmdlet.

Aside from implementing the resource in C# as cmdlets, the process of creating the
MOF schema, creating the folder structure, importing and using your custom DSC
resource are the same as described in Writing a custom DSC resource with MOF.

Writing a cmdlet-based resource


For this example, we will implement a simple resource that manages a text file and its
contents.

Writing the MOF schema

The following is the MOF resource definition.


Copy

[ClassVersion("1.0.0"), FriendlyName("xDemoFile")]
class MSFT_XDemoFile : OMI_BaseResource
{
[Key, Description("path")] String Path;
[Write, Description("Should the file be present"),
ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
[Write, Description("Contentof file.")] String Content;
};

Setting up the Visual Studio project

Setting up a cmdlet project

1. Open Visual Studio.


2. Create a C# project and provide the name.
3. Select Class Library from the available project templates.
4. Click Ok.
5. Add an assembly reference to System.Automation.Management.dll to your project.
6. Change the assembly name to match the resource name. In this case, the assembly should be
named MSFT_XDemoFile.

Writing the cmdlet code

The following C# code implements the Get-TargetResource, Set-TargetResource,


and Test-TargetResource cmdlets.
C#Copy

namespace cSharpDSCResourceExample
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Management.Automation; // Windows PowerShell assembly.

#region Get-TargetResource

[OutputType(typeof(System.Collections.Hashtable))]
[Cmdlet(VerbsCommon.Get, "TargetResource")]
public class GetTargetResource : PSCmdlet
{
[Parameter(Mandatory = true)]
public string Path { get; set; }

/// <summary>
/// Implement the logic to return the current state of the resource as a
hashtable with keys being the resource properties
/// and the values are the corresponding current value on the machine.
/// </summary>
protected override void ProcessRecord()
{
var currentResourceState = new Dictionary<string, string>();
if (File.Exists(Path))
{
currentResourceState.Add("Ensure", "Present");

// read current content


string CurrentContent = "";
using (var reader = new StreamReader(Path))
{
CurrentContent = reader.ReadToEnd();
}
currentResourceState.Add("Content", CurrentContent);
}
else
{
currentResourceState.Add("Ensure", "Absent");
currentResourceState.Add("Content", "");
}
// write the hashtable in the PS console.
WriteObject(currentResourceState);
}
}

# endregion

#region Set-TargetResource
[OutputType(typeof(void))]
[Cmdlet(VerbsCommon.Set, "TargetResource")]
public class SetTargetResource : PSCmdlet
{
[Parameter(Mandatory = true)]
public string Path { get; set; }

[Parameter(Mandatory = false)]

[ValidateSet("Present", "Absent", IgnoreCase = true)]


public string Ensure {
get
{
// set the default to present.
return (this._ensure ?? "Present") ;
}
set
{
this._ensure = value;
}
}

[Parameter(Mandatory = false)]
public string Content {
get { return (string.IsNullOrEmpty(this._content) ? "" : this._content);
}
set { this._content = value; }
}

private string _ensure;


private string _content;

/// <summary>
/// Implement the logic to set the state of the machine to the desired state.
/// </summary>
protected override void ProcessRecord()
{
WriteVerbose(string.Format("Running set with parameters {0}{1}{2}", Path,
Ensure, Content));
if (File.Exists(Path))
{
if (Ensure.Equals("absent",
StringComparison.InvariantCultureIgnoreCase))
{
File.Delete(Path);
}
else
{
// file already exist and ensure "present" is specified. start
writing the content to a file
if (!string.IsNullOrEmpty(Content))
{
string existingContent = null;
using (var reader = new StreamReader(Path))
{
existingContent = reader.ReadToEnd();
}
// check if the content of the file mathes the content passed
if (!existingContent.Equals(Content,
StringComparison.InvariantCultureIgnoreCase))
{
WriteVerbose("Existing content did not match with desired
content updating the content of the file");
using (var writer = new StreamWriter(Path))
{
writer.Write(Content);
writer.Flush();
}
}
}
}

}
else
{
if (Ensure.Equals("present",
StringComparison.InvariantCultureIgnoreCase))
{
// if nothing is passed for content just write "" otherwise write
the content passed.
using (var writer = new StreamWriter(Path))
{
WriteVerbose(string.Format("Creating a file under path {0}
with content {1}", Path, Content));
writer.Write(Content);
}
}

/* if you need to reboot the VM. please add the following two line of
code.
PSVariable DscMachineStatus = new PSVariable("DSCMachineStatus", 1,
ScopedItemOptions.AllScope);
this.SessionState.PSVariable.Set(DscMachineStatus);
*/

# endregion

#region Test-TargetResource

[Cmdlet("Test", "TargetResource")]
[OutputType(typeof(Boolean))]
public class TestTargetResource : PSCmdlet
{
[Parameter(Mandatory = true)]
public string Path { get; set; }

[Parameter(Mandatory = false)]
[ValidateSet("Present", "Absent", IgnoreCase = true)]
public string Ensure
{
get
{
// set the default to present.
return (this._ensure ?? "Present");
}
set
{
this._ensure = value;
}
}

[Parameter(Mandatory = false)]
public string Content
{
get { return (string.IsNullOrEmpty(this._content) ? "" : this._content);
}
set { this._content = value; }
}

private string _ensure;


private string _content;

/// <summary>
/// Return a boolean value which indicates wheather the current machine is in
desired state or not.
/// </summary>
protected override void ProcessRecord()
{
if (File.Exists(Path))
{
if( Ensure.Equals("absent",
StringComparison.InvariantCultureIgnoreCase))
{
WriteObject(false);
}
else
{
// check if the content matches

string existingContent = null;


using (var stream = new StreamReader(Path))
{
existingContent = stream.ReadToEnd();
}

WriteObject(Content.Equals(existingContent,
StringComparison.InvariantCultureIgnoreCase));
}
}
else
{
WriteObject(Ensure.Equals("Absent",
StringComparison.InvariantCultureIgnoreCase));
}
}
}

# endregion

Deploying the resource

The compiled dll file should be saved in a file structure similar to a script-based
resource. The following is the folder structure for this resource.
Copy

$env: psmodulepath (folder)


|- MyDscResources (folder)
|- MyDscResources.psd1 (file, required)
|- DSCResources (folder)
|- MSFT_XDemoFile (folder)
|- MSFT_XDemoFile.psd1 (file, optional)
|- MSFT_XDemoFile.dll (file, required)
|- MSFT_XDemoFile.schema.mof (file, required)

See Also

Concepts

Writing a custom DSC resource with MOF


Other Resources

Writing a Windows PowerShell Cmdlet


Writing a custom DSC resource with
PowerShell classes
Applies To: Windows Windows PowerShell 5.0

With the introduction of PowerShell classes in Windows PowerShell 5.0, you can now
define a DSC resource by creating a class. The class defines both the schema and the
implementation of the resource, so there is no need to create a separate MOF file. The
folder structure for a class-based resource is also simpler, because
a DSCResources folder is not necessary.

In a class-based DSC resource, the schema is defined as properties of the class which
can be modified with attributes to specify the property type.. The resource is
implemented by Get(), Set(), and Test() methods (equivalent to the Get-
TargetResource, Set-TargetResource, and Test-TargetResource functions in a script
resource.

In this topic, we will create a simple resource named FileResource that manages a file
in a specified path.

For more information about DSC resources, see Build Custom Windows PowerShell
Desired State Configuration Resources

Note: Generic collections are not supported in class-based resources.

Folder structure for a class resource


To implement a DSC custom resource with a PowerShell class, create the following
folder structure. The class is defined in MyDscResource.psm1and the module manifest
is defined in MyDscResource.psd1.
Copy

$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
|- MyDscResource.psm1
MyDscResource.psd1
Create the class
You use the class keyword to create a PowerShell class. To specify that a class is a DSC
resource, use the DscResource() attribute. The name of the class is the name of the
DSC resource.
PowerShellCopy

[DscResource()]
class FileResource {
}

Declare properties

The DSC resource schema is defined as properties of the class. We declare three
properties as follows.
PowerShellCopy

[DscProperty(Key)]
[string]$Path

[DscProperty(Mandatory)]
[Ensure] $Ensure

[DscProperty(Mandatory)]
[string] $SourcePath

[DscProperty(NotConfigurable)]
[Nullable[datetime]] $CreationTime

Notice that the properties are modified by attributes. The meaning of the attributes is as
follows:

DscProperty(Key): The property is required. The property is a key. The values of all properties
marked as keys must combine to uniquely identify a resource instance within a configuration.
DscProperty(Mandatory): The property is required.
DscProperty(NotConfigurable): The property is read-only. Properties marked with this attribute
cannot be set by a configuration, but are populated by the Get() method when present.
DscProperty(): The property is configurable, but it is not required.
The $Path and $SourcePath properties are both strings. The $CreationTime is
a DateTime property. The $Ensure property is an enumeration type, defined as follows.
PowerShellCopy

enum Ensure
{
Absent
Present
}

Implementing the methods

The Get(), Set(), and Test() methods are analogous to the Get-TargetResource, Set-
TargetResource, and Test-TargetResource functions in a script resource.

This code also includes the CopyFile() function, a helper function that copies the file
from $SourcePath to $Path.
PowerShellCopy

<#
This method is equivalent of the Set-TargetResource script function.
It sets the resource to the desired state.
#>
[void] Set()
{
$fileExists = $this.TestFilePath($this.Path)

if ($this.ensure -eq [Ensure]::Present)


{
if(-not $fileExists)
{
$this.CopyFile()
}
}
else
{
if ($fileExists)
{
Write-Verbose -Message "Deleting the file $($this.Path)"
Remove-Item -LiteralPath $this.Path -Force
}
}
}

<#
This method is equivalent of the Test-TargetResource script function.
It should return True or False, showing whether the resource
is in a desired state.
#>
[bool] Test()
{
$present = $this.TestFilePath($this.Path)

if ($this.Ensure -eq [Ensure]::Present)


{
return $present
}
else
{
return -not $present
}
}

<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate resources.
This method returns an instance of this class with the updated key
properties.
#>
[FileResource] Get()
{
$present = $this.TestFilePath($this.Path)

if ($present)
{
$file = Get-ChildItem -LiteralPath $this.Path
$this.CreationTime = $file.CreationTime
$this.Ensure = [Ensure]::Present
}
else
{
$this.CreationTime = $null
$this.Ensure = [Ensure]::Absent
}

return $this
}

<#
Helper method to check if the file exists and it is file
#>
[bool] TestFilePath([string] $location)
{
$present = $true

$item = Get-ChildItem -LiteralPath $location -ErrorAction Ignore

if ($item -eq $null)


{
$present = $false
}
elseif ($item.PSProvider.Name -ne "FileSystem")
{
throw "Path $($location) is not a file path."
}
elseif ($item.PSIsContainer)
{
throw "Path $($location) is a directory path."
}

return $present
}

<#
Helper method to copy file from source to path
#>
[void] CopyFile()
{
if (-not $this.TestFilePath($this.SourcePath))
{
throw "SourcePath $($this.SourcePath) is not found."
}

[System.IO.FileInfo] $destFileInfo = New-Object -TypeName


System.IO.FileInfo($this.Path)

if (-not $destFileInfo.Directory.Exists)
{
Write-Verbose -Message "Creating directory
$($destFileInfo.Directory.FullName)"
<#
Use CreateDirectory instead of New-Item to avoid code
to handle the non-terminating error
#>
[System.IO.Directory]::CreateDirectory($destFileInfo.Directory.FullName)
}

if (Test-Path -LiteralPath $this.Path -PathType Container)


{
throw "Path $($this.Path) is a directory path"
}

Write-Verbose -Message "Copying $($this.SourcePath) to $($this.Path)"

# DSC engine catches and reports any error that occurs


Copy-Item -LiteralPath $this.SourcePath -Destination $this.Path -Force
}

The complete file

The complete class file follows.


PowerShellCopy

enum Ensure
{
Absent
Present
}

<#
This resource manages the file in a specific path.
[DscResource()] indicates the class is a DSC resource
#>

[DscResource()]
class FileResource
{
<#
This property is the fully qualified path to the file that is
expected to be present or absent.

The [DscProperty(Key)] attribute indicates the property is a


key and its value uniquely identifies a resource instance.
Defining this attribute also means the property is required
and DSC will ensure a value is set before calling the resource.

A DSC resource must define at least one key property.


#>
[DscProperty(Key)]
[string]$Path

<#
This property indicates if the settings should be present or absent
on the system. For present, the resource ensures the file pointed
to by $Path exists. For absent, it ensures the file point to by
$Path does not exist.

The [DscProperty(Mandatory)] attribute indicates the property is


required and DSC will guarantee it is set.

If Mandatory is not specified or if it is defined as


Mandatory=$false, the value is not guaranteed to be set when DSC
calls the resource. This is appropriate for optional properties.
#>
[DscProperty(Mandatory)]
[Ensure] $Ensure

<#
This property defines the fully qualified path to a file that will
be placed on the system if $Ensure = Present and $Path does not
exist.

NOTE: This property is required because [DscProperty(Mandatory)] is


set.
#>
[DscProperty(Mandatory)]
[string] $SourcePath

<#
This property reports the file's create timestamp.

[DscProperty(NotConfigurable)] attribute indicates the property is


not configurable in DSC configuration. Properties marked this way
are populated by the Get() method to report additional details
about the resource when it is present.

#>
[DscProperty(NotConfigurable)]
[Nullable[datetime]] $CreationTime

<#
This method is equivalent of the Set-TargetResource script function.
It sets the resource to the desired state.
#>
[void] Set()
{
$fileExists = $this.TestFilePath($this.Path)
if ($this.ensure -eq [Ensure]::Present)
{
if (-not $fileExists)
{
$this.CopyFile()
}
}
else
{
if ($fileExists)
{
Write-Verbose -Message "Deleting the file $($this.Path)"
Remove-Item -LiteralPath $this.Path -Force
}
}
}

<#
This method is equivalent of the Test-TargetResource script function.
It should return True or False, showing whether the resource
is in a desired state.
#>
[bool] Test()
{
$present = $this.TestFilePath($this.Path)

if ($this.Ensure -eq [Ensure]::Present)


{
return $present
}
else
{
return -not $present
}
}
<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate resources.
This method returns an instance of this class with the updated key
properties.
#>
[FileResource] Get()
{
$present = $this.TestFilePath($this.Path)

if ($present)
{
$file = Get-ChildItem -LiteralPath $this.Path
$this.CreationTime = $file.CreationTime
$this.Ensure = [Ensure]::Present
}
else
{
$this.CreationTime = $null
$this.Ensure = [Ensure]::Absent
}

return $this
}

<#
Helper method to check if the file exists and it is file
#>
[bool] TestFilePath([string] $location)
{
$present = $true

$item = Get-ChildItem -LiteralPath $location -ea Ignore


if ($item -eq $null)
{
$present = $false
}
elseif ($item.PSProvider.Name -ne "FileSystem")
{
throw "Path $($location) is not a file path."
}
elseif ($item.PSIsContainer)
{
throw "Path $($location) is a directory path."
}
return $present
}

<#
Helper method to copy file from source to path
#>
[void] CopyFile()
{
if (-not $this.TestFilePath($this.SourcePath))
{
throw "SourcePath $($this.SourcePath) is not found."
}

[System.IO.FileInfo] $destFileInfo = new-object


System.IO.FileInfo($this.Path)
if (-not $destFileInfo.Directory.Exists)
{
Write-Verbose -Message "Creating directory
$($destFileInfo.Directory.FullName)"

<#
Use CreateDirectory instead of New-Item to avoid code
to handle the non-terminating error
#>
[System.IO.Directory]::CreateDirectory($destFileInfo.Directory.FullName)
}

if (Test-Path -LiteralPath $this.Path -PathType Container)


{
throw "Path $($this.Path) is a directory path"
}

Write-Verbose -Message "Copying $($this.SourcePath) to $($this.Path)"

# DSC engine catches and reports any error that occurs


Copy-Item -LiteralPath $this.SourcePath -Destination $this.Path -Force
}
} # This module defines a class for a DSC "FileResource" provider.

Create a manifest
To make a class-based resource available to the DSC engine, you must include
a DscResourcesToExport statement in the manifest file that instructs the module to
export the resource. Our manifest looks like this:
PowerShellCopy

@{

# Script module or binary module file associated with this manifest.


RootModule = 'MyDscResource.psm1'

DscResourcesToExport = 'FileResource'

# Version number of this module.


ModuleVersion = '1.0'

# ID used to uniquely identify this module


GUID = '81624038-5e71-40f8-8905-b1a87afe22d7'

# Author of this module


Author = 'Microsoft Corporation'

# Company or vendor of this module


CompanyName = 'Microsoft Corporation'

# Copyright statement for this module


Copyright = '(c) 2014 Microsoft. All rights reserved.'

# Description of the functionality provided by this module


# Description = ''

# Minimum version of the Windows PowerShell engine required by this module


PowerShellVersion = '5.0'

# Name of the Windows PowerShell host required by this module


# PowerShellHostName = ''
}

Test the resource


After saving the class and manifest files in the folder structure as described earlier, you
can create a configuration that uses the new resource. For information about how to run
a DSC configuration, see Enacting configurations. The following configuration will check
to see whether the file at c:\test\test.txt exists, and, if not, copies the file
from c:\test.txt (you should create c:\test.txt before you run the configuration).
PowerShellCopy

Configuration Test
{
Import-DSCResource -module MyDscResource
FileResource file
{
Path = "C:\test\test.txt"
SourcePath = "c:\test.txt"
Ensure = "Present"
}
}
Test
Start-DscConfiguration -Wait -Force Test

Supporting PsDscRunAsCredential
Note: PsDscRunAsCredential is supported in PowerShell 5.0 and later.

The PsDscRunAsCredential property can be used in DSC configurations resource


block to specify that the resource should be run under a specified set of credentials. For
more information, see Running DSC with user credentials.

Require or disallow PsDscRunAsCredential for your resource

The DscResource() attribute takes an optional parameter RunAsCredential. This


parameter takes one of three values:

Optional PsDscRunAsCredential is optional for configurations that call this resource. This is the
default value.
Mandatory PsDscRunAsCredential must be used for any configuration that calls this resource.
NotSupported Configurations that call this resource cannot use PsDscRunAsCredential.
Default Same as Optional .

For example, use the following attribute to specify that your custom resource does not
support using PsDscRunAsCredential:
PowerShellCopy
[DscResource(RunAsCredential=NotSupported)]
class FileResource {
}

Access the user context

To access the user context from within a custom resource, you can use the automatic
variable $global:PsDscContext .

For example the following code would write the user context under which the resource
is running to the verbose output stream:
PowerShellCopy

if (PsDscContext.RunAsUser) {
Write-Verbose "User: $global:PsDscContext.RunAsUser";
}

See Also

Concepts

Build Custom Windows PowerShell Desired State Configuration Resources


Composite resources: Using a DSC
configuration as a resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

In real-world situations, configurations can become long and complex, calling many
different resources and setting a vast number of properties. To help address this
complexity, you can use a Windows PowerShell Desired State Configuration (DSC)
configuration as a resource for other configurations. We call this a composite resource.
A composite resource is a DSC configuration that takes parameters. The parameters of
the configuration act as the properties of the resource. The configuration is saved as a
file with a .schema.psm1 extension, and takes the place of both the MOF schema and
the resource script in a typical DSC resource (for more information about DSC resources,
see Windows PowerShell Desired State Configuration Resources.

Creating the composite resource


In our example, we create a configuration that invokes a number of existing resources to
configure virtual machines. Instead of specifying the values to be set in configuration
blocks, the configuration takes a number of parameters that are then used in the
configuration blocks.
PowerShellCopy

Configuration xVirtualMachine
{
param
(
# Name of VMs
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String[]] $VMName,

# Name of Switch to create


[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $SwitchName,

# Type of Switch to create


[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $SwitchType,

# Source Path for VHD


[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $VHDParentPath,

# Destination path for diff VHD


[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $VHDPath,

# Startup Memory for VM


[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $VMStartupMemory,

# State of the VM
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $VMState
)

# Import the module that defines custom resources


Import-DscResource -Module xComputerManagement,xHyper-V

# Install the Hyper-V role


WindowsFeature HyperV
{
Ensure = "Present"
Name = "Hyper-V"
}

# Create the virtual switch


xVMSwitch $SwitchName
{
Ensure = "Present"
Name = $SwitchName
Type = $SwitchType
DependsOn = "[WindowsFeature]HyperV"
}

# Check for Parent VHD file


File ParentVHDFile
{
Ensure = "Present"
DestinationPath = $VHDParentPath
Type = "File"
DependsOn = "[WindowsFeature]HyperV"
}

# Check the destination VHD folder


File VHDFolder
{
Ensure = "Present"
DestinationPath = $VHDPath
Type = "Directory"
DependsOn = "[File]ParentVHDFile"
}

# Creae VM specific diff VHD


foreach ($Name in $VMName)
{
xVHD "VHD$Name"
{
Ensure = "Present"
Name = $Name
Path = $VHDPath
ParentPath = $VHDParentPath
DependsOn = @("[WindowsFeature]HyperV",
"[File]VHDFolder")
}
}

# Create VM using the above VHD


foreach($Name in $VMName)
{
xVMHyperV "VMachine$Name"
{
Ensure = "Present"
Name = $Name
VhDPath = (Join-Path -Path $VHDPath -ChildPath $Name)
SwitchName = $SwitchName
StartupMemory = $VMStartupMemory
State = $VMState
MACAddress = $MACAddress
WaitForIP = $true
DependsOn = @("[WindowsFeature]HyperV",
"[xVHD]VHD$Name")
}
}
}

Saving the configuration as a composite resource

To use the parameterized configuration as a DSC resource, save it in a directory


structure like that of any other MOF-based resource, and name it with
a .schema.psm1 extension. For this example, well name the
file xVirtualMachine.schema.psm1. You also need to create a manifest
named xVirtualMachine.psd1 that contains the following line. Note that this is in
addition to MyDscResources.psd1, the module manifest for all resources under
the MyDscResources folder.
PowerShellCopy

RootModule = 'xVirtualMachine.schema.psm1'

When you are done, the folder structure should be as follows.


Copy

$env: psmodulepath
|- MyDscResources
MyDscResources.psd1
|- DSCResources
|- xVirtualMachine
|- xVirtualMachine.psd1
|- xVirtualMachine.schema.psm1

The resource is now discoverable by using the Get-DscResource cmdlet, and its
properties are discoverable by either that cmdlet or by using Ctrl+Space auto-complete
in the Windows PowerShell ISE.

Using the composite resource


Next we create a configuration that calls the composite resource. This configuration calls
the xVirtualMachine composite resource to create a virtual machine, and then calls
the xComputer resource to rename it.
PowerShellCopy
configuration RenameVM
{

Import-DscResource -Module TestCompositeResource


Node localhost
{
xVirtualMachine VM
{
VMName = "Test"
SwitchName = "Internal"
SwitchType = "Internal"
VhdParentPath = "C:\Demo\VHD\RTM.vhd"
VHDPath = "C:\Demo\VHD"
VMStartupMemory = 1024MB
VMState = "Running"
}
}

Node "192.168.10.1"
{
xComputer Name
{
Name = "SQL01"
DomainName = "fourthcoffee.com"
}
}
}

Supporting PsDscRunAsCredential
Note: PsDscRunAsCredential is supported in PowerShell 5.0 and later.

The PsDscRunAsCredential property can be used in DSC configurations resource


block to specify that the resource should be run under a specified set of credentials. For
more information, see Running DSC with user credentials.

To access the user context from within a custom resource, you can use the automatic
variable $PsDscContext .
For example the following code would write the user context under which the resource
is running to the verbose output stream:
PowerShellCopy

if (PsDscContext.RunAsUser) {
Write-Verbose "User: $PsDscContext.RunAsUser";
}

See Also

Concepts

Writing a custom DSC resource with MOF


Get Started with Windows PowerShell Desired State Configuration
Writing a single-instance DSC resource (best
practice)
Note: This topic describes a best practice for defining a DSC resource that allows only a
single instance in a configuration. Currently, there is no built-in DSC feature to do this.
That might change in the future.

There are situations where you don't want to allow a resource to be used multiple times
in a configuration. For example, in a previous implementation of
the xTimeZone resource, a configuration could call the resource multiple times, setting
the time zone to a different setting in each resource block:
PowerShellCopy

Configuration SetTimeZone
{
Param
(
[String[]]$NodeName = $env:COMPUTERNAME

Import-DSCResource -ModuleName xTimeZone

Node $NodeName
{
xTimeZone TimeZoneExample
{

TimeZone = 'Eastern Standard Time'


}

xTimeZone TimeZoneExample2
{

TimeZone = 'Pacific Standard Time'

}
}
This is because of the way DSC resource keys work. A resource must have at least one
key property. A resource instance is considered unique if the combination of the values
of all of its key properties is unique. In its previous implementation,
the xTimeZone resource had only one property--TimeZone, which was required to be a
key. Because of this, a configuration such as the one above would compile and run
without warning. Each of the xTimeZone resource blocks is considered unique. This
would cause the configuration to be repeatedly applied to the node, cycling the
timezone back and forth.

To ensure that a configuration could set the time zone for a target node only once, the
resource was updated to add a second property, IsSingleInstance, that became the key
property. The IsSingleInstance was limited to a single value, "Yes" by using
a ValueMap. The old MOF schema for the resource was:
PowerShellCopy

[ClassVersion("1.0.0.0"), FriendlyName("xTimeZone")]
class xTimeZone : OMI_BaseResource
{
[Key, Description("Specifies the TimeZone.")] String TimeZone;
};

The updated MOF schema for the resource is:


PowerShellCopy

[ClassVersion("1.0.0.0"), FriendlyName("xTimeZone")]
class xTimeZone : OMI_BaseResource
{
[Key, Description("Specifies the resource is a single instance, the value must be
'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance;
[Required, Description("Specifies the TimeZone.")] String TimeZone;
};

The resource script was also updated to use the new parameter. Here is the old resource
script:
PowerShellCopy

function Get-TargetResource
{
[CmdletBinding()]
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,

[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)

#Get the current TimeZone


$CurrentTimeZone = Get-TimeZone

$returnValue = @{
TimeZone = $CurrentTimeZone
IsSingleInstance = 'Yes'
}

#Output the target resource


$returnValue
}

function Set-TargetResource
{
[CmdletBinding(SupportsShouldProcess=$true)]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,

[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)

#Output the result of Get-TargetResource function.


$CurrentTimeZone = Get-TimeZone

if($PSCmdlet.ShouldProcess("'$TimeZone'","Replace the System Time Zone"))


{
try
{
if($CurrentTimeZone -ne $TimeZone)
{
Write-Verbose -Verbose "Setting the TimeZone"
Set-TimeZone -TimeZone $TimeZone}
else
{
Write-Verbose -Verbose "TimeZone already set to $TimeZone"
}
}
catch
{
$ErrorMsg = $_.Exception.Message
Write-Verbose -Verbose $ErrorMsg
}
}
}

function Test-TargetResource
{
[CmdletBinding()]
[OutputType([Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,

[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)

#Output from Get-TargetResource


$CurrentTimeZone = Get-TimeZone

if($TimeZone -eq $CurrentTimeZone)


{
return $true
}
else
{
return $false
}
}

Function Get-TimeZone {
[CmdletBinding()]
param()

& tzutil.exe /g
}

Function Set-TimeZone {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[System.String]
$TimeZone
)

try
{
& tzutil.exe /s $TimeZone
}
catch
{
$ErrorMsg = $_.Exception.Message
Write-Verbose $ErrorMsg
}
}

Export-ModuleMember -Function *-TargetResource

Notice that the TimeZone property is no longer a key. Now, if a configuration attempts
to set the time zone twice (by using two different xTimeZone blocks with
different TimeZone values), attempting to compile the configuration will cause an error:
PowerShellCopy

Test-ConflictingResources : A conflict was detected between resources


'[xTimeZone]TimeZoneExample (::15::10::xTimeZone)' and
'[xTimeZone]TimeZoneExample2 (::22::10::xTimeZone)' in node 'CONTOSO-CLIENT'.
Resources have identical key properties but there are differences in the
following non-key properties: 'TimeZone'. Values 'Eastern Standard Time' don't match
values 'Pacific Standard Time'. Please update these property
values so that they are identical in both cases.
At line:271 char:9
+ Test-ConflictingResources $keywordName $canonicalizedValue $k ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Write-Error],
InvalidOperationException
+ FullyQualifiedErrorId : ConflictingDuplicateResource,Test-ConflictingResources
Errors occurred while processing configuration 'SetTimeZone'.
At
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesi
redStateConfiguration.psm1:3705 char:5
+ throw $ErrorRecord
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (SetTimeZone:String) [],
InvalidOperationException
+ FullyQualifiedErrorId : FailToProcessConfiguration
Resource authoring checklist
This checklist is a list of best practices when authoring a new DSC Resource.

Resource module contains .psd1 file and schema.mof for


every resource
Check that your resource has correct structure and contains all required files. Every
resource module should contain a .psd1 file and every non-composite resource should
have schema.mof file. Resources that do not contain schema will not be listed by Get-
DscResource and users will not be able to use the intellisense when writing code
against those modules in ISE. The directory structure for xRemoteFile resource, which is
part of the xPSDesiredStateConfiguration resource module, looks as follows:
Copy

xPSDesiredStateConfiguration
DSCResources
MSFT_xRemoteFile
MSFT_xRemoteFile.psm1
MSFT_xRemoteFile.schema.mof
Examples
xRemoteFile_DownloadFile.ps1
ResourceDesignerScripts
GenerateXRemoteFileSchema.ps1
Tests
ResourceDesignerTests.ps1
xPSDesiredStateConfiguration.psd1

Resource and schema are correct##


Verify the resource schema (*.schema.mof) file. You can use the DSC Resource
Designer to help develop and test your schema. Make sure that:

Property types are correct (e.g. dont use String for properties which accept
numeric values, you should use UInt32 or other numeric types instead)
Property attributes are specified correctly as: ([key], [required], [write], [read])
At least one parameter in the schema has to be marked as [key]
[read] property does not coexist together with any of: [required], [key], [write]
If multiple qualifiers are specified except [read], then [key] takes precedence
If [write] and [required] are specified, then [required] takes precedence
ValueMap is specified where appropriate

Example:
Copy

[Read, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}, Description("Says


whether DestinationPath exists on the machine")] String Ensure;

Friendly name is specified and confirms to DSC naming conventions

Example: [ClassVersion("1.0.0.0"), FriendlyName("xRemoteFile")]

Every field has meaningful description. The PowerShell GitHub repository has good
examples, such as the .schema.mof for xRemoteFile

Additionally, you should use Test-xDscResource and Test-xDscSchema cmdlets


from DSC Resource Designer to automatically verify the resource and schema:
Copy

Test-xDscResource <Resource_folder>
Test-xDscSchema <Path_to_resource_schema_file>

For example:
PowerShellCopy

Test-xDscResource ..\DSCResources\MSFT_xRemoteFile
Test-xDscSchema ..\DSCResources\MSFT_xRemoteFile\MSFT_xRemoteFile.schema.mof

Resource loads without errors


Check whether the resource module can be successfully loaded. This can be achieved
manually, by running Import-Module <resource_module> -force and confirming that no
errors occurred, or by writing test automation. In case of the latter, you can follow this
structure in your test case:
PowerShellCopy

$error = $null
Import-Module <resource_module> force
If ($error.count ne 0) {
Throw Module was not imported correctly. Errors returned: $error
}

Resource is idempotent in the positive case


One of the fundamental characteristics of DSC resources is be idempotence. It means
that applying a DSC configuration containing that resource multiple times will always
achieve the same result. For example, if we create a configuration which contains the
following File resource:
PowerShellCopy

File file {
DestinationPath = "C:\test\test.txt"
Contents = "Sample text"
}

After applying it for the first time, file test.txt should appear in C:\test folder. However,
subsequent runs of the same configuration should not change the state of the machine
(e.g. no copies of the test.txt file should be created). To ensure a resource is idempotent
you can repeatedly call Set-TargetResource when testing the resource directly, or
call Start-DscConfiguration multiple times when doing end to end testing. The result
should be the same after every run.

Test user modification scenario


By changing the state of the machine and then rerunning DSC, you can verify that Set-
TargetResource and Test-TargetResource function properly. Here are steps you
should take:

1. Start with the resource not in the desired state.


2. Run configuration with your resource
3. Verify Test-DscConfiguration returns True
4. Modify the configured item to be out of the desired state
5. Verify Test-DscConfiguration returns false Heres a more concrete example using
Registry resource:
6. Start with registry key not in the desired state
7. Run Start-DscConfiguration with a configuration to put it in the desired state and
verify it passes.
8. Run Test-DscConfiguration and verify it returns true
9. Modify the value of the key so that it is not in the desired state
10. Run Test-DscConfiguration and verify it returns false
11. Get-TargetResource functionality was verified using Get-DscConfiguration

Get-TargetResource should return details of the current state of the resource. Make sure
to test it by calling Get-DscConfiguration after you apply the configuration and verifying
that output correctly reflects the current state of the machine. It's important to test it
separately, since any issues in this area won't appear when calling Start-
DscConfiguration.

Call Get/Set/Test-TargetResource functions directly


Make sure you test the Get/Set/Test-TargetResource functions implemented in your
resource by calling them directly and verifying that they work as expected.

Verify End to End using Start-DscConfiguration


Testing Get/Set/Test-TargetResource functions by calling them directly is important,
but not all issues will be discovered this way. You should focus significant part of your
testing on using Start-DscConfiguration or the pull server. In fact, this is how users will
use the resource, so dont underestimate the significance of this type of tests. Possible
types of issues:

Credential/Session may behave differently because the DSC agent runs as a


service. Be sure to test any features here end to end.
Errors output by Start-DscConfiguration may be different than those displayed
when calling the Set-TargetResource function directly.

Test compatability on all DSC supported platforms


Resource should work on all DSC supported platforms (Windows Server 2008 R2 and
newer). Install the latest WMF (Windows Management Framework) on your OS to get
the latest version of DSC. If your resource does not work on some of these platforms by
design, a specific error message should be returned. Also, make sure your resource
checks whether cmdlets you are calling are present on particular machine. Windows
Server 2012 added a large number of new cmdlets that are not available on Windows
Server 2008R2, even with WMF installed.

Verify on Windows Client (if applicable)


One very common test gap is verifying the resource only on server versions of Windows.
Many resources are also designed to work on Client SKUs, so if thats true in your case,
dont forget to test it on those platforms as well.

Get-DSCResource lists the resource


After deploying the module, calling Get-DscResource should list your resource among
others as a result. If you cant find your resource in the list, make sure that schema.mof
file for that resource exists.

Resource module contains examples


Creating quality examples which will help others understand how to use it. This is crucial,
especially since many users treat sample code as documentation.

First, you should determine the examples that will be included with the module
at minimum, you should cover most important use cases for your resource:
If your module contains several resources that need to work together for an end-
to-end scenario, the basic end-to-end example would ideally be first.
The initial examples should be very simple -- how to get started with your
resources in small manageable chunks (e.g. creating a new VHD)
Subsequent examples should build on those examples (e.g. creating a VM from a
VHD, removing VM, modifying VM), and show advanced functionality (e.g. creating
a VM with dynamic memory)
Example configurations should be parameterized (all values should be passed to
the configuration as parameters and there should be no hardcoded values):

PowerShellCopy

configuration Sample_xRemoteFile_DownloadFile
{
param
(
[string[]] $nodeName = 'localhost',

[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String] $destinationPath,

[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String] $uri,

[String] $userAgent,

[Hashtable] $headers
)

Import-DscResource -Name MSFT_xRemoteFile -ModuleName


xPSDesiredStateConfiguration

Node $nodeName
{
xRemoteFile DownloadFile
{
DestinationPath = $destinationPath
Uri = $uri
UserAgent = $userAgent
Headers = $headers
}
}
}

Its a good practice to include (commented out) example of how to call the
configuration with the actual values at the end of the example script. For example,
in the configuration above it isn't neccessarily obvious that the best way to specify
UserAgent is:

UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer
In which case a comment can clarify the intended execution of the configuration:
Copy

<#
Sample use (parameter values need to be changed according to your scenario):
Sample_xRemoteFile_DownloadFile -destinationPath "$env:SystemDrive\fileName.jpg" -uri
"http://www.contoso.com/image.jpg"

Sample_xRemoteFile_DownloadFile -destinationPath "$env:SystemDrive\fileName.jpg" -uri


"http://www.contoso.com/image.jpg" `
-userAgent [Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer -headers
@{"Accept-Language" = "en-US"}
#>

For each example, write a short description which explains what it does, and the
meaning of the parameters.
Make sure examples cover most the important scenarios for your resource and if
theres nothing missing, verify that they all execute and put machine in the desired
state.

Error messages are easy to understand and help users


solve problems
Good error messages should be:

There: The biggest problem with error messages is that they often dont exist, so
make sure they are there.
Easy to understand: Human readable, no obscure error codes
Precise: Describe whats exactly the problem
Constructive: Advice how to fix the issue
Polite: Dont blame user or make them feel bad Make sure you verify errors in End
to End scenarios (using Start-DscConfiguration), because they may differ from
those returned when running resource functions directly.

Log messages are easy to understand and informative


(including verbose, debug and ETW logs)
Ensure that logs outputted by the resource are easy to understand and provide value to
the user. Resources should output all information which might be helpful to the user,
but more logs is not always better. You should avoid redundancy and outputting data
which does not provide additional value dont make someone go through hundreds of
log entries in order to find what they're looking for. Of course, no logs is not an
acceptable solution for this problem either.
When testing, you should also analyze verbose and debug logs (by running Start-
DscConfiguration with verbose and debug switches appropriately), as well as ETW
logs. To see DSC ETW logs, go to Event Viewer and open the following folder:
Applications and Services- Microsoft - Windows - Desired State Configuration. By
default there will be Operational channel, but make sure you enable Analytic and Debug
channels before running the configuration. To enable Analytic/Debug channels, you can
execute script below:
PowerShellCopy

$statusEnabled = $true
# Use "Analytic" to enable Analytic channel
$eventLogFullName = "Microsoft-Windows-Dsc/Debug"
$commandToExecute = "wevtutil set-log $eventLogFullName /e:$statusEnabled
/q:$statusEnabled "
$log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration
$eventLogFullName
if($statusEnabled -eq $log.IsEnabled)
{
Write-Host -Verbose "The channel event log is already enabled"
return
}
Invoke-Expression $commandToExecute

Resource implementation does not contain hardcoded


paths
Ensure there are no hardcoded paths in the resource implementation, particularly if they
assume language (en-us), or when there are system variables that can be used. If your
resource need to access specific paths, use environment variables instead of hardcoding
the path, as it may differ on other machines.

Example:

Instead of:
Copy

$tempPath = "C:\Users\kkaczma\AppData\Local\Temp\MyResource"
$programFilesPath = "C:\Program Files (x86)"
You can write:
Copy

$tempPath = Join-Path $env:temp "MyResource"


$programFilesPath = ${env:ProgramFiles(x86)}

Resource implementation does not contain user


information
Make sure there are no email names, account information, or names of people in the
code.

Resource was tested with valid/invalid credentials


If your resource takes a credential as parameter:

Verify the resource works when Local System (or the computer account for remote
resources) does not have access.
Verify the resource works with a credential specified for Get, Set and Test
If your resource accesses shares, test all the variants you need to support, such as:
o Standard windows shares.
o DFS shares.
o SAMBA shares (if you want to support Linux.)

Resource does not require interactive input


Get/Set/Test-TargetResource functions should be executed automatically and must
not wait for users input at any stage of execution (e.g. you should not use Get-
Credential inside these functions). If you need to provide users input, you should pass
it to the configuration as parameter during the compilation phase.

Resource functionality was thoroughly tested


This checklist contains items which are important to be tested and/or are often missed.
There will be bunch of tests, mainly functional ones which will be specific to the resource
you are testing and are not mentioned here. Dont forget about negative test cases.
Best practice: Resource module contains Tests folder with
ResourceDesignerTests.ps1 script
Its a good practice to create folder Tests inside resource module, create
ResourceDesignerTests.ps1 file and add tests using Test-xDscResourceand Test-
xDscSchema for all resources in given module. This way you can quickly validate
schemas of all resources from the given modules and do a sanity check before
publishing. For xRemoteFile, ResourceTests.ps1 could look as simple as:
PowerShellCopy

Test-xDscResource ..\DSCResources\MSFT_xRemoteFile
Test-xDscSchema ..\DSCResources\MSFT_xRemoteFile\MSFT_xRemoteFile.schema.mof

Best practice: Resource folder contains resource designer


script for generating schema##
Each resource should contain a resource designer script which generates a mof schema
of the resource. This file should be placed in \ResourceDesignerScripts and be named
GenerateSchema.ps1 For xRemoteFile resource this file would be called
GenerateXRemoteFileSchema.ps1 and contain:
PowerShellCopy

$DestinationPath = New-xDscResourceProperty -Name DestinationPath -Type String -


Attribute Key -Description 'Path under which downloaded or copied file should be
accessible after operation.'
$Uri = New-xDscResourceProperty -Name Uri -Type String -Attribute Required -
Description 'Uri of a file which should be copied or downloaded. This parameter
supports HTTP and HTTPS values.'
$Headers = New-xDscResourceProperty -Name Headers -Type Hashtable[] -Attribute Write
-Description 'Headers of the web request.'
$UserAgent = New-xDscResourceProperty -Name UserAgent -Type String -Attribute Write -
Description 'User agent for the web request.'
$Ensure = New-xDscResourceProperty -Name Ensure -Type String -Attribute Read -
ValidateSet "Present", "Absent" -Description 'Says whether DestinationPath exists on
the machine'
$Credential = New-xDscResourceProperty -Name Credential -Type PSCredential -Attribute
Write -Description 'Specifies a user account that has permission to send the
request.'
$CertificateThumbprint = New-xDscResourceProperty -Name CertificateThumbprint -Type
String -Attribute Write -Description 'Digital public key certificate that is used to
send the request.'

New-xDscResource -Name MSFT_xRemoteFile -Property @($DestinationPath, $Uri, $Headers,


$UserAgent, $Ensure, $Credential, $CertificateThumbprint) -ModuleName
xPSDesiredStateConfiguration2 -FriendlyName xRemoteFile

Best practice: Resource supports -whatif


If your resource is performing dangerous operations, its a good practice to implement
-whatif functionality. After its done, make sure that whatif output correctly describes
operations which would happen if command was executed without whatif switch. Also,
verify that operations does not execute (no changes to the nodes state are made) when
whatif switch is present. For example, lets assume we are testing File resource. Below is
simple configuration which creates file test.txt with contents test:
PowerShellCopy

configuration config
{
node localhost
{
File file
{
Contents="test"
DestinationPath="C:\test\test.txt"
}
}
}
config

If we compile and then execute the configuration with the whatif switch, the output is
telling us exactly what would happen when we run the configuration. The configuration
itself however was not executed (test.txt file was not created).
PowerShellCopy

Start-DscConfiguration -path .\config -ComputerName localhost -wait -verbose -whatif


VERBOSE: Perform operation 'Invoke CimMethod' with following parameters,
''methodName' =
SendConfigurationApply,'className' =
MSFT_DSCLocalConfigurationManager,'namespaceName' =
root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer CHARLESX1 with user sid
S-1-5-21-397955417-626881126-188441444-5179871.
What if: [X]: LCM: [ Start Set ]
What if: [X]: LCM: [ Start Resource ] [[File]file]
What if: [X]: LCM: [ Start Test ] [[File]file]
What if: [X]: [[File]file] The system cannot find the file
specified.
What if: [X]: [[File]file] The related file/directory is:
C:\test\test.txt.
What if: [X]: LCM: [ End Test ] [[File]file] in 0.0270 seconds.
What if: [X]: LCM: [ Start Set ] [[File]file]
What if: [X]: [[File]file] The system cannot find the file
specified.
What if: [X]: [[File]file] The related file/directory is:
C:\test\test.txt.
What if: [X]: [C:\test\test.txt] Creating and writing
contents and setting attributes.
What if: [X]: LCM: [ End Set ] [[File]file] in 0.0180 seconds.
What if: [X]: LCM: [ End Resource ] [[File]file]
What if: [X]: LCM: [ End Set ]
VERBOSE: [X]: LCM: [ End Set ] in 0.1050 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.

This list is not exhaustive, but it covers many important issues which can be encountered
while designing, developing and testing DSC resources.+
Debugging DSC resources
Applies To: Windows PowerShell 5.0

In PowerShell 5.0, a new feature was introduced in Desired State Configuraiton (DSC)
that allows you to debug a DSC resource as a configuration is being applied.

Enabling DSC debugging


Before you can debug a resource, you have to enable debugging by calling the Enable-
DscDebug cmdlet. This cmdlet takes a mandatory parameter, BreakAll.

You can verify that debugging has been enabled by looking at the result of a call to Get-
DscLocalConfigurationManager.

The following PowerShell output shows the result of enabling debugging:


PowerShellCopy

PS C:\DebugTest> $LCM = Get-DscLocalConfigurationManager

PS C:\DebugTest> $LCM.DebugMode
NONE

PS C:\DebugTest> Enable-DscDebug -BreakAll

PS C:\DebugTest> $LCM = Get-DscLocalConfigurationManager

PS C:\DebugTest> $LCM.DebugMode
ForceModuleImport
ResourceScriptBreakAll

PS C:\DebugTest>

Starting a configuration with debug enabled


To debug a DSC resource, you start a configuration that calls that resource. For this
example, we'll look at a simple configuration that calls the WindowsFeature resource to
ensure that the "WindowsPowerShellWebAccess" feature is installed:
PowerShellCopy
Configuration PSWebAccess
{
Import-DscResource -ModuleName 'PsDesiredStateConfiguration'
Node localhost
{
WindowsFeature PSWA
{
Name = 'WindowsPowerShellWebAccess'
Ensure = 'Present'
}
}
}
PSWebAccess

After compiling the configuration, start it by calling Start-DscConfiguration. The


configuration will stop when the Local Configuration Manager (LCM) calls into the first
resource in the configuration. If you use the -Verbose and -Wait parameters, the output
displays the lines you need to enter to start debugging.
PowerShellCopy

Start-DscConfiguration .\PSWebAccess -Wait -Verbose


VERBOSE: Perform operation 'Invoke CimMethod' with following parameters,
''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfiguration
Manager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer TEST-SRV with user sid S-1-5-21-
2127521184-1604012920-1887927527-108583.
VERBOSE: An LCM method call arrived from computer TEST-SRV with user sid S-1-5-21-
2127521184-1604012920-1887927527-108583.
VERBOSE: [TEST-SRV]: LCM: [ Start Set ]
WARNING: [TEST-SRV]: [DSCEngine] Warning LCM is in Debug
'ResourceScriptBreakAll' mode. Resource script processing will
be stopped to wait for PowerShell script debugger to attach.
VERBOSE: [TEST-SRV]: [DSCEngine] Importing the module
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateCo
nfiguration\DscResources\MSFT_RoleResource\MSFT_RoleResource.psm1 in force mode.
VERBOSE: [TEST-SRV]: LCM: [ Start Resource ] [[WindowsFeature]PSWA]
VERBOSE: [TEST-SRV]: LCM: [ Start Test ] [[WindowsFeature]PSWA]
VERBOSE: [TEST-SRV]: [[WindowsFeature]PSWA] Importing the
module MSFT_RoleResource in force mode.
WARNING: [TEST-SRV]: [[WindowsFeature]PSWA] Resource is
waiting for PowerShell script debugger to attach.
Use the following commands to begin debugging this resource script:
Enter-PSSession -ComputerName TEST-SRV -Credential <credentials>
Enter-PSHostProcess -Id 9000 -AppDomainName DscPsPluginWkr_AppDomain
Debug-Runspace -Id 9

At this point, the LCM has called the resource, and come to the first break point. The last
three lines in the output show you how to attach to the process and start debugging the
resource script.

Debugging the resource script


Start a new instance of the PowerShell ISE. In the console pane, enter the last three lines
of output from the Start-DscConfiguration output as commands,
replacing <credentials> with valid user credentials. You should now see a prompt that
looks similar to:
PowerShellCopy

[TEST-SRV]: [DBG]: [Process:9000]: [RemoteHost]: PS C:\DebugTest>>

The resource script will open in the script pane, and the debugger is stopped at the first
line of the Test-TargetResource function (the Test()method of a class-based resource).
Now you can use the debug commands in the ISE to step through the resource script,
look at variable values, view the call stack, and so on. For information about debugging
in the PowerShell ISE, see How to Debug Scripts in Windows PowerShell ISE. Remember
that every line in the resource script (or class) is set as a break point.

Disabling DSC debugging


After calling Enable-DscDebug, all calls to Start-DscConfiguration will result in the
configuration breaking into the debugger. To allow configurations to run normally, you
must disable debugging by calling the Disable-DscDebug cmdlet.

Note: Rebooting does not change the debug state of the LCM. If debugging is enabled,
starting a configuration will still break into the debugger after a reboot.

See Also
Writing a custom DSC resource with MOF
Writing a custom DSC resource with PowerShell classes
Calling DSC resource methods directly
Applies To: Windows PowerShell 5.0

You can use the Invoke-DscResource cmdlet to directly call the functions or methods of
a DSC resource (The Get-TargetResource, Set-TargetResource, and Test-
TargetResource functions of a MOF-based resource, or the Get, Set,
and Test methods of a class-based resource). This can be used by third-parties that
want to use DSC resources, or as a helpful tool while developing resources.

This cmdlet is typically used in combination with a metaconfiguration


property refreshMode = 'Disabled' , but it can be used no matter what refreshMode is
set to.

When calling the Invoke-DscResource cmdlet, you specify which method or function
to call by using the Method parameter. You specify the properties of the resource by
passing a hashtable as the value of the Property parameter.

The following are examples of directly calling resource methods:

Ensure a file is present


PowerShellCopy

$result = Invoke-DscResource -Name File -Method Set -Property @{


DestinationPath = "$env:SystemDrive\\DirectAccess.txt";
Contents = 'This file is create by Invoke-DscResource'} -
Verbose
$result | fl

Test that a file is present


PowerShellCopy

$result = Invoke-DscResource -Name File -Method Test -Property @{


DestinationPath="$env:SystemDrive\\DirectAccess.txt";
Contents='This file is create by Invoke-DscResource'} -
Verbose
$result | fl

Get the contents of file


PowerShellCopy

$result = Invoke-DscResource -Name File -Method Get -Property @{


DestinationPath="$env:SystemDrive\\DirectAccess.txt";
Contents='This file is create by Invoke-DscResource'} -
Verbose
$result.ItemValue | fl

Note: Directly calling composite resource methods is not supported. Instead, call the
methods of the underlying resources that make up the composite resource.

See Also
Writing a custom DSC resource with MOF
Writing a custom DSC resource with PowerShell classes
Debugging DSC resources
Configuring the Local Configuration Manager
Applies To: Windows PowerShell 5.0

The Local Configuration Manager (LCM) is the engine of Windows PowerShell Desired
State Configuration (DSC). The LCM runs on every target node, and is responsible for
parsing and enacting configurations that are sent to the node. It is also responsible for a
number of other aspects of DSC, including the following.

Determining refresh mode (push or pull).


Specifying how often a node pulls and enacts configurations.
Associating the node with pull servers.
Specifying partial configurations.

You use a special type of configuration to configure the LCM to specify each of these
behaviors. The following sections describe how to configure the LCM.

Note: This topic applies to the LCM introduced in Windows PowerShell 5.0. For
information about configuring the LCM in Windows PowerShell 4.0, see Windows
PowerShell 4.0 Desired State Configuration Local Configuration Manager.

Writing and enacting an LCM configuration


To configure the LCM, you create and run a special type of configuration. To specify an
LCM configuration, you use the DscLocalConfigurationManager attribute. The following
shows a simple configuration that sets the LCM to push mode.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration LCMConfig
{
Node localhost
{
Settings
{
RefreshMode = 'Push'
}
}
}
You call and run the configuration to create the configuration MOF, just as you would a
normal configuration (for information on creating the configuration MOF, see Compiling
the configuration). Unlike normal configurations, you do not enact an LCM configuration
by calling the Start-DscConfiguration cmdlet. Instead, you call the Set-
DscLocalConfigurationManager cmdlet, supplying the path to the configuration MOF as
a parameter. After you enact the configuration, you can see the properties of the LCM
by calling the Get-DscLocalConfigurationManager cmdlet.1

An LCM configuration can contain blocks only for a limited set of resources. In the
previous example, the only resource called is Settings. The other available resources
are:

ConfigurationRepositoryWeb: specifies an HTTP pull server for configurations.


ConfigurationRepositoryShare: specifies an SMB pull server for configurations.
ResourceRepositoryWeb: specifies an HTTP pull server for modules.
ResourceRepositoryShare: specifies an SMB pull server for modules.
ReportServerWeb: specifies an HTTP pull server to which reports are sent.
PartialConfiguration: specifies partial configurations.

Basic settings
Other than specifying pull servers and partial configurations, all of the properties of the
LCM are configured in a Settings block. The following properties are available in
a Settings block.
Property Type Description

ConfigurationModeFrequencyMins UInt32 How often, in minutes, the current configuration is checked a


ConfigurationMode property is set to ApplyOnly. The default

RebootNodeIfNeeded bool Set this to $true to automatically reboot the node after a con
you will have to manually reboot the node for any configurati

ConfigurationMode string Specifies how the LCM actually applies the configuration to t
are "ApplyOnly","ApplyandMonitior", and "ApplyandAut

ApplyOnly: DSC applies the configuration and does n


the target node or when a new configuration is pulled
configuration, DSC does not check for drift from a prev
apply the configuration until it is successful before App
Property Type Description

ApplyAndMonitor: This is the default value. The LCM


application of a new configuration, if the target node d
discrepancy in logs. Note that DSC will attempt to app
before ApplyAndMonitor takes effect.
ApplyAndAutoCorrect: DSC applies any new configu
if the target node drifts from the desired state, DSC re
current configuration.

ActionAfterReboot string Specifies what happens after a reboot during the application
are "ContinueConfiguration" and "StopConfiguration".

ContinueConfiguration: Continue applying the curren


default falue
StopConfiguration: Stop the current configuration aft

RefreshMode string Specifies how the LCM gets configurations. The possible val

Disabled: DSC configurations are disabled for this no


Push: Configurations are initiated by calling the Start-
immediately to the node. This is the default value.
Pull: The node is configured to regularly check for con
to Pull, you must specify a pull server in
a ConfigurationRepositoryWeb or ConfigurationRe
servers, see Setting up a DSC pull server.

CertificateID string The thumbprint of a certificate used to secure credentials pas


to secure credentials in Windows PowerShell Desired State

ConfigurationID string A GUID that identifies the configuration file to get from a pull
on the pull server if the name of the configuration MOF is na
Note: If you set this property, registering the node with a pul
more information, see Setting up a pull client with configurati

RefreshFrequencyMins Uint32 The time interval, in minutes, at which the LCM checks a pul
ignored if the LCM is not configured in pull mode. The defaul

AllowModuleOverwrite bool $TRUE if new configurations downloaded from the configura


target node. Otherwise, $FALSE.
Property Type Description

DebugMode string Possible values are None, ForceModuleImport, and All.

Set to None to use cached resources. This is the defa


Setting to ForceModuleImport, causes the LCM to re
been previously loaded and cached. This impacts the
reloaded on use. Typically you would use this value w
In this release, All is same as ForceModuleImport

ConfigurationDownloadManagers CimInstance[] Obsolete. Use ConfigurationRepositoryWeb and Configur


pull servers.

ResourceModuleManagers CimInstance[] Obsolete. Use ResourceRepositoryWeb and ResourceRe

ReportManagers CimInstance[] Obsolete. Use ReportServerWeb blocks to define report pu

PartialConfigurations CimInstance Not implemented. Do not use.

StatusRetentionTimeInDays UInt32 The number of days the LCM keeps the status of the current

Pull servers
A pull server is either an OData web service or an SMB share that is used as a central
location for DSC files. LCM configuration supports defining the following types of pull
servers:

Configuration server: A repository for DSC configurations. Define configuration servers by


using ConfigurationRepositoryWeb (for web-based servers)
and ConfigurationRepositoryShare (for SMB-based servers) blocks.
Resource serverA repository for DSC resources, packaged as PowerShell modules. Define
resource servers by using ResourceRepositoryWeb (for web-based servers)
and ResourceRepositoryShare (for SMB-based servers) blocks.
Report serverA service that DSC sends report data to. Define report servers by
using ReportServerWeb blocks. A report server must be a web service.

For information about setting up and using pull servers, see Setting up a DSC pull
server.
Configuration server blocks
To define a web-based configuration server, you create
a ConfigurationRepositoryWeb block. A ConfigurationRepositoryWeb defines the
following properties.
Property Type Description

AllowUnsecureConnection bool Set to $TRUE to allow connections from the node to the server without auth

CertificateID string The thumbprint of a certificate used to authenticate to the server.

ConfigurationNames String[] An array of names of configurations to be pulled by the target node. These
server by using a RegistrationKey. For more information, see Setting up a

RegistrationKey string A GUID that registers the node with the pull server. For more information, s

ServerURL string The URL of the configuration server.

To define an SMB-based configuration server, you create


a ConfigurationRepositoryShare block. A ConfigurationRepositoryShare defines
the following properties.
Property Type Description

Credential MSFT_Credential The credential used to authenticate to the SMB

SourcePath string The path of the SMB share.

Resource server blocks


To define a web-based resource server, you create a ResourceRepositoryWeb block.
A ResourceRepositoryWeb defines the following properties.
Property Type Description

AllowUnsecureConnection bool Set to $TRUE to allow connections from the node to the server without auth

CertificateID string The thumbprint of a certificate used to authenticate to the server.

RegistrationKey string A GUID that identifies the node to the pull server. For more information, see

ServerURL string The URL of the configuration server.

To define an SMB-based resource server, you create


a ResourceRepositoryShare block. ResourceRepositoryShare defines the following
properties.
Property Type Description

Credential MSFT_Credential The credential used to authenticate to the SMB share. For an example of passi

SourcePath string The path of the SMB share.

Report server blocks


A report server must be an OData web service. To define a report server, you create
a ReportServerWeb block. ReportServerWeb defines the following properties.
Property Type Description

AllowUnsecureConnection bool Set to $TRUE to allow connections from the node to the server without auth

CertificateID string The thumbprint of a certificate used to authenticate to the server.

RegistrationKey string A GUID that identifies the node to the pull server. For more information, see
Property Type Description

ServerURL string The URL of the configuration server.

Partial configurations
To define a partial configuration, you create a PartialConfiguration block. For more
information about partial configurations, see DSC Partial
configurations. PartialConfiguration defines the following properties.
Property Type Description

ConfigurationSource string[] An array of names of configuration servers, previously defined


in ConfigurationRepositoryWeb and ConfigurationRepositoryShare block

DependsOn string{} A list of names of other configurations that must be completed before this part

Description string Text used to describe the partial configuration.

ExclusiveResources string[] An array of resources exclusive to this partial configuration.

RefreshMode string Specifies how the LCM gets this partial configuration. The possible values are

Disabled: This partial configuration is disabled.


Push: The partial configuration is pushed to the node by calling the Pub
configurations for the node are either pushed or pulled from a server, th
DscConfiguration UseExisting . This is the default value.
Pull: The node is configured to regularly check for partial configuration
must specify a pull server in a ConfigurationSource property. For mor
pull server.

ResourceModuleSource string[] An array of the names of resource servers from which to download required re
must refer to resource servers previously defined in ResourceRepositoryWe
See Also

Concepts

Windows PowerShell Desired State Configuration Overview

Setting up a DSC pull server

Windows PowerShell 4.0 Desired State Configuration Local Configuration Manager

Other Resources

Set-DscLocalConfigurationManager

Setting up a pull client with configuration names


Windows PowerShell 4.0 Desired State
Configuration Local Configuration Manager
(LCM)
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Local Configuration Manager is the Windows PowerShell Desired State Configuration


(DSC) engine. It runs on all target nodes, and it is responsible for calling the
configuration resources that are included in a DSC configuration script. This topic lists
the properties of Local Configuration Manager and describes how you can modify the
Local Configuration Manager settings on a target node.

Local Configuration Manager properties


The following lists the Local Configuration Manager properties that you can set or
retrieve.

AllowModuleOverwrite: Controls whether new configurations downloaded from the configuration


server are allowed to overwrite the old ones on the target node. Possible values are True and False.
CertificateID: The thumbprint of a certificate used to secure credentials passed in a configuration.
For more information see Want to secure credentials in Windows PowerShell Desired State
Configuration?.
ConfigurationID: Indicates a GUID which is used to get a particular configuration file from a server
set up as a pull server. The GUID ensures that the correct configuration file is accessed.
ConfigurationMode: Specifies how the Local Configuration Manager actually applies the
configuration to the target nodes. It can take the following values:
o ApplyOnly: With this option, DSC applies the configuration and does nothing further unless a
new configuration is detected, either by you sending a new configuration directly to the target
node (push) or if you have configured a pull server and DSC discovers a new configuration
when it checks with the pull server. If the target nodes configuration drifts, no action is taken.
o ApplyAndMonitor: With this option (which is the default), DSC applies any new configurations,
whether sent by you directly to the target node or discovered on a pull server. Thereafter, if
the configuration of the target node drifts from the configuration file, DSC reports the
discrepancy in logs. For more about DSC logging, see Using Event Logs to Diagnose Errors in
Desired State Configuration.
o ApplyAndAutoCorrect: With this option, DSC applies any new configurations, whether sent by
you directly to the target node or discovered on a pull server. Thereafter, if the configuration
of the target node drifts from the configuration file, DSC reports the discrepancy in logs, and
then attempts to adjust the target node configuration to bring in compliance with the
configuration file.
ConfigurationModeFrequencyMins: Represents the frequency (in minutes) at which the
background application of DSC attempts to implement the current configuration on the target
node. The default value is 15. This value can be set in conjunction with RefreshMode. When
RefreshMode is set to PULL, the target node contacts the configuration server at an interval set by
RefreshFrequencyMins and downloads the current configuration. Regardless of the RefreshMode
value, at the interval set by ConfigurationModeFrequencyMins, the consistency engine applies the
latest configuration that was downloaded to the target node. RefreshFrequencyMins should be set
to an integer multiple of ConfigurationModeFrequencyMins.
Credential: Indicates credentials (as with Get-Credential) required to access remote resources, such
as to contact the configuration server.
DownloadManagerCustomData: Represents an array that contains custom data specific to the
download manager.
DownloadManagerName: Indicates the name of the configuration and module download
manager.
RebootNodeIfNeeded: Certain configuration changes on a target node might require it to be
restarted for the changes to be applied. With the value True, this property will restart the node as
soon as the configuration has been completely applies, without further warning. If False(the default
value), the configuration will be completed, but the node must be restarted manually for the
changes to take effect.
RefreshFrequencyMins: Used when you have set up a pull server. Represents the frequency (in
minutes) at which the Local Configuration Manager contacts a pull server to download the current
configuration. This value can be set in conjunction with ConfigurationModeFrequencyMins. When
RefreshMode is set to PULL, the target node contacts the pull server at an interval set by
RefreshFrequencyMins and downloads the current configuration. At the interval set by
ConfigurationModeFrequencyMins, the consistency engine then applies the latest configuration
that was downloaded to the target node. If RefreshFrequencyMins is not set to an integer multiple
of ConfigurationModeFrequencyMins, the system will round it up. The default value is 30.
RefreshMode: Possible values are Push (the default) and Pull. In the push configuration, you
must place a configuration file on each target node, using any client computer. In the pull mode,
you must set up a pull server for Local Configuration Manager to contact and access the
configuration files.

Example of updating Local Configuration Manager settings

You can update the Local Configuration Manager settings of a target node by including
a LocalConfigurationManager block inside the node block in a configuration script, as
shown in the following example.
PowerShellCopy

Configuration ExampleConfig
{
Node Server001
{
LocalConfigurationManager
{
ConfigurationID = "646e48cb-3082-4a12-9fd9-f71b9a562d4e"
ConfigurationModeFrequencyMins = 45
ConfigurationMode = "ApplyAndAutocorrect"
RefreshMode = "Pull"
RefreshFrequencyMins = 90
DownloadManagerName = "WebDownloadManager"
DownloadManagerCustomData =
(@{ServerUrl="https://$PullServer/psdscpullserver.svc"})
CertificateID = "71AA68562316FE3F73536F1096B85D66289ED60E"
Credential = $cred
RebootNodeIfNeeded = $true
AllowModuleOverwrite = $false
}
# One or more resource blocks can be added here
}
}

# The following line invokes the configuration and creates a file called
Server001.meta.mof at the specified path
ExampleConfig -OutputPath "c:\users\public\dsc"

Running the script in the previous example generates a MOF file that specifies and
stores the desired settings. To apply the settings, you can use the Set-
DscLocalConfigurationManager cmdlet, as shown in the following example.
PowerShellCopy

Set-DscLocalConfigurationManager -Path "c:\users\public\dsc"

Note: For the Path parameter, you must specify the same path that you specified for
the OutputPath parameter when you invoked the configuration in the previous
example.

To see the current Local Configuration Manager settings, you can use the Get-
DscLocalConfigurationManager cmdlet. If you invoke this cmdlet with no parameters,
by default it will get the Local Configuration Manager settings for the node on which
you run it. To specify another node, use the CimSession parameter with this cmdlet.
Setting up a DSC web pull server
Applies To: Windows PowerShell 5.0

A DSC web pull server is a web service in IIS that uses an OData interface to make DSC
configuration files available to target nodes when those nodes ask for them.

Requirements for using a pull server:

A server running:
o WMF/PowerShell 5.0 or greater
o IIS server role
o DSC Service
Ideally, some means of generating a certificate, to secure credentials passed to the Local
Configuration Manager (LCM) on target nodes

You can add the IIS server role and DSC Service with the Add Roles and Features wizard
in Server Manager, or by using PowerShell. The sample scripts included in this topic will
handle both of these steps for you as well.

Using the xDSCWebService resource


The easiest way to set up a web pull server is to use the xWebService resource, included
in the xPSDesiredStateConfiguration module. The following steps explain how to use the
resource in a configuration that sets up the web service.

1. Call the Install-Module cmdlet to install the xPSDesiredStateConfiguration module. Note: Install-
Module is included in the PowerShellGetmodule, which is included in PowerShell 5.0. You can
download the PowerShellGet module for PowerShell 3.0 and 4.0 at PackageManagement
PowerShell Modules Preview.
2. Get an SSL certificate for the DSC Pull server from a trusted Certificate Authority, either within your
organization or a public authority. The certificate received from the authority is usually in the PFX
format. Install the certificate on the node that will become the DSC Pull server in the default
location which should be CERT:\LocalMachine\My. Make a note of the certificate thumbprint.
3. Select a GUID to be used as the Registration Key. To generate one using PowerShell enter the
following at the PS prompt and press enter: ' [guid]::newGuid() ' or ' New-Guid '. This key will be
used by client nodes as a shared key to authenticate during registration. For more information see
the Registration Key section below.
4. In the PowerShell ISE, start (F5) the following configuration script (included in the
Example folder of the xPSDesiredStateConfigurationmodule as
Sample_xDscWebService.ps1). This script sets up the pull server.
PowerShellCopy

configuration Sample_xDscPullServer
{
param
(
[string[]]$NodeName = 'localhost',

[ValidateNotNullOrEmpty()]
[string] $certificateThumbPrint,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $RegistrationKey
)

Import-DSCResource -ModuleName xPSDesiredStateConfiguration


Import-DSCResource ModuleName PSDesiredStateConfiguration

Node $NodeName
{
WindowsFeature DSCServiceFeature
{
Ensure = 'Present'
Name = 'DSC-Service'
}

xDscWebService PSDSCPullServer
{
Ensure = 'Present'
EndpointName = 'PSDSCPullServer'
Port = 8080
PhysicalPath =
"$env:SystemDrive\inetpub\PSDSCPullServer"
CertificateThumbPrint = $certificateThumbPrint
ModulePath =
"$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
ConfigurationPath =
"$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
State = 'Started'
DependsOn = '[WindowsFeature]DSCServiceFeature'
UseSecurityBestPractices = $false
}
File RegistrationKeyFile
{
Ensure = 'Present'
Type = 'File'
DestinationPath =
"$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt"
Contents = $RegistrationKey
}
}
}

5. Run the configuration, passing the thumbprint of the SSL certificate as


the certificateThumbPrint parameter and a GUID registration key as
the RegistrationKey parameter:

PowerShellCopy

# To find the Thumbprint for an installed SSL certificate for use with the pull
server list all certificates in your local store
# and then copy the thumbprint for the appropriate certificate by reviewing the
certificate subjects
dir Cert:\LocalMachine\my

# Then include this thumbprint when running the configuration


Sample_xDSCPullServer -certificateThumbprint
'A7000024B753FA6FFF88E966FD6E19301FAE9CCC' -RegistrationKey '140a952b-b9d6-
406b-b416-e0f759c9c0e4' -OutputPath c:\Configs\PullServer

# Run the compiled configuration to make the target node a DSC Pull Server
Start-DscConfiguration -Path c:\Configs\PullServer -Wait -Verbose

Registration Key
To allow client nodes to register with the server so that they can use configuration
names instead of a configuration ID, a registration key which was created by the above
configuration is saved in a file named RegistrationKeys.txt in C:\Program
Files\WindowsPowerShell\DscService . The registration key functions as a shared secret
used during the initial registration by the client with the pull server. The client will
generate a self-signed certificate which is used to uniquely authenticate to the pull
server once registration is successfully completed. The thumbprint of this certificate is
stored locally and associated with the URL of the pull server.

Note: Registration keys are not supported in PowerShell 4.0.

In order to configure a node to authenticate with the pull server the registration key
needs to be in the metaconfiguration for any target node that will be registering with
this pull server. Note that the RegistrationKey in the metaconfiguration below is
removed after the target machine has successfully registered, and that the value
'140a952b-b9d6-406b-b416-e0f759c9c0e4' must match the value stored in the
RegistrationKeys.txt file on the pull server. Always treat the registration key value
securely, because knowing it allows any target machine to register with the pull server.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '140a952b-b9d6-406b-b416-e0f759c9c0e4'
ConfigurationNames = @('ClientConfig')
}

ReportServerWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '140a952b-b9d6-406b-b416-e0f759c9c0e4'
}
}
}

PullClientConfigID -OutputPath c:\Configs\TargetNodes


Note: The ReportServerWeb section allows reporting data to be sent to the pull server.

The lack of the ConfigurationID property in the metaconfiguration file implicitly means
that pull server is supporting the V2 version of the pull server protocol so an initial
registration is required. Conversely, the presence of a ConfigurationID means that the
V1 version of the pull server protocol is used and there is no registration processing.

Note: In a PUSH scenario, a bug exists in the current relase that makes it necessary to
define a ConfigurationID property in the metaconfiguration file for nodes that have
never registered with a pull server. This will force the V1 Pull Server protocol and avoid
registration failure messages.

Placing configurations and resources


After the pull server setup completes, the folders defined by
the ConfigurationPath and ModulePath properties in the pull server configuration are
where you will place modules and configurations that will be available for target nodes
to pull. These files need to be in a specific format in order for the pull server to correctly
process them.

DSC resource module package format

Each resource module needs to be zipped and named according the following
pattern {Module Name}_{Module Version}.zip . For example, a module named
xWebAdminstration with a module version of 3.1.2.0 would be named
'xWebAdministration_3.2.1.0.zip'. Each version of a module must be contained in a single
zip file. Since there is only a single version of a resource in each zip file the module
format added in WMF 5.0 with support for multiple module versions in a single directory
is not supported. This means that before packaging up DSC resource modules for use
with pull server you will need to make a small change to the directory structure. The
default format of modules containing DSC resource in WMF 5.0 is '{Module
Folder}{Module Version}\DscResources{DSC Resource Folder}\'. Before packaging up for
the pull server simply remove the {Module version} folder so the path becomes
'{Module Folder}\DscResources{DSC Resource Folder}\'. With this change, zip the folder
as described above and place these zip files in the ModulePath folder.

Use new-dscchecksum {module zip file} to create a checksum file for the newly-added
module.
Configuration MOF format

A configuration MOF file needs to be paired with a checksum file so that an LCM on a
target node can validate the configuration. To create a checksum, call the New-
DSCCheckSum cmdlet. The cmdlet takes a Path parameter that specifies the folder
where the configuration MOF is located. The cmdlet creates a checksum file
named ConfigurationMOFName.mof.checksum , where ConfigurationMOFName is the name of
the configuration mof file. If there are more than one configuration MOF files in the
specified folder, a checksum is created for each configuration in the folder. Place the
MOF files and their associated checksum files in the the ConfigurationPath folder.

Note: If you change the configuration MOF file in any way, you must also recreate the
checksum file.

Tooling
In order to make setting up, validating and managing the pull server easier, the
following tools are included as examples in the latest version of the
xPSDesiredStateConfiguration module:

1. A module that will help with packaging DSC resource modules and configuration
files for use on the pull server. PublishModulesAndMofsToPullServer.psm1.
Examples below:

PowerShellCopy

# Example 1 - Package all versions of given modules installed locally and


MOF files are in c:\LocalDepot
$moduleList = @("xWebAdministration", "xPhp")
Publish-DSCModuleAndMof -Source C:\LocalDepot -ModuleNameList $moduleList

# Example 2 - Package modules and mof documents from c:\LocalDepot


Publish-DSCModuleAndMof -Source C:\LocalDepot -Force

2. A script that validates the pull server is configured


correctly. PullServerSetupTests.ps1.

Pull client configuration


The following topics describe setting up pull clients in detail:

Setting up a DSC pull client using a configuration ID


Setting up a DSC pull client using configuration names
Partial configurations

See also
Windows PowerShell Desired State Configuration Overview
Enacting configurations
Using a DSC report server
Setting up a DSC SMB pull server
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

A DSC SMB pull server is a computer hosting SMB file shares that make DSC
configuration files and DSC resources available to target nodes when those nodes ask
for them.

To use an SMB pull server for DSC, you have to:

Set up an SMB file share on a server running PowerShell 4.0 or higher


Configure a client running PowerShell 4.0 or higher to pull from that SMB share

Using the xSmbShare resource to create an SMB file share


There are a number of ways to set up an SMB file share, but let's look at how you can do
this by using DSC.

Install the xSmbShare resource

Call the Install-Module cmdlet to install the xSmbShare module.

Note: Install-Module is included in the PowerShellGet module, which is included in


PowerShell 5.0. You can download the PowerShellGetmodule for PowerShell 3.0 and
4.0 at PackageManagement PowerShell Modules Preview. The xSmbShare contains the
DSC resource xSmbShare, which can be used to create an SMB file share.

Create the directory and file share

The following configuration uses the File resource to create the directory for the share
and the xSmbShare resource to set up the SMB share:
PowerShellCopy

Configuration SmbShare {

Import-DscResource -ModuleName PSDesiredStateConfiguration


Import-DscResource -ModuleName xSmbShare

Node localhost {
File CreateFolder {

DestinationPath = 'C:\DscSmbShare'
Type = 'Directory'
Ensure = 'Present'

xSMBShare CreateShare {

Name = 'DscSmbShare'
Path = 'C:\DscSmbShare'
FullAccess = 'admininstrator'
ReadAccess = 'myDomain\Contoso-Server$'
FolderEnumerationMode = 'AccessBased'
Ensure = 'Present'
DependsOn = '[File]CreateFolder'

The configuration creates the directory C:\DscSmbShare if it doesn't already exists, and
then uses that directory as an SMB file share. FullAccessshould be given to any
account that needs to write to or delete from the file share, and ReadAccess must be
given to any client nodes that get configurations and/or DSC resources from the share (
this is because DSC runs as the system account by default, so the computer itself has to
have access to the share).

Give file system access to the pull client

Giving ReadAccess to a client node allows that node to access the SMB share, but not
to files or folders within that share. You have to explicitly grant client nodes access to
the SMB share folder and sub-folders. We can do this with DSC by adding using
the cNtfsPermissionEntry resource, which is contained in
the CNtfsAccessControl module. The following configuration adds
a cNtfsPermissionEntry block that grants ReadAndExecute access to the pull client:
PowerShellCopy
Configuration DSCSMB {

Import-DscResource -ModuleName PSDesiredStateConfiguration


Import-DscResource -ModuleName xSmbShare
Import-DscResource -ModuleName cNtfsAccessControl

Node localhost {

File CreateFolder {

DestinationPath = 'DscSmbShare'
Type = 'Directory'
Ensure = 'Present'

xSMBShare CreateShare {

Name = 'DscSmbShare'
Path = 'DscSmbShare'
FullAccess = 'administrator'
ReadAccess = 'myDomain\Contoso-Server$'
FolderEnumerationMode = 'AccessBased'
Ensure = 'Present'
DependsOn = '[File]CreateFolder'

cNtfsPermissionEntry PermissionSet1 {

Ensure = 'Present'
Path = 'C:\DSCSMB'
Principal = 'myDomain\Contoso-Server$'
AccessControlInformation = @(
cNtfsAccessControlInformation
{
AccessControlType = 'Allow'
FileSystemRights = 'ReadAndExecute'
Inheritance = 'ThisFolderSubfoldersAndFiles'
NoPropagateInherit = $false
}
)
DependsOn = '[File]CreateFolder'
}

Placing configurations and resources


Save any configuration MOF files and/or DSC resources that you want client nodes to
pull in the SMB share folder.

Any configuration MOF file must be named ConfigurationID.mof,


where ConfigurationID is the value of the ConfigurationID property of the target node's
LCM. For more information about setting up pull clients, see Setting up a pull client
using configuration ID.

Note: You must use configuration IDs if you are using an SMB pull server. Configuration
names are not supported for SMB.

Each resource module needs to be zipped and named according the the following
pattern {Module Name}_{Module Version}.zip . For example, a module named
xWebAdminstration with a module version of 3.1.2.0 would be named
'xWebAdministration_3.2.1.0.zip'. Each version of a module must be contained in a single
zip file. Since there is only a single version of a resource in each zip file the module
format added in WMF 5.0 with support for multiple module versions in a single directory
is not supported. This means that before packaging up DSC resource modules for use
with pull server you need to make a small change to the directory structure. The default
format of modules containing DSC resource in WMF 5.0 is '{Module Folder}{Module
Version}\DscResources{DSC Resource Folder}\'. Before packaging up for the pull server
simply remove the {Module version} folder so the path becomes '{Module
Folder}\DscResources{DSC Resource Folder}\'. With this change, zip the folder as
described above and place these zip files in the SMB share folder.

Creating the MOF checksum


A configuration MOF file needs to be paired with a checksum file so that an LCM on a
target node can validate the configuration. To create a checksum, call the New-
DSCCheckSum cmdlet. The cmdlet takes a Path parameter that specifies the folder
where the configuration MOF is located. The cmdlet creates a checksum file
named ConfigurationMOFName.mof.checksum , where ConfigurationMOFName is the name of
the configuration mof file. If there are more than one configuration MOF files in the
specified folder, a checksum is created for each configuration in the folder.

The checksum file must be present in the same directory as the configuration MOF file
( $env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration by default), and have
the same name with the .checksum extension appended.

Note: If you change the configuration MOF file in any way, you must also recreate the
checksum file.

Setting up a pull client for SMB


To set up a client that pulls configurations and/or resources from an SMB share, you
configure the client's Local Configuration Manager (LCM)
with ConfigurationRepositoryShare and ResourceRepositoryShare blocks that
specify the share from which to pull configurations and DSC resources.

For more information about configuring the LCM, see Setting up a pull client using
configuration ID.

Note: For simplicity, this example uses the PSDscAllowPlainTextPassword to allow


passing a plaintext password to the Credentialparameter. For information about
passing credentials more securely, see Credentials Options in Configuration Data.

Note: You must specify a ConfigurationID in the Settings block of a metaconfiguration


for an SMB pull server, even if you are only pulling resources.
PowerShellCopy

$secpasswd = ConvertTo-SecureString Pass1Word -AsPlainText -Force


$mycreds = New-Object System.Management.Automation.PSCredential (TestUser,
$secpasswd)

[DSCLocalConfigurationManager()]
configuration SmbCredTest
{
Node $AllNodes.NodeName
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
ConfigurationID = '16db7357-9083-4806-a80c-ebbaf4acd6c1'
}

ConfigurationRepositoryShare SmbConfigShare
{
SourcePath = '\\WIN-E0TRU6U11B1\DscSmbShare'
Credential = $mycreds
}

ResourceRepositoryShare SmbResourceShare
{
SourcePath = '\\WIN-E0TRU6U11B1\DscSmbShare'
Credential = $mycreds

}
}
}

$ConfigurationData = @{

AllNodes = @(

@{

#the "*" means "all nodes named in ConfigData" so we don't have to repeat
ourselves

NodeName="localhost"

PSDscAllowPlainTextPassword = $true

})

Acknowledgements
Special thanks to the following:

Mike F. Robbins, whose posts on using SMB for DSC helped inform the content in this topic. His
blog is at Mike F Robbins.
Serge Nikalaichyk, who authored the cNtfsAccessControl module. The source for this module is
at https://github.com/SNikalaichyk/cNtfsAccessControl.

See also
Windows PowerShell Desired State Configuration Overview
Enacting configurations
Setting up a pull client using configuration ID
Setting up a DSC pull client
6/12/2017 1 min to read Contributors

Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Each target node has to be told to use pull mode and given the URL or file location
where it can contact the pull server to get configurations and resources, and where it
should send report data.

The following topics explain how to set up pull clients:

Setting up a pull client using configuration names


Setting up a pull client using configuration ID

Note: These topics apply to PowerShell 5.0. To set up a pull client in PowerShell 4.0,
see Setting up a pull client using configuration ID in PowerShell 4.0.
Setting up a pull client using configuration
names
Applies To: Windows PowerShell 5.0

Each target node has to be told to use pull mode and given the URL where it can
contact the pull server to get configurations. To do this, you have to configure the Local
Configuration Manager (LCM) with the necessary information. To configure the LCM,
you create a special type of configuration, decorated with
the DSCLocalConfigurationManager attribute. For more information about
configuring the LCM, see Configuring the Local Configuration Manager.

Note: This topic applies to PowerShell 5.0. For information on setting up a pull client in
PowerShell 4.0, see Setting up a pull client using configuration ID in PowerShell 4.0

The following script configures the LCM to pull configurations from a server named
"CONTOSO-PullSrv":
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigNames
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '140a952b-b9d6-406b-b416-e0f759c9c0e4'
ConfigurationNames = @('ClientConfig')
}
}
}
PullClientConfigNames
In the script, the ConfigurationRepositoryWeb block defines the pull server.
The ServerURL property specifies the endpoint for the pull server.

The RegistrationKey property is a shared key between all client nodes for a pull server
and that pull server. The same value is stored in a file on the pull server.

The ConfigurationNames property is an array that specifies the names of the


configurations intended for the client node. On the pull server, the configuration MOF
file for this client node must be named ConfigurationNames.mof,
where ConfigurationNames matches the value of the ConfigurationNames property
you set in this metaconfiguration.

Note: If you specify more than one value in the ConfigurationNames, you must also
specify PartialConfiguration blocks in your configuration. For information about partial
configurations, see PowerShell Desired State Configuration partial configurations.

After this script runs, it creates a new output folder named PullClientConfigNames and
puts a metaconfiguration MOF file there. In this case, the metaconfiguration MOF file
will be named localhost.meta.mof .

To apply the configuration, call the Set-DscLocalConfigurationManager cmdlet, with


the Path set to the location of the metaconfiguration MOF file.
PowerShellCopy

Set-DSCLocalConfigurationManager localhost Path .\PullClientConfigNames Verbose.

Note: Registration keys work only with web pull servers. You must still
use ConfigurationID with an SMB pull server. For information about configuring a pull
server by using ConfigurationID, see Setting up a pull client using configuration ID

Resource and report servers


If you specify only
a ConfigurationRepositoryWeb or ConfigurationRepositoryShare block in your LCM
configuration (as in the previous example), the pull client will pull resources from the
specified server, but it will not send reports to it. You can use a single pull server for
configurations, resources, and reporting, but you have to create
a ReportRepositoryWeb block to set up reporting. The following example shows a
metaconfiguration that sets up a client to pull configurations and resources, and send
reporting data, to a single pull server.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigNames
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = 'fbc6ef09-ad98-4aad-a062-92b0e0327562'
}

ReportServerWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
}
}
}
PullClientConfigNames

You can also specify different pull servers for resources and reporting. To specify a
resource server, you use either a ResourceRepositoryWeb (for a web pull server) or
a ResourceRepositoryShare block (for an SMB pull server). To specify a report server,
you use a ReportRepositoryWebblock. A report server cannot be an SMB server. The
following metaconfiguration configures a pull client to get its configurations
from CONTOSO-PullSrv and its resources from CONTOSO-ResourceSrv, and to send
status reports to CONTOSO-ReportSrv:
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigNames
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = 'fbc6ef09-ad98-4aad-a062-92b0e0327562'
}

ResourceRepositoryWeb CONTOSO-ResourceSrv
{
ServerURL = 'https://CONTOSO-ResourceSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '30ef9bd8-9acf-4e01-8374-4dc35710fc90'
}

ReportServerWeb CONTOSO-ReportSrv
{
ServerURL = 'https://CONTOSO-ReportSrv:8080/PSDSCPullServer.svc'
RegistrationKey = '6b392c6a-818c-4b24-bf38-47124f1e2f14'
}
}
}
PullClientConfigNames

See Also
Setting up a pull client with configuration ID
Setting up a DSC web pull server
Setting up a pull client using configuration ID
Applies To: Windows PowerShell 5.0

Each target node has to be told to use pull mode and given the URL where it can
contact the pull server to get configurations. To do this, you have to configure the Local
Configuration Manager (LCM) with the necessary information. To configure the LCM,
you create a special type of configuration, decorated with
the DSCLocalConfigurationManager attribute. For more information about
configuring the LCM, see Configuring the Local Configuration Manager.

Note: This topic applies to PowerShell 5.0. For information on setting up a pull client in
PowerShell 4.0, see Setting up a pull client using configuration ID in PowerShell 4.0

The following script configures the LCM to pull configurations from a server named
"CONTOSO-PullSrv".
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'

}
}
}
PullClientConfigID

In the script, the ConfigurationRepositoryWeb block defines the pull server.


The ServerURL
After this script runs, it creates a new output folder named PullClientConfigID and puts
a metaconfiguration MOF file there. In this case, the metaconfiguration MOF file will be
named localhost.meta.mof .

To apply the configuration, call the Set-DscLocalConfigurationManager cmdlet, with


the Path set to the location of the metaconfiguration MOF file. For example: Set-
DSCLocalConfigurationManager localhost Path .\PullClientConfigID Verbose.

Configuration ID
The script sets the ConfigurationID property of LCM to a GUID that had been
previously created for this purpose (you can create a GUID by using the New-
Guid cmdlet). The ConfigurationID is what the LCM uses to find the appropriate
configuration on the pull server. The configuration MOF file on the pull server must be
named ConfigurationID.mof, where ConfigurationID is the value of
the ConfigurationID property of the target node's LCM.

SMB pull server


To set up a client to pull configurations from an SMB server, use
a ConfigurationRepositoryShare block. In a ConfigurationRepositoryShareblock,
you specify the path to the server by setting the SourcePath property. The following
metaconfiguration configures the target node to pull from an SMB pull server
named SMBPullServer.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryShare SMBPullServer
{
SourcePath = '\\SMBPullServer\PullSource'

}
}
}
PullClientConfigID

Resource and report servers


If you specify only
a ConfigurationRepositoryWeb or ConfigurationRepositoryShare block in your LCM
configuration (as in the previous example), the pull client will pull resources from the
specified server, but it will not send reports to it. You can use a single pull server for
configurations, resources, and reporting, but you have to create
a ReportRepositoryWeb block to set up reporting.

The following example shows a metaconfiguration that sets up a client to pull


configurations and resources, and send reporting data, to a single pull server.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'

ReportServerWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
}
}
}
PullClientConfigID

You can also specify different pull servers for resources and reporting. To specify a
resource server, you use either a ResourceRepositoryWeb (for a web pull server) or
a ResourceRepositoryShare block (for an SMB pull server). To specify a report server,
you use a ReportRepositoryWebblock. A report server cannot be an SMB server. The
following metaconfiguration configures a pull client to get its configurations
from CONTOSO-PullSrv and its resources from CONTOSO-ResourceSrv, and to send
status reports to CONTOSO-ReportSrv:
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'

ResourceRepositoryWeb CONTOSO-ResourceSrv
{
ServerURL = 'https://CONTOSO-REsourceSrv:8080/PSDSCPullServer.svc'
}

ReportServerWeb CONTOSO-ReportSrv
{
ServerURL = 'https://CONTOSO-REsourceSrv:8080/PSDSCPullServer.svc'
}
}
}
PullClientConfigID

See Also
Setting up a pull client with configuration names
Using a DSC report server
Applies To: Windows PowerShell 5.0

Note: The report server described in this topic is not available in PowerShell 4.0.

The Local Configuration Manager (LCM) of a node can be configured to send reports
about its configuration status to a pull server, which can then be queried to retrieve that
data. Each time the node checks and applies a configuration, it sends a report to the
report server. These reports are stored in a database on the server, and can be retrieved
by calling the reporting web service. Each report contains information such as what
configurations were applied and whether they succeeded, the resources used, any errors
that were thrown, and start and finish times.2

Configuring a node to send reports


You tell a node to send reports to a server by using a ReportServerWeb block in the
node's LCM configuration (for information about configuring the LCM, see Configuring
the Local Configuration Manager). The server to which the node sends reports must be
set up as a web pull server (you cannot send reports to an SMB share). For information
about setting up a pull server, see Setting up a DSC web pull server. The report server
can be the same service from which the node pulls configurations and gets resources, or
it can be a different service.

In the ReportServerWeb block, you specify the URL of the pull service and a
registration key that is known to the server.

The following configuration configures a node to pull configurations from one service,
and send reports to a service on a different server.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration ReportClientConfig
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PULL:8080/PSDSCPullServer.svc'
RegistrationKey = 'bbb9778f-43f2-47de-b61e-a0daff474c6d'
ConfigurationNames = @('ClientConfig')
}

ReportServerWeb CONTOSO-ReportSrv
{
ServerURL = 'http://CONTOSO-
REPORT:8080/PSDSCReportServer.svc'
RegistrationKey = 'ba39daaa-96c5-4f2f-9149-f95c46460faa'
AllowUnsecureConnection = $true
}
}
}
ReportClientConfig

The following configuration configures a node to use a single server for configurations,
resources, and reporting.
PowerShellCopy

[DSCLocalConfigurationManager()]
configuration PullClientConfig
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}

ConfigurationRepositoryWeb CONTOSO-PullSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
RegistrationKey = 'fbc6ef09-ad98-4aad-a062-92b0e0327562'
}
ReportServerWeb CONTOSO-ReportSrv
{
ServerURL = 'https://CONTOSO-PullSrv:8080/PSDSCPullServer.svc'
}
}
}
PullClientConfig

Note: You can name the web service whatever you want when you set up a pull server,
but the ServerURL property must match the service name.

Getting report data


Reports sent to the pull server are entered into a database on the server. The reports are
available through calls to the web service. To retrieve reports for a specific node, send
an HTTP request to the report web service in the following form: http://CONTOSO-
REPORT:8080/PSDSCReportServer.svc/Nodes(AgentId=
'MyNodeAgentId')/Reports where MyNodeAgentId is the AgentId of the node for which
you want to get reports. You can get the AgentID for a node by calling Get-
DscLocalConfigurationManager on that node.

The reports are returned as an array of JSON objects.

The following script returns the reports for the node on which it is run:
PowerShellCopy

function GetReport
{
param($AgentId = "$((glcm).AgentId)", $serviceURL = "http://CONTOSO-
REPORT:8080/PSDSCPullServer.svc")
$requestUri = "$serviceURL/Nodes(AgentId= '$AgentId')/Reports"
$request = Invoke-WebRequest -Uri $requestUri -ContentType
"application/json;odata=minimalmetadata;streaming=true;charset=utf-8" `
-UseBasicParsing -Headers @{Accept =
"application/json";ProtocolVersion = "2.0"} `
-ErrorAction SilentlyContinue -ErrorVariable ev
$object = ConvertFrom-Json $request.content
return $object.value
}
Viewing report data
If you set a variable to the result of the GetReport function, you can view the individual
fields in an element of the array that is returned:
PowerShellCopy

$reports = GetReport
$reports[1]

JobId : 019dfbe5-f99f-11e5-80c6-001dd8b8065c
OperationType : Consistency
RefreshMode : Pull
Status : Success
ReportFormatVersion : 2.0
ConfigurationVersion : 2.0.0
StartTime : 04/03/2016 06:21:43
EndTime : 04/03/2016 06:22:04
RebootRequested : False
Errors : {}
StatusData : {{"StartDate":"2016-04-03T06:21:43.7220000-
07:00","IPV6Addresses":["2001:4898:d8:f2f2:852b:b255:b071:283b","fe80::852b:b255:b071

:283b%12","::2000:0:0:0","::1","::2000:0:0:0"],"DurationInSeconds":"21","JobID":"{019
DFBE5-F99F-11E5-80C6-001DD8B8065C}","Curren

tChecksum":"A7797571CB9C3AF4D74C39A0FDA11DAF33273349E1182385528FFC1E47151F7F","MetaDa
ta":"Author: configAuthor; Name:
Sample_ArchiveFirewall; Version: 2.0.0; GenerationDate:
04/01/2016 15:23:30; GenerationHost: CONTOSO-PullSrv;","RebootRequested":"False

","Status":"Success","IPV4Addresses":["10.240.179.151","127.0.0.1"],"LCMVersion":"2.0
","ResourcesNotInDesiredState":[{"SourceInf

o":"C:\\ReportTest\\Sample_xFirewall_AddFirewallRule.ps1::23::9::xFirewall","ModuleNa
me":"xNetworking","DurationInSeconds":"8.785",
"InstanceName":"Firewall","StartDate":"2016-04-
03T06:21:56.4650000-07:00","ResourceName":"xFirewall","ModuleVersion":"2.7.0.0","

RebootRequested":"False","ResourceId":"[xFirewall]Firewall","ConfigurationName":"Samp
le_ArchiveFirewall","InDesiredState":"False

"}],"NumberOfResources":"2","Type":"Consistency","HostName":"CONTOSO-
PULLCLI","ResourcesInDesiredState":[{"SourceInfo":"C:\\ReportTest\\Sample_xFirewall_A
ddFirewallRule.ps1::16::9::Archive","ModuleName":"PSDesiredStateConfiguration","Durat
ionInSeconds":"1.848",
"InstanceName":"ArchiveExample","StartDate":"2016-04-
03T06:21:56.4650000-07:00","ResourceName":"Archive","ModuleVersion":"1.1","

RebootRequested":"False","ResourceId":"[Archive]ArchiveExample","ConfigurationName":"
Sample_ArchiveFirewall","InDesiredState":"T
rue"}],"MACAddresses":["00-1D-D8-B8-06-5C","00-00-00-00-00-00-
00-E0"],"MetaConfiguration":{"AgentId":"52DA826D-00DE-4166-8ACB-73F2B46A7E00",

"ConfigurationDownloadManagers":[{"SourceInfo":"C:\\ReportTest\\LCMConfig.ps1::14::9:
:ConfigurationRepositoryWeb","A
llowUnsecureConnection":"True","ServerURL":"http://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc","RegistrationKey":"","ResourceId":"[Config
urationRepositoryWeb]CONTOSO-
PullSrv","ConfigurationNames":["ClientConfig"]}],"ActionAfterReboot":"ContinueConfigu
ration","LCMCo

mpatibleVersions":["1.0","2.0"],"LCMState":"Idle","ResourceModuleManagers":[],"Report
Managers":[{"AllowUnsecureConnection":"True
","RegistrationKey":"","ServerURL":"http://CONTOSO-
PullSrv:8080/PSDSCPullServer.svc","ResourceId":"[ReportServerWeb]CONTOSO-PullSrv","S

ourceInfo":"C:\\ReportTest\\LCMConfig.ps1::24::9::ReportServerWeb"}],"StatusRetention
TimeInDays":"10","LCMVersion":"2.0","Config

urationMode":"ApplyAndMonitor","RefreshFrequencyMins":"30","RebootNodeIfNeeded":"True
","RefreshMode":"Pull","DebugMode":["NONE"]

,"LCMStateDetail":"","AllowModuleOverwrite":"False","ConfigurationModeFrequencyMins":
"15"},"Locale":"en-US","Mode":"Pull"}}
AdditionalData : {}

By default, the reports are sorted by JobID. To get the most recent report, you can sort
the reports by descending StartTime property, and then get the first element of the
array:
PowerShellCopy

$reportsByStartTime = $reports | Sort-Object {$_."StartTime" -as [DateTime] } -


Descending
$reportMostRecent = $reportsByStartTime[0]
Notice that the StatusData property is an object with a number of properties. This is
where much of the reporting data is. Let's look at the individual fields of
the StatusData property for the most recent report:
PowerShellCopy

$statusData = $reportMostRecent.StatusData | ConvertFrom-Json


$statusData

StartDate : 2016-04-04T11:21:41.2990000-07:00
IPV6Addresses : {2001:4898:d8:f2f2:852b:b255:b071:283b,
fe80::852b:b255:b071:283b%12, ::2000:0:0:0, ::1...}
DurationInSeconds : 25
JobID : {135D230E-FA92-11E5-80C6-001DD8B8065C}
CurrentChecksum :
A7797571CB9C3AF4D74C39A0FDA11DAF33273349E1182385528FFC1E47151F7F
MetaData : Author: configAuthor; Name: Sample_ArchiveFirewall;
Version: 2.0.0; GenerationDate: 04/01/2016 15:23:30; GenerationHost:
CONTOSO-PullSrv;
RebootRequested : False
Status : Success
IPV4Addresses : {10.240.179.151, 127.0.0.1}
LCMVersion : 2.0
ResourcesNotInDesiredState :
{@{SourceInfo=C:\ReportTest\Sample_xFirewall_AddFirewallRule.ps1::23::9::xFirewall;
ModuleName=xNetworking;
DurationInSeconds=10.725; InstanceName=Firewall;
StartDate=2016-04-04T11:21:55.7200000-07:00; ResourceName=xFirewall;
ModuleVersion=2.7.0.0; RebootRequested=False;
ResourceId=[xFirewall]Firewall; ConfigurationName=Sample_ArchiveFirewall;
InDesiredState=False}}
NumberOfResources : 2
Type : Consistency
HostName : CONTOSO-PULLCLI
ResourcesInDesiredState :
{@{SourceInfo=C:\ReportTest\Sample_xFirewall_AddFirewallRule.ps1::16::9::Archive;
ModuleName=PSDesiredStateConfiguration;
DurationInSeconds=2.672; InstanceName=ArchiveExample;
StartDate=2016-04-04T11:21:55.7200000-07:00; ResourceName=Archive;
ModuleVersion=1.1; RebootRequested=False;
ResourceId=[Archive]ArchiveExample; ConfigurationName=Sample_ArchiveFirewall;
InDesiredState=True}}
MACAddresses : {00-1D-D8-B8-06-5C, 00-00-00-00-00-00-00-E0}
MetaConfiguration : @{AgentId=52DA826D-00DE-4166-8ACB-73F2B46A7E00;
ConfigurationDownloadManagers=System.Object[];
ActionAfterReboot=ContinueConfiguration;
LCMCompatibleVersions=System.Object[]; LCMState=Idle;
ResourceModuleManagers=System.Object[];
ReportManagers=System.Object[]; StatusRetentionTimeInDays=10; LCMVersion=2.0;
ConfigurationMode=ApplyAndMonitor;
RefreshFrequencyMins=30; RebootNodeIfNeeded=True; RefreshMode=Pull;
DebugMode=System.Object[]; LCMStateDetail=;
AllowModuleOverwrite=False; ConfigurationModeFrequencyMins=15}
Locale : en-US
Mode : Pull

Among other things, this shows that the most recent configuration called two resources,
and that one of them was in the desired state, and one of them was not. You can get a
more readable output of just the ResourcesNotInDesiredState property:
PowerShellCopy

$statusData.ResourcesInDesiredState

SourceInfo :
C:\ReportTest\Sample_xFirewall_AddFirewallRule.ps1::16::9::Archive
ModuleName : PSDesiredStateConfiguration
DurationInSeconds : 2.672
InstanceName : ArchiveExample
StartDate : 2016-04-04T11:21:55.7200000-07:00
ResourceName : Archive
ModuleVersion : 1.1
RebootRequested : False
ResourceId : [Archive]ArchiveExample
ConfigurationName : Sample_ArchiveFirewall
InDesiredState : True

Note that these examples are meant to give you an idea of what you can do with report
data. For an introduction on working with JSON in PowerShell, see Playing with JSON
and PowerShell.

See Also
Configuring the Local Configuration Manager
Setting up a DSC web pull server
Setting up a pull client using configuration names
Pull server best practices
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

Summary: This document is intended to include process and extensibility to assist


engineers who are preparing for the solution. Details should provide best practices as
identified by customers and then validated by the product team to ensure
recommendations are future facing and considered stable.
Doc Info

Author Michael Greene

Reviewers Ben Gelens, Ravikanth Chaganti, Aleksandar Nikolic

Published April, 2015

Abstract
This document is designed to provide official guidance for anyone planning for a
Windows PowerShell Desired State Configuration pull server implementation. A pull
server is a simple service that should take only minutes to deploy. Although this
document will offer technical how-to guidance that can be used in a deployment, the
value of this document is as a reference for best practices and what to think about
before deploying. Readers should have basic familiarity with DSC, and the terms used to
describe the components that are included in a DSC deployment. For more information,
see the Windows PowerShell Desired State Configuration Overview topic. As DSC is
expected to evolve at cloud cadence, the underlying technology including pull server is
also expected to evolve and to introduce new capabilities. This document includes a
version table in the appendix that provides references to previous releases and
references to future looking solutions to encourage forward-looking designs.

The two major sections of this document:

Configuration Planning
Installation Guide
Versions of the Windows Management Framework

The information in this document is intended to apply to Windows Management


Framework 5.0. While WMF 5.0 is not required for deploying and operating a pull server,
version 5.0 is the focus of this document.

Windows PowerShell Desired State Configuration

Desired State Configuration (DSC) is a management platform that enables deploying


and managing configuration data by using an industry syntax named the Managed
Object Format (MOF) to describe the Common Information Model (CIM). An open
source project, Open Management Infrastructure (OMI), exists to further development of
these standards across platforms including Linux and network hardware operating
systems. For more information, see the DMTF page linking to MOF specifications,
and OMI Documents and Source.

Windows PowerShell provides a set of language extensions for Desired State


Configuration that you can use to create and manage declarative configurations.

Pull server role

A pull server provides a centralized service to store configurations that will be accessible
to target nodes.

The pull server role can be deployed as either a Web Server instance or an SMB file
share. The web server capability includes an OData interface and can optionally include
capabilities for target nodes to report back confirmation of success or failure as
configurations are applied. This functionality is useful in environments where there are a
large number of target nodes. After configuring a target node (also referred to as a
client) to point to the pull server the latest configuration data and any required scripts
are downloaded and applied. This can happen as a one-time deployment or as a re-
occurring job which also makes the pull server an important asset for managing change
at scale. For more information, seeWindows PowerShell Desired State Configuration Pull
Servers and Push and Pull Configuration Modes.

Configuration planning
For any enterprise software deployment there is information that can be collected in
advance to help plan for the correct architecture and to be prepared for the steps
required to complete the deployment. The following sections provide information
regarding how to prepare and the organizational connections that will likely need to
happen in advance.

Software requirements

Deployment of a pull server requires the DSC Service feature of Windows Server. This
feature was introduced in Windows Server 2012, and has been updated through
ongoing releases of Windows Management Framework (WMF).

Software downloads

In addition to installing the latest content from Windows Update, there are two
downloads considered best practice to deploy a DSC pull server: The latest version of
Windows Management Framework, and a DSC module to automate pull server
provisioning.

WMF

Windows Server 2012 R2 includes a feature named the DSC Service. The DSC Service
feature provides the pull server functionality, including the binaries that support the
OData endpoint. WMF is included in Windows Server and is updated on an agile
cadence between Windows Server releases. New versions of WMF 5.0 can include
updates to the DSC Service feature. For this reason, it is a best practice to download the
latest release of WMF and to review the release notes to determine if the release
includes an update to the DSC service feature. You should also review the section of the
release notes that indicates whether the design status for an update or scenario is listed
as stable or experimental. To allow for an agile release cycle, individual features can be
declared stable, which indicates the feature is ready to be used in a production
environment even while WMF is released in preview. Other features that have historically
been updated by WMF releases (see the WMF Release Notes for further detail):

Windows PowerShell Windows PowerShell Integrated Scripting


Environment (ISE) Windows PowerShell Web Services (Management OData
IIS Extension) Windows PowerShell Desired State Configuration (DSC)
Windows Remote Management (WinRM) Windows Management Instrumentation (WMI)
DSC resource

A pull server deployment can be simplified by provisioning the service using a DSC
configuration script. This document includes configuration scripts that can be used to
deploy a production ready server node. To use the configuration scripts, a DSC module
is required that is not included in Windows Server. The required module name
is xPSDesiredStateConfiguration, which includes the DSC resource xDscWebService.
The xPSDesiredStateConfiguration module can be downloaded here.

Use the Install-Module cmdlet from the PowerShellGet module.


PowerShellCopy

Install-Module xPSDesiredStateConfiguration

The PowerShellGet module will download the module to:

C:\Program Files\Windows PowerShell\Modules

Planning task

Do you have access to the installation files for Windows Server 2012 R2?

Will the deployment environment have Internet access to download WMF and the module from the online gallery?

How will you install the latest security updates after installing the operating system?

Will the environment have Internet access to obtain updates, or will it have a local Windows Server Update Services (W

Do you have access to Windows Server installation files that already include updates through offline injection?

Hardware requirements

Pull server deployments are supported on both physical and virtual servers. The sizing
requirements for pull server align with the requirements for Windows Server 2012 R2.
CPU: 1.4 GHz 64-bit processor
Memory: 512 MB
Disk Space: 32 GB
Network: Gigabit Ethernet Adapter
Planning task

Will you deploy on physical hardware or on a virtualization platform?

What is the process to request a new server for your target environment?

What is the average turnaround time for a server to become available?

What size server will you request?

Accounts

There are no service account requirements to deploy a pull server instance. However,
there are scenarios where the website could run in the context of a local user account.
For example, if there is a need to access a storage share for website content and either
the Windows Server or the device hosting the storage share are not domain joined.

DNS records

You will need a server name to use when configuring clients to work with a pull server
environment. In test environments, typically the server hostname is used, or the IP
address for the server can be used if DNS name resolution is not available. In production
environments or in a lab environment that is intended to represent a production
deployment, the best practice is to create a DNS CNAME record.

A DNS CNAME allows you to create an alias to refer to your host (A) record. The intent
of the additional name record is to increase flexibility should a change be required in
the future. A CNAME can help to isolate the client configuration so that changes to the
server environment, such as replacing a pull server or adding additional pull servers, will
not require a corresponding change to the client configuration.
When choosing a name for the DNS record, keep the solution architecture in mind. If
using load balancing, the certificate used to secure traffic over HTTPS will need to share
the same name as the DNS record.
Scenario Best Practice

Test Environment Reproduce the planned production environment, if possible. A server hostname is suitable fo
address may be used in lieu of a hostname.

Single Node Create a DNS CNAME record that points to the server hostname.
Deployment

For more information, see Configuring DNS Round Robin in Windows Server.
Planning task

Do you know who to contact to have DNS records created and changed?

What is the average turnaround for a request for a DNS record?

Do you need to request static Hostname (A) records for servers?

What will you request as a CNAME?

If needed, what type of Load Balancing solution will you utilize? (see section titled Load Balancing for details)

Public Key Infrastructure

Most organizations today require that network traffic, especially traffic that includes
such sensitive data as how servers are configured, must be validated and/or encrypted
during transit. While it is possible to deploy a pull server using HTTP which facilitates
client requests in clear text, it is a best practice to secure traffic using HTTPS. The service
can be configured to use HTTPS using a set of parameters in the DSC
resource xPSDesiredStateConfiguration.
The certificate requirements to secure HTTPS traffic for pull server are not different than
securing any other HTTPS web site. The Web Servertemplate in a Windows Server
Certificate Services satisfies the required capabilities.
Planning task

If certificate requests are not automated, who will you need to contact to requests a certificate?

What is the average turnaround for the request?

How will the certificate file be transferred to you?

How will the certificate private key be transferred to you?

How long is the default expiration time?

Have you settled on a DNS name for the pull server environment, that you can use for the certificate name?

Choosing an architecture

A pull server can be deployed using either a web service hosted on IIS, or an SMB file
share. In most situations, the web service option will provide greater flexibility. It is not
uncommon for HTTPS traffic to traverse network boundaries, whereas SMB traffic is
often filtered or blocked between networks. The web service also offers the option to
include a Conformance Server or Web Reporting Manager (both topics to be addressed
in a future version of this document) that provide a mechanism for clients to report
status back to a server for centralized visibility. SMB provides an option for
environments where policy dictates that a web server should not be utilized, and for
other environmental requirements that make a web server role undesirable. In either
case, remember to evaluate the requirements for signing and encrypting traffic. HTTPS,
SMB signing, and IPSEC policies are all options worth considering.

Load balancing

Clients interacting with the web service make a request for information that is returned
in a single response. No sequential requests are required, so it is not necessary for the
load balancing platform to ensure sessions are maintained on a single server at any
point in time.
Planning task

What solution will be used for load balancing traffic across servers?

If using a hardware load balancer, who will take a request to add a new configuration to the device?

What is the average turnaround for a request to configure a new load balanced web service?

What information will be required for the request?

Will you need to request an additional IP or will the team responsible for load balancing handle that?

Do you have the DNS records needed, and will this be required by the team responsible for configuring the load balanci

Does the load balancing solution require that PKI be handled by the device or can it load balance HTTPS traffic as long

Staging configurations and modules on the pull server

As part of configuration planning, you will need to think about which DSC modules and
configurations will be hosted by the pull server. For the purpose of configuration
planning it is important to have a basic understanding of how to prepare and deploy
content to a pull server.

In the future, this section will be expanded and included in an Operations Guide for DSC
Pull Server. The guide will discuss the day to day process for managing modules and
configurations over time with automation.

DSC modules

Clients that request a configuration will need the required DSC modules. A functionality
of the pull server is to automate distribution on demand of DSC modules to clients. If
you are deploying a pull server for the first time, perhaps as a lab or proof of concept,
you are likely going to depend on DSC modules that are available from public
repositories such as the PowerShell Gallery or the PowerShell.org GitHub repositories for
DSC modules.

It is critical to remember that even for trusted online sources such as the PowerShell
Gallery, any module that is downloaded from a public repository should be reviewed by
someone with PowerShell experience and knowledge of the environment where the
modules will be used prior to being used in production. While completing this task it is a
good time to check for any additional payload in the module that can be removed such
as documentation and example scripts. This will reduce the network bandwidth per
client in their first request, when modules will be downloaded over the network from
server to client.

Each module must be packaged in a specific format, a ZIP file named


ModuleName_Version.zip that contains the module payload. After the file is copied to
the server a checksum file must be created. When clients connect to the server, the
checksum is used to verify the content of the DSC module has not changed since it was
published.
PowerShellCopy

New-DscCheckSum -ConfigurationPath .\ -OutPath .\

Planning task

If you are planning a test or lab environment which scenarios are key to validate?

Are there publicly available modules that contain resources to cover everything you need or will you need to author your

Will your environment have Internet access to retrieve public modules?

Who will be responsible for reviewing DSC modules?

If you are planning a production environment what will you use as a local repository for storing DSC modules?

Will a central team accept DSC modules from application teams? What will the process be?

Will you automate packaging, copying, and creating a checksum for production-ready DSC modules to the server, from
Planning task

Will your team be responsible for managing the automation platform as well?

DSC configurations

The purpose of a pull server is to provide a centralized mechanism for distributing DSC
configurations to client nodes. The configurations are stored on the server as MOF
documents. Each document will be named with a unique GUID. When clients are
configured to connect with a pull server, they are also given the GUID for the
configuration they should request. This system of referencing configurations by GUID
guarantees global uniqueness and is flexible such that a configuration can be applied
with granularity per node, or as a role configuration that spans many servers that should
have identical configurations.

GUIDs

Planning for configuration GUIDs is worth additional attention when thinking through a
pull server deployment. There is no specific requirement for how to handle GUIDs and
the process is likely to be unique for each environment. The process can range from
simple to complex: a centrally stored CSV file, a simple SQL table, a CMDB, or a complex
solution requiring integration with another tool or software solution. There are two
general approaches:

Assigning GUIDs per server Provides a measure of assurance that every server configuration is
controlled individually. This provides a level of precision around updates and can work well in
environments with few servers.
Assigning GUIDs per server role All servers that perform the same function, such as web
servers, use the same GUID to reference the required configuration data. Be aware that if many
servers share the same GUID, all of them would be updated simultaneously when the configuration
changes.

The GUID is something that should be considered sensitive data because it could be
leveraged by someone with malicious intent to gain intelligence about how servers are
deployed and configured in your environment. For more information, see Securely
allocating GUIDs in PowerShell Desired State Configuration Pull Mode.
Planning task

Who will be responsible for copying configurations in to the pull server folder when they are ready?

If Configurations are authored by an application team, what will the process be to hand them off?

Will you leverage a repository to store configurations as they are being authored, across teams?

Will you automate the process of copying configurations to the server and creating a checksum when they are ready?

How will you map GUIDs to servers or roles, and where will this be stored?

What will you use as a process to configure client machines, and how will it integrate with your process for creating and

Installation Guide
Scripts given in this document are stable examples. Always review scripts carefully before
executing them in a production environment.

Prerequisites

To verify the version of PowerShell on your server use the following command.
PowerShellCopy

$PSVersionTable.PSVersion

If possible, upgrade to the latest version of Windows Management Framework. Next,


download the xPsDesiredStateConfiguration module using the following command.
PowerShellCopy

Install-Module xPSDesiredStateConfiguration

The command will ask for your approval before downloading the module.
Installation and configuration scripts

The best method to deploy a DSC pull server is to use a DSC configuration script. This
document will present scripts including both basic settings that would configure only
the DSC web service and advanced settings that would configure a Windows Server
end-to-end including DSC web service.

Note: Currently the xPSDesiredStateConfiguation DSC module requires the server to be


EN-US locale.

Basic configuration for Windows Server 2012

PowerShellCopy

# This is a very basic Configuration to deploy a pull server instance in a lab


environment on Windows Server 2012.

Configuration PullServer {
Import-DscResource -ModuleName xPSDesiredStateConfiguration

# Load the Windows Server DSC Service feature


WindowsFeature DSCServiceFeature
{
Ensure = 'Present'
Name = 'DSC-Service'
}

# Use the DSC Resource to simplify deployment of the web service


xDSCWebService PSDSCPullServer
{
Ensure = 'Present'
EndpointName = 'PSDSCPullServer'
Port = 8080
PhysicalPath = "$env:SYSTEMDRIVE\inetpub\wwwroot\PSDSCPullServer"
CertificateThumbPrint = 'AllowUnencryptedTraffic'
ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
ConfigurationPath =
"$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
State = 'Started'
DependsOn = '[WindowsFeature]DSCServiceFeature'
}
}
PullServer -OutputPath 'C:\PullServerConfig\'
Start-DscConfiguration -Wait -Force -Verbose -Path 'C:\PullServerConfig\'

Advanced configuration for Windows Server 2012 R2

PowerShellCopy

# This is an advanced Configuration example for Pull Server production deployments on


Windows Server 2012 R2.
# Many of the features demonstrated are optional and provided to demonstrate how to
adapt the Configuration for multiple scenarios
# Select the needed resources based on the requirements for each environment.
# Optional scenarios include:
# * Reduce footprint to Server Core
# * Rename server and join domain
# * Switch from SSL to TLS for HTTPS
# * Automatically load certificate from Certificate Authority
# * Locate Modules and Configuration data on remote SMB share
# * Manage state of default websites in IIS

param (
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[System.String] $ServerName,
[System.String] $DomainName,
[System.String] $CARootName,
[System.String] $CAServerFQDN,
[System.String] $CertSubject,
[System.String] $SMBShare,
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[PsCredential] $Credential
)

Configuration PullServer {
Import-DscResource -ModuleName xPSDesiredStateConfiguration, xWebAdministration,
xCertificate, xComputerManagement
Node localhost
{
# Configure the server to automatically corret configuration drift including
reboots if needed.
LocalConfigurationManager
{
ConfigurationMode = 'ApplyAndAutoCorrect'
RebootNodeifNeeded = $node.RebootNodeifNeeded
CertificateId = $node.Thumbprint
}

# Remove all GUI interfaces so the server has minimum running footprint.
WindowsFeature ServerCore
{
Ensure = 'Absent'
Name = 'User-Interfaces-Infra'
}

# Set the server name and if needed, join a domain. If not joining a domain,
remove the DomainName parameter.
xComputer DomainJoin
{
Name = $Node.ServerName
DomainName = $Node.DomainName
Credential = $Node.Credential
}

# The next series of settings disable SSL and enable TLS, for environments
where that is required by policy.
Registry TLS1_2ServerEnabled
{
Ensure = 'Present'
Key =
'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server'
ValueName = 'Enabled'
ValueData = 1
ValueType = 'Dword'
}
Registry TLS1_2ServerDisabledByDefault
{
Ensure = 'Present'
Key =
'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server'
ValueName = 'DisabledByDefault'
ValueData = 0
ValueType = 'Dword'
}
Registry TLS1_2ClientEnabled
{
Ensure = 'Present'
Key =
'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client'
ValueName = 'Enabled'
ValueData = 1
ValueType = 'Dword'
}
Registry TLS1_2ClientDisabledByDefault
{
Ensure = 'Present'
Key =
'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client'
ValueName = 'DisabledByDefault'
ValueData = 0
ValueType = 'Dword'
}
Registry SSL2ServerDisabled
{
Ensure = 'Present'
Key =
'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL
2.0\Server'
ValueName = 'Enabled'
ValueData = 0
ValueType = 'Dword'
}

# Install the Windows Server DSC Service feature


WindowsFeature DSCServiceFeature
{
Ensure = 'Present'
Name = 'DSC-Service'
}

# If using a certificate from a local Active Directory Enterprise Root


Certificate Authority, complete a request and install the certificate
xCertReq SSLCert
{
CARootName = $Node.CARootName
CAServerFQDN = $Node.CAServerFQDN
Subject = $Node.CertSubject
AutoRenew = $Node.AutoRenew
Credential = $Node.Credential
}

# Use the DSC resource to simplify deployment of the web service. You might
also consider modifying the default port, possibly leveraging port 443 in
environments where that is enforced as a standard.
xDSCWebService PSDSCPullServer
{
Ensure = 'Present'
EndpointName = 'PSDSCPullServer'
Port = 8080
PhysicalPath = "$env:SYSTEMDRIVE\inetpub\wwwroot\PSDSCPullServer"
CertificateThumbPrint = 'CertificateSubject'
CertificateSubject = $Node.CertSubject
ModulePath = "$($Node.SMBShare)\DscService\Modules"
ConfigurationPath = "$($Node.SMBShare)\DscService\Configuration"
State = 'Started'
DependsOn = '[WindowsFeature]DSCServiceFeature'
}

# Validate web config file contains current DB settings


xWebConfigKeyValue CorrectDBProvider
{
ConfigSection = 'AppSettings'
Key = 'dbprovider'
Value = 'System.Data.OleDb'
WebsitePath = 'IIS:\sites\PSDSCPullServer'
DependsOn = '[xDSCWebService]PSDSCPullServer'
}
xWebConfigKeyValue CorrectDBConnectionStr
{
ConfigSection = 'AppSettings'
Key = 'dbconnectionstr'
Value = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program
Files\WindowsPowerShell\DscService\Devices.mdb;'
WebsitePath = 'IIS:\sites\PSDSCPullServer'
DependsOn = '[xDSCWebService]PSDSCPullServer'
}

# Stop the default website


xWebsite StopDefaultSite
{
Ensure = 'Present'
Name = 'Default Web Site'
State = 'Stopped'
PhysicalPath = 'C:\inetpub\wwwroot'
DependsOn = '[WindowsFeature]DSCServiceFeature'
}
}
}
$configData = @{
AllNodes = @(
@{
NodeName = 'localhost'
ServerName = $ServerName
DomainName = $DomainName
CARootName = $CARootName
CAServerFQDN = $CAServerFQDN
CertSubject = $CertSubject
AutoRenew = $true
SMBShare = $SMBShare
Credential = $Credential
RebootNodeifNeeded = $true
CertificateFile = 'c:\PullServerConfig\Cert.cer'
Thumbprint = 'B9A39921918B466EB1ADF2509E00F5DECB2EFDA9'
}
)
}
PullServer -ConfigurationData $configData -OutputPath 'C:\PullServerConfig\'
Set-DscLocalConfigurationManager -ComputerName localhost -Path 'C:\PullServerConfig\'
Start-DscConfiguration -Wait -Force -Verbose -Path 'C:\PullServerConfig\'

# .\Script.ps1 -ServerName web1 -domainname 'test.pha' -carootname 'test-dc01-ca' -


caserverfqdn 'dc01.test.pha' -certsubject 'CN=service.test.pha' -smbshare
'\\sofs1.test.pha\share'

Verify pull server functionality

PowerShellCopy

# This function is meant to simplify a check against a DSC pull server. If you do not
use the default service URL, you will need to adjust accordingly.
function Verify-DSCPullServer ($fqdn) {
([xml](invoke-webrequest "https://$($fqdn):8080/psdscpullserver.svc" | %
Content)).service.workspace.collection.href
}
Verify-DSCPullServer 'INSERT SERVER FQDN'

Expected Result:
Action
Module
StatusReport
Node

Configure clients

PowerShellCopy

Configuration PullClient {
param(
$ID,
$Server
)
LocalConfigurationManager
{
ConfigurationID = $ID;
RefreshMode = 'PULL';
DownloadManagerName = 'WebDownloadManager';
RebootNodeIfNeeded = $true;
RefreshFrequencyMins = 30;
ConfigurationModeFrequencyMins = 15;
ConfigurationMode = 'ApplyAndAutoCorrect';
DownloadManagerCustomData = @{ServerUrl =
"http://"+$Server+":8080/PSDSCPullServer.svc"; AllowUnsecureConnection = $true}
}
}
PullClient -ID 'INSERTGUID' -Server 'INSERTSERVER' -Output 'C:\DSCConfig\'
Set-DscLocalConfigurationManager -ComputerName 'Localhost' -Path 'C:\DSCConfig\' -
Verbose

Additional references, snippets, and examples


This example shows how to manually initiate a client connection (requires WMF5) for
testing.
PowerShellCopy
Update-DSCConfiguration Wait -Verbose

The Add-DnsServerResourceRecordName cmdlet is used to add a type CNAME record


to a DNS zone.

The PowerShell Function to Create a Checksum and Publish DSC MOF to SMB Pull
Server automatically generates the required checksum, and then copies both the MOF
configuration and checksum files to the SMB pull server.

Appendix - Understanding ODATA service data file types


A data file is stored to create information during deployment of a pull server that
includes the OData web service. The type of file depends on the operating system, as
described below.

Windows Server 2012


The file type will always be .mdb
Windows Server 2012 R2
The file type will default to .edb unless a .mdb is specified in the configuration

In the Advanced example script for installing a Pull Server, you will also find an example
of how to automatically control the web.config file settings to prevent any chance of
error caused by file type.
DSC examples
This section contains DSC examples:

Building a CI-CD pipeline with DSC, Pester, and Visual Studio Team Services
Separating configuration and environment data
Building a Continuous Integration and
Continuous Deplyoment pipeline with DSC
This example demonstrates how to build a Continuous Integration/Continuous
Deployment (CI/CD) pipeline by using PowerShell, DSC, Pester, and Visual Studio Team
Foundation Server (TFS).

After the pipeline is built and configured, you can use it to fully deploy, configure and
test a DNS server and associated host records. This process simulates the first part of a
pipeline that would be used in a development environment.

An automated CI/CD pipeline helps you update software faster and more reliably,
ensuring that all code is tested, and that a current build of your code is available at all
times.

Prerequisites
To use this example, you should be familiar with the following:

CI-CD concepts. A good reference can be found at The Release Pipeline Model.
Git source control
The Pester testing framework
Team Foundation Server

What you will need


To build and run this example, you will need an environment with several computers
and/or virtual machines.

Client

This is the computer where you'll do all of the work setting up and running the example.

The client computer must be a Windows computer with the following installed:

Git
a local git repo cloned from https://github.com/PowerShell/Demo_CI
a text editor, such as Visual Studio Code
TFSSrv1

The computer that hosts the TFS server where you will define your build and release.
This computer must have Team Foundation Server 2017installed.

BuildAgent

The computer that runs the Windows build agent that builds the project. This computer
must have a Windows build agent installed and running. See Deploy an agent on
Windows for instructions on how to install and run a Windows build agent.

You also need to install both the xDnsServer and xNetworking DSC modules on this
computer.

TestAgent1

This is the computer that is configured as a DNS server by the DSC configuration in this
example. The computer must be running Windows Server 2016.

TestAgent2

This is the computer that hosts the website this example configures. The computer must
be running Windows Server 2016.

Add the code to TFS


We'll start out by creating a Git repository in TFS, and importing the code from your
local repository on the client computer. If you have not already cloned the Demo_CI
repository to your client computer, do so now by running the following git command:

git clone https://github.com/PowerShell/Demo_CI

1. On your client computer, navigate to your TFS server in a web browser.


2. In TFS, Create a new team project named Demo_CI.

Make sure that Version control is set to Git.

3. On your client computer, add a remote to the repository you just created in TFS
with the following command:
git remote add tfs <YourTFSRepoURL>

Where <YourTFSRepoURL> is the clone URL to the TFS repository you created in the
previous step.

If you don't know where to find this URL, see Clone an existing Git repo.

4. Push the code from your local repository to your TFS repository with the following
command:

git push tfs --all

5. The TFS repository will be populated with the Demo_CI code.

Note: This example uses the code in the ci-cd-example branch of the Git repo. Be sure
to specify this branch as the default branch in your TFS project, and for the CI/CD
triggers you create.

Understanding the code


Before we create the build and deployment pipelines, let's look at some of the code to
understand what is going on. On your client computer, open your favorite text editor
and navigate to the root of your Demo_CI Git repository.

The DSC configuration

Open the file DNSServer.ps1 (from the root of the local Demo_CI
repository, ./InfraDNS/Configs/DNSServer.ps1 ).

This file contains the DSC configuration that sets up the DNS server. Here it is in its
entirety:
PowerShellCopy

configuration DNSServer
{
Import-DscResource -module 'xDnsServer','xNetworking',
'PSDesiredStateConfiguration'

Node $AllNodes.Where{$_.Role -eq 'DNSServer'}.NodeName


{
WindowsFeature DNS
{
Ensure = 'Present'
Name = 'DNS'
}

xDnsServerPrimaryZone $Node.zone
{
Ensure = 'Present'
Name = $Node.Zone
DependsOn = '[WindowsFeature]DNS'
}

foreach ($ARec in $Node.ARecords.keys) {


xDnsRecord $ARec
{
Ensure = 'Present'
Name = $ARec
Zone = $Node.Zone
Type = 'ARecord'
Target = $Node.ARecords[$ARec]
DependsOn = '[WindowsFeature]DNS'
}
}

foreach ($CName in $Node.CNameRecords.keys) {


xDnsRecord $CName
{
Ensure = 'Present'
Name = $CName
Zone = $Node.Zone
Type = 'CName'
Target = $Node.CNameRecords[$CName]
DependsOn = '[WindowsFeature]DNS'
}
}
}
}

Notice the Node statement:


PowerShellCopy
Node $AllNodes.Where{$_.Role -eq 'DNSServer'}.NodeName

This finds any nodes that were defined as having a role of DNSServer in
the configuration data, which is created by the DevEnv.ps1 script.

Using configuration data to define nodes is important when doing CI because node
information will likely change between environments, and using configuration data
allows you to easily make changes to node information without changing the
configuration code.

In the first resource block, the configuration calls the WindowsFeature to ensure that the
DNS feature is enabled. The resource blocks that follow call resources from
the xDnsServer module to configure the primary zone and DNS records.

Notice that the two xDnsRecord blocks are wrapped in foreach loops that iterate
through arrays in the configuration data. Again, the configuration data is created by
the DevEnv.ps1 script, which we'll look at next.

Configuration data

The DevEnv.ps1 file (from the root of the local Demo_CI


repository, ./InfraDNS/DevEnv.ps1 ) specifies the environment-specific configuration data
in a hashtable, and then passes that hashtable to a call to the New-
DscConfigurationDataDocument function, which is defined
in DscPipelineTools.psm ( ./Assets/DscPipelineTools/DscPipelineTools.psm1 ).

The DevEnv.ps1 file:


PowerShellCopy

param(
[parameter(Mandatory=$true)]
[string]
$OutputPath
)

Import-Module $PSScriptRoot\..\Assets\DscPipelineTools\DscPipelineTools.psd1 -Force

# Define Unit Test Environment


$DevEnvironment = @{
Name = 'DevEnv';
Roles = @(
@{ Role = 'DNSServer';
VMName = 'TestAgent1';
Zone = 'Contoso.com';
ARecords = @{'TFSSrv1'=
'10.0.0.10';'Client'='10.0.0.15';'BuildAgent'='10.0.0.30';'TestAgent1'='10.0.0.40';'T
estAgent2'='10.0.0.50'};
CNameRecords = @{'DNS' = 'TestAgent1.contoso.com'};
}
)
}

Return New-DscConfigurationDataDocument -RawEnvData $DevEnvironment -OutputPath


$OutputPath

The New-DscConfigurationDataDocument function (defined


in \Assets\DscPipelineTools\DscPipelineTools.psm1 ) programmatically creates a
configuration data document from the hashtable (node data) and array (non-node data)
that are passed as the RawEnvData and OtherEnvData parameters.

In our case, only the RawEnvData parameter is used.

The psake build script

The psake build script defined in Build.ps1 (from the root of the Demo_CI
repository, ./InfraDNS/Build.ps1 ) defines tasks that are part of the build. It also defines
which other tasks each task depends on. When invoked, the psake script ensures that
the specified task (or the task named Default if none is specified) runs, and that all
dependencies also run (this is recursive, so that dependencies of dependencies run, and
so on).

In this example, the Default task is defined as:


PowerShellCopy

Task Default -depends UnitTests


The Default task has no implementation itself, but has a dependency on
the CompileConfigs task. The resulting chain of task dependencies ensures that all tasks
in the build script are run.

In this example, the psake script is invoked by a call to Invoke-PSake in


the Initiate.ps1 file (located at the root of the Demo_CI repository):
PowerShellCopy

param(
[parameter()]
[ValidateSet('Build','Deploy')]
[string]
$fileName
)

#$Error.Clear()

Invoke-PSake $PSScriptRoot\InfraDNS\$fileName.ps1

<#if($Error.count)
{
Throw "$fileName script failed. Check logs for failure details."
}
#>

When we create the build definition for our example in TFS, we will supply our psake
script file as the fileName parameter for this script.

The build script defines the following tasks:

GenerateEnvironmentFiles

Runs DevEnv.ps1 , which generates the configuration data file.

InstallModules

Installs the modules required by the configuration DNSServer.ps1 .


ScriptAnalysis

Calls the PSScriptAnalyzer.

UnitTests

Runs the Pester unit tests.

CompileConfigs

Compiles the configuration ( DNSServer.ps1 ) into a MOF file, using the configuration
data generated by the GenerateEnvironmentFiles task.

Clean

Creates the folders used for the example, and removes any test results, configuration
data files, and modules from previous runs.

The psake deploy script

The psake deployment script defined in Deploy.ps1 (from the root of the Demo_CI
repository, ./InfraDNS/Deploy.ps1 ) defines tasks that deploy and run the configuration.

Deploy.ps1 defines the following tasks:

DeployModules

Starts a PowerShell session on TestAgent1 and installs the modules containing the DSC
resources required for the configuration.

DeployConfigs

Calls the Start-DscConfiguration cmdlet to run the configuration on TestAgent1 .


IntegrationTests

Runs the Pester integration tests.

AcceptanceTests

Runs the Pester acceptance tests.

Clean

Removes any modules installed in previous runs, and ensures that the test result folder
exists.

Test scripts

Acceptance, Integration, and Unit tests are defined in scripts in the Tests folder (from
the root of the Demo_CI repository, ./InfraDNS/Tests ), each in files
named DNSServer.tests.ps1 in their respective folders.

The test scripts use Pester and PoshSpec syntax.

Unit tests

The unit tests test the DSC configurations themselves to ensure that the configurations
will do what is expected when they run. The unit test script uses Pester.

Integration tests

The integration tests test the configuration of the system to ensure that when integrated
with other components, the system is configured as expected. These tests run on the
target node after it has been configured with DSC. The integration test script uses a
mixture of Pester andPoshSpec syntax.

Acceptance tests

Acceptance tests test the system to ensure that it behaves as expected. For example, it
tests to ensure a web page returns the right information when queried. These tests run
remotely from the target node in order to test real world scenarios. The integration test
script uses a mixture of Pester and PoshSpec syntax.

Define the build


Now that we've uploaded our code to TFS and looked at what it does, let's define our
build.

Here, we'll cover only the build steps that you'll add to the build. For instructions on
how to create a build definition in TFS, see Create and queue a build definition.

Create a new build definition (select the Empty template) named "InfraDNS". Add the
following steps to you build definition:

PowerShell Script
Publish Test Results
Copy Files
Publish Artifact

After adding these build steps, edit the properties of each step as follows:

PowerShell Script

1. Set the Type property to File Path .


2. Set the Script Path property to initiate.ps1 .
3. Add -fileName build to the Arguments property.

This build step runs the initiate.ps1 file, which calls the psake build script.

Publish Test Results

1. Set Test Result Format to NUnit


2. Set Test Results Files to InfraDNS/Tests/Results/*.xml
3. Set Test Run Title to Unit .
4. Make sure Control Options Enabled and Always run are both selected.

This build step runs the unit tests in the Pester script we looked at earlier, and stores the
results in the InfraDNS/Tests/Results/*.xml folder.
Copy Files

1. Add each of the following lines to Contents:

Copy

initiate.ps1
**\deploy.ps1
**\Acceptance\**
**\Integration\**

2. Set TargetFolder to $(BuildArtifactStagingDirectory)\

This step copies the build and test scripts to the staging directory so that the can be
published as build artifacts by the next step.

Publish Artifact

1. Set Path to Publish to $(Build.ArtifactStagingDirectory)\


2. Set Artifact Name to Deploy
3. Set Artifact Type to Server
4. Select Enabled in Control Options

Enable continuous integration


Now we'll set up a trigger that causes the project to build any time a change is checked
in to the ci-cd-example branch of the git repository.

1. In TFS, click the Build & Release tab


2. Select the DNS Infra build definition, and click Edit
3. Click the Triggers tab
4. Select Continuous integration (CI), and select refs/heads/ci-cd-example in the branch drop-
down list
5. Click Save and then OK

Now any change in the TFS git repository triggers an automated build.
Create the release definition
Let's create a release definition so that the project is deployed to the development
environment with every code check-in.

To do this, add a new release definition associated with the InfraDNS build definition
you created previously. Be sure to select Continuous deployment so that a new release
will be triggered any time a new build is completed. (How to: Work with release
definitions) and configure it as follows:

Add the following steps to the release definition:

PowerShell Script
Publish Test Results
Publish Test Results

Edit the steps as follows:

PowerShell Script

1. Set the Script Path field to $(Build.DefinitionName)\Deploy\initiate.ps1"


2. Set the Arguments field to -fileName Deploy

First Publish Test Results

1. Select NUnit for the Test Result Format field


2. Set the Test Result Files field
to $(Build.DefinitionName)\Deploy\InfraDNS\Tests\Results\Integration*.xml
3. Set the Test Run Title to Integration
4. Under Control Options, check Always run

Second Publish Test Results

1. Select NUnit for the Test Result Format field


2. Set the Test Result Files field
to $(Build.DefinitionName)\Deploy\InfraDNS\Tests\Results\Acceptance*.xml
3. Set the Test Run Title to Acceptance
4. Under Control Options, check Always run
Verify your results
Now, any time you push changes in the ci-cd-example branch to TFS, a new build will
start. If the build completes successfully, a new deployment is triggered.

You can check the result of the deployment by opening a browser on the client machine
and navigating to www.contoso.com .

Next steps
This example configures the DNS server TestAgent1 so that the
URL www.contoso.com resolves to TestAgent2 , but it does not actually deploy a website.
The skeleton for doing so is provided in the repo under the WebApp folder. You can use
the stubs provided to create psake scripts, Pester tests, and DSC configurations to
deploy your own website.
Separating configuration and environment
data
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

It can be useful to separate the data used in a DSC configuration from the configuration
itself by using configuration data. By doing this, you can use a single configuration for
multiple environments.

For example, if you are developing an application, you can use one configuration for
both development and production environments, and use configuration data to specify
data for each environment.

What is configuration data?


Configuration data is data that is defined in a hashtable and passed to a DSC
configuration when you compile that configuration.

For a detailed description of the ConfigurationData hashtable, see Using configuration


data.

A simple example
Let's look at a very simple example to see how this works. We'll create a single
configuration that ensures that IIS is present on some nodes, and that Hyper-V is
present on others:
PowerShellCopy

Configuration MyDscConfiguration {

Node $AllNodes.Where{$_.Role -eq "WebServer"}.NodeName


{
WindowsFeature IISInstall {
Ensure = 'Present'
Name = 'Web-Server'
}

}
Node $AllNodes.Where{$_.Role -eq "VMHost"}.NodeName
{
WindowsFeature HyperVInstall {
Ensure = 'Present'
Name = 'Hyper-V'
}
}
}

$MyData =
@{
AllNodes =
@(
@{
NodeName = 'VM-1'
Role = 'WebServer'
},

@{
NodeName = 'VM-2'
Role = 'VMHost'
}
)
}

MyDscConfiguration -ConfigurationData $MyData

The last line in this script compiles the configuration, passing $MyData as the
value ConfigurationData parameter.

The result is that two MOF files are created:


Copy

Directory: C:\DscTests\MyDscConfiguration

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 3/31/2017 5:09 PM 1968 VM-1.mof
-a---- 3/31/2017 5:09 PM 1970 VM-2.mof
$MyData specifies two different nodes, each with its own NodeName and Role . The
configuration dynamically creates Node blocks by taking the collection of nodes it gets
from $MyData (specifically, $AllNodes ) and filters that collection against
the Role property..

Using configuration data to define development and


production environments
Let's look at a complete example that uses a single configuration to set up both
development and production environments of a website. In the development
environment, both IIS and SQL Server are installed on a single nodes. In the production
environment, IIS and SQL Server are installed on separate nodes. We'll use a
configuration data .psd1 file to specify the data for the two different environments.

Configuration data file

We'll define the development and production environment data in a file


namd DevProdEnvData.psd1 as follows:
PowerShellCopy

@{

AllNodes = @(

@{
NodeName = "*"
SQLServerName = "MySQLServer"
SqlSource = "C:\Software\Sql"
DotNetSrc = "C:\Software\sxs"
},

@{
NodeName = "Prod-SQL"
Role = "MSSQL"
},

@{
NodeName = "Prod-IIS"
Role = "Web"
SiteContents = "C:\Website\Prod\SiteContents\"
SitePath = "\\Prod-IIS\Website\"
},

@{
NodeName = "Dev"
Role = "MSSQL", "Web"
SiteContents = "C:\Website\Dev\SiteContents\"
SitePath = "\\Dev\Website\"
}
)
}

Configuration script file

Now, in the configuration, which is defined in a .ps1 file, we filter the nodes we defined
in DevProdEnvData.psd1 by their role ( MSSQL , Dev , or both), and configure them
accordingly. The development environment has both the SQL Server and IIS on one
node, while the production environment has them on two different nodes. The site
contents is also different, as specified by the SiteContents properties.

At the end of the configuration script, we call the configuration (compile it into a MOF
document), passing DevProdEnvData.psd1 as the $ConfigurationData parameter.

Note: This configuration requires the modules xSqlPs and xWebAdministration to be


installed on the target node.

Let's define the configuration in a file named MyWebApp.ps1 :


PowerShellCopy

Configuration MyWebApp
{
Import-DscResource -Module PSDesiredStateConfiguration
Import-DscResource -Module xSqlPs
Import-DscResource -Module xWebAdministration

Node $AllNodes.Where{$_.Role -contains "MSSQL"}.Nodename


{
# Install prerequisites
WindowsFeature installdotNet35
{
Ensure = "Present"
Name = "Net-Framework-Core"
Source = "c:\software\sxs"
}

# Install SQL Server


xSqlServerInstall InstallSqlServer
{
InstanceName = $Node.SQLServerName
SourcePath = $Node.SqlSource
Features = "SQLEngine,SSMS"
DependsOn = "[WindowsFeature]installdotNet35"

}
}

Node $AllNodes.Where{$_.Role -contains "Web"}.NodeName


{
# Install the IIS role
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}

# Install the ASP .NET 4.5 role


WindowsFeature AspNet45
{
Ensure = 'Present'
Name = 'Web-Asp-Net45'

# Stop the default website


xWebsite DefaultSite
{
Ensure = 'Present'
Name = 'Default Web Site'
State = 'Stopped'
PhysicalPath = 'C:\inetpub\wwwroot'
DependsOn = '[WindowsFeature]IIS'

# Copy the website content


File WebContent
{
Ensure = 'Present'
SourcePath = $Node.SiteContents
DestinationPath = $Node.SitePath
Recurse = $true
Type = 'Directory'
DependsOn = '[WindowsFeature]AspNet45'

# Create the new Website

xWebsite NewWebsite

Ensure = 'Present'
Name = $WebSiteName
State = 'Started'
PhysicalPath = $Node.SitePath
DependsOn = '[File]WebContent'
}

MyWebApp -ConfigurationData DevProdEnvData.psd1

When you run this configuration, three MOF files are created (one for each named entry
in the AllNodes array):
Copy

Directory: C:\DscTests\MyWebApp

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a---- 3/31/2017 5:47 PM 2944 Prod-SQL.mof
-a---- 3/31/2017 5:47 PM 6994 Dev.mof
-a---- 3/31/2017 5:47 PM 5338 Prod-IIS.mof

Using non-node data


You can add additional keys to the ConfigurationData hashtable for data that is not
specific to a node. The following configuration ensures the presence of two websites.
Data for each website are defined in the AllNodes array. The file Config.xml is used for
both websites, so we define it in an additional key with the name NonNodeData . Note
that you can have as many additional keys as you want, and you can name them
anything you want. NonNodeData is not a reserved word, it is just what we decided to
name the additional key.

You access additional keys by using the special variable $ConfigurationData. In this
example, ConfigFileContents is accessed with the line:
PowerShellCopy

Contents = $ConfigurationData.NonNodeData.ConfigFileContents

in the File resource block.


PowerShellCopy

$MyData =
@{
AllNodes =
@(
@{
NodeName = *
LogPath = C:\Logs
},

@{
NodeName = VM-1
SiteContents = C:\Site1
SiteName = Website1
},

@{
NodeName = VM-2;
SiteContents = C:\Site2
SiteName = Website2
}
);

NonNodeData =
@{
ConfigFileContents = (Get-Content C:\Template\Config.xml)
}
}

configuration WebsiteConfig
{
Import-DscResource -ModuleName xWebAdministration -Name MSFT_xWebsite

node $AllNodes.NodeName
{
xWebsite Site
{
Name = $Node.SiteName
PhysicalPath = $Node.SiteContents
Ensure = Present
}

File ConfigFile
{
DestinationPath = $Node.SiteContents + \\config.xml
Contents = $ConfigurationData.NonNodeData.ConfigFileContents
}
}
}

See Also
Using configuration data
Credentials Options in Configuration Data
DSC Configurations
Troubleshooting DSC
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0

This topic describes ways to troubleshoot DSC when problems arise.

WinRM Dependency
Windows PowerShell Desired State Configuration (DSC) depends on WinRM. WinRM is
not enabled by default on Windows Server 2008 R2 and Windows 7. Run Set-
WSManQuickConfig , in a Windows PowerShell elevated session, to enable WinRM.

Using Get-DscConfigurationStatus
The Get-DscConfigurationStatus cmdlet gets information about configuration status
from a target node. A rich object is returned that includes high-level information about
whether or not the configuration run was successful or not. You can dig into the object
to discover details about the configuration run such as:

All of the resources that failed


Any resource that requested a reboot
Meta-Configuration settings at time of configuration run
Etc.

The following parameter set returns the status information for the last configuration run:
PowerShellCopy

Get-DscConfigurationStatus [-CimSession <CimSession[]>]


[-ThrottleLimit <int>]
[-AsJob]
[<CommonParameters>]

The following parameter set returns the status information for all previous configuration
runs:
PowerShellCopy

Get-DscConfigurationStatus -All
[-CimSession <CimSession[]>]
[-ThrottleLimit <int>]
[-AsJob]
[<CommonParameters>]

Example
PowerShellCopy

PS C:\> $Status = Get-DscConfigurationStatus

PS C:\> $Status

Status StartDate Type Mode RebootRequested


NumberOfResources
------ --------- ---- ---- --------------- -----
------------
Failure 11/24/2015 3:44:56 Consistency Push True 36

PS C:\> $Status.ResourcesNotInDesiredState

ConfigurationName : MyService
DependsOn :
ModuleName : PSDesiredStateConfiguration
ModuleVersion : 1.1
PsDscRunAsCredential :
ResourceID : [File]ServiceDll
SourceInfo :
c:\git\CustomerService\Configs\MyCustomService.ps1::5::34::File
DurationInSeconds : 0.19
Error : SourcePath must be accessible for current configuration.
The related file/directory is:
\\Server93\Shared\contosoApp.dll. The related ResourceID
is [File]ServiceDll
FinalState :
InDesiredState : False
InitialState :
InstanceName : ServiceDll
RebootRequested : False
ReosurceName : File
StartDate : 11/24/2015 3:44:56
PSComputerName :
My script wont run: Using DSC logs to diagnose script
errors
Like all Windows software, DSC records errors and events in logs that can be viewed
from the Event Viewer. Examining these logs can help you understand why a particular
operation failed, and how to prevent failure in the future. Writing configuration scripts
can be tricky, so to make tracking errors easier as you author, use the DSC Log resource
to track the progress of your configuration in the DSC Analytic event log.

Where are DSC event logs?


In Event Viewer, DSC events are in: Applications and Services
Logs/Microsoft/Windows/Desired State Configuration

The corresponding PowerShell cmdlet, Get-WinEvent, can also be run to view the event
logs:
Copy

PS C:\> Get-WinEvent -LogName "Microsoft-Windows-Dsc/Operational"


ProviderName: Microsoft-Windows-DSC
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
11/17/2014 10:27:23 PM 4102 Information Job {02C38626-D95A-47F1-9DA2-
C1D44A7128E7} :

As shown above, DSCs primary log name is Microsoft->Windows->DSC (other log


names under Windows are not shown here for brevity). The primary name is appended
to the channel name to create the complete log name. The DSC engine writes mainly
into three types of logs: Operational, Analytic, and Debug logs. Since the analytic and
debug logs are turned off by default, you should enable them in Event Viewer. To do
this, open Event Viewer by typing Show-EventLog in Windows PowerShell; or, click
the Start button, click Control Panel, click Administrative Tools, and then click Event
Viewer. On the View menu in Event viewer, click Show Analytic and Debug Logs. The
log name for the analytic channel is Microsoft-Windows-Dsc/Analytic, and the debug
channel is Microsoft-Windows-Dsc/Debug. You could also use the wevtutil utility to
enable the logs, as shown in the following example.
PowerShellCopy
wevtutil.exe set-log Microsoft-Windows-Dsc/Analytic /q:true /e:true

What do DSC logs contain?


DSC logs are split over the three log channels based on the importance of the message.
The operational log in DSC contains all error messages, and can be used to identify a
problem. The analytic log has a higher volume of events, and can identify where error(s)
occurred. This channel also contains verbose messages (if any). The debug log contains
logs that can help you understand how the errors occurred. DSC event messages are
structured such that every event message begins with a job ID that uniquely represents
a DSC operation. The example below attempts to obtain the message from the first
event logged into the operational DSC log.
PowerShellCopy

PS C:\> $AllDscOpEvents = Get-WinEvent -LogName "Microsoft-Windows-Dsc/Operational"


PS C:\> $FirstOperationalEvent = $AllDscOpEvents[0]
PS C:\> $FirstOperationalEvent.Message
Job {02C38626-D95A-47F1-9DA2-C1D44A7128E7} :
Consistency engine was run successfully.

DSC events are logged in a particular structure that enables the user to aggregate
events from one DSC job. The structure is as follows:

Job ID :

Gathering events from a single DSC operation


DSC event logs contain events generated by various DSC operations. However, youll
usually be concerned with the detail about just one particular operation. All DSC logs
can be grouped by the job ID property that is unique for every DSC operation. The job
ID is displayed as the first property value in all DSC events. The following steps explain
how to accumulate all events in a grouped array structure.
PowerShellCopy

<##########################################################################
Step 1 : Enable analytic and debug DSC channels (Operational channel is enabled by
default)
###########################################################################>

wevtutil.exe set-log Microsoft-Windows-Dsc/Analytic /q:true /e:true


wevtutil.exe set-log Microsoft-Windows-Dsc/Debug /q:True /e:true

<##########################################################################
Step 2 : Perform the required DSC operation (Below is an example, you could run any
DSC operation instead)
###########################################################################>

Get-DscLocalConfigurationManager

<##########################################################################
Step 3 : Collect all DSC Logs, from the Analytic, Debug and Operational channels
###########################################################################>

$DscEvents=[System.Array](Get-WinEvent "Microsoft-Windows-Dsc/Operational") `
+ [System.Array](Get-WinEvent "Microsoft-Windows-Dsc/Analytic" -Oldest) `
+ [System.Array](Get-WinEvent "Microsoft-Windows-Dsc/Debug" -Oldest)

<##########################################################################
Step 4 : Group all logs based on the job ID
###########################################################################>
$SeparateDscOperations = $DscEvents | Group {$_.Properties[0].value}

Here, the variable $SeparateDscOperations contains logs grouped by the job IDs. Each
array element of this variable represents a group of events logged by a different DSC
operation, allowing access to more information about the logs.
Copy

PS C:\> $SeparateDscOperations

Count Name Group


----- ---- -----
48 {1A776B6A-5BAC-11E3-BF... {System.Diagnostics.Eventing.Reader.EventLogRecord,
System.Diagnostics....
40 {E557E999-5BA8-11E3-BF... {System.Diagnostics.Eventing.Reader.EventLogRecord,
System.Diagnostics....
PS C:\> $SeparateDscOperations[0].Group
ProviderName: Microsoft-Windows-DSC
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
12/2/2013 3:47:29 PM 4115 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4198 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4114 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4102 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4098 Warning Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4098 Warning Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4176 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...
12/2/2013 3:47:29 PM 4182 Information Job {1A776B6A-5BAC-11E3-BF41-
00155D553612} : ...

You can extract the data in the variable $SeparateDscOperations using Where-Object.
Following are five scenarios in which you might want to extract data for troubleshooting
DSC:

1: Operations failures

All events have severity levels. This information can be used to identify the error events:
Copy

PS C:\> $SeparateDscOperations | Where-Object {$_.Group.LevelDisplayName -contains


"Error"}
Count Name Group
----- ---- -----
38 {5BCA8BE7-5BB6-11E3-BF... {System.Diagnostics.Eventing.Reader.EventLogRecord,
System.Diagnostics....

2: Details of operations run in the last half hour

TimeCreated , a property of every Windows event, states the time the event was created.
Comparing this property with a particular date/time object can be used to filter all
events:
PowerShellCopy

PS C:\> $DateLatest = (Get-Date).AddMinutes(-30)


PS C:\> $SeparateDscOperations | Where-Object {$_.Group.TimeCreated -gt $DateLatest}
Count Name Group
----- ---- -----
1 {6CEC5B09-5BB0-11E3-BF... {System.Diagnostics.Eventing.Reader.EventLogRecord}

3: Messages from the latest operation

The latest operation is stored in the first index of the array


group $SeparateDscOperations . Querying the groups messages for index 0 returns all
messages for the latest operation:
powershelllCopy

PS C:\> $SeparateDscOperations[0].Group.Message
Job {5BCA8BE7-5BB6-11E3-BF41-00155D553612} :
Running consistency engine.
Job {1A776B6A-5BAC-11E3-BF41-00155D553612} :
Configuration is sent from computer NULL by user sid S-1-5-18.
Job {1A776B6A-5BAC-11E3-BF41-00155D553612} :
Displaying messages from built-in DSC resources:
WMI channel 1
ResourceID:
Message : [INCH-VM]: [] Starting consistency engine.
Job {1A776B6A-5BAC-11E3-BF41-00155D553612} :
Displaying messages from built-in DSC resources:
WMI channel 1
ResourceID:
Message : [INCH-VM]: [] Consistency check completed.

4: Error messages logged for recent failed operations

$SeparateDscOperations[0].Group contains a set of events for the latest operation. Run


the Where-Object cmdlet to filter the events based on their level display name. Results
are stored in the $myFailedEvent variable, which can be further dissected to get the
event message:
PowerShellCopy

PS C:\> $myFailedEvent = ($SeparateDscOperations[0].Group | Where-Object


{$_.LevelDisplayName -eq "Error"})

PS C:\> $myFailedEvent.Message
Job {5BCA8BE7-5BB6-11E3-BF41-00155D553612} :
DSC Engine Error :
Error Message Current configuration does not exist. Execute Start-DscConfiguration
command with -Path pa
rameter to specify a configuration file and create a current configuration first.
Error Code : 1

5: All events generated for a particular job ID.

$SeparateDscOperations is an array of groups, each of which has the name as the unique
job ID. By running the Where-Object cmdlet, you can extract those groups of events that
have a particular job ID:
PowerShellCopy

PS C:\> ($SeparateDscOperations | Where-Object {$_.Name -eq $jobX} ).Group

ProviderName: Microsoft-Windows-DSC

TimeCreated Id LevelDisplayName Message


----------- -- ---------------- -------
12/2/2013 4:33:24 PM 4102 Information Job {847A5619-5BB2-11E3-BF41-
00155D553612} : ...
12/2/2013 4:33:24 PM 4168 Information Job {847A5619-5BB2-11E3-BF41-
00155D553612} : ...
12/2/2013 4:33:24 PM 4146 Information Job {847A5619-5BB2-11E3-BF41-
00155D553612} : ...
12/2/2013 4:33:24 PM 4120 Information Job {847A5619-5BB2-11E3-BF41-
00155D553612} : ...

Using xDscDiagnostics to analyze DSC logs


xDscDiagnostics is a PowerShell module that consists of several functions that can
help analyze DSC failures on your machine. These functions can help you identify all
local events from past DSC operations, or DSC events on remote computers (with valid
credentials). Here, the term DSC operation is used to define a single unique DSC
execution from its start to its end. For example, Test-DscConfiguration would be a
separate DSC operation. Similarly, every other cmdlet in DSC (such as Get-
DscConfiguration , Start-DscConfiguration , etc.) could each be identified as separate
DSC operations. The functions are explained at xDscDiagnostics. Help is available by
running Get-Help <cmdlet name> .

Getting details of DSC operations

The Get-xDscOperation function lets you find the results of the DSC operations that run
on one or multiple computers, and returns an object that contains the collection of
events produced by each DSC operation. For example, in the following output, three
commands were run. The first one passed, and the other two failed. These results are
summarized in the output of Get-xDscOperation .
PowerShellCopy

PS C:\DiagnosticsTest> Get-xDscOperation

ComputerName SequenceId TimeCreated Result JobID


AllEvents
------------ ---------- ----------- ------ -----
---------
SRV1 1 6/23/2016 9:37:52 AM Failure 9701aadf-395e-11e6-9165-00155d390509
{@{Message=; TimeC...
SRV1 2 6/23/2016 9:36:54 AM Failure 7e8e2d6e-395c-11e6-9165-00155d390509
{@{Message=; TimeC...
SRV1 3 6/23/2016 9:36:54 AM Success af72c6aa-3960-11e6-9165-00155d390509
{@{Message=Operati...
You can also specify that you want only results for the most recent operations by using
the Newest parameter:
PowerShellCopy

PS C:\DiagnosticsTest> Get-xDscOperation -Newest 5


ComputerName SequenceId TimeCreated Result JobID
AllEvents
------------ ---------- ----------- ------ -----
---------
SRV1 1 6/23/2016 4:36:54 PM Success
{@{Message=; TimeC...
SRV1 2 6/23/2016 4:36:54 PM Success 5c06402b-399b-11e6-9165-00155d390509
{@{Message=Operati...
SRV1 3 6/23/2016 4:36:54 PM Success
{@{Message=; TimeC...
SRV1 4 6/23/2016 4:36:54 PM Success 5c06402a-399b-11e6-9165-00155d390509
{@{Message=Operati...
SRV1 5 6/23/2016 4:36:51 PM Success
{@{Message=; TimeC...

Getting details of DSC events

The Trace-xDscOperation cmdlet returns an object containing a collection of events,


their event types, and the message output generated from a particular DSC operation.
Typically, when you find a failure in any of the operations using Get-xDscOperation , you
would trace that operation to find out which of the events caused a failure.

Use the SequenceID parameter to get the events for a specific operation for a specific
computer. For example, if you specify a SequenceID of 9, Trace-xDscOperaion get the
trace for the DSC operation that was 9th from the last operation:
PowerShellCopy

PS C:\DiagnosticsTest> Trace-xDscOperation -SequenceID 9

ComputerName EventType TimeCreated Message


------------ --------- ----------- -------
SRV1 OPERATIONAL 6/24/2016 10:51:52 AM Operation Consistency Check or Pull started
by user sid S-1-5-20 from computer NULL.
SRV1 OPERATIONAL 6/24/2016 10:51:52 AM Running consistency engine.
SRV1 OPERATIONAL 6/24/2016 10:51:52 AM The local configuration manager is updating
the PSModulePath to WindowsPowerShell\Modules;C:\Prog...
SRV1 OPERATIONAL 6/24/2016 10:51:53 AM Resource execution sequence ::
[WindowsFeature]DSCServiceFeature, [xDSCWebService]PSDSCPullServer.
SRV1 OPERATIONAL 6/24/2016 10:51:54 AM Consistency engine was run successfully.
SRV1 OPERATIONAL 6/24/2016 10:51:54 AM Job runs under the following LCM setting.
...
SRV1 OPERATIONAL 6/24/2016 10:51:54 AM Operation Consistency Check or Pull
completed successfully.

Pass the GUID assigned to a specific DSC operation (as returned by the Get-
xDscOperation cmldet) to get the event details for that DSC operation:
PowerShellCopy

PS C:\DiagnosticsTest> Trace-xDscOperation -JobID 9e0bfb6b-3a3a-11e6-9165-


00155d390509

ComputerName EventType TimeCreated Message


------------ --------- ----------- -------
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Operation Consistency Check or Pull started
by user sid S-1-5-20 from computer NULL.
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCache.mof
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Running consistency engine.
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: []
Starting consistency engine.
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Applying configuration from
C:\Windows\System32\Configuration\Current.mof.
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Parsing the configuration to apply.
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Resource execution sequence ::
[WindowsFeature]DSCServiceFeature, [xDSCWebService]PSDSCPullServer.
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ Start Resource ]
[[WindowsFeature]DSCServiceFeature]
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Executing operations for PS DSC resource
MSFT_RoleResource with resource name [WindowsFeature]DSC...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ Start Test ]
[[WindowsFeature]DSCServiceFeature]
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[WindowsFeature]DSCServiceFeature] The operation 'Get...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[WindowsFeature]DSCServiceFeature] The operation 'Get...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ End Test ]
[[WindowsFeature]DSCServiceFeature] True in 0.3130 sec...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ End Resource ]
[[WindowsFeature]DSCServiceFeature]
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ Start Resource ]
[[xDSCWebService]PSDSCPullServer]
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Executing operations for PS DSC resource
MSFT_xDSCWebService with resource name [xDSCWebService]P...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ Start Test ]
[[xDSCWebService]PSDSCPullServer]
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[xDSCWebService]PSDSCPullServer] Check Ensure
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[xDSCWebService]PSDSCPullServer] Check Port
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[xDSCWebService]PSDSCPullServer] Check Physical Path ...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[xDSCWebService]PSDSCPullServer] Check State
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]:
[[xDSCWebService]PSDSCPullServer] Get Full Path for We...
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ End Test ]
[[xDSCWebService]PSDSCPullServer] True in 0.0160 seconds.
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: LCM: [ End Resource ]
[[xDSCWebService]PSDSCPullServer]
SRV1 VERBOSE 6/24/2016 11:36:56 AM [SRV1]: []
Consistency check completed.
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCache.mof
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Consistency engine was run successfully.
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Job runs under the following LCM setting.
...
SRV1 OPERATIONAL 6/24/2016 11:36:56 AM Operation Consistency Check or Pull
completed successfully.
SRV1 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCache.mof

Note that, since Trace-xDscOperation aggregates events from the Analytic, Debug, and
Operational logs, it will prompt you to enable these logs as described above.

Alternately, you can gather information on the events by saving the output of Trace-
xDscOperation into a variable. You can use the following commands to display all the
events for a particular DSC operation.
PowerShellCopy

PS C:\DiagnosticsTest> $Trace = Trace-xDscOperation -SequenceID 4


PS C:\DiagnosticsTest> $Trace.Event

This will display the same results as the Get-WinEvent cmdlet, such as in the output
below:
PowerShellCopy

ProviderName: Microsoft-Windows-DSC

TimeCreated Id LevelDisplayName Message


----------- -- ---------------- -------
6/23/2016 1:36:53 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 1:36:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 2:07:00 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 2:07:01 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 2:36:55 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 2:36:56 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 3:06:55 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 3:06:55 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 3:36:55 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 3:36:55 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 4:06:53 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 4:06:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 4:36:52 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 4:36:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 5:06:52 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 5:06:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 5:36:54 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 5:36:54 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 6:06:52 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 6:06:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 6:36:56 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 6:36:57 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 7:06:52 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 7:06:53 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 7:36:53 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.
6/23/2016 7:36:54 AM 4343 Information The DscTimer has successfully run
LCM method PerformRequiredConfigurationChecks with flag 5.
6/23/2016 8:06:54 AM 4312 Information The DscTimer is running LCM
method PerformRequiredConfigurationChecks with the flag set to 5.

Ideally, you would first use Get-xDscOperation to list out the last few DSC configuration
runs on your machines. Following this, you can examine any single operation (using its
SequenceID or JobID) with Trace-xDscOperation to discover what it did behind the
scenes.

Getting events for a remote computer

Use the ComputerName parameter of the Trace-xDscOperation cmdlet to get the event
details on a remote computer. Before you can do this, you have to create a firewall rule
to allow remote administration on the remote computer:
PowerShellCopy

New-NetFirewallRule -Name "Service RemoteAdmin" -DisplayName "Remote" -Action Allow

Now you can specify that computer in your call to Trace-xDscOperation :


PowerShellCopy
PS C:\DiagnosticsTest> Trace-xDscOperation -ComputerName SRV2 -Credential Get-
Credential -SequenceID 5

ComputerName EventType TimeCreated Message


------------ --------- ----------- -------
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Operation Consistency Check or Pull started
by user sid S-1-5-20 f...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCach...
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Running consistency engine.
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: []
Starting consistency...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Applying configuration from
C:\Windows\System32\Configuration\Curr...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Parsing the configuration to apply.
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Resource execution sequence ::
[WindowsFeature]DSCServiceFeature,...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ Start Resource ]
[[WindowsFeature]DSCSer...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Executing operations for PS DSC resource
MSFT_RoleResource with re...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ Start Test ]
[[WindowsFeature]DSCSer...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[WindowsFeature]DSCSer...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[WindowsFeature]DSCSer...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ End Test ]
[[WindowsFeature]DSCSer...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ End Resource ]
[[WindowsFeature]DSCSer...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ Start Resource ]
[[xDSCWebService]PSDSCP...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Executing operations for PS DSC resource
MSFT_xDSCWebService with ...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ Start Test ]
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]:
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ End Test ]
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: LCM: [ End Resource ]
[[xDSCWebService]PSDSCP...
SRV2 VERBOSE 6/24/2016 11:36:56 AM [SRV2]: []
Consistency check co...
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCach...
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Consistency engine was run successfully.
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Job runs under the following LCM setting.
...
SRV2 OPERATIONAL 6/24/2016 11:36:56 AM Operation Consistency Check or Pull
completed successfully.
SRV2 ANALYTIC 6/24/2016 11:36:56 AM Deleting file from
C:\Windows\System32\Configuration\DSCEngineCach...

My resources wont update: How to reset the cache


The DSC engine caches resources implemented as a PowerShell module for efficiency
purposes. However, this can cause problems when you are authoring a resource and
testing it simultaneously because DSC will load the cached version until the process is
restarted. The only way to make DSC load the newer version is to explicitly kill the
process hosting the DSC engine.

Similarly, when you run Start-DscConfiguration , after adding and modifying a custom
resource, the modification may not execute unless, or until, the computer is rebooted.
This is because DSC runs in the WMI Provider Host Process (WmiPrvSE), and usually,
there are many instances of WmiPrvSE running at once. When you reboot, the host
process is restarted and the cache is cleared.

To successfully recycle the configuration and clear the cache without rebooting, you
must stop and then restart the host process. This can be done on a per instance basis,
whereby you identify the process, stop it, and restart it. Or, you can use DebugMode , as
demonstrated below, to reload the PowerShell DSC resource.

To identify which process is hosting the DSC engine and stop it on a per instance basis,
you can list the process ID of the WmiPrvSE which is hosting the DSC engine. Then, to
update the provider, stop the WmiPrvSE process using the commands below, and then
run Start-DscConfiguration again.
PowerShellCopy

###
### find the process that is hosting the DSC engine
###
$dscProcessID = Get-WmiObject msft_providers |
Where-Object {$_.provider -like 'dsccore'} |
Select-Object -ExpandProperty HostProcessIdentifier

###
### Stop the process
###
Get-Process -Id $dscProcessID | Stop-Process

Using DebugMode
You can configure the DSC Local Configuration Manager (LCM) to use DebugMode to
always clear the cache when the host process is restarted. When set to TRUE, it causes
the engine to always reload the PowerShell DSC resource. Once you are done writing
your resource, you can set it back to FALSE and the engine will revert to its behavior of
caching the modules.

Following is a demonstration to show how DebugMode can automatically refresh the


cache. First, lets look at the default configuration:
Copy

PS C:\> Get-DscLocalConfigurationManager

AllowModuleOverwrite : False
CertificateID :
ConfigurationID :
ConfigurationMode : ApplyAndMonitor
ConfigurationModeFrequencyMins : 30
Credential :
DebugMode : False
DownloadManagerCustomData :
DownloadManagerName :
LocalConfigurationManagerState : Ready
RebootNodeIfNeeded : False
RefreshFrequencyMins : 15
RefreshMode : PUSH
PSComputerName :

You can see that DebugMode is set to FALSE.

To set up the DebugMode demonstration, use the following PowerShell resource:


PowerShellCopy

function Get-TargetResource
{
param
(
[Parameter(Mandatory)]
$onlyProperty
)
return @{onlyProperty = Get-Content -Path
"$env:SystemDrive\OutputFromTestProviderDebugMode.txt"}
}
function Set-TargetResource
{
param
(
[Parameter(Mandatory)]
$onlyProperty
)
"1" | Out-File -PSPath "$env:SystemDrive\OutputFromTestProviderDebugMode.txt"
}
function Test-TargetResource
{
param
(
[Parameter(Mandatory)]
$onlyProperty
)
return $false
}

Now, author a configuration using the above resource called TestProviderDebugMode :


PowerShellCopy
Configuration ConfigTestDebugMode
{
Import-DscResource -Name TestProviderDebugMode
Node localhost
{
TestProviderDebugMode test
{
onlyProperty = "blah"
}
}
}
ConfigTestDebugMode

You will see that the contents of file:


$env:SystemDrive\OutputFromTestProviderDebugMode.txt is 1.

Now, update the provider code using the following script:


PowerShellCopy

$newResourceOutput = Get-Random -Minimum 5 -Maximum 30


$content = @"
function Get-TargetResource
{
param
(
[Parameter(Mandatory)]
`$onlyProperty
)
return @{onlyProperty = Get-Content -Path
"$env:SystemDrive\OutputFromTestProviderDebugMode.txt"}
}
function Set-TargetResource
{
param
(
[Parameter(Mandatory)]
`$onlyProperty
)
"$newResourceOutput" | Out-File -PSPath C:\OutputFromTestProviderDebugMode.txt
}
function Test-TargetResource
{
param
(
[Parameter(Mandatory)]
`$onlyProperty
)
return `$false
}
"@ | Out-File -FilePath "C:\Program
Files\WindowsPowerShell\Modules\MyPowerShellModules\DSCResources\TestProviderDebugMod
e\TestProviderDebugMode.psm1

This script generates a random number and updates the provider code accordingly.
With DebugMode set to false, the contents of the file
$env:SystemDrive\OutputFromTestProviderDebugMode.txt are never changed.

Now, set DebugMode to TRUE in your configuration script:


PowerShellCopy

LocalConfigurationManager
{
DebugMode = $true
}

When you run the above script again, you will see that the content of the file is different
every time. (You can run Get-DscConfiguration to check it). Below is the result of two
additional runs (your results may be different when you run the script):
PowerShellCopy

PS C:\> Get-DscConfiguration -CimSession (New-CimSession localhost)

onlyProperty PSComputerName
------------ --------------
20 localhost

PS C:\> Get-DscConfiguration -CimSession (New-CimSession localhost)

onlyProperty PSComputerName
------------ --------------
14 localhost
See Also

Reference

DSC Log Resource

Concepts

Build Custom Windows PowerShell Desired State Configuration Resources

Other Resources

Windows PowerShell Desired State Configuration Cmdlets


Using DSC on Nano Server
Applies To: Windows PowerShell 5.0

DSC on Nano Server is an optional package in the NanoServer\Packages folder of the


Windows Server 2016 media. The package can be installed when you create a VHD for a
Nano Server by specifying Microsoft-NanoServer-DSC-Package as the value of
the Packages parameter of the New-NanoServerImage function. For example, if you
are creating a VHD for a virtual machine, the command would look like the following:
PowerShellCopy

New-NanoServerImage -Edition Standard -DeploymentType Guest -MediaPath f:\ -BasePath


.\Base -TargetPath .\Nano1\Nano.vhd -ComputerName Nano1 -Packages Microsoft-
NanoServer-DSC-Package

For information about installing and using Nano Server, as well as how to manage Nano
Server with PowerShell Remoting, see Getting Started with Nano Server.

DSC features available on Nano Server


Because Nano Server supports only a limited set of APIs compared to a full version of
Windows Server, DSC on Nano Server does not have full functional parity with DSC
running on full SKUs for the time being. DSC on Nano Server is in active development
and is not yet feature complete.

The following DSC features are currently available on Nano Server:

Both push and pull modes


All DSC cmdlets that exist on a full version of Windows Server, including the
following:
o Get-DscLocalConfigurationManager
o Set-DscLocalConfigurationManager
o Enable-DscDebug
o Disable-DscDebug
o Start-DscConfiguration
o Stop-DscConfiguration
o Get-DscConfiguration
o Test-DscConfiguration
Publish-DscConfiguraiton
o
o Update-DscConfiguration
o Restore-DscConfiguration
o Remove-DscConfigurationDocument
o Get-DscConfigurationStatus
o Invoke-DscResource
o Find-DscResource
o Get-DscResource
o New-DscChecksum
Compiling configurations (see DSC configurations)

Issue: Password encryption (see Securing the MOF File) during configuration
compilation doesn't work.

Compiling metaconfigurations (see Configuring the Local Configuration Manager)


Running a resource under user context (see Running DSC with user credentials
(RunAs))
Class-based resources (see Writing a custom DSC resource with PowerShell
classes)
Debugging of DSC resources (see Debugging DSC resources)

Issue: Doesn't work if a resource is using PsDscRunAsCredential (see Running DSC


with user credentials)

Specifying cross-node dependencies


Resource versioning
Pull client (configurations & resources) (see Setting up a pull client using
configuration names)
Partial configurations (pull & push)
Reporting to pull server
MOF encryption
Event logging
Azure Automation DSC reporting
Resources that are fully functional
o Archive
o Environment
o File
o Log
o ProcessSet
o Registry
o Script
WindowsPackageCab
o
o WindowsProcess
o WaitForAll (see Specifying cross-node dependencies)
o WaitForAny (see Specifying cross-node dependencies)
o WaitForSome (see Specifying cross-node dependencies)
Resources that are partially functional
o Group
o GroupSet

Issue: Above resources fail if specific instance is called twice (running the same
configuration twice)

o Service
o ServiceSet

Issue: Only works for starting/stopping (status) service. Fails, if one tries to change
other service attributes like startuptype, credentials, description etc.. The error
thrown is similar to:

Cannot find type [management.managementobject]: verify that the assembly


containing this type is loaded.

Resources that are not functional


o User

DSC features not available on Nano Server


The following DSC features are not currently available on Nano Server:

Decrypting MOF document with encrypted password(s)


Pull Server--you cannot currently set up a pull server on Nano Server
Anything that is not in the list of feature works

Using custom DSC resources on Nano Server


Due to a limited sets of Windows APIs and CLR libraries available on Nano Server, DSC
resources that work on the full CLR version of Windows do not necessarily work on
Nano Server. Complete end-to-end testing before deploying any DSC custom resources
to a production environment.
See Also
Getting Started with Nano Server
Get started with Desired State Configuration
(DSC) for Linux
This topic explains how to get started using PowerShell Desired State Configuration
(DSC) for Linux. For general information about DSC, see Get Started with Windows
PowerShell Desired State Configuration.

Supported Linux operation system versions


The following Linux operating system versions are supported for DSC for Linux.

CentOS 5, 6, and 7 (x86/x64)


Debian GNU/Linux 6 and 7 (x86/x64)
Oracle Linux 5, 6 and 7 (x86/x64)
Red Hat Enterprise Linux Server 5, 6 and 7 (x86/x64)
SUSE Linux Enterprise Server 10, 11 and 12 (x86/x64)
Ubuntu Server 12.04 LTS and 14.04 LTS (x86/x64)

The following table describes the required package dependencies for DSC for Linux.
Required package Description M

glibc GNU Library 2

python Python 2

omiserver Open Management Infrastructure 1

openssl OpenSSL Libraries 0

ctypes Python CTypes library M

libcurl cURL http client library 7


Installing DSC for Linux
You must install the Open Management Infrastructure (OMI) before installing DSC for
Linux.

Installing OMI

Desired State Configuration for Linux requires the Open Management Infrastructure
(OMI) CIM server, version 1.0.8.1. OMI can be downloaded from The Open Group: Open
Management Infrastructure (OMI).

To install OMI, install the package that is appropriate for your Linux system (.rpm or
.deb) and OpenSSL version (ssl_098 or ssl_100), and architecture (x64/x86). RPM
packages are appropriate for CentOS, Red Hat Enterprise Linux, SUSE Linux Enterprise
Server, and Oracle Linux. DEB packages are appropriate for Debian GNU/Linux and
Ubuntu Server. The ssl_098 packages are appropriate for computers with OpenSSL 0.9.8
installed while the ssl_100 packages are appropriate for computers with OpenSSL 1.0
installed.

Note: To determine the installed OpenSSL version, run the command openssl version .

Run the following command to install OMI on a CentOS 7 x64 system.

# sudo rpm -Uvh omiserver-1.0.8.ssl_100.rpm

Installing DSC

DSC for Linux is available for download here.

To install DSC, install the package that is appropriate for your Linux system (.rpm or
.deb) and OpenSSL version (ssl_098 or ssl_100), and architecture (x64/x86). RPM
packages are appropriate for CentOS, Red Hat Enterprise Linux, SUSE Linux Enterprise
Server, and Oracle Linux. DEB packages are appropriate for Debian GNU/Linux and
Ubuntu Server. The ssl_098 packages are appropriate for computers with OpenSSL 0.9.8
installed while the ssl_100 packages are appropriate for computers with OpenSSL 1.0
installed.

Note: To determine the installed OpenSSL version, run the command openssl version.

Run the following command to install DSC on a CentOS 7 x64 system.


# sudo rpm -Uvh dsc-1.0.0-254.ssl_100.x64.rpm

Using DSC for Linux


The following sections explain how to create and run DSC configurations on Linux
computers.

Creating a configuration MOF document

The Windows PowerShell Configuration keyword is used to create a configuration for


Linux computers, just like for Windows computers. The following steps describe the
creation of a configuration document for a Linux computer using Windows PowerShell.

1. Import the nx module. The nx Windows PowerShell module contains the schema
for Built-In resources for DSC for Linux, and must be installed to your local
computer and imported in the configuration.

-To install the nx module, copy the nx module directory to


either $env:USERPROFILE\Documents\WindowsPowerShell\Modules\ or $PSHOME\Modules .
The nx module is included in the DSC for Linux installation package (MSI). To
import the nx module in your configuration, use the Import-
DSCResource command:
PowerShellCopy

Configuration ExampleConfiguration{

Import-DSCResource -Module nx

1. Define a configuration and generate the configuration document:

PowerShellCopy

Configuration ExampleConfiguration{

Import-DscResource -Module nx

Node "linuxhost.contoso.com"{
nxFile ExampleFile {
DestinationPath = "/tmp/example"
Contents = "hello world `n"
Ensure = "Present"
Type = "File"
}

}
}
ExampleConfiguration -OutputPath:"C:\temp"

Push the configuration to the Linux computer

Configuration documents (MOF files) can be pushed to the Linux computer using
the Start-DscConfiguration cmdlet. In order to use this cmdlet, along with the Get-
DscConfiguration.aspx, or Test-DscConfiguration cmdlets, remotely to a Linux computer,
you must use a CIMSession. The New-CimSession cmdlet is used to create a CIMSession
to the Linux computer.

The following code shows how to create a CIMSession for DSC for Linux.
PowerShellCopy

$Node = "ostc-dsc-01"
$Credential = Get-Credential -UserName:"root" -Message:"Enter Password:"

#Ignore SSL certificate validation


#$opt = New-CimSessionOption -UseSsl:$true -SkipCACheck:$true -SkipCNCheck:$true -
SkipRevocationCheck:$true

#Options for a trusted SSL certificate


$opt = New-CimSessionOption -UseSsl:$true
$Sess=New-CimSession -Credential:$credential -ComputerName:$Node -Port:5986 -
Authentication:basic -SessionOption:$opt -OperationTimeoutSec:90

Note:

For Push mode, the user credential must be the root user on the Linux computer.
Only SSL/TLS connections are supported for DSC for Linux, the New-CimSession must be used with
the UseSSL parameter set to $true.
The SSL certificate used by OMI (for DSC) is specified in the
file: /opt/omi/etc/omiserver.conf with the properties: pemfile and keyfile. If this certificate is
not trusted by the Windows computer that you are running the New-CimSession cmdlet on, you
can choose to ignore certificate validation with the CIMSession Options: -SkipCACheck:$true -
SkipCNCheck:$true -SkipRevocationCheck:$true

Run the following command to push the DSC configuration to the Linux node.

Start-DscConfiguration -Path:"C:\temp" -CimSession:$Sess -Wait -Verbose

Distribute the configuration with a pull server

Configurations can be distributed to a Linux computer with a pull server, just like for
Windows computers. For guidance on using a pull server, see Windows PowerShell
Desired State Configuration Pull Servers. For additional information and limitations
related to using Linux computers with a pull server, see the Release Notes for Desired
State Configuration for Linux.

Working with configurations locally

DSC for Linux includes scripts to work with configuration from the local Linux computer.
These scripts are locate in /opt/microsoft/dsc/Scripts and include the following:

GetDscConfiguration.py

Returns the current configuration applied to the computer. Similar to the Windows
PowerShell cmdlet Get-DscConfiguration cmdlet.

# sudo ./GetDscConfiguration.py

GetDscLocalConfigurationManager.py

Returns the current meta-configuration applied to the computer. Similar to the


cmdlet Get-DSCLocalConfigurationManager cmdlet.

# sudo ./GetDscLocalConfigurationManager.py

InstallModule.py

Installs a custom DSC resource module. Requires the path to a .zip file containing
the module shared object library and schema MOF files.
# sudo ./InstallModule.py /tmp/cnx_Resource.zip

RemoveModule.py

Removes a custom DSC resource module. Requires the name of the module to
remove.

# sudo ./RemoveModule.py cnx_Resource

StartDscLocalConfigurationManager.py

Applies a configuration MOF file to the computer. Similar to the Start-


DscConfiguration cmdlet. Requires the path to the configuration MOF to apply.

# sudo ./StartDscLocalConfigurationManager.py configurationmof /tmp/localhost.mof

SetDscLocalConfigurationManager.py

Applies a Meta Configuration MOF file to the computer. Similar to the Set-
DSCLocalConfigurationManager cmdlet. Requires the path to the Meta
Configuration MOF to apply.

# sudo ./SetDscLocalConfigurationManager.py configurationmof


/tmp/localhost.meta.mof

PowerShell Desired State Configuration for Linux Log Files


The following log files are generated for DSC for Linux messages.
Log file Directory Description

omiserver.log /var/opt/omi/log Messages relating to the operation of the OMI CIM server.

dsc.log /var/opt/omi/log Messages relating to the operation of the Local Configuration Manager (L
Built-In Desired State Configuration Resources
for Linux
Resources are building blocks that you can use to write a PowerShell Desired State
Configuration (DSC) script. DSC for Linux comes with a set of built-in functionality for
configuring resources such as files and folders, packages, environment variables, and
services and processes.

Built-in resources
The following table provides a list of these resources and links to topics that describe
them in detail.

nxArchive Resource--Provides a mechanism to unpack archive (.tar, .zip) files at a


specific path.
nxEnvironment Resource--Manages environment variables on target nodes.
nxFile Resource--Manages Linux files and directories.
nxFileLine Resource--Manages individual lines in a Linux file.
nxGroup Resource--Manages local Linux groups.
nxPackage Resource--Manages packages on Linux nodes.
nxScript Resource--Runs scripts on target nodes.
nxService Resource--Manages Linux services (daemons).
nxSshAuthorizedKeys Resource--Manages public ssh keys for a Linux user.
nxUser Resource--Manages local Linux users.
DSC for Linux nxArchive Resource
The nxArchive resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to unpack archive (.tar, .zip) files at a specific path on a Linux node.

Syntax
Copy

nxArchive <string> #ResourceName


{
SourcePath = <string>
DestinationPath = <string>
[ Checksum = <string> { ctime | mtime | md5 } ]
[ Force = <bool> ]
[ DependsOn = <string[]> ]
[ Ensure = <string> { Absent | Present } ]
}

Properties
Property Description

SourcePath Specifies the source path of the archive file. This should be a .tar, .zip, or .tar.gz file.

DestinationPath Specifies the location where you want to ensure the archive contents are extracted.

Checksum Defines the type to use when determining whether the source archive has been updated. V
default value is "md5".

Force Certain file operations (such as overwriting a file or deleting a directory that is not empty
overrides such errors. The default value is $false.

DependsOn Indicates that the configuration of another resource must run before this resource is confi
configuration script block that you want to run first is ResourceName and its type is R
is DependsOn = "[ResourceType]ResourceName" .
Property Description

Ensure Determines whether to check if the content of the archive exists at the Destination. Set
exist. Set it to "Absent" to ensure they do not exist. The default value is "Present".

Example
The following example shows how to use the nxArchive resource to ensure that the
contents of an archive file called website.tar exist and are extracted at a given
destination.
Copy

Import-DSCResource -Module nx

nxFile SyncArchiveFromWeb
{
Ensure = "Present"
SourcePath = http://release.contoso.com/releases/website.tar
DestinationPath = "/usr/release/staging/website.tar"
Type = "File"
Checksum = mtime
}

nxArchive SyncWebDir
{
SourcePath = /usr/release/staging/website.tar
DestinationPath = /usr/local/apache2/htdocs/
Force = $false
DependsOn = "[nxFile]SyncArchiveFromWeb"
}
DSC for Linux nxEnvironment Resource
The nxEnvironment resource in PowerShell Desired State Configuration (DSC) provides
a mechanism to to manage system environment variables on a Linux node.

Syntax
Copy

nxEnvironment <string> #ResourceName


{
Name = <string>
[ Value = <string>
[ Ensure = <string> { Absent | Present } ]
[ Path = <bool> }
[ DependsOn = <string[]> ]

Properties
Property Description

Name Indicates the name of the environment variable for which you want to ensure a specific state.

Value The value to assign to the environment variable.

Ensure Determines whether to check if the variable exists. Set this property to "Present" to ensure the
variable does not exist. The default value is "Present".

Path Defines the environment variable that is being configured. Set this property to $true if the va
to $false. The default is $false. If the variable being configured is the Path variable, the va
appended to the existing value.

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .
Additional Information
If Path is absent or set to $false, environment variables are managed
in /etc/environment . Your programs or scripts may require configuration to source
the /etc/environment file to access the managed environment variables.
If Path is set to $true, the environment variable is managed in the
file /etc/profile.d/DSCenvironment.sh . This file will be created if it does not exist.
If Ensure is set to "Absent" and Path is set to $true, an existing environment
variable will only be removed from /etc/profile.d/DSCenvironment.sh and not
from other files.

Example
The following example shows how to use the nxEnvironment resource to ensure
that TestEnvironmentVariable is present and has the value "Test-Value".
If TestEnvironmentVariable is not present, it will be created.
Copy

Import-DSCResource -Module nx

nxEnvironment EnvironmentExample
{
Ensure = Present
Name = TestEnvironmentVariable
Value = TestValue
}

DSC for Linux nxFile Resource


The nxFile resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to to manage files and directories on a Linux node.

Syntax
Copy

nxFile <string> #ResourceName


{
DestinationPath = <string>
[ SourcePath = <string> ]
[ Ensure = <string> { Absent | Present } ]
[ Type = <string> { directory | file | link } ]
[ Contents = <string> ]
[ Checksum = <string> { ctime | mtime | md5 } ]
[ Recurse = <bool> ]
[ Force = <bool> ]
[ Links = <string> { follow | manage } ]
[ Group = <string> ]
[ Mode = <string> ]
[ Owner = <string> ]
[ DependsOn = <string[]> ]

Properties
Property Description

DestinationPath Specifies the location where you want to ensure the state for a file or directory.

SourcePath Specifies the path from which to copy the file or folder resource. This path may be a loca
Remote http/https/ftp URLs are only supported when the value of the Type property

Ensure Determines whether to check if the file exists. Set this property to "Present" to ensure the
does not exist. The default value is "Present".

Type Specifies whether the resource being configured is a directory or a file. Set this property t
directory. Set it to "file" to indicate that the resource is a file. The default value is "file"

Contents Specifies the contents of a file, such as a particular string.

Checksum Defines the type to use when determining whether two files are the same. If Checksum
used for comparison. Values are: "ctime", "mtime", or "md5".

Recurse Indicates if subdirectories are included. Set this property to $true to indicate that you wa
is $false. Note: This property is only valid when the Type property is set to directory.
Property Description

Force Certain file operations (such as overwriting a file or deleting a directory that is not empty
overrides such errors. The default value is $false.

Links Specifies the desired behavior for symbolic links. Set this property to "follow" to follow s
example. copy the file instead of the link). Set this property to "manage" to act on the link
property to "ignore" to ignore symbolic links.

Group The name of the Group to own the file or directory.

Mode Specifies the desired permissions for the resource, in octal or symbolic notation. (for exam
notation, do not provide the first character which indicates directory or file.

DependsOn Indicates that the configuration of another resource must run before this resource is confi
configuration script block that you want to run first is ResourceName and its type is R
is DependsOn = "[ResourceType]ResourceName" .

Additional Information
Linux and Windows use different line break characters in text files by default, and this
can cause unexpected results when configuring some files on a Linux computer
with nxFile. There are multiple ways to manage the content of a Linux file while
avoiding issues caused by unexpected line break characters:

Step 1: Copy the file from a remote source (http, https, or ftp): create a file on Linux with
the desired contents, and stage it on a web or ftp server accessible the node(s) you will
configure. Define the SourcePath property in the nxFile resource with the web or ftp
URL to the file.
Copy

Import-DSCResource -Module nx
Node $Node
{
nxFile resolvConf
{
SourcePath = "http://10.185.85.11/conf/resolv.conf"
DestinationPath = "/etc/resolv.conf"
Mode = "644"
Type = "file"
}

Step 2: Read the file contents in the PowerShell script with Get-Content after setting
the $OFS property to use the Linux line-break character.
Copy

Import-DSCResource -Module nx
Node $Node
{
$OFS = "`n"
$Contents = Get-Content C:\temp\resolv.conf

nxFile resolvConf
{
DestinationPath = "/etc/resolv.conf"
Mode = "644"
Type = "file"
Contents = "$Contents"
}

Step 3: Use a PowerShell function to replace Windows line breaks with Linux line-break
characters.
Copy

Function LinuxString($inputStr){
$outputStr = $inputStr.Replace("`r`n","`n")
$ouputStr += "`n"
Return $outputStr
}

Import-DSCResource -Module nx
Node $Node
{

$Contents = @'
search contoso.com
domain contoso.com
nameserver 10.185.85.11
'@

$Contents = LinuxString $Contents

nxFile resolvConf
{
DestinationPath = "/etc/resolv.conf"
Mode = "644"
Type = "file"
Contents = $Contents

}
}

Example
The following example ensures that the directory /opt/mydir exists, and that a file with
specified contents exists this directory.
Copy

Import-DSCResource -Module nx

Node $node {
nxFile DirectoryExample
{
Ensure = "Present"
DestinationPath = "/opt/mydir"
Type = "Directory"
}

nxFile FileExample
{
Ensure = "Present"
Destinationpath = "/opt/mydir/myfile"
Contents=@"
#!/bin/bash`necho "hello world"`n
"@
Mode = 755
DependsOn = "[nxFile]DirectoryExample"
}
}
DSC for Linux nxFileLine Resource
The nxFileLine resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to to manage lines within a configuration file on a Linux node.

Syntax
Copy

nxFileLine <string> #ResourceName


{
FilePath = <string>
ContainsLine = <string>
[ DoesNotContainPattern = <string> ]
[ DependsOn = <string[]> ]

Properties
Property Description

FilePath The full path to the file to manage lines in on the target node.

ContainsLine A line to ensure exists in the file. This line will be appended to the file if it does n
but can be set to an empty string (`ContainsLine = ``) if it is not needed.

DoesNotContainPattern A regular expression pattern for lines that should not exist in the file. For any line
expression, the line will be removed from the file.

DependsOn Indicates that the configuration of another resource must run before this resource
resource configuration script block that you want to run first is ResourceName
using this property is DependsOn = "[ResourceType]ResourceName" .

Example
This example demonstrates using the nxFileLine resource to configure
the /etc/sudoers file, ensuring that the user: monuser is configured to not requiretty.
Copy

Import-DSCResource -Module nx

nxFileLine DoNotRequireTTY
{
FilePath = /etc/sudoers
ContainsLine = 'Defaults:monuser !requiretty'
DoesNotContainPattern = "Defaults:monuser[ ]+requiretty"
}
DSC for Linux nxGroup Resource
The nxGroup resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to manage local groups on a Linux node.

Syntax
PowerShellCopy

nxGroup <string> #ResourceName


{
GroupName = <string>
[ Ensure = <string> { Absent | Present } ]
[ Members = <string[]> ]
[ MebersToInclude = <string[]>]
[ MembersToExclude = <string[]> ]
[ DependsOn = <string[]> ]
}

Properties
Property Description

GroupName Specifies the name of the group for which you want to ensure a specific state.

Ensure Determines whether to check if the group exists. Set this property to "Present" to ens
the group does not exist. The default value is "Present".

Members Specifies the members that form the group.

MembersToInclude Specifies the users who you want to ensure are members of the group.

MembersToExclude Specifies the users who you want to ensure are not members of the group.

PreferredGroupID Sets the group id to the provided value if possible. If the group id is currently in use,
Property Description

DependsOn Indicates that the configuration of another resource must run before this resource is c
configuration script block that you want to run first is ResourceName and its type
property is DependsOn = "[ResourceType]ResourceName" .

Example
The following example ensures that the user monuser exists and is a member of the
group "DBusers".
Copy

Import-DSCResource -Module nx

Node $node {

nxUser UserExample{
UserName = "monuser"
Description = "Monitoring user"
Password =
'$6$fZAne/Qc$MZejMrOxDK0ogv9SLiBP5J5qZFBvXLnDu8HY1Oy7ycX.Y3C7mGPUfeQy3A82ev3zIabhDQnj
2ayeuGn02CqE/0'
Ensure = "Present"
HomeDirectory = "/home/monuser"
}

nxGroup GroupExample{
GroupName = "DBusers"
Ensure = "Present"
MembersToInclude = "monuser"
DependsOn = "[nxUser]UserExample"
}
}
DSC for Linux nxPackage Resource
The nxPackage resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to manage packages on a Linux node.

Syntax
Copy

nxPackage <string> #ResourceName


{
Name = <string>
[ Ensure = <string> { Absent | Present } ]
[ PackageManager = <string> { Yum | Apt | Zypper } ]
[ PackageGroup = <bool>]
[ Arguments = <string> ]
[ ReturnCode = <uint32> ]
[ LogPath = <string> ]
[ DependsOn = <string[]> ]

Properties
Property Description

Name The name of the package for which you want to ensure a specific state.

Ensure Determines whether to check if the package exists. Set this property to "Present" to ensu
the package does not exist. The default value is "Present".

PackageManager Supported values are "yum", "apt", and "zypper". Specifies the package manager to use
specified, the provided path will be used to install the package. Otherwise, a Package M
pre-configured repository. If neither PackageManager nor FilePath are provided, th
used.

FilePath The file path where the package resides


Property Description

PackageGroup If $true, the Name is expected to be the name of a package group for use with a Pack
when providing a FilePath.

Arguments A string of arguments that will be passed to the package exactly as provided.

ReturnCode The expected return code. If the actual return code does not match the expected value pr

DependsOn Indicates that the configuration of another resource must run before this resource is conf
configuration script block that you want to run first is ResourceName and its type is R
property is DependsOn = "[ResourceType]ResourceName" .

Example
The following example ensures that the package named "httpd" is installed on a Linux
computer, using the Yum package manager.
Copy

Import-DSCResource -Module nx

Node $node {
nxPackage httpd
{
Name = "httpd"
Ensure = "Present"
PackageManager = "Yum"
}
}
DSC for Linux nxService Resource
The nxService resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to manage services on a Linux node.

Syntax
Copy

nxService <string> #ResourceName


{
Name = <string>
[ Controller = <string> { init | upstart | systemd } ]
[ Enabled = <bool> ]
[ State = <string> { Running | Stopped } ]
[ DependsOn = <string[]> ]

Properties
Property Description

Name The name of the service/daemon to configure.

Controller The type of service controller to use when configuring the service.

Enabled Indicates whether the service starts on boot.

State Indicates whether the service is running. Set this property to "Stopped" to ensure that the serv
that the service is not running.

DependsOn Indicates that the configuration of another resource must run before this resource is configure
configuration script block that you want to run first is ResourceName and its type is Reso
is DependsOn = "[ResourceType]ResourceName" .
Additional Information
The nxService resource will not create a service definition or script for the service if it
does not exist. You can use the PowerShell Desired State Configuration nxFile Resource
resource to manage the existence or contents of the service definition file or script.

Example
The following example shows configuration of the httpd service (for Apache HTTP
Server), registered with the SystemD service controller.
Copy

Import-DSCResource -Module nx

Node $node {
#Apache Service
nxService ApacheService
{
Name = "httpd"
State = "running"
Enabled = $true
Controller = "systemd"
}
}
DSC for Linux nxSshAuthorizedKeys Resource
The nxAuthorizedKeys resource in PowerShell Desired State Configuration (DSC)
provides a mechanism to manage authorized ssh keys for a specified user.

Syntax
Copy

nxAuthorizedKeys <string> #ResourceName


{
KeyComment = <string>
[ Ensure = <string> { Absent | Present } ]
[ Username = <string> ]
[ Key = <string> ]
[ DependsOn = <string[]> ]

Properties
Property Description

KeyComment A unique comment for the key. This is used to uniquely identify keys.

Ensure Specifies whether the key is defined. Set this property to "Absent" to ensure the key does n
"Present" to ensure the key is defined in the users authorized key file.

Username The username to manage ssh authorized keys for. If not defined, the default user is "root".

Key The contents of the key. This is required if Ensure is set to "Present".

DependsOn Indicates that the configuration of another resource must run before this resource is configu
configuration script block that you want to run first is ResourceName and its type is Res
is DependsOn = "[ResourceType]ResourceName" .
Example
The following example defines a public ssh authorized key for the user "monuser".
Copy

Import-DSCResource -Module nx

Node $node {

nxSshAuthorizedKeys myKey{
KeyComment = "myKey"
Ensure = "Present"
Key = 'ssh-rsa
AAAAB3NzaC1yc2EAAAABJQAAAQEA0b+0xSd07QXRifm3FXj7Pn/DblA6QI5VAkDm6OivFzj3U6qGD1VJ6AAxW
PCyMl/qhtpRtxZJDu/TxD8AyZNgc8aN2CljN1hOMbBRvH2q5QPf/nCnnJRaGsrxIqZjyZdYo9ZEEzjZUuMDM5
HI1LA9B99k/K6PK2Bc1NLivpu7nbtVG2tLOQs+GefsnHuetsRMwo/+c3LtwYm9M0XfkGjYVCLO4CoFuSQpvX6
AB3TedUy6NZ0iuxC0kRGg1rIQTwSRcw+McLhslF0drs33fw6tYdzlLBnnzimShMuiDWiT37WqCRovRGYrGCaE
FGTG2e0CN8Co8nryXkyWc6NSDNpMzw== rsa-key-20150401'
UserName = "monuser"
}
}
DSC for Linux nxUser Resource
The nxUser resource in PowerShell Desired State Configuration (DSC) provides a
mechanism to to manage local users on a Linux node.

Syntax
Copy

nxUser <string> #ResourceName


{
UserName = <string>
[ Ensure = <string> { Absent | Present } ]
[ FullName = <string> ]
[ Description = <string> ]
[ Password = <string> ]
[ Disabled = <bool> ]
[ PasswordChangeRequired = <bool> ]
[ HomeDirectory = <string> ]
[ GroupID = <string> ]
[ DependsOn = <string[]> ]

Properties
Property Indicates the account name for which you want to ensure a specific stat

UserName Specifies the location where you want to ensure the state for a file or directory.

Ensure Specifies whether the account exists. Set this property to "Present" to ensure th
ensure that the account does not exist.

FullName A string that contains the full name to use for the user account.

Description The description for the user account.


Property Indicates the account name for which you want to ensure a specific stat

Password The hash of the users password in the appropriate form for the Linux computer
hash. On Debian and Ubuntu Linux, this value can be generated with the mkpa
method of Pythons Crypt library can be used to generate the hash.

Disabled Indicates whether the account is enabled. Set this property to $true to ensure t
ensure that it is enabled.

PasswordChangeRequired Indicates whether the user can change the password. Set this property to $true
password, and set it to $false to allow the user to change the password. The de
evaluated if the user account did not exist previously and is being created.

HomeDirectory The home directory for the user.

GroupID The primary group ID for the user.

DependsOn Indicates that the configuration of another resource must run before this resour
resource configuration script block that you want to run first is "ResourceName
using this property is DependsOn = "[ResourceType]ResourceName" .

Example
The following example ensures that the user "monuser" exists and is a member of the
group "DBusers".
Copy

Import-DSCResource -Module nx

Node $node {
nxUser UserExample{
UserName = "monuser"
Description = "Monitoring user"
Password =
'$6$fZAne/Qc$MZejMrOxDK0ogv9SLiBP5J5qZFBvXLnDu8HY1Oy7ycX.Y3C7mGPUfeQy3A82ev3zIabhDQnj
2ayeuGn02CqE/0'
Ensure = "Present"
HomeDirectory = "/home/monuser"
}
nxGroup GroupExample{
GroupName = "DBusers"
Ensure = "Present"
MembersToInclude = "monuser"
DependsOn = "[nxUser]UserExample"
}
}
Using DSC on Microsoft Azure
Desired State Configuration (DSC) is supported in Microsoft Azure through the Azure
Desired State Configuration extension handler and throughAzure Automation DSC.

Azure Desired State Configuration extension handler


The Azure DSC extension allows VMs hosted in Microsoft Azure to be managed with
DSC. For more information, see the following topics:

Azure Desired State Configuration extension handler


Windows VMSS and Desired State Configuration with Azure Resource Manager
templates
Passing credentials to the Azure DSC extension handler

Azure Automation DSC


The Azure Automation service allows you to manage DSC configurations, resources, and
managed nodes from within Azure. For more information, see the following topics:

Azure Automation DSC


Getting started with Azure Automation DSC
Onboarding machines for management by Azure Automation DSC
MSFT_DSCLocalConfigurationManager class
The Local Configuration Manager (LCM) that controls the states of configuration files
and uses Configuration Agent to apply the configurations.

The following syntax is simplified from Managed Object Format (MOF) code and
includes all of the inherited properties.

Syntax

syntaxCopy

[ClassVersion("1.0.0"), dynamic, provider("dsccore"), AMENDMENT]


class MSFT_DSCLocalConfigurationManager
{
};

Members

The MSFT_DSCLocalConfigurationManager class has the following members:

[Methods][]

Methods

The MSFT_DSCLocalConfigurationManager class has these methods.


Method Description

ApplyConfiguration Uses the Configuration Agent to apply the configuration that is pending.

DisableDebugConfiguration Disables DSC resource debugging.


Method Description

EnableDebugConfiguration Enables DSC resource debugging.

GetConfiguration Sends the configuration document to the managed node and uses the Get m
configuration.

GetConfigurationResultOutput Gets the Configuration Agent output relating to a specific job.

GetConfigurationStatus Get the configuration status history.

GetMetaConfiguration Gets the LCM settings that are used to control Configuration Agent.

PerformRequiredConfigurationChecks Starts the consistency check.

RemoveConfiguration Removes the configuration files.

ResourceGet Directly calls the Get method of a DSC resource.

ResourceSet Directly calls the Set method of a DSC resource.

ResourceTest Directly calls the Test method of a DSC resource.

RollBack Rolls back to a previous configuration.

SendConfiguration Sends the configuration document to the managed node and saves it as a p

SendConfigurationApply Sends the configuration document to the managed node and uses the Confi

SendConfigurationApplyAsync Send the configuration document to the managed node and start using the C
GetConfigurationResultOutput to retrieve result output.
Method Description

SendMetaConfigurationApply Sets the LCM settings that are used to control the Configuration Agent.

StopConfiguration Stops the configuration that is in progress.

TestConfiguration Sends the configuration document to the managed node and verifies the cur

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration
ApplyConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Uses the Configuration Agent to apply the configuration that is pending.

If there is no configuration pending, this method reapplies the current configuration.

Syntax

mofCopy

uint32 ApplyConfiguration(
[in] boolean force
);

Parameters

force [in]
If this is true, the current configuration is reapplied, even if there is a configuration
pending.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements
MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
DisableDebugConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Disables DSC resource debugging.

Syntax
mofCopy

uint32 DisableDebugConfiguration();

Parameters
This method has no parameters.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
EnableDebugConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Enables DSC resource debugging.

Syntax
mofCopy

uint32 EnableDebugConfiguration(
[in] boolean BreakAll
);

Parameters
BreakAll [in]
Sets a breakpoint at every line in the resource script.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration
See also
MSFT_DSCLocalConfigurationManager
GetConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Sends the configuration document to the managed node and uses the Get method of
the Configuration Agent to apply the configuration.

Syntax
mofCopy

uint32 GetConfiguration(
[in] uint8 configurationData[],
[out] OMI_BaseResource configurations[]
);

Parameters
configurationData [in]
Specifies the configuration data to send.

configurations [out]
On return, contains an embedded instance of the configurations.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements
MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
GetConfigurationResultOutput method of the
MSFT_DSCLocalConfigurationManager class
Gets the Configuration Agent output associated with a specific job.

Syntax
mofCopy

uint32 GetConfigurationResultOutput(
[in] string jobId,
[in] uint8 resumeOutputBookmark[],
[out] MSFT_DSCConfigurationOutput output[]
);

Parameters
jobId [in]
The ID of the job for which to get output data.

resumeOutputBookmark [in]
Specifies that the output should be a continuation from a previous bookmark.

output [out]
The output for the specified job.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.
Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
GetConfigurationStatus method of the
MSFT_DSCLocalConfigurationManager class
Get the configuration status history.

Syntax
mofCopy

uint32 GetConfigurationStatus(
[in] boolean All,
[out] MSFT_DSCConfigurationStatus configurationStatus[]
);

Parameters
All [in]
true if this method should return information about all the configuration runs on the
machine, including the configuration application and the consistency check.

configurationStatus [out]
On return, contains an embedded instance of
the MSFT_DSCConfigurationStatus class that defines the settings.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.
Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
GetMetaConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Gets the local Configuration Manager settings that are used to control the Configuration
Agent.

Syntax
mofCopy

uint32 GetMetaConfiguration(
[out] MSFT_DSCMetaConfiguration MetaConfiguration
);

Parameters
MetaConfiguration [out]
On return, contains an embedded instance of the MSFT_DSCMetaConfiguration class
that defines the settings.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof
Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
PerformRequiredConfigurationChecks method
of the MSFT_DSCLocalConfigurationManager
class
Starts a consistency check by using the Task Scheduler.

Syntax
mofCopy

uint32 PerformRequiredConfigurationChecks(
[in] uint32 Flags
);

Parameters
Flags [in]
A bitmask that specifies the type of consistency check to run. The following values are
valid, and can be combined by using a bitwise OR operation:

Value Description

1 A normal consistency check.

2 A continuation of a consistency check after a reboot. This value should not be combined with other

4 The configuration should be pulled from the pull server specified in the metaconfiguration for the n
with 1, for a value of 5.

8 Send status to the report server.

Return value
Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
RemoveConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Removes the configuration files.

Syntax
mofCopy

uint32 RemoveConfiguration(
[in] uint32 Stage,
[in] boolean Force
);

Parameters
Stage [in]
Specifies which configuration document to remove. The following values are valid:

Value Description

1 The Current configuration document (current.mof).

2 The Pending configuration document (pending.mof).

4 The Previous configuration document (previous.mof).

Force [in]
true to force the removal of the configuration.

Return value

Returns zero on success; otherwise returns an error code.


Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
ResourceGet method of the
MSFT_DSCLocalConfigurationManager class
Directly calls the Get method of a DSC resource.

Syntax
mofCopy

uint32 ResourceGet(
[in] string ResourceType,
[in] string ModuleName,
[in] uint8 resourceProperty[],
[out] OMI_BaseResource configurations
);

Parameters
ResourceType [in]
The name of the resource to call.

ModuleName [in]
The name of the module that contains the resource to call.

resourceProperty [in]
Specifies the resource property name and its value in a hash table as key and value,
respectively. Use the Get-DscResource cmdlet to discover resource properties and their
types.

configurations [out]
On return, contains an embedded instance of the configurations.

Return value

Returns zero on success; otherwise returns an error code.


Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
ResourceSet method of the
MSFT_DSCLocalConfigurationManager class
Directly calls the Set method of a DSC resource.

Syntax
mofCopy

uint32 ResourceSet(
[in] string ResourceType,
[in] string ModuleName,
[in] uint8 resourceProperty[],
[out] boolean RebootRequired
);

Parameters
ResourceType [in]
The name of the resource to call.

ModuleName [in]
The name of the module that contains the resource to call.

resourceProperty [in]
Specifies the resource property name and its value in a hash table as key and value,
respectively. Use the Get-DscResource cmdlet to discover resource properties and their
types.

RebootRequired [out]
On return, this property is set to true if the target node needs to be rebooted.

Return value

Returns zero on success; otherwise returns an error code.


Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
ResourceTest method of the
MSFT_DSCLocalConfigurationManager class
Directly calls the Test method of a DSC resource.

Syntax
mofCopy

uint32 ResourceTest(
[in] string ResourceType,
[in] string ModuleName,
[in] uint8 resourceProperty[],
[out] boolean InDesiredState
);

Parameters
ResourceType [in]
The name of the resource to call.

ModuleName [in]
The name of the module that contains the resource to call.

resourceProperty [in]
Specifies the resource property name and its value in a hash table as key and value,
respectively. Use the Get-DscResource cmdlet to discover resource properties and their
types.

InDesiredState [out]
On return, this property is set to true if the target node is in the desired state.

Return value

Returns zero on success; otherwise returns an error code.


Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
RollBack method of the
MSFT_DSCLocalConfigurationManager class
Rolls back the configuration to a previous version.

Syntax
mofCopy

uint32 RollBack(
[in] uint8 configurationNumber
);

Parameters
configurationNumber [in]
Specifies the requested configuration.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration
See also
MSFT_DSCLocalConfigurationManager
SendConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Sends the configuration document to the managed node and saves it as a pending
change.

Syntax
mofCopy

uint32 SendConfiguration(
[in] uint8 ConfigurationData[],
[in] boolean force
);

Parameters
ConfigurationData [in]
The environment data for the configuration.

force [in]
true to force the configuration to stop.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements
MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
SendConfigurationApply method of the
MSFT_DSCLocalConfigurationManager class
Sends the configuration document to the managed node and uses the Configuration
Agent to apply the configuration.

Syntax
mofCopy

uint32 SendConfigurationApply(
[in] uint8 ConfigurationData[],
[in] boolean force
);

Parameters
ConfigurationData [in]
The environment data for the configuration.

force [in]
true to force the configuration to stop.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements
MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
SendConfigurationApplyAsync method of the
MSFT_DSCLocalConfigurationManager class
Sends the configuration document asynchronously to the managed node and uses the
Configuration Agent to apply the configuration.

Syntax
mofCopy

uint32 SendConfigurationApplyAsync(
[in] uint8 ConfigurationData[],
[in] boolean force,
[in] string jobId
);

Parameters
ConfigurationData [in]
The environment data for the configuration.

force [in]
true to force the configuration to stop.

jobId [in]
The ID of the job for which to send the configuration.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.
Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
SendMetaConfigurationApply method of the
MSFT_DSCLocalConfigurationManager class
Sets the Local Configuration Manager settings that are used to control the
Configuration Agent.

Syntax
mofCopy

uint32 SendMetaConfigurationApply(
[in] uint8 ConfigurationData[],
[in] boolean force
);

Parameters
ConfigurationData [in]
The environment data for the configuration.

force [in]
true to force the configuration to stop.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements
MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager
StopConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Stops the configuration change that is in progress.

Syntax
mofCopy

uint32 StopConfiguration(
[in] boolean force
);

Parameters
force [in]
true to force the configuration to stop.

Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration
See also
MSFT_DSCLocalConfigurationManager
TestConfiguration method of the
MSFT_DSCLocalConfigurationManager class
Sends the configuration document to the managed node and verifies the current
configuration against the document.

Syntax
mofCopy

uint32 TestConfiguration(
[in] uint8 configurationData[],
[out] boolean InDesiredState,
[out] MSFT_ResourceInDesiredState ResourcesInDesiredState[],
[out] MSFT_ResourceNotInDesiredState ResourcesNotInDesiredState[]
);

Parameters
configurationData [in]
Environment data for the confuguration.

InDesiredState [out]
On return, specifies whether the managed node is in the state specified by the
configuration document.

ResourcesInDesiredState [out]
On return, contains an embedded instance of
the MSFT_ResourceInDesiredState class that specifies resources that are in the
desired state.

ResourcesNotInDesiredState [out]
On return, contains an embedded instance of
the MSFT_ResourceNotInDesiredState class that specifies resources that are not in
the desired state.
Return value

Returns zero on success; otherwise returns an error code.

Remarks
This is a static method.

Requirements

MOF: DscCore.mof

Namespace: Root\Microsoft\Windows\DesiredStateConfiguration

See also
MSFT_DSCLocalConfigurationManager

You might also like