
Zarządzanie coraz większą ilością zasobów IT jest trudnym zadaniem, a zapobieganie tak zwanemu dryfu konfiguracji bez kompleksowego rozwiązania robi się wręcz niemożliwe. Dlatego coraz częściej spoglądamy w kierunku narzędzi typu Configuration Manager takich jak Chef, Ansible, Puppet czy PowerShell Desired State Configuration (DSC).
Niestety nigdy nie wcześniej nie poświęciłem wystarczająco dużo czasu na poznanie tego ostatniego rozwiązania. Zmieniło się, to wraz z przygotowaniami do egzaminu AZ-400, gdzie odkryłem PowerShell DSC na nowo.
Zapraszam do pierwszego wpisu omawiającego podstawowe kwestie PowerShell Desired State Configuration.
Co to Desired State Configuration?
Desired State Configuration to platforma, która zapewnia deklaratywne (nieważne jak, ważne co) i idempotentne (powtarzalne) wdrożanie i utrzymanie zgodność konfiguracji. Wszystko to z pudełka w systemach w system Windows.
Za analizowanie i wdrażanie konfiguracji DSC w systemie odpowiedzialny jest Local Configuration Manager. LCM działa na każdym docelowym hoście i pełni rolę silnika, który akceptuję plik tekstowe w formacie Managed Object Format (MOF). To one zawierają instrukcję o oczekiwanej konfiguracji.
Pliki MOF do LCM mogą trafiać na dwa sposoby. Pierwszy to tryb Push, gdzie samodzielnie wypychamy konfigurację do docelowych hostów.

Drugi to tryb Pull, gdzie następuje cykliczne sprawdzanie, pobieranie i przetwarzanie plików MOF przez serwery.

Jeśli interesuje Cię szczegółowe informację o działaniu DSC, to odsyłam do dokumentacji lub książki, która wpełni pokrywa ten temat.
PowerShell Desired State Configuration
Nasuwa się pytanie, gdzie w tym wszystkim PowerShell?
Tak naprawdę to jeden z elementów układanki, ale bardzo ułatwiający pracę z Desired State Configuration. Konkretnie wykorzystasz go do przygotowywania dokumentów konfiguracji, które ostatecznie i tak trafią na hosty w formacie MOF.
Pierwszy PowerShell DSC
Do Desired State Configuration w PowerShell używamy specjalnego typu funkcji, gdzie słowem kluczowym jest Configuration i zaraz po nim nadajemy nazwę naszej konfiguracji.
W bloku Configuration możesz wykorzystywać znane Ci elementy z normalnych funkcji PowerShell. Nic nie stoi na przeszkodzie aby zdefiniować blok z parametrami lub wykorzystać elementy Requires (w następnym wpisie pokaże Ci do czego je wykorzystuję).
Configuration FirstDsc { param( [Parameter(Mandatory)] [string[]]$ComputerName ) }
W bloku takiej funkcji musi się znaleźć co najmniej jeden blok Node, który wskazuje, dla jakich hostów przeznaczona jest konfiguracja. Blok Node może akceptować wiele nazw komputerów, które możesz przekazać np. poprzez parametr.
Configuration FirstDsc { param( [Parameter(Mandatory)] $ComputerName ) # bez parametru, na szytwno nazwy serwerów # Node IT-MN-M { Node $ComputerName { } }
Kolejny element to definiowanie żądanej konfiguracji przy wykorzystaniu zasobów DSC (Resource DSC). Ich ilość oraz rodzaj będzie oczywiście podyktowana złożonością konfiguracji.
Każdy zasób ma inną składnię i wymagane właściwości. Jak sprawdzić, znajdziesz poniżej, teraz zobacz przykładowe użycie zasóbu WindowsFeature, do instalacji usługi IIS na serwerze.
Configuration FirstDsc { param( [Parameter(Mandatory)] $ComputerName ) # bez parametru # Node IT-MN -M { Node $ComputerName { WindowsFeature WebServer { Ensure = "Present" Name = "Web-Server" } } }
Tak przygotowaną konfigurację moglibyśmy już przekonwertować i wysłać Local Configuration Manager, aby została wdrożona na docelowy host, jednak przed tym kilka ważnych słów (choć wyszło kilkanaście) o zasobach DSC.
DSC Resource (zasoby DSC)
Zasoby DSC dostarczają instrukcje do LCM o tym, jak pobierać, sprawdzać oraz wdrażać zdefiniowane konfigurację. Każdy z zasobów DSC posiada metody umożliwiające wykonanie każdej z tych operacji.
Całość najlepiej zobrazować na zasobie Script, (umożliwia nam wykonanie dowolnego skryptu PowerShell), który wymaga zdefiniowania odpowiednich bloków skryptu odpowiadającym metodą Get, Test i Set.
# przyklad wyjasniajacy metody Get, Test i Set w DSC Configuration Script { Node localhost { Script Version { # it must be a hashtable containing a Result key whose value is a String. GetScript = { $Version = Get-Content C:\Temp\Version.ini Write-Output @{ 'Result' = $Version } } TestScript = { $Version = Get-Content C:\Temp\Version.ini -ErrorAction SilentlyContinue if ($Version -ne '7.1.0') { return $false } return $true } SetScript = { "7.1.0" | Set-Content -Path C:\Temp\Version.ini -Force } } } }
🔍 Get – pobiera stan zasobu, jaki został skonfigurowany na docelowym węźle. Poleceniem Get-DscConfiguration możesz wymusić wykonanie tej metody dla każdego zasobu zastosowanego na hoście.
# gdy konfiguracja jest już wdrożona Get-DscConfiguration # ResourceId : [Script]Version # SourceInfo : # Credential : # GetScript : # Result : 7.1.0 # SetScript : # TestScript : # Credential : # GetScript : # Result : 7.1.0 # SetScript : # TestScript : # PSComputerName : # CimClassName : MSFT_ScriptResource
🧪 Test – metoda testuje, czy węzeł docelowy jest obecnie zgodny z żądanym stanem zasobu. Po wywołaniu Test-DscConfiguration, LCM wywoła metodę Test dla każdego zasobu. Jeśli żądany stan jest zgodny z konfiguracją, zobaczymy True.
Test-DscConfiguration -Detailed # PSComputerName ResourcesInDesiredState ResourcesNotInDesiredState InDesiredState # -------------- ----------------------- -------------------------- -------------- # localhost {[Script]Version} True
⚙️ Set – metoda wymuszania zgodności z żądanym stanem zasobu. Polecenie Start-DscConfiguration wykonuję metody TEST i SET. Zmiana konfiguracji następuje tylko wtedy, gdy TEST zwróci wartość False (chyba, że wykorzystamy parametr -Force).
Start-DscConfiguration -Path .\Script\ -Wait -Verbose # VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'. # VERBOSE: An LCM method call arrived from computer IT-MN-M with user sid S-1-5-21-1150076337-2743262687-197554711-1001. # VERBOSE: [IT-MN-M]: LCM: [ Start Set ] # VERBOSE: [IT-MN-M]: LCM: [ Start Resource ] [[Script]Version] # VERBOSE: [IT-MN-M]: LCM: [ Start Test ] [[Script]Version] # VERBOSE: [IT-MN-M]: LCM: [ End Test ] [[Script]Version] in 0.1330 seconds. # VERBOSE: [IT-MN-M]: LCM: [ Start Set ] [[Script]Version] # VERBOSE: [IT-MN-M]: [[Script]Version] Performing the operation "Set-TargetResource" on target "Executing the SetScript with the user supplied # credential". # VERBOSE: [IT-MN-M]: LCM: [ End Set ] [[Script]Version] in 0.0840 seconds. # VERBOSE: [IT-MN-M]: LCM: [ End Resource ] [[Script]Version] # VERBOSE: [IT-MN-M]: LCM: [ End Set ] # VERBOSE: [IT-MN-M]: LCM: [ End Set ] in 0.5620 seconds. # VERBOSE: Operation 'Invoke CimMethod' complete. # VERBOSE: Time taken for configuration job to complete is 0.673 seconds # VERBOSE: Time taken for configuration job to complete is 0.272 seconds
Dodawania zasobów DSC
Wbudowanych zasobów w systemie Windows (sprawdź poleceniem Get-DscResource) nie ma za wiele i na pewno nie pozwoli na wszystko czego potrzebujesz.
Jednak liczba zasobów DSC na PowerShell Gallery jest już dużo, dużo większa. Do znalezienia i instalacji wykorzystaj najpierw polecenie Find-DscResource a później Install-Module.
# polecenie posiada parametr -Name, ale nie działa ze znakami wildcard # dlatego lepiej się sprawdzi: Find-DSCResource | Where-Object {$_.Name -like "*Share*"}

Załóżmy, że SmbShare jest zasobem, który potrzebujemy i jest dostępy w module ComputerManagementDsc. W taki przypadku instalujemy taki moduł wykorzystując polecenie:
Install-Module -Name ComputerManagementDsc -Force
💡 Warto zapoznać się z obecną i poprzednią konwencją nazewniczą zasobów DSC. Odsyłam do wpisu lub do dokumentu na GitHub.
⚠️ Jeśli wykorzystujesz zasoby DSC z PowerShell Gallery lub innych źródeł, pamiętaj o tym, że one również muszą się znaleźć na hostach, dla których przygotowujesz konfigurację.
Jak sprawdzić składnie Zasobu DSC?
Wykorzystaj polecenie Get-DscResource z parametrem -Syntax. Tak jak w składni dla cmdletów i funkcji, wszystko, co otoczone nawiasami kwadratowymi []
to elementy opcjonalne.
Get-DscResource SmbShare -Syntax # SmbShare [String] #ResourceName # { # Name = [string] # Path = [string] # [CachingMode = [string]{ BranchCache | Documents | Manual | None | Programs }] # [ChangeAccess = [string[]]] # [ConcurrentUserLimit = [UInt32]] # [ContinuouslyAvailable = [bool]] # [DependsOn = [string[]]] # [Description = [string]] # [EncryptData = [bool]] # [Ensure = [string]{ Absent | Present }] # [FolderEnumerationMode = [string]{ AccessBased | Unrestricted }] # [Force = [bool]] # [FullAccess = [string[]]] # [NoAccess = [string[]]] # [PsDscRunAsCredential = [PSCredential]] # [ReadAccess = [string[]]] # [ScopeName = [string]] # }
Wdrażanie DSC w trybie Push
Jeśli konfiguracja jest gotowa to najwyższy czas ją wdrożyć.
W pierwszym kroku musisz wygenerować dokument konfiguracji MOF. Funkcję Configuration załaduj do pamięci i wykonaj (tak jak standardową funkcję PowerShell), podając parametry (jeśli są wykorzystywane).
Configuration FirstDsc { param( [Parameter(Mandatory)] $ComputerName ) Node $ComputerName { Script Version { # it must be a hashtable containing a Result key whose value is a String. GetScript = { $Version = Get-Content C:\Temp\Version.ini Write-Output @{ 'Result' = $Version } } TestScript = { $Version = Get-Content C:\Temp\Version.ini -ErrorAction SilentlyContinue if ($Version -ne '7.1.0') { return $false } return $true } SetScript = { "7.1.0" | Set-Content -Path C:\Temp\Version.ini -Force } } } } FirstDsc -ComputerName IT-MN-N -OutputPath C:\Temp\Dsc # Directory: C:\Temp\Dsc # Mode LastWriteTime Length Name # ---- ------------ - ------ ---- # -a---- 28.12.2020 17:58 2776 IT-MN-N.mof
Jeśli nie wskażemy lokalizacji parametrem -OutputPath, to plik .mof to zostanie wygenerowany w ścieżce, w której się obecnie znajdujemy.
Tak przygotowany dokument konfiguracji, możemy wdrożyć na zdalny serwer. Parametr -Path musi wskazywać, na folder, gdzie znajduję się plik MOF dla naszego hosta.
Start-DscConfiguration -Path C:\Temp\Dsc -ComputerName IT-MN-M -Wait -Verbose
💡 Warto dodać parametry -Wait oraz -Verbose. Dzięki nim konsola będzie czekać na zakończenie konfiguracji i dodatkowo zobaczysz szczegóły jej wykonywania.
W celu sprawdzenia, czy rzeczywiście konfiguracja na węzłach jest zgodna z żądaną konfiguracją, wykorzystaj polecenie Test-DscConfiguration.
Test-DscConfiguration -ComputerName IT-MN-M -Detailed

Podsumowanie
To pierwszy wpis, gdzie opisałem czym jest Desired State Configuration, jak wykorzystać PowerShell do przygotowywania dokumentu konfiguracji oraz jak go wypchnąć na zdalny serwer.
W następnych wpisach o planuję pokazać Ci jak poradzić sobie z instalacją wymaganych modułów na zdalnych hostach przy trybie Push oraz jak wykorzystać Azure Automation do wdrażania DSC w trybie Pull.
No comments yet.