Authoring RPS DSC Partial Configurations
Last updated on March 9, 2020.
Last Reviewed and Approved on PENDING REVIEW
DSC Partial Configurations (Partial Configs) are used to organize and apply a set of configuration settings to a target computer. Multiple partial configs can be applied and combined to form the full DSC configuration applied to a target computer. RPS-enabled Partial Configs are ones that adhere to specific guidelines which allow them to be used by RPS to configure and publish configurations to computers on an RPS Node.
This document contains the guidelines to create RPS-enabled Partial Configurations.
Outline
- RPS-Enabled Partial Config
- Common Parameters
- RPS-Mapped Parameters
- DependsOn
- Importing Partial Configs into RPS
- Testing Partial Config data with RPS
- Publishing from RPS
RPS-Enabled Partial Config
What is "RPS-Enabled"?
"RPS-Enabled" indicates that a Partial Config is capable of being automatically published by RPS. In order to do this, a partial must adhere to certain rules:
- Partial must contain baseline parameters used for secure publishing.
- Partial must describe its dependencies and required inputs.
- Partial and DSC Modules must be imported into RPS.
Sample Partial Config
This sample partial configuration shows the common elements of an RPS-enabled partial.
using namespace Rps.Api.PowerShell
using namespace Rps.Api.Constants
[DependsOn(DscPartialName = 'OSCore')]
Param
(
[Parameter(Mandatory = $true)]
[ValidateScript({[ipaddress]::Parse($_)})]
[string]
$IPAddress,
[Parameter(Mandatory = $true)]
[ResourceItemMapping(EntityType = [ResourceTypes]::Certificate, Role = 'DSCEncryption')]
[Hashtable]
$DSCEncryptionCertificate,
[Parameter(Mandatory = $true)]
[string]
$OutputPath
)
Configuration SampleConfiguration
{
Import-DscResource -ModuleName 'PSDesiredStateConfiguration' -ModuleVersion 1.1
Import-DscResource -ModuleName 'SampleDscModule' -ModuleVersion 1.0
Node $IPAddress
{
File SampleFile
{
Ensure = 'Present'
SourcePath = "sourcepath"
DestinationPath = "destinationPath"
Force = $true
}
SampleDscResource SampleResourceName
{
Ensure = 'Present'
Properties = Values
}
}
}
$certificatesPath = (Get-Item "$PSScriptRoot\..\..\Certificates").FullName
$ConfigData = @{
AllNodes = @(
@{
# DSC Encryption common data
CertificateFile = ConvertTo-RootedPath -Filename $DSCEncryptionCertificate.PublicKeyPath -FolderPath $certificatesPath
Thumbprint = $DSCEncryptionCertificate.Thumbprint
NodeName = $IPAddress
PSDscAllowDomainUser = $true
}
)
}
$null = SampleConfiguration -ConfigurationData $ConfigData -OutputPath $OutputPath
Common Parameters
All RPS Partial Configs must define the following parameters:
- IPAddress - Accessible IPAddress of the computer we'll publish DSC Configuration to.
- DSCEncryptionCertificate - Information about the certificate used to encrypt the mof (configuration). The LCM is set to use this certificate and any partials that are not secured will not run on a target.
- OutputPath - Location to temporarily store the mof file once its compiled.
RPS-Mapped Parameters
The main advantage of using RPS-enabled partials is that they can be dynamically built from data within RPS' CMDB. When published through RPS, RPS will supply a partial config with values for all parameters from the CMDB. This system of mapping is based on a few simple conventions and parameter attributes.
For more information on RPS-Mapped Parameters see How to configure Rps-Mapped Parameters
RPS Native Parameters
RPS supports another parameter type, [Rps.Api.TargetItem]
. If you supply a parameter of this type,
RPS will return the native TargetItem you are publishing to. From there, you are free to use the Rps-Api
module and objects to access any data.
Partial Config Dependencies
Some Partial Configs rely on others, and to optimize publishing, they need to be compiled and published in the right order.
To indicate to RPS a dependency, use the [DependsOn]
attribute above the param block:
[DependsOn(DscPartialName = 'OSCore', Mandatory = $true)]
- DscPartialName is the name of the partial which is depended on.
- Mandatory indicates that the dependent partial is required on this target. If
$false
, this dependency is ignored if the dependent partial isn't assigned to the target.
Importing Partial Configs into RPS
Partial Configs must be imported into RPS in order to be published via RPS. When a partial is imported, RPS parses the file and stores the metadata about the partial, its parameters and its dependencies as ResourceItems. Once imported, the partial is able to be assigned to a computer, represented as a TargetItem.
Importing a Partial
- Save Partial configs in the \DSC\PartialConfigurations\ folder.
- Save any referenced DSC Resources to the \DSC\Modules\ folder.
- Import the Partial via the
Import-DscPartial
cmdlet, found in the Rps-Dsc module. - Specify a folder or file for
-Path
Example: Import all DSC Partials
Set-Location $ContentStore
Import-Module .\Modules\Rps-Api
Import-Module .\Modules\Rps-Dsc
Enter-RpsSession
Import-DscPartial -Path .\DSC\PartialConfigurations
Testing a Partial
You can test the RPS supplied configuration data for a partial by using the Get-DscPartialParam
cmdlet.
This is useful for understanding how configuration data from Targets and Resources is passed to the DSC Partial.
The cmdlet returns a Hashtable
that can be splatted for use directly with the Partial.
Example: Get Config Data for OSCore
Set-Location $ContentStore
Import-Module .\Modules\Rps-Api
Import-Module .\Modules\Rps-Dsc
Enter-RpsSession
# import partial for OSCore
$partialPath = ".\dsc\PartialConfigurations"
Import-DscPartial -Path $partialPath
$osCorePartial = Set-RpsResourceItem -Type $Rps.ResourceTypes.DscPartial -Name OSCore
# create target item
$computer = Set-RpsTargetItem -Type $Rps.TargetTypes.Computer -Name "TestComputer1" `
-Properties @{ ComputerName = "DEMO"; IPAddress = "10.0.0.1"; JoinDomain = "true" }
# set node properties
$containerNode = Get-RpsContainerNode -TargetItem $computer
$containerNode.SystemTimeZone = "UTC"
$containerNode.OutputPath = "c:\temp"
$containerNode.DomainName = "rps.master"
Set-RpsNode -Node $containerNode
# assign certificate
$dscCert = Set-RpsResourceItem -Type $Rps.ResourceTypes.Certificate -Name "DSCCert" `
-Properties @{ Role = "DscEncryption"; Path = "test"; Password = "something" }
$null = New-RpsResourceAssignment -ResourceItem $dscCert -TargetItem $computer
# assign partial
$assignment = New-RpsResourceAssignment -ResourceItem $osCorePartial -TargetItem $computer
# get DSC Params
Get-DscPartialParam -PartialAssignment $assignment
Output
PS > Get-DscPartialParam -PartialAssignment $assignment
[12:55:30 INF] No credential resolved on 4ca80061-7951-4ecc-bf40-b7afcd297119: DomainAdmin
[12:55:30 INF] No value resolved on 4ca80061-7951-4ecc-bf40-b7afcd297119: ServerAdmin mapping ResourceItem in OSCore didn't yield one match.
Name Value
---- -----
SystemTimeZone UTC
LocalAccount {}
DomainName rps.master
ComputerName DEMO
DomainAdmin
DscEncryptionCertificate {Path, Password, Role, Name...}
NetworkConfig {}
IPAddress 10.0.0.1
JoinDomain True
IsDC False
OutputPath c:\temp\6c94d0db-235c-418b-ad48-f40944899960\OSCore
ServerAdmin
Assigning a Partial
Once imported, the Partial Config is saved as a ResourceItem in RPS. To publish a configuration from RPS, you must first assign one or more ResourceItems representing partials to the desired computer TargetItem.
Import-Module .\Modules\Rps-Api
$vm = New-RpsTargetItem -Type $Rps.TargetTypes.VirtualMachine -Name DemoVM1 -Properties { IPAddress = "10.0.0.17" }
$softwarePartial = Get-RpsResourceItem -Type $Rps.ResourceTypes.DscPartial -Name "SoftwareDistribution"
New-RpsResourceAssignment -ResourceItem $softwarePartial -TargetItem $vm
Publishing a Partial
RPS Publishes DSC Partials using the Publish-RpsConfiguration runbook. This runbook is triggered from a fresh RPS Install, from an assigned Task or TaskMap, or via RPS Web.
Additional Tips
Using statements at the top improve readability. Without them, you must fully qualify Rps specific objects.
using namespace Rps.Api.PowerShell using namespace Rps.Api.Constants [DependsOn(DscPartialName = 'OSCore')] # instead of [Rps.Api.PowerShell.DependsOn(...)]
- ConfigurationName - Use a meaningful name for the configuration. This name identifies the Partial Config in RPS and the
DependsOn
attribute. - For all resources you use in your partial you will need to import the module inside the configuration block. Include the
-ModuleVersion
in your import statements to avoid issues with multiple module versions.
Import-DscResource –ModuleName 'RPS_RPSApi' -ModuleVersion 1.0
$certificatesPath
indicates the location where certificates are stored. Do not modify its value.- configData - This is the basic configuration for a partial. You can add parameters to this HashTable but this is the minimum. This sets up the mof encryption for the target.