Professional Documents
Culture Documents
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.
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:
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.
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.
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.
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
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.
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
$shareExists = $false
$smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue
if($smbShare -ne $null)
{
Write-Verbose -Message "Share with name $Name exists"
$shareExists = $true
}
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
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.
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.
<head></head>
<body>
<p>Hello World!</p>
</body>
Configuration WebsiteTest {
# 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'
}
}
}
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.
. .\WebsiteTest.ps1
WebsiteTest
Directory: C:\ConfigurationTest\WebsiteTest
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.
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
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
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.
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
. .\MyDscConfiguration.ps1
MyDscConfiguration -ComputerName 'MyTestNode'
Copy
Configuration DependsOnExample {
Node Test-PC1 {
Group GroupExample {
Ensure = "Present"
GroupName = "TestGroup"
}
User UserExample {
Ensure = "Present"
UserName = "TestUser"
FullName = "TestUser"
DependsOn = "[Group]GroupExample"
}
}
}
DependsOnExample
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'
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:
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.
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 "VMHost"}.NodeName
{
WindowsFeature HyperVInstall {
Ensure = 'Present'
Name = 'Hyper-V'
}
}
}
$MyData =
@{
AllNodes =
@(
@{
NodeName = 'VM-1'
Role = 'WebServer'
},
@{
NodeName = 'VM-2'
Role = 'VMHost'
}
)
}
The last line in this script compiles the configuration, passing $MyData as the
value ConfigurationData parameter.
Directory: C:\DscTests\MyDscConfiguration
@{
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\"
}
)
}
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.
Configuration MyWebApp
{
Import-DscResource -Module PSDesiredStateConfiguration
Import-DscResource -Module xSqlPs
Import-DscResource -Module xWebAdministration
}
}
xWebsite NewWebsite
Ensure = 'Present'
Name = $WebSiteName
State = 'Started'
PhysicalPath = $Node.SitePath
DependsOn = '[File]WebContent'
}
When you run this configuration, three MOF files are created (one for each named entry
in the AllNodes array):
Copy
Directory: C:\DscTests\MyWebApp
You access additional keys by using the special variable $ConfigurationData. In this
example, ConfigFileContents is accessed with the line:
PowerShellCopy
Contents = $ConfigurationData.NonNodeData.ConfigFileContents
$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.
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
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
}
}
}
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.
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'
}
)
}
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.
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 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 = ""
}
$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 ).
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'
}
)
}
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.
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
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
$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.
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
PsDscAllowPlainTextPassword
PsDscAllowDomainUser
Note: Using plaintext passwords is not secure. Securing credentials by using the
techniques covered later in this topic is recommended.
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
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.
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
}
}
}
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
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.
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
}
)
}
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.
Configuration FileConfig
{
param (
[Parameter(Mandatory = $true)]
[String] $CopyFrom,
[Parameter(Mandatory = $true)]
[String] $CopyTo
)
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.
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:
Once exported, the DscPublicKey.cer would need to be copied to the Authoring Node.
Once exported, the DscPublicKey.cer would need to be copied to 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.
Once exported, the DscPrivateKey.cer would need to be copied to the Target Node.
On the Target Node: import the certs private key as a trusted root
PowerShellCopy
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"
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
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
}
}
}
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.
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.
LocalConfigurationManager
{
CertificateId = $node.Thumbprint
}
}
}
$ConfigData= @{
AllNodes = @(
@{
# The name of the node we are describing
NodeName = "$computerName"
#region HelperFunctions
$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
}
Start-CredentialEncryptionExample
PowerShell Desired State Configuration partial
configurations
Applies To: Windows PowerShell 5.0 and later.
You can use partial configurations in push mode, pull mode, or a combination of the
two.
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 .
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
Directory: C:\PartialConfigTest
Directory: C:\PartialConfigTest\ServiceAccountConfig
Directory: C:\DscTests\SharePointConfig
Note: The user running the Publish-DSCConfiguration cmdlet must have administrator
privileges on the target node.
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.
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'
}
[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.
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.
ServiceAccountConfig.mof
ServiceAccountConfig.mof.checksum
SharePointConfig.mof
SharePointConfig.mof.checksum
Naming and placing the configuration documents on the pull server
(ConfigurationID)
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
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.
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.
Configuration ServiceAccountConfig
{
Param (
[Parameter(Mandatory,
HelpMessage="Domain credentials required to add
domain\sharepoint_svc to the local Administrators group.")]
[ValidateNotNullOrEmpty()]
[pscredential]$Credential
)
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
)
Node localhost
{
xSPInstall SharePointDefault
{
Ensure = 'Present'
BinaryDir = '\\FileServer\Installers\Sharepoint\'
ProductKey = $ProductKey
}
}
}
SharePointConfig
See Also
Concepts Windows PowerShell Desired State Configuration Pull Servers
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"
}
}
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.
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.
Configuration SampleIISInstall
{
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
node ('localhost')
{
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}
}
}
1. Mount the VHD into which you want to inject the configuration by calling
the Mount-VHD cmdlet. For example:
PowerShellCopy
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
PowerShellCopy
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.
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')
}
}
}
1. Mount the VHD into which you want to inject the metaconfiguration by calling
the Mount-VHD cmdlet. For example:
PowerShellCopy
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
PowerShellCopy
PowerShellCopy
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.
PowerShellCopy
Copy
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`
PowerShellCopy
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
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".
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
Syntax
MOFCopy
Properties
Property Description
Destination Specifies the location where you want to ensure the archive contents are extracted.
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
Syntax
mofCopy
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
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
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
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
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
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
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
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
}
)
}
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
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.
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
Syntax
Copy
Properties
Property Description
Name Indicates the name of the package for which you want to ensure a specific state.
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
Syntax
Copy
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.
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
Syntax
Copy
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" .
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
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
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
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
Syntax
Copy
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.
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
Use this resource when you want to configure a number of services to the same state.
Syntax
Copy
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
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.
Syntax
Copy
Properties
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.
Syntax
Copy
Properties
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 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.
Syntax
Copy
Properties
Property Description
NodeCount The minimum number of nodes that must be in the desired state for this resource to succ
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
Syntax
Copy
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
Use this resource when you want to configure a number of Windows Features to the
same state.
Syntax
Copy
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.
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
Syntax
Copy
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".
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
Use this resource when you want to configure a number of Windows optional features
to the same state.
Syntax
Copy
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
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 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.
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]
$LogPath
)
WindowsPackageCab WindowsPackageCab1
{
Name = $Name
Ensure = 'Present'
SourcePath = $SourcePath
LogPath = $LogPath
}
}
DSC WindowsProcess Resource
Applies To: Windows PowerShell 4.0, Windows PowerShell 5.0
Syntax
Copy
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
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
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.
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.
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.
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;
};
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.
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.
# 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 #>
$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:
[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.
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
)
#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.
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
@{
# 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")
Supporting PsDscRunAsCredential
Note: PsDscRunAsCredential is supported in PowerShell 5.0 and later.
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
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.
[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;
};
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");
# 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)]
[Parameter(Mandatory = false)]
public string Content {
get { return (string.IsNullOrEmpty(this._content) ? "" : this._content);
}
set { this._content = value; }
}
/// <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; }
}
/// <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
WriteObject(Content.Equals(existingContent,
StringComparison.InvariantCultureIgnoreCase));
}
}
else
{
WriteObject(Ensure.Equals("Absent",
StringComparison.InvariantCultureIgnoreCase));
}
}
}
# endregion
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
See Also
Concepts
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
$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
}
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)
<#
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)
<#
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
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."
}
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)
}
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.
<#
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.
<#
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.
<#
This property reports the file's create timestamp.
#>
[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 ($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
<#
Helper method to copy file from source to path
#>
[void] CopyFile()
{
if (-not $this.TestFilePath($this.SourcePath))
{
throw "SourcePath $($this.SourcePath) is not found."
}
<#
Use CreateDirectory instead of New-Item to avoid code
to handle the non-terminating error
#>
[System.IO.Directory]::CreateDirectory($destFileInfo.Directory.FullName)
}
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
@{
DscResourcesToExport = 'FileResource'
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.
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 {
}
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
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.
Configuration xVirtualMachine
{
param
(
# Name of VMs
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String[]] $VMName,
# State of the VM
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[String] $VMState
)
RootModule = 'xVirtualMachine.schema.psm1'
$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.
Node "192.168.10.1"
{
xComputer Name
{
Name = "SQL01"
DomainName = "fourthcoffee.com"
}
}
}
Supporting PsDscRunAsCredential
Note: PsDscRunAsCredential is supported in PowerShell 5.0 and later.
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
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
Node $NodeName
{
xTimeZone TimeZoneExample
{
xTimeZone TimeZoneExample2
{
}
}
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;
};
[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
)
$returnValue = @{
TimeZone = $CurrentTimeZone
IsSingleInstance = 'Yes'
}
function Set-TargetResource
{
[CmdletBinding(SupportsShouldProcess=$true)]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)
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
}
}
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
xPSDesiredStateConfiguration
DSCResources
MSFT_xRemoteFile
MSFT_xRemoteFile.psm1
MSFT_xRemoteFile.schema.mof
Examples
xRemoteFile_DownloadFile.ps1
ResourceDesignerScripts
GenerateXRemoteFileSchema.ps1
Tests
ResourceDesignerTests.ps1
xPSDesiredStateConfiguration.psd1
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
Every field has meaningful description. The PowerShell GitHub repository has good
examples, such as the .schema.mof for xRemoteFile
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
$error = $null
Import-Module <resource_module> force
If ($error.count ne 0) {
Throw Module was not imported correctly. Errors returned: $error
}
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.
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.
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
)
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"
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.
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.
$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
Example:
Instead of:
Copy
$tempPath = "C:\Users\kkaczma\AppData\Local\Temp\MyResource"
$programFilesPath = "C:\Program Files (x86)"
You can write:
Copy
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.)
Test-xDscResource ..\DSCResources\MSFT_xRemoteFile
Test-xDscSchema ..\DSCResources\MSFT_xRemoteFile\MSFT_xRemoteFile.schema.mof
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
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.
You can verify that debugging has been enabled by looking at the result of a call to Get-
DscLocalConfigurationManager.
PS C:\DebugTest> $LCM.DebugMode
NONE
PS C:\DebugTest> $LCM.DebugMode
ForceModuleImport
ResourceScriptBreakAll
PS C:\DebugTest>
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.
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.
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.
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.
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.
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.
[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:
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
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
ActionAfterReboot string Specifies what happens after a reboot during the application
are "ContinueConfiguration" and "StopConfiguration".
RefreshMode string Specifies how the LCM gets configurations. The possible val
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
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:
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
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
AllowUnsecureConnection bool Set to $TRUE to allow connections from the node to the server without auth
RegistrationKey string A GUID that identifies the node to the pull server. For more information, see
Credential MSFT_Credential The credential used to authenticate to the SMB share. For an example of passi
AllowUnsecureConnection bool Set to $TRUE to allow connections from the node to the server without auth
RegistrationKey string A GUID that identifies the node to the pull server. For more information, see
Property Type Description
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
DependsOn string{} A list of names of other configurations that must be completed before this part
RefreshMode string Specifies how the LCM gets this partial configuration. The possible values are
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
Other Resources
Set-DscLocalConfigurationManager
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
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.
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.
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
)
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
}
}
}
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
# 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.
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'
}
}
}
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.
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
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.
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 {
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).
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 {
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'
}
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.
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.
For more information about configuring the LCM, see Setting up a pull client using
configuration ID.
[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
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.
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.
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 .
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
[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
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.
[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
ConfigurationID = '1d545e3b-60c3-47a0-bf65-5afc05182fd0'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryShare SMBPullServer
{
SourcePath = '\\SMBPullServer\PullSource'
}
}
}
PullClientConfigID
[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
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.
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
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
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.
Configuration Planning
Installation Guide
Versions of the Windows Management Framework
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):
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.
Install-Module xPSDesiredStateConfiguration
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
What is the process to request a new server for your target environment?
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?
If needed, what type of Load Balancing solution will you utilize? (see section titled Load Balancing for details)
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?
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?
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
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.
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
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
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.
PowerShellCopy
Configuration PullServer {
Import-DscResource -ModuleName xPSDesiredStateConfiguration
PowerShellCopy
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'
}
# 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'
}
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
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.
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
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.
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:
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.
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'
xDnsServerPrimaryZone $Node.zone
{
Ensure = 'Present'
Name = $Node.Zone
DependsOn = '[WindowsFeature]DNS'
}
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
param(
[parameter(Mandatory=$true)]
[string]
$OutputPath
)
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).
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.
GenerateEnvironmentFiles
InstallModules
UnitTests
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 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.
DeployModules
Starts a PowerShell session on TestAgent1 and installs the modules containing the DSC
resources required for the configuration.
DeployConfigs
AcceptanceTests
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.
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.
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
This build step runs the initiate.ps1 file, which calls the psake build script.
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
Copy
initiate.ps1
**\deploy.ps1
**\Acceptance\**
**\Integration\**
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
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:
PowerShell Script
Publish Test Results
Publish Test Results
PowerShell Script
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.
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 "VMHost"}.NodeName
{
WindowsFeature HyperVInstall {
Ensure = 'Present'
Name = 'Hyper-V'
}
}
}
$MyData =
@{
AllNodes =
@(
@{
NodeName = 'VM-1'
Role = 'WebServer'
},
@{
NodeName = 'VM-2'
Role = 'VMHost'
}
)
}
The last line in this script compiles the configuration, passing $MyData as the
value ConfigurationData parameter.
Directory: C:\DscTests\MyDscConfiguration
@{
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\"
}
)
}
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.
Configuration MyWebApp
{
Import-DscResource -Module PSDesiredStateConfiguration
Import-DscResource -Module xSqlPs
Import-DscResource -Module xWebAdministration
}
}
xWebsite NewWebsite
Ensure = 'Present'
Name = $WebSiteName
State = 'Started'
PhysicalPath = $Node.SitePath
DependsOn = '[File]WebContent'
}
When you run this configuration, three MOF files are created (one for each named entry
in the AllNodes array):
Copy
Directory: C:\DscTests\MyWebApp
You access additional keys by using the special variable $ConfigurationData. In this
example, ConfigFileContents is accessed with the line:
PowerShellCopy
Contents = $ConfigurationData.NonNodeData.ConfigFileContents
$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
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:
The following parameter set returns the status information for the last configuration run:
PowerShellCopy
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
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.
The corresponding PowerShell cmdlet, Get-WinEvent, can also be run to view the event
logs:
Copy
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 :
<##########################################################################
Step 1 : Enable analytic and debug DSC channels (Operational channel is enabled by
default)
###########################################################################>
<##########################################################################
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
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
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:\> $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.
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
$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
ProviderName: Microsoft-Windows-DSC
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
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
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
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
This will display the same results as the Get-WinEvent cmdlet, such as in the output
below:
PowerShellCopy
ProviderName: Microsoft-Windows-DSC
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.
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
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.
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 :
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
}
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.
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
onlyProperty PSComputerName
------------ --------------
20 localhost
onlyProperty PSComputerName
------------ --------------
14 localhost
See Also
Reference
Concepts
Other Resources
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.
Issue: Password encryption (see Securing the MOF File) during configuration
compilation doesn't work.
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:
The following table describes the required package dependencies for DSC for Linux.
Required package Description M
python Python 2
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 .
Installing DSC
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.
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.
Configuration ExampleConfiguration{
Import-DSCResource -Module nx
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"
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:"
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.
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.
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
# 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.
StartDscLocalConfigurationManager.py
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.
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.
Syntax
Copy
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
Properties
Property Description
Name Indicates the name of the environment variable for which you want to ensure a specific state.
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
}
Syntax
Copy
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"
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.
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
'@
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
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
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".
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
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.
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
Properties
Property Description
Controller The type of service controller to use when configuring the service.
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
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
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.
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.
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.
The following syntax is simplified from Managed Object Format (MOF) code and
includes all of the inherited properties.
Syntax
syntaxCopy
Members
[Methods][]
Methods
ApplyConfiguration Uses the Configuration Agent to apply the configuration that is pending.
GetConfiguration Sends the configuration document to the managed node and uses the Get m
configuration.
GetMetaConfiguration Gets the LCM settings that are used to control Configuration Agent.
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.
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.
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
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
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
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
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
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
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
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
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.
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
Force [in]
true to force the removal of the configuration.
Return value
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
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
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
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
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
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
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
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
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
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
Remarks
This is a static method.
Requirements
MOF: DscCore.mof
Namespace: Root\Microsoft\Windows\DesiredStateConfiguration
See also
MSFT_DSCLocalConfigurationManager