Custom Resources
Creating Custom Resources¶
Custom DSC resources are essential when existing built-in resources do not meet specific administrative needs, such as managing proprietary applications, custom configurations, or unique system components. By creating custom resources, you can encapsulate complex logic, ensure consistency, and extend DSC’s capabilities to align with organizational requirements.
Core Concepts and Structure¶
A DSC custom resource is a PowerShell class that implements three core methods:
1. Get-TargetResource: Retrieves the current state of the target node.
2. Set-TargetResource: Applies the desired configuration.
3. Test-TargetResource: Validates whether the current state matches the desired state.
Resources must also define a DSCResourceSchema to enforce parameter validation and structure. The schema is manually defined in the resource module (note: New-DSCResource is deprecated in PowerShell 7.0 and removed in 7.2).
Step-by-Step Creation Process¶
-
Create a PowerShell Module
Organize your resource in a module directory structure. For example:
-
Define the Resource Class
Create a.psm1file (e.g.,MyCustomResource.psm1) with the resource class:
# MyCustomResource.psm1 [DscResource()] class MyCustomResource { [DscProperty(Mandatory)] [string]$Ensure [DscProperty()] [string]$Path [void] Get-TargetResource() { # Logic to retrieve current state } [void] Set-TargetResource() { # Logic to apply desired state } [bool] Test-TargetResource() { # Logic to validate state return $true } } -
Manually Define Schema
Create aMyCustomResource.schema.moffile with schema definitions (example structure):
-
Test and Validate
UseTest-DscConfigurationto verify your resource behaves as expected.
Example: Custom Resource for File Management¶
Here’s a resource that ensures a file exists with specific content:
# MyCustomResource.psm1
[DscResource()]
class FileContentResource {
[DscProperty(Mandatory)]
[string]$Path
[DscProperty(Mandatory)]
[string]$Content
[DscProperty()]
[System.String]$Ensure = "Present"
[void] Get-TargetResource() {
$currentContent = Get-Content -Path $Path -ErrorAction SilentlyContinue
return @{"Path" = $Path; "Content" = $currentContent; "Ensure" = $Ensure}
}
[void] Set-TargetResource() {
if ($Ensure -eq "Present") {
if (-not (Test-Path -Path $Path)) {
New-Item -Path $Path -ItemType File | Out-Null
}
Set-Content -Path $Path -Value $Content
} else {
if (Test-Path -Path $Path) {
Remove-Item -Path $Path -Force
}
}
}
[bool] Test-TargetResource() {
$currentContent = Get-Content -Path $Path -ErrorAction SilentlyContinue
return ($currentContent -join "`n") -eq $Content -and (Test-Path -Path $Path)
}
}
Use the resource in a configuration:
Configuration FileConfig {
Node localhost {
FileContentResource MyFile {
Path = "C:\Test\myfile.txt"
Content = "This is the desired content."
Ensure = "Present"
}
}
}
Best Practices¶
- Use
DSCResourceSchemafor parameter validation and documentation. - Handle errors gracefully to avoid partial configurations.
- Ensure idempotency by avoiding destructive operations unless explicitly required.
- Package resources as modules for reuse across environments.
Key takeaways¶
- Custom DSC resources extend DSC’s capabilities for specialized tasks.
- Implement
Get-TargetResource,Set-TargetResource, andTest-TargetResourcemethods. - Validate parameters with
DSCResourceSchemaand test thoroughly. - Structure resources for idempotency and reusability.
- Package resources as PowerShell modules for deployment.