Ever thought about trying DSC but felt the learning curve is too steep? Or maybe you never saw yourself using it in production, therefore he did not bother?
Using DSC does not have to be difficult or complex, and you don't need a gigantic infrastructure to make it worth your while. This post will talk about DSC and how to get started, and includes examples of how you can get started by applying it on a small scale in production.
What is DSC?
The desired state settings (DSC) is a configuration management system that is built into Windows and enables you to configure your system as code. Uses a configuration written in PowerShell which is then converted to a managed object format (MOF).
The MOF file is then read and applied by the Local Configuration Manager Service on the target node (computer).
The configuration that is created and executed uses different DSCs means from Módulos DSC. DSC modules are like a normal PowerShell module and resources are their functions. As an example, you can install them using Install-Module
, and are stored below in the PSModulePath.
What can I use DSC for?
The hardest part of DSC for many is finding use cases. People tend to talk and write about DSC only when it comes to orchestrating and spinning large venues, or test and QA for different applications, which is a distant subject for many administrators.
We can use DSC for our daily routines and much more, without having to restructure our entire organization. I compiled a list of some areas that you can fully or partially automate with DSC:
Example: reading and writing a DSC configuration
A few lines from DSC can equal hundreds of lines with raw PowerShell, this is why it can be so incredibly powerful.
A DSC configuration consists mainly of 2 parts: DSC configuration and configuration data.
Configuration data (that are explained below) can be included externally, generally from a PSD file, or be included in the configuration file. The recommended and easiest to maintain approach is to include this from a separate file.
Then, shows an example of how to create a DSC MOF that downloads and installs a generic MSI when applied:
Configuration MyDSCConfiguration {
# Import DSC modules with resources to use in the configuration
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion "8.10.0.0"
##############################################
# Creates configuration for the server fileserver-1
##############################################
Node "fileserver-1" {
# Create C:ProgramDataSoftwarePackages to download files to on all nodes
File SoftwarePackagesDirectory {
# Identifier "SoftwarePackagesDirectory" using the DSC resource "File" from DSC module "PSDesiredStateConfiguration"
DestinationPath = "C:ProgramDataSoftwarePackages"
Type = "Directory" # Is a directory
Ensure = "Present" # Ensure that it exists
}
# Download MSI
xRemoteFile DownloadBackupAgent {
# The xRemoteFile resource from xPSDesiredStateConfiguration DSC module used to download an MSI through HTTP
DependsOn = "[File]SoftwarePackagesDirectory" # Tells DSC to not run this if the previous step hasn't completed successfully
Uri = "http://web.contoso.com/packages/backupagent.msi" # Where to download the remote file from
DestinationPath = "C:ProgramDataSoftwarePackagesBackupAgent.msi" # Where to save the downloaded file
}
# Install MSI
xMsiPackage InstallBackupAgent {
# The xMsiPackage resource from xPSDesiredStateConfiguration DSC module used to install the MSI we just downloaded
DependsOn = "[xRemoteFile]DownloadBackupAgent" # Depends on previous step being completed before starting
ProductId = "d29c3fa9-e03e-40e0-a6ed-556c6f05476a" # The MSI package ProductID
Path = "C:ProgramDataSoftwarePackagesBackupAgent.msi" # Path to the MSI file we just downloaded
Ensure = "Present" # Ensure that it's present (install the MSI), 'Ensure = "Absent"' would uninstall the MSI
}
}
}
After running this code, creates a config function in current PowerShell session that can be used. Create a subfolder with the same name as the configuration where you save the generated MOF files:
PS51> MyDSCConfiguration
Directory: C:TutorialsDSCMyDSCConfiguration
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-10-28 16:38 3952 fileserver-1.mof
You can apply all the DSC settings in the MyDSCConfiguration folder to your host by running:
PS51> Start-DscConfiguration -Path .MyDSCConfiguration -Wait
Using DSC with ConfigurationData
Configuration data contains configuration data for DSC configuration. The information includes a node name (computer name) and may contain other data such as information about how to install an MSI package or registry key values, etc. This gives us a dynamic and more versatile approach to DSC., so that it can be reused. and easily modifiable.
Let's say you have these three servers and each one needs a unique combination of packages:
- fileserver-1
- database-1
- Needs: BackupAgent, BackupAgent-DatabaseAddon
- application server-1
- Needs: BackupAgent, MonitoringAgent
The best approach is to create a file with the configuration data you need, not just specifying the nodes (servers), but also adding a list of packages in it:
# Save as ConfigurationData.psd1
@{
#############################
# Specify server nodes
#############################
AllNodes = @(
@{
NodeName = "*"
}
# File server node
@{
NodeName = "fileserver-1"
Role = "Fileserver"
# Selects what packages to install
Packages = @(
'BackupAgent'
)
},
# Database server node
@{
NodeName = "database-1"
Role = "Database"
# Selects what packages to install
Packages = @(
'BackupAgent',
'BackupAgent-DataBaseAddon'
)
},
# Appserver node
@{
NodeName = "appserver-1"
Role = "Appserver"
# Selects what packages to install
Packages = @(
'BackupAgent',
'MonitoringAgent'
)
}
)
#############################
# Establece each package
#############################
Packages = @(
@{
Name = "BackupAgent"
ProductId = "3c4e21b5-8de2-408e-84e0-a42b0507b8b1"
FileName = "BackupAgent.msi"
Ensure = "Present"
},
@{
Name = "BackupAgent-DataBaseAddon"
ProductId = "97f860f6-0a58-4bf3-aef8-abc0f796e9df"
FileName = "BackupAgent-DataBaseAddon.msi"
Ensure = "Present"
},
@{
Name = "MonitoringAgent"
ProductId = "77b29b12-c222-4d85-b812-bbd4136ad0ff"
FileName = "MonitoringAgent.msi"
Ensure = "Present"
}
)
}
You can now use this configuration data file to dynamically generate DSC configurations for your servers.:
Configuration MyDSCConfiguration {
# Import DSC modules with resources to use in the configuration
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion "8.10.0.0"
# Get Packages from the ConfigurationData
$Packages = $ConfigurationData.Packages
##############################################
# Applies to all nodes
##############################################
Node $AllNodes.NodeName {
# Create C:ProgramDataSoftwarePackages to download files to on all nodes
File SoftwarePackagesDirectory {
DestinationPath = "C:ProgramDataSoftwarePackages"
Type = "Directory" # Is a directory
Ensure = "Present" # Ensure that it exists
}
# Start dynamically generating DSC configuration by running through all the package names in Node.Packages
Foreach($PackageName in $Node.Packages){
$Package = $Packages.Where{$_.Name -eq $PackageName}
xRemoteFile "PackageDownload-$($Package.Name)" {
DependsOn = "[File]SoftwarePackagesDirectory"
DestinationPath = "C:SoftwarePackages$($Package.FileName)"
Uri = "http://web.contso.com/packages/$($Package.FileName)"
}
xMsiPackage "Install$($Package.Name)" {
DependsOn = "[xRemoteFile]PackageDownload-$($Package.Name)"
ProductId = $Package.ProductId
Path = "C:ProgramDataSoftwarePackages$($Package.FileName)"
Ensure = $Package.Ensure
}
}
}
}
If you run this, the DSC function generates a MOF file for each of your servers that can be used to install the packages you defined in the ConfigurationData.psd1 proceedings:
PS51> MyDSCConfiguration -ConfigurationData .ConfigurationData.psd1
Directory: C:TutorialsDSCMyDSCConfiguration
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019-10-28 17:25 3962 fileserver-1.mof
-a---- 2019-10-28 17:25 6012 database-1.mof
-a---- 2019-10-28 17:25 5894 appserver-1.mof
# Applies the configuration to the servers
PS51> Start-DscConfiguration -Path .MyDSCConfiguration -Wait
If you want to add new packages, modify your ConfigurationData.psd1 file and run the above code one more time.
conclusion
Getting started with DSC can be quite a short and steep learning curve. But the hardest part for many is finding use cases where they can use it.
Using the above method that uses HTTP (o HTTPS) to search for packages gives you a versatile way to deliver software to your servers. And because it is HTTPS, plus it's easier to expose and you can use it to manage software on DMZ and other less reliable networks.
At the same time, using setup data instead of hard-coding everything in your DSC setups gives you a much easier approach to maintain. You can even generate this configuration data from external sources like CSV, SQL, Sharepoint and everything else that can be read with PowerShell.
I hope you have some ideas for your environment to start making your daily tasks with DSC easier..