PowerShell Desired State Configuration

PowerShell DSC ist die Infrastructure as Code Variante von Microsoft mit Hilfe von PowerShell. Dabei werden die Server Konfigurationen wie bei Ansible oder Puppet. Dabei werden die Konfigurationen innerhalb eines Skriptes zusammengefasst und nach dem der Server Installation angewendet. So wird keine Anpassung des Images benötigt (Custom Image) sondern die Konfigurationen können auf jeden Vanilla Image angewandt werden.

Aufgrund der immer komplexer werdenden Konfigurationen von der Servern und Anwendungen hilft PowerShell DSC dabei, den Desired State (also die gewünschte Konfiguration) beizubehalten (Declarative Programming). Sprich: Sobald etwas (oder jemand) die Konfiguration ändert, kann PowerShell DSC diese Änderung bzw. Abweichung vom Desired State erkennen und automatisch beheben.

Minimalbeispiel

#Set-ExecutionPolicy unrestricted -Force
#Enable-PSRemoting -Force
 
 
Configuration WebServer #"Configuration" kann man sich als eine spezielle Funktion vorstellen die man hier erstellt
{
    param
    (
        # Target nodes to apply the configuration
        [string[]]$NodeName = 'localhost'
    )
    Import-DscResource –ModuleName 'PSDesiredStateConfiguration'
 
    Node $NodeName # Möglichkeit einen oder mehrere Server durch eben den NodeName mit der Konfiguration auszustatten
    {
        # Install the IIS role
        WindowsFeature Install-Web-Server # "Install-Web-Server" ist nur eine Name für den Block der ausgeführt wird. Er wird auch beim Debugging oder in Logs angezeigt.
        {
            Ensure          = "Present"
            Name            = "Web-Server"
        }
        WindowsFeature Install-Web-Mgmt-Tools
        {
            Ensure          = "Present"
            Name            = "Web-Mgmt-Tools"
		}
    }
}
 
#Create the MOF
WebServer -NodeName localhost
 
#Apply the configuration
Start-DscConfiguration -Path .\WebServer -Wait -Verbose
 

  1. Kann man sich wie eine Funktion vorstellen
  2. WindowsFeature ist ein DscResource
    1. Mit Hilfe von Get-DscResource kann man sich alle verfügbaren DscResources anzeigen lassen
  3. Name vom DscResource, welcher in Logs und Debugging auftaucht

Separierung von Code und Konfiguration

Durch die Auslagerung von der Konfiguration in eine separate Datei kann ein besserer Überblick behalten werden. Dazu kann mit Hilfe des -ConfigrationData Parameters eine .psd1 Datei übergeben werden, worin die Konfiguration in Form einer HashTable1 definiert ist.
So kann die gleiche Konfiguration von DEV nach TEST bis Prod überführt werden alleinig durch das hinzufügen der Nodes.

Configuration Data

@{
	AllNodes = @(
	    @{
	        NodeName = "DCSSVR1"
	        Enviroment = "TEST"
	     }   
	     @{
	        NodeName = "DCSSVR2"
	        Enviroment = "PROD"
	     }
	)
	
    WindowsFeatures = @(
		@{
	        Name = "Web-Server"
	        Ensure = "Present"
        },
        @{
	        Name = "Web-Mgmt-Tools"
	        Ensure = "Present"
        },
        @{
	        Ensure = "Present"
	        Name = "Web-Asp-Net45"
        }
    )
}
 

Code

Configuration WebServerConfiguration
{  
    Import-DscResource –ModuleName 'PSDesiredStateConfiguration'
	Node $AllNodes.NodeName
	{   
		# Loop through the defined features
	    ForEach($Feature in $Node.WindowsFeatures)
	    {
		      # Define component
			WindowsFeature $Feature.Name
		    {
			    Name = $Feature.Name
		        Ensure = $Feature.Ensure
		    }
	    }
	}
}
 
WebServerConfiguration -ConfigurationData "C:\Users\Administrator\Downloads\DscConfiguration.psd1"
 

Auslagerung in weitere Module

Es besteht die Möglichkeit sich eigene DSC Module zu schreiben und diese dann per Import-DscResource zu importieren und dann zu verwenden. Innerhalb vom dem Modul wird eine weitere Configuration erzeugt.

Beispiel DSC Module

Configuration CreateInstallationFolders {
 
	param
	(
		[String] $InstallPath,
		[String] $UninstallPath
	)
 
Import-DscResource -ModuleName PSDesiredStateConfiguration
 
if($InstallPath) {
	File CreateInstallDir {
		DestinationPath = $InstallPath
		Ensure = 'Present'
		Type = 'Directory'
	}
}
if($UninstallPath) {
	File CreateUninstallDir {
		DestinationPath = $UninstallPath
		Ensure = 'Present'
		Type = 'Directory'
	}
}
 

Aufruf DSC Module

Configuration CreateFolders {
 
	Import-DscResource -ModuleName PSDesiredStateConfiguration
	Import-DscResource -ModuleName CompositeResources #Hinzufügen des eigenen DSC Modules!
 
	Node @('dscsvr1', 'dscsvr2') {
		CreateInstallationFolders InstallationFolders { #CreateInstallationFolders ist die Configuration Funktion des eigenen Modul!
			InstallPath = "C:\ProgramData\Install\"
			UserLogPath = "C:\ProgramData\Uninstall\"
		}
	}
}
 
# Creates a configuration command
Get-Command -CommandType Configuration
 
# Generates 2 MOF files, one for each node
CreateSqlFolder -Output .\Output\
 
## cleanup
# Remove-Item .\output\*.mof
 

References

Footnotes

  1. Die HashTable muss einen AllNodes Key besitzen um akzeptiert zu werden. Siehe Beispiel.