Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Začněte vytvářet prostředek DSC založený na třídě pro správu konfiguračního souboru. Absolvováním tohoto kurzu získáte funkční prostředek DSC založený na třídě v modulu, který můžete použít k dalšímu učení a přizpůsobení.
V tomto kurzu se naučíte:
- Generování modulu prostředků DSC
- Přidání prostředku DSC založeného na třídě
- Definování vlastností prostředku DSC
- Implementace metod prostředků DSC
- Export prostředku DSC v manifestu modulu
- Ruční testování prostředku DSC
Poznámka
Ukázkový výstup v tomto kurzu odpovídá PowerShellu 7.2 na počítači s Windows. Kurz platí pro Windows PowerShell a PowerShell na počítači s Linuxem nebo macOS. Pouze výstup je specifický pro spouštění příkazů v PowerShellu na počítači s Windows.
Požadavky
- PowerShell nebo Windows PowerShell 5.1
- VS Code s rozšířením PowerShellu
1. Generování modulu prostředků DSC
Prostředky DSC musí být definované v modulu PowerShellu.
Vytvoření složky modulu
Vytvořte novou složku s názvem ExampleResources. Tato složka se používá jako kořenová složka modulu a veškerý kód v tomto kurzu.
New-Item -Path './ExampleResources' -ItemType Directory
Directory: C:\code\dsc
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 9/8/2022 12:54 PM ExampleResources
Vytvoření modulu pomocí VS Code
Otevřete složku v editoru ExampleResources VS Code. Otevřete integrovaný terminál v nástroji VS Code. Ujistěte se, že na terminálu běží PowerShell nebo Windows PowerShell.
Důležité
Ve zbývající části tohoto kurzu spusťte zadané příkazy v integrovaném terminálu v kořenové složce modulu. Toto je výchozí pracovní adresář v editoru VS Code.
Vytvoření souborů modulu
Vytvořte manifest modulu pomocí rutiny New-ModuleManifest . Použijte ./ExampleResources.psd1 jako cestu. Zadejte RootModule jako ExampleResources.psm1 a DscResourcesToExport jako Tailspin.
$ModuleSettings = @{
RootModule = 'ExampleResources.psm1'
DscResourcesToExport = 'Tailspin'
}
New-ModuleManifest -Path ./ExampleResources.psd1 @ModuleSettings
Get-Module -ListAvailable -Name ./ExampleResources.psd1 | Format-List
Name : ExampleResources
Path : C:\code\dsc\ExampleResources\ExampleResources.psd1
Description :
ModuleType : Script
Version : 0.0.1
PreRelease :
NestedModules : {}
ExportedFunctions :
ExportedCmdlets :
ExportedVariables :
ExportedAliases :
Vytvořte soubor kořenového modulu jako ExampleResources.psm1.
New-Item -Path ./ExampleResources.psm1
Directory: C:\code\dsc\ExampleResources
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 9/8/2022 1:57 PM 0 ExampleResources.psm1
Vytvořte soubor skriptu s názvem Helpers.ps1.
New-Item -Path ./Helpers.ps1
Directory: C:\code\dsc\ExampleResources
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 9/8/2022 1:58 PM 0 Helpers.ps1
Otevřete Helpers.ps1 v editoru VS Code. Přidejte následující řádek a nahraďte <Separator>; za , pokud používáte Windows a : pokud používáte Linux nebo macOS.
$env:PSModulePath += "<Separator>$pwd"
Otevřete ExampleResources.psm1 v editoru VS Code. Modul je teď vygenerovaný a připravený k vytvoření prostředku DSC.
2. Přidání prostředku DSC založeného na třídě
K definování prostředku DSC založeného na třídě zapíšeme třídu PowerShellu do souboru modulu a přidáme do ní atribut DscResource .
Definování třídy
Do ExampleResources.psm1souboru přidejte následující kód:
[DscResource()]
class Tailspin {
}
Tento kód přidá Tailspin jako prostředek DSC založený na třídě do modulu ExampleResources .
Nastavte ukazatel myši na [DscResource()] a přečtěte si upozornění.
Když najedete myší na atribut DSCResource, zobrazí se čtyři upozornění. 1. Prostředku DSC Tailspin chybí metoda Set(), která vrací [void] a nepřijímá žádné parametry. 2. Prostředku DSC Tailspin chybí metoda Get(), která vrací [Tailspin] a nepřijímá žádné parametry. 3. Prostředku DSC Tailspin chybí metoda Test(), která vrací [bool] a nepřijímá žádné parametry. 4. Prostředek DSC Tailspin musí mít aspoň jednu vlastnost klíče (pomocí syntaxe [DscProperty(Klíč)]).)
Tato upozornění uvádějí požadavky na to, aby třída byla platným prostředkem DSC.
Minimální implementace požadovaných metod
Přidejte do třídy minimální implementaci Get()metod , Test()a Set() .
class Tailspin {
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
return $CurrentState
}
[bool] Test() {
return $true
}
[void] Set() {}
}
S přidanými metodami atribut DscResource pouze upozorní na třídu, která nemá vlastnost Key .
3. Definování vlastností prostředku DSC
Před metodami byste měli definovat vlastnosti prostředku DSC. Vlastnosti definují spravovatelná nastavení prostředku DSC. Používají se v metodách.
Vysvětlení aplikace TSToy
Než budete moct definovat vlastnosti prostředku DSC, musíte pochopit, jaká nastavení chcete spravovat.
Pro účely tohoto kurzu definujeme prostředek DSC pro správu nastavení fiktivní aplikace TSToy prostřednictvím jejího konfiguračního souboru. TSToy je aplikace, která má konfiguraci na úrovni uživatele a počítače. Prostředek DSC by měl být schopný nakonfigurovat oba soubory.
Prostředek DSC by měl uživatelům umožnit konfiguraci:
- Rozsah konfigurace, kterou spravuje, buď
Machine, neboUser - Jestli má konfigurační soubor existovat
- Jestli se má TSToy aktualizovat automaticky
- Jak často by měl TSToy kontrolovat aktualizace, mezi 1 a 90 dny
Přidání vlastnosti ConfigurationScope
Pokud chcete spravovat Machine konfigurační soubor nebo User , musíte definovat vlastnost prostředku DSC. Pokud chcete definovat $ConfigurationScope vlastnost v prostředku, přidejte do třídy před metody následující kód:
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
Tento kód definuje $ConfigurationScope jako vlastnost Key prostředku DSC. Vlastnost Key slouží k jednoznačné identifikaci instance prostředku DSC. Přidání této vlastnosti splňuje jeden z požadavků atributu DscResource , na který upozorňoval při generování třídy.
Také určuje, že $ConfigurationScopetyp je TailspinScope. Chcete-li definovat typ TailspinScope , přidejte následující výčet TailspinScope za definici třídy v ExampleResources.psm1:
enum TailspinScope {
Machine
User
}
Tento výčet vytvoří MachineUser a jediné platné hodnoty pro $ConfigurationScope vlastnost prostředku DSC.
Přidání vlastnosti Ensure
Osvědčeným postupem je definovat $Ensure vlastnost, která určuje, jestli existuje instance prostředku DSC. Vlastnost $Ensure má obvykle dvě platné hodnoty, Absent a Present.
- Pokud
$Ensureje zadaný jakoPresent, prostředek DSC vytvoří položku, pokud neexistuje. - Pokud
$EnsurejeAbsent, prostředek DSC odstraní položku, pokud existuje.
Pro prostředek Tailspin DSC je položka, která se má vytvořit nebo odstranit, konfigurační soubor pro zadaný $ConfigurationScope.
Definovat TailspinEnsure jako výčet za TailspinScope. Měl by mít hodnoty Absent a Present.
enum TailspinEnsure {
Absent
Present
}
Dále přidejte $Ensure vlastnost ve třídě za $ConfigurationScope vlastnost . Měl by mít prázdný atribut DscProperty a jeho typ by měl být TailspinEnsure. Výchozí hodnota by měla být Present.
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
Přidání vlastnosti UpdateAutomatically
Pokud chcete spravovat automatické aktualizace, definujte $UpdateAutomatically vlastnost ve třídě za $Ensure vlastností . Jeho atribut DscProperty by měl označovat, že je povinný, a jeho typ by měl být logický.
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
Přidání vlastnosti UpdateFrequency
Pokud chcete spravovat, jak často má TSToy kontrolovat aktualizace, přidejte $UpdateFrequency za $UpdateAutomatically vlastnost vlastnost do třídy . Měl by mít prázdný atribut DscProperty a jeho typ by měl být int. Pomocí atributu ValidateRange omezte platné hodnoty pro $UpdateFrequency na 1 až 90.
[DscProperty()] [int] [ValidateRange(1, 90)]
$UpdateFrequency
Přidání skrytých vlastností mezipaměti
Dále přidejte dvě skryté vlastnosti pro ukládání aktuálního stavu prostředku do mezipaměti: $CachedCurrentState a $CachedData. Nastavte typ $CachedCurrentState na Tailspin, stejně jako třída a návratový typ pro metodu Get() . Nastavte typ psCustomObject$CachedData. Předpona obou vlastností klíčovým slovem hidden . Nezadávejte atribut DscProperty .
hidden [Tailspin] $CachedCurrentState
hidden [PSCustomObject] $CachedData
Tyto skryté vlastnosti se použijí v Get() metodách a Set() , které definujete později.
Kontrola souboru modulu
V tomto okamžiku ExampleResources.psm1 by měl definovat:
- Třída Tailspin s vlastnostmi
$ConfigurationScope,$Ensure,$UpdateAutomaticallya$UpdateFrequency - Výčet TailspinScope s hodnotami
MachineaUser -
TailspinEnsure výčet s hodnotami
PresentaAbsent - Minimální implementace
Get()metod ,Test()aSet().
[DscResource()]
class Tailspin {
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
[DscProperty()] [int] [ValidateRange(1,90)]
$UpdateFrequency
hidden [Tailspin] $CachedCurrentState
hidden [PSCustomObject] $CachedData
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
return $CurrentState
}
[bool] Test() {
$InDesiredState = $true
return $InDesiredState
}
[void] Set() {}
}
enum TailspinScope {
Machine
User
}
enum TailspinEnsure {
Absent
Present
}
Teď, když prostředek DSC splňuje požadavky, můžete ho zobrazit pomocí Get-DscResource nástroje . Ve VS Code otevřete nový terminál PowerShellu.
. ./Helpers.ps1
Get-DscResource -Name Tailspin -Module ExampleResources | Format-List
Get-DscResource -Name Tailspin -Module ExampleResources -Syntax
ImplementationDetail : ClassBased
ResourceType : Tailspin
Name : Tailspin
FriendlyName :
Module : ExampleResources
ModuleName : ExampleResources
Version : 0.0.1
Path : C:\code\dsc\ExampleResources\ExampleResources.psd1
ParentPath : C:\code\dsc\ExampleResources
ImplementedAs : PowerShell
CompanyName : Unknown
Properties : {ConfigurationScope, UpdateAutomatically, DependsOn, Ensure…}
Tailspin [String] #ResourceName
{
ConfigurationScope = [string]{ Machine | User }
UpdateAutomatically = [bool]
[DependsOn = [string[]]]
[Ensure = [string]{ Absent | Present }]
[PsDscRunAsCredential = [PSCredential]]
[UpdateFrequency = [Int32]]
}
4. Implementace metod prostředků DSC
Metody prostředku DSC definují, jak načíst aktuální stav prostředku DSC, ověřit ho proti požadovanému stavu a vynutit požadovaný stav.
Metoda Get
Metoda Get() načte aktuální stav prostředku DSC. Používá se k ruční kontrole prostředku DSC a volá se metodou Test() .
Metoda Get() nemá žádné parametry a jako výstup vrátí instanci třídy.
Tailspin Minimální implementace prostředku DSC vypadá takto:
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
return $CurrentState
}
Jediná věc, kterou tato implementace dělá, je vytvořit instanci tailspin třídy a vrátit ji. Můžete volat metodu s Invoke-DscResource , abyste viděli toto chování.
Invoke-DscResource -Name Tailspin -Module ExampleResources -Method Get -Property @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
Machine Present False 0
Všechny vlastnosti vráceného objektu jsou nastaveny na výchozí hodnotu. Hodnota $ConfigurationScope by vždy měla být hodnota, kterou uživatel zadal. Aby byla Get() metoda užitečná, musí vrátit skutečný stav prostředku DSC.
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
$CurrentState.ConfigurationScope = $this.ConfigurationScope
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
Proměnná $this odkazuje na pracovní instanci prostředku DSC. Teď, pokud použijete Invoke-DscResource znovu, $ConfigurationScope má správnou hodnotu.
Invoke-DscResource -Name Tailspin -Module ExampleResources -Method Get -Property @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present False 0
Dále musí prostředek DSC určit, jestli konfigurační soubor existuje. Pokud ano, $Ensure měl by být Present. Pokud tomu tak není, $Ensure měl by být Absent.
Umístění konfiguračních souborů TSToy závisí na operačním systému a oboru konfigurace:
- Počítače s Windows:
- Konfigurační
Machinesoubor je%PROGRAMDATA%\TailSpinToys\tstoy\tstoy.config.json - Konfigurační
Usersoubor je%APPDATA%\TailSpinToys\tstoy\tstoy.config.json
- Konfigurační
- Počítače s Linuxem:
- Konfigurační
Machinesoubor je/etc/xdg/TailSpinToys/tstoy/tstoy.config.json - Konfigurační
Usersoubor je~/.config/TailSpinToys/tstoy/tstoy.config.json
- Konfigurační
- Počítače s macOS:
- Konfigurační
Machinesoubor je/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json - Konfigurační
Usersoubor je~/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json
- Konfigurační
Pokud chcete tyto cesty zpracovat, musíte vytvořit pomocnou metodu GetConfigurationFile().
[string] GetConfigurationFile() {
$FilePaths = @{
Linux = @{
Machine = '/etc/xdg/TailSpinToys/tstoy/tstoy.config.json'
User = '~/.config/TailSpinToys/tstoy/tstoy.config.json'
}
MacOS = @{
Machine = '/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json'
User = '~/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json'
}
Windows = @{
Machine = "$env:ProgramData\TailSpinToys\tstoy\tstoy.config.json"
User = "$env:APPDATA\TailSpinToys\tstoy\tstoy.config.json"
}
}
$Scope = $this.ConfigurationScope.ToString()
if ($Global:PSVersionTable.PSVersion.Major -lt 6 -or $Global:IsWindows) {
return $FilePaths.Windows.$Scope
} elseif ($Global:IsLinux) {
return $FilePaths.Linux.$Scope
} else {
return $FilePaths.MacOS.$Scope
}
}
Chcete-li otestovat tuto novou metodu using , spusťte příkaz pro načtení tříd a výčtů modulu ExampleResources do aktuální relace.
using module ./ExampleResources.psd1
$Example = [Tailspin]::new()
$Example
$Example.GetConfigurationFile()
$Example.ConfigurationScope = 'User'
$Example.GetConfigurationFile()
Ensure ConfigurationScope UpdateAutomatically UpdateFrequency
------- ------------------ ------------------- ---------------
Present Machine False 0
C:\ProgramData\TailSpinToys\tstoy\tstoy.config.json
C:\Users\mikey\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json
Otevřete Helpers.ps1 v editoru VS Code. Zkopírujte a vložte cesty ke konfiguračním souborům do skriptu a přiřaďte je k $TSToyMachinePath a $TSToyUserPath. Soubor by měl vypadat takto:
$env:PSModulePath += "<separator>$pwd"
$TSToyMachinePath = '<machine configuration file path>'
$TSToyUserPath = '<user configuration file path>'
Ukončete terminál ve VS Code a otevřete nový terminál. Dot-source Helpers.ps1.
. ./Helpers.ps1
Teď můžete napsat zbytek Get() metody.
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
$CurrentState.ConfigurationScope = $this.ConfigurationScope
$FilePath = $this.GetConfigurationFile()
if (!(Test-Path -Path $FilePath)) {
$CurrentState.Ensure = [TailspinEnsure]::Absent
return $CurrentState
}
$Data = Get-Content -Raw -Path $FilePath |
ConvertFrom-Json -ErrorAction Stop
$this.CachedData = $Data
if ($null -ne $Data.Updates.Automatic) {
$CurrentState.UpdateAutomatically = $Data.Updates.Automatic
}
if ($null -ne $Data.Updates.CheckFrequency) {
$CurrentState.UpdateFrequency = $Data.Updates.CheckFrequency
}
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
Po nastavení $ConfigurationScope a určení cesty konfiguračního souboru metoda zkontroluje, jestli soubor existuje. Pokud neexistuje, stačí nastavit $EnsureAbsent a vrátit výsledek.
Pokud soubor existuje, musí metoda převést obsah z JSON, aby se vytvořil aktuální stav konfigurace. Dále metoda zkontroluje, jestli klíče mají nějakou hodnotu, než je přiřadí k vlastnostem aktuálního stavu. Pokud nejsou zadané, musí je prostředek DSC považovat za nenastavený a ve výchozím stavu.
V tomto okamžiku prostředek DSC ukládá data do mezipaměti. Ukládání dat do mezipaměti umožňuje kontrolovat data během vývoje a bude užitečné při implementaci Set() metody.
Toto chování můžete ověřit místně.
$GetParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Method = 'Get'
Property = @{
ConfigurationScope = 'User'
}
}
Invoke-DscResource @GetParameters
New-Item -Path $UserPath -Force
Invoke-DscResource @GetParameters
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Absent False 0
Directory: C:\Users\mikey\AppData\Roaming\TailSpinToys\tstoy
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 9/15/2022 3:43 PM 0 tstoy.config.json
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present False 0
Otevřete konfigurační soubor oboru v nástroji User VS Code.
code $UserPath
Zkopírujte tuto konfiguraci JSON do souboru a uložte ji.
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
Zavolejte Invoke-DscResource znovu a podívejte se na hodnoty, které se projeví ve výsledcích.
Invoke-DscResource @GetParameters
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
Metoda Get() teď vrací přesné informace o aktuálním stavu prostředku DSC.
Metoda Test
S implementovanou metodou Get() můžete ověřit, jestli aktuální stav vyhovuje požadovanému stavu.
Minimální Test() implementace metod vždy vrátí $true.
[bool] Test() {
return $true
}
To můžete ověřit spuštěním příkazu Invoke-DscResource.
$SharedParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $false
}
}
Invoke-DscResource -Method Get @SharedParameters
Invoke-DscResource -Method Test @SharedParameters
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
InDesiredState
--------------
True
Je potřeba, aby metoda přesně odrážela Test() , jestli je prostředek DSC v požadovaném stavu. Metoda Test() by měla vždy volat metodu Get() , aby měla aktuální stav pro porovnání s požadovaným stavem. Pak zkontrolujte, jestli $Ensure je vlastnost správná. Pokud není, vraťte se $false okamžitě. Pokud $Ensure je vlastnost mimo požadovaný stav, nevyžadují se žádné další kontroly.
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
return $true
}
Teď můžete ověřit aktualizované chování.
$TestParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $false
Ensure = 'Absent'
}
}
Invoke-DscResource -Method Test @TestParameters
$TestParameters.Property.Ensure = 'Present'
Invoke-DscResource -Method Test @TestParameters
InDesiredState
--------------
False
InDesiredState
--------------
True
Dále zkontrolujte, jestli je Absenthodnota $Ensure . Pokud konfigurační soubor neexistuje a neměl by existovat, není důvod kontrolovat zbývající vlastnosti.
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $true
}
return $true
}
Dále musí metoda porovnat aktuální stav vlastností, které spravují chování aktualizace TSToy. Nejprve zkontrolujte, jestli $UpdateAutomatically je vlastnost ve správném stavu. Pokud není, vraťte $false.
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $true
}
if ($CurrentState.UpdateAutomatically -ne $this.UpdateAutomatically) {
return $false
}
return $true
}
Abychom mohli porovnat $UpdateFrequency, musíme zjistit, jestli uživatel zadal hodnotu. Protože $UpdateFrequency je inicializován do 0 a atribut ValidateRange vlastnosti určuje, že musí být mezi 1 a 90, víme, že hodnota 0 indikuje, že vlastnost nebyla zadána.
S použitím této informace Test() by metoda měla:
- Vrácení
$true, pokud uživatel nezadal$UpdateFrequency - Vrátit
$false, pokud uživatel zadal$UpdateFrequencya hodnota systému se nerovná hodnotě zadané uživatelem. - Vrácení
$true, pokud nebyla splněna žádná z předchozích podmínek
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $true
}
if ($CurrentState.UpdateAutomatically -ne $this.UpdateAutomatically) {
return $false
}
if ($this.UpdateFrequency -eq 0) {
return $true
}
if ($CurrentState.UpdateFrequency -ne $this.UpdateFrequency) {
return $false
}
return $true
}
Teď metoda Test() používá následující pořadí operací:
- Načtěte aktuální stav konfigurace TSToy.
- Vraťte
$falsese, pokud konfigurace existuje, když by neměla nebo neexistuje, když by měla. - Vraťte
$truese, pokud konfigurace neexistuje a neměla by existovat. - Vraťte
$falsese, pokud nastavení automatické aktualizace konfigurace neodpovídá požadovanému. - Vraťte
$truese, pokud uživatel nezadal hodnotu pro nastavení četnosti aktualizací. - Pokud zadaná hodnota uživatele pro nastavení četnosti aktualizací neodpovídá nastavení konfigurace, vraťte se
$falsezpět. - Vrácení
$true, pokud nebyla splněna žádná z předchozích podmínek.
Metodu Test() můžete ověřit místně:
$SharedParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
Ensure = 'Present'
UpdateAutomatically = $false
}
}
Invoke-DscResource -Method Get @SharedParameters
Invoke-DscResource -Method Test @SharedParameters
$SharedParameters.Property.UpdateAutomatically = $true
Invoke-DscResource -Method Test @SharedParameters
$SharedParameters.Property.UpdateFrequency = 1
Invoke-DscResource -Method Test @SharedParameters
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
InDesiredState
--------------
False
InDesiredState
--------------
True
InDesiredState
--------------
False
S tímto kódem Test() je metoda schopna přesně určit, zda je konfigurační soubor v požadovaném stavu.
Metoda Set
Teď, když Get() metody a Test() spolehlivě fungují, můžete definovat metodu Set() , která skutečně vynucuje požadovaný stav.
V minimální implementaci Set() metoda nedělá nic.
[void] Set() {}
Nejprve je potřeba určit, Set() jestli je potřeba prostředek DSC vytvořit, aktualizovat nebo odstranit.
[void] Set() {
if ($this.Test()) {
return
}
$CurrentState = $this.CachedCurrentState
$IsAbsent = $CurrentState.Ensure -eq [TailspinEnsure]::Absent
$ShouldBeAbsent = $this.Ensure -eq [TailspinEnsure]::Absent
if ($IsAbsent) {
# Create
} elseif ($ShouldBeAbsent) {
# Remove
} else {
# Update
}
}
Set() nejprve zavolá metodu, Test() aby se zjistilo, jestli je skutečně potřeba něco udělat. Některé nástroje, jako je funkce konfigurace počítače Azure Automanage, zajišťují, že Set() se metoda volá pouze po Test() metodě. Pokud ale použijete rutinu Invoke-DscResource , neexistuje žádná taková záruka.
Vzhledem k tomu, že Test() metoda volá Get(), který ukládá aktuální stav do mezipaměti, může prostředek DSC přistupovat k aktuálnímu stavu uloženému v mezipaměti bez nutnosti znovu volat metodu Get() .
Dále musí prostředek DSC rozlišovat chování při vytváření, odebrání a aktualizaci konfiguračního souboru. Pokud konfigurační soubor neexistuje, víme, že by se měl vytvořit. Pokud konfigurační soubor existuje a neměl by, víme, že je potřeba ho odebrat. Pokud konfigurační soubor existuje a měl by existovat, víme, že je potřeba ho aktualizovat.
Vytvořte tři nové metody pro zpracování těchto operací a podle potřeby je volejte v Set() metodě.
Návratový typ pro všechny tři by měl být neplatný.
[void] Set() {
if ($this.Test()) {
return
}
$CurrentState = $this.CachedCurrentState
$IsAbsent = $CurrentState.Ensure -eq [TailspinEnsure]::Absent
$ShouldBeAbsent = $this.Ensure -eq [TailspinEnsure]::Absent
if ($IsAbsent) {
$this.Create()
} elseif ($ShouldBeAbsent) {
$this.Remove()
} else {
$this.Update()
}
}
[void] Create() {}
[void] Remove() {}
[void] Update() {}
Vytvořte také novou metodu s názvem ToConfigJson(). Jeho návratovým typem by měl být řetězec. Tato metoda převede prostředek DSC na JSON, který konfigurační soubor očekává. Můžete začít s následující minimální implementací:
[string] ToConfigJson() {
$config = @{}
return ($config | ConvertTo-Json)
}
Metoda ToConfigJson
Minimální implementace vrátí prázdný objekt JSON jako řetězec. Aby byl užitečný, musí vrátit skutečnou reprezentaci nastavení ve formátu JSON v konfiguračním souboru TSToy.
Nejprve předem naplňte $config hashtable nastavením povinných automatických aktualizací přidáním updates klíče s jeho hodnotou jako hashtable. Hodnota hashtable by měla mít automatic klíč. Přiřaďte klíči hodnotu vlastnosti automatic třídy$UpdateAutomatically.
[string] ToConfigJson() {
$config = @{
updates = @{
automatic = $this.UpdateAutomatically
}
}
return ($config | ConvertTo-Json)
}
Tento kód přeloží reprezentaci prostředků DSC nastavení TSToy na strukturu, kterou očekává konfigurační soubor TSToy.
Dále musí metoda zkontrolovat, jestli třída neuchovala data z existujícího konfiguračního souboru. Data uložená v mezipaměti umožňují prostředku DSC spravovat definovaná nastavení bez přepsání nebo odebrání nespravovaných nastavení.
[string] ToConfigJson() {
$config = @{
updates = @{
automatic = $this.UpdateAutomatically
}
}
if ($this.CachedData) {
# Copy unmanaged settings without changing the cached values
$this.CachedData |
Get-Member -MemberType NoteProperty |
Where-Object -Property Name -NE -Value 'updates' |
ForEach-Object -Process {
$setting = $_.Name
$config.$setting = $this.CachedData.$setting
}
# Add the checkFrequency to the hashtable if it is set in the cache
if ($frequency = $this.CachedData.updates.checkFrequency) {
$config.updates.checkFrequency = $frequency
}
}
# If the user specified an UpdateFrequency, use that value
if ($this.UpdateFrequency -ne 0) {
$config.updates.checkFrequency = $this.UpdateFrequency
}
return ($config | ConvertTo-Json)
}
Pokud třída uloží nastavení do mezipaměti z existující konfigurace, bude:
Zkontroluje vlastnosti dat uložených v mezipaměti a vyhledá všechny vlastnosti, které prostředek DSC nespravuje. Pokud nějakou najde, metoda vloží tyto nespravované vlastnosti do
$confighashtable.Vzhledem k tomu, že prostředek DSC spravuje pouze nastavení aktualizace, vloží se každé nastavení s výjimkou
updates.Zkontroluje, jestli
checkFrequencyje nastavení vupdatessouboru nastavené. Pokud je nastavená, metoda vloží tuto hodnotu do$confighashtable.Tato operace umožňuje prostředku DSC ignorovat
$UpdateFrequencyvlastnost, pokud ji uživatel nezadá.Nakonec musí metoda zkontrolovat, jestli uživatel zadal
$UpdateFrequencyvlastnost, a pokud ano, vložte ji do$confighashtable.
S tímto kódem metoda ToConfigJson() :
- Vrátí přesnou reprezentaci požadovaného stavu ve formátu JSON, který aplikace TSToy očekává v konfiguračním souboru.
- Respektuje jakékoli nastavení TSToy, které prostředek DSC explicitně nespravuje.
- Respektuje existující hodnotu četnosti aktualizací TSToy, pokud ji uživatel nezadal, včetně toho, že je nedefinovaná v konfiguračním souboru.
Pokud chcete otestovat tuto novou metodu, zavřete terminál VS Code a otevřete nový. Spuštěním using příkazu načtěte třídy modulu ExampleResources a výčty do aktuální relace a dot-source helpers.ps1 skriptu.
using module ./ExampleResources.psd1
. ./Helpers.ps1
$Example = [Tailspin]::new()
Get-Content -Path $UserPath
$Example.ConfigurationScope = 'User'
$Example.ToConfigJson()
Před zavolání Get() metody je jedinou hodnotou ve výstupu ToJsonConfig metoda převedená hodnota vlastnosti $UpdateAutomatically .
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
{
"updates": {
"automatic": false
}
}
$Example.Get()
$Example.ToConfigJson()
Po volání Get()obsahuje výstup nespravovaný klíč unmanaged_keynejvyšší úrovně . Obsahuje také existující nastavení v konfiguračním souboru pro $UpdateFrequency , protože nebylo explicitně nastaveno u prostředku DSC.
Ensure ConfigurationScope UpdateAutomatically UpdateFrequency
------ ------------------ ------------------- ---------------
Present User True 30
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": false
}
}
$Example.UpdateFrequency = 7
$Example.ToConfigJson()
Po $UpdateFrequency nastavení se ve výstupu zobrazí zadaná hodnota.
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 7,
"automatic": false
}
}
Metoda Create
Abychom mohli implementovat metodu Create() , musíme převést uživatelem zadané vlastnosti prostředku DSC na JSON, který TSToy očekává v konfiguračním souboru, a zapsat je do daného souboru.
[void] Create() {
$ErrorActionPreference = 'Stop'
$Json = $this.ToConfigJson()
$FilePath = $this.GetConfigurationFile()
$FolderPath = Split-Path -Path $FilePath
if (!(Test-Path -Path $FolderPath)) {
New-Item -Path $FolderPath -ItemType Directory -Force
}
Set-Content -Path $FilePath -Value $Json -Encoding utf8 -Force
}
Metoda používá metodu ToConfigJson() k získání KÓDU JSON konfiguračního souboru. Zkontroluje, jestli složka konfiguračního souboru existuje, a v případě potřeby ji vytvoří. Nakonec vytvoří konfigurační soubor a zapíše do něj JSON.
Metoda Remove
Metoda Remove() má nejjednodušší chování. Pokud konfigurační soubor existuje, odstraňte ho.
[void] Remove() {
Remove-Item -Path $this.GetConfigurationFile() -Force -ErrorAction Stop
}
Metoda Update
Implementace Update() metody je podobná metodě Create . Musí převést uživatelem zadané vlastnosti prostředku DSC na JSON, který TSToy očekává v konfiguračním souboru, a nahradit nastavení v daném souboru.
[void] Update() {
$ErrorActionPreference = 'Stop'
$Json = $this.ToConfigJson()
$FilePath = $this.GetConfigurationFile()
Set-Content -Path $FilePath -Value $Json -Encoding utf8 -Force
}
5. Ruční testování prostředku DSC
Když je prostředek DSC plně implementovaný, můžete teď otestovat jeho chování.
Před testováním zavřete terminál VS Code a otevřete nový. Dot-source Helpers.ps1 skript.
Pro každý testovací scénář vytvořte $DesiredState hashtable obsahující sdílené parametry a volejte metody v následujícím pořadí:
-
Get(), pro načtení počátečního stavu prostředku DSC -
Test(), abyste zjistili, jestli prostředek DSC považuje ho za v požadovaném stavu -
Set(), aby se vynutil požadovaný stav -
Test(), abyste zjistili, jestli prostředek DSC považuje za správně nastavený -
Get()k potvrzení konečného stavu prostředku DSC
Scénář: TSToy by se neměl automaticky aktualizovat v oboru uživatele.
V tomto scénáři je potřeba nakonfigurovat existující konfiguraci v oboru uživatele tak, aby se neaktualizovat automaticky. Všechna ostatní nastavení by měla zůstat nedotčená.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $false
Ensure = 'Present'
}
}
Get-Content -Path $UserPath
Invoke-DscResource @DesiredState -Method Get
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Set
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Get
Get-Content -Path $UserPath
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
InDesiredState
--------------
False
RebootRequired
--------------
False
InDesiredState
--------------
True
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present False 30
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": false
}
}
Scénář: Tailspin by se měl automaticky aktualizovat podle libovolného plánu v oboru uživatele.
V tomto scénáři je potřeba nakonfigurovat existující konfiguraci v oboru uživatele tak, aby se aktualizovala automaticky. Všechna ostatní nastavení by měla zůstat nedotčená.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
Ensure = 'Present'
}
}
Get-Content -Path $UserPath
Invoke-DscResource @DesiredState -Method Get
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Set
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Get
Get-Content -Path $UserPath
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": false
}
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present False 30
InDesiredState
--------------
False
RebootRequired
--------------
False
InDesiredState
--------------
True
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": true
}
}
Scénář: TSToy by se měl aktualizovat automaticky každý den v oboru uživatele.
V tomto scénáři je potřeba nakonfigurovat existující konfiguraci v oboru uživatele tak, aby se aktualizovala automaticky a denně. Všechna ostatní nastavení by měla zůstat nedotčená.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
UpdateFrequency = 1
Ensure = 'Present'
}
}
Get-Content -Path $UserPath
Invoke-DscResource @DesiredState -Method Get
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Set
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Get
Get-Content -Path $UserPath
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": true
}
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
InDesiredState
--------------
False
RebootRequired
--------------
False
InDesiredState
--------------
True
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 1
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 1
}
}
Scénář: TSToy by neměl mít konfiguraci oboru uživatele.
V tomto scénáři by konfigurační soubor pro TSToy v oboru uživatele neměl existovat. Pokud ano, měl by prostředek DSC soubor odstranit.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
Ensure = 'Absent'
}
}
Get-Content -Path $UserPath
Invoke-DscResource @DesiredState -Method Get
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Set
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Get
Test-Path -Path $UserPath
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 30,
"automatic": true
}
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
InDesiredState
--------------
False
RebootRequired
--------------
False
InDesiredState
--------------
True
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Absent False 0
False
Scénář: TSToy by se měl aktualizovat automaticky každý týden v oboru počítače.
V tomto scénáři není v oboru počítače žádná definovaná konfigurace. Obor počítače musí být nakonfigurovaný tak, aby se aktualizoval automaticky a denně. Prostředek DSC by měl podle potřeby vytvořit soubor a všechny nadřazené složky.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'Machine'
UpdateAutomatically = $true
Ensure = 'Present'
}
}
Test-Path -Path $MachinePath, (Split-Path -Path $MachinePath)
Invoke-DscResource @DesiredState -Method Get
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Set
Invoke-DscResource @DesiredState -Method Test
Invoke-DscResource @DesiredState -Method Get
Get-Content -Path $MachinePath
False
False
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
Machine Absent False 0
InDesiredState
--------------
False
RebootRequired
--------------
False
InDesiredState
--------------
True
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
Machine Present True 0
{
"updates": {
"automatic": true
}
}
Opakování
V tomto kurzu jste:
- Vygeneroval modul PowerShellu a implementoval
Tailspinprostředek DSC založený na třídě. - Definice vlastností prostředku DSC pro správu chování aplikace TSToy při aktualizaci v oboru počítače a uživatele s ověřením těchto vlastností
- Implementované výčty vlastností
$Ensurea$ConfigurationScope - Implementovali pomocnou metodu
GetConfigurationFile()pro spolehlivé zjišťování umístění konfigurace aplikace TSToy v oboru počítače a uživatele napříč platformami. - Implementovala metodu
Get()pro načtení aktuálního stavu prostředku DSC a ukládání do mezipaměti pro použití vTest()metodách aSet() - Implementovali metodu
Test()pro ověření aktuálního stavu chování aktualizace TSToy v konkrétním oboru proti požadovanému stavu. - Implementovali metodu ToConfigJson pro převod požadovaného stavu prostředku DSC na objekt JSON, který aplikace TSToy vyžaduje pro svůj konfigurační soubor, a respektovala nespravovaná nastavení.
- Implementovali metodu
Set()a pomocné metody Create, Remove a Update , které idempotentním způsobem vynucují požadovaný stav pro chování aktualizace TSToy v konkrétním oboru, čímž se zajistí, že prostředek DSC nebude mít nežádoucí vedlejší účinky. - Ručně otestované běžné scénáře použití prostředku DSC
Na konci implementace vypadá definice modulu takto:
[DscResource()]
class Tailspin {
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
[DscProperty()] [int] [ValidateRange(1, 90)]
$UpdateFrequency
hidden [Tailspin] $CachedCurrentState
hidden [PSCustomObject] $CachedData
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
$CurrentState.ConfigurationScope = $this.ConfigurationScope
$FilePath = $this.GetConfigurationFile()
if (!(Test-Path -Path $FilePath)) {
$CurrentState.Ensure = [TailspinEnsure]::Absent
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
$CurrentState.Ensure = [TailspinEnsure]::Present
$Data = Get-Content -Raw -Path $FilePath |
ConvertFrom-Json -ErrorAction Stop
$this.CachedData = $Data
if ($null -ne $Data.Updates.Automatic) {
$CurrentState.UpdateAutomatically = $Data.Updates.Automatic
}
if ($null -ne $Data.Updates.CheckFrequency) {
$CurrentState.UpdateFrequency = $Data.Updates.CheckFrequency
}
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
if ($CurrentState.UpdateAutomatically -ne $this.UpdateAutomatically) {
return $false
}
if ($this.UpdateFrequency -eq 0) {
return $true
}
if ($CurrentState.UpdateFrequency -ne $this.UpdateFrequency) {
return $false
}
return $true
}
[void] Set() {
if ($this.Test()) {
return
}
$CurrentState = $this.CachedCurrentState
$IsAbsent = $CurrentState.Ensure -eq [TailspinEnsure]::Absent
$ShouldBeAbsent = $this.Ensure -eq [TailspinEnsure]::Absent
if ($IsAbsent) {
$this.Create()
} elseif ($ShouldBeAbsent) {
$this.Remove()
} else {
$this.Update()
}
}
[string] GetConfigurationFile() {
$FilePaths = @{
Linux = @{
Machine = '/etc/xdg/TailSpinToys/tstoy/tstoy.config.json'
User = '~/.config/TailSpinToys/tstoy/tstoy.config.json'
}
MacOS = @{
Machine = '/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json'
User = '~/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json'
}
Windows = @{
Machine = "$env:ProgramData\TailSpinToys\tstoy\tstoy.config.json"
User = "$env:APPDATA\TailSpinToys\tstoy\tstoy.config.json"
}
}
$Scope = $this.ConfigurationScope.ToString()
if ($Global:PSVersionTable.PSVersion.Major -lt 6 -or $Global:IsWindows) {
return $FilePaths.Windows.$Scope
}
elseif ($Global:IsLinux) {
return $FilePaths.Linux.$Scope
}
else {
return $FilePaths.MacOS.$Scope
}
}
[void] Create() {
$ErrorActionPreference = 'Stop'
$Json = $this.ToConfigJson()
$FilePath = $this.GetConfigurationFile()
$FolderPath = Split-Path -Path $FilePath
if (!(Test-Path -Path $FolderPath)) {
New-Item -Path $FolderPath -ItemType Directory -Force
}
Set-Content -Path $FilePath -Value $Json -Encoding utf8 -Force
}
[void] Remove() {
Remove-Item -Path $this.GetConfigurationFile() -Force -ErrorAction Stop
}
[void] Update() {
$ErrorActionPreference = 'Stop'
$Json = $this.ToConfigJson()
$FilePath = $this.GetConfigurationFile()
Set-Content -Path $FilePath -Value $Json -Encoding utf8 -Force
}
[string] ToConfigJson() {
$config = @{
updates = @{
automatic = $this.UpdateAutomatically
}
}
if ($this.CachedData) {
$this.CachedData |
Get-Member -MemberType NoteProperty |
Where-Object -Property Name -NE -Value 'updates' |
ForEach-Object -Process {
$setting = $_.Name
$config.$setting = $this.CachedData.$setting
}
if ($frequency = $this.CachedData.updates.CheckFrequency) {
$config.updates.checkFrequency = $frequency
}
}
if ($this.UpdateFrequency -ne 0) {
$config.updates.checkFrequency = $this.UpdateFrequency
}
return ($config | ConvertTo-Json)
}
}
enum TailspinScope {
Machine
User
}
enum TailspinEnsure {
Absent
Present
}
Vyčištění
Pokud tento modul nebudete dál používat, odstraňte ExampleResources složku a soubory v ní.
Další kroky
- Přečtěte si o prostředcích DSC založených na třídách, zjistěte, jak fungují, a zvažte, proč je prostředek DSC v tomto kurzu implementovaný tímto způsobem.
- Zvažte, jak tento prostředek DSC vylepšit. Existují nějaké hraniční případy nebo funkce, které nezvládá? Aktualizujte implementaci, aby je zvládla.