Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Beginnen Sie mit der Erstellung einer klassenbasierten DSC-Ressource, um eine Konfigurationsdatei mit dem Computerkonfigurationsfeature von Azure Automanage zu verwalten. Wenn Sie dieses Tutorial abschließen, erhalten Sie eine klassenbasierte DSC-Ressource, die mit der Computerkonfiguration kompatibel ist, in einem Modul, das Sie für weiteres Lernen und Anpassen verwenden können.
In diesem Tutorial lernen Sie Folgendes:
- Gerüstbau eines DSC-Ressourcenmoduls
- Hinzufügen einer klassenbasierten DSC-Ressource
- Definieren von DSC-Ressourceneigenschaften
- Implementieren der DSC-Ressourcenmethoden
- Exportieren einer DSC-Ressource in einem Modulmanifest
- Manuelles Testen einer DSC-Ressource
Hinweis
Die Beispielausgabe in diesem Tutorial entspricht PowerShell 7.2 auf einem Windows-Computer. Das Tutorial ist mit Windows PowerShell und PowerShell auf einem Linux- oder macOS-Computer gültig. Nur die Ausgabe ist spezifisch für die Ausführung der Befehle in PowerShell auf einem Windows-Computer.
Voraussetzungen
- PowerShell oder Windows PowerShell 5.1
- VS Code mit der PowerShell-Erweiterung
1: Gerüstbau eines DSC-Ressourcenmoduls
DSC-Ressourcen müssen in einem PowerShell-Modul definiert werden.
Erstellen des Modulordners
Erstellen Sie einen neuen Ordner mit dem Namen ExampleResources
. Dieser Ordner wird als Stammordner für das Modul und den gesamten Code in diesem Tutorial verwendet.
New-Item -Path './ExampleResources' -ItemType Directory
Directory: C:\code\dsc
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 9/8/2022 12:54 PM ExampleResources
Verwenden von VS Code zum Erstellen des Moduls
Öffnen Sie den Ordner ExampleResources
in VS Code. Öffnen Sie das integrierte Terminal in VS Code. Stellen Sie sicher, dass auf Ihrem Terminal PowerShell oder Windows PowerShell ausgeführt wird.
Wichtig
Führen Sie im weiteren Verlauf dieses Tutorials die angegebenen Befehle im integrierten Terminal im Stammverzeichnis des Modulordners aus. Dies ist das Standardarbeitsverzeichnis in VS Code.
Erstellen der Moduldateien
Erstellen Sie das Modulmanifest mit dem New-ModuleManifest
Cmdlet. Verwenden Sie ./ExampleResources.psd1
als Pfad. Geben Sie RootModule als ExampleResources.psm1
und DscResourcesToExport als an 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 :
Erstellen Sie die Stammmoduldatei als 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
Erstellen Sie eine Skriptdatei mit dem Namen 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
Öffnen Sie Helpers.ps1
in VS Code. Fügen Sie die folgende Zeile hinzu.
$env:PSModulePath += "$([System.IO.Path]::PathSeparator)$pwd"
Öffnen Sie ExampleResources.psm1
in VS Code. Das Modul ist jetzt gerüstet und kann eine DSC-Ressource erstellen.
2: Hinzufügen einer klassenbasierten DSC-Ressource
Um eine klassenbasierte DSC-Ressource zu definieren, schreiben wir eine PowerShell-Klasse in einer Moduldatei und fügen ihr das DscResource-Attribut hinzu.
Definieren der -Klasse
Fügen Sie in ExampleResources.psm1
den folgenden Code hinzu:
[DscResource()]
class Tailspin {
}
Dieser Code fügt dem ExampleResources-Modul als klassenbasierte DSC-Ressource hinzuTailspin
.
Zeigen Sie auf [DscResource()]
die Warnungen, und lesen Sie sie.
Wenn Sie auf das DSCResource-Attribut zeigen, werden vier Warnungen angezeigt. 1. Der DSC-Ressource "Tailspin" fehlt eine Set()-Methode, die "[void]" zurückgibt und keine Parameter akzeptiert. 2. Der DSC-Ressource "Tailspin" fehlt eine Get()-Methode, die "[Tailspin]" zurückgibt und keine Parameter akzeptiert. 3. Der DSC-Ressource "Tailspin" fehlt eine "Test()"-Methode, die "[bool]" zurückgibt und keine Parameter akzeptiert. 4. Die DSC-Ressource "Tailspin" muss mindestens eine Schlüsseleigenschaft aufweisen (mit der Syntax "[DscProperty(Key)]".)
In diesen Warnungen werden die Anforderungen aufgeführt, damit die Klasse eine gültige DSC-Ressource sein muss.
Erforderliche Methoden minimal implementieren
Fügen Sie der -Klasse eine minimale Implementierung der Get()
Methoden , Test()
und Set()
hinzu.
class Tailspin {
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
return $CurrentState
}
[bool] Test() {
return $true
}
[void] Set() {}
}
Nachdem die Methoden hinzugefügt wurden, warnt das DscResource-Attribut nur davor, dass die Klasse keine Key-Eigenschaft hat.
3: Definieren von DSC-Ressourceneigenschaften
Sie sollten die Eigenschaften der DSC-Ressource vor den Methoden definieren. Die Eigenschaften definieren die verwaltbaren Einstellungen für die DSC-Ressource. Sie werden in den Methoden verwendet.
Grundlegendes zur TSToy-Anwendung
Bevor Sie die Eigenschaften Ihrer DSC-Ressource definieren können, müssen Sie wissen, welche Einstellungen Sie verwalten möchten.
In diesem Tutorial definieren wir eine DSC-Ressource zum Verwalten der Einstellungen der fiktiven TSToy-Anwendung über die zugehörige Konfigurationsdatei. TSToy ist eine Anwendung, die auf Benutzer- und Computerebene konfiguriert ist. Die DSC-Ressource sollte in der Lage sein, beide Dateien zu konfigurieren.
Die DSC-Ressource sollte Es Benutzern ermöglichen, Folgendes zu definieren:
- Der Bereich der Konfiguration, die verwaltet wird, entweder
Machine
oderUser
- Ob die Konfigurationsdatei vorhanden sein soll
- Gibt an, ob TSToy automatisch aktualisiert werden soll
- Wie häufig tsToy zwischen 1 und 90 Tagen nach Updates suchen sollte
Hinzufügen der ConfigurationScope-Eigenschaft
Um die Machine
Konfigurationsdatei oder User
zu verwalten, müssen Sie eine Eigenschaft der DSC-Ressource definieren. Um die $ConfigurationScope
-Eigenschaft in der Ressource zu definieren, fügen Sie den folgenden Code in der -Klasse vor den Methoden hinzu:
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
Dieser Code definiert $ConfigurationScope
als Key-Eigenschaft der DSC-Ressource. Eine Key-Eigenschaft wird verwendet, um eine Instanz der DSC-Ressource eindeutig zu identifizieren. Das Hinzufügen dieser Eigenschaft erfüllt eine der Anforderungen, vor die das DscResource-Attribut beim Erstellen eines Gerüsts für die Klasse gewarnt hat.
Außerdem wird angegeben, dass $ConfigurationScope
der Typ tailspinScope ist. Um den TailspinScope-Typ zu definieren, fügen Sie die folgende TailspinScope-Enumeration nach der Klassendefinition in ExampleResources.psm1
hinzu:
enum TailspinScope {
Machine
User
}
Diese Enumeration macht Machine
und User
die einzigen gültigen Werte für die $ConfigurationScope
Eigenschaft der DSC-Ressource.
Hinzufügen der Ensure-Eigenschaft
Es empfiehlt sich, eine $Ensure
Eigenschaft zu definieren, um zu steuern, ob eine Instanz einer DSC-Ressource vorhanden ist. Eine $Ensure
Eigenschaft verfügt in der Regel über zwei gültige Werte: Absent
und Present
.
- Wenn
$Ensure
alsPresent
angegeben ist, erstellt die DSC-Ressource das Element, wenn es nicht vorhanden ist. - Wenn
$Ensure
istAbsent
, löscht die DSC-Ressource das Element, sofern vorhanden.
Für die Tailspin DSC-Ressource ist das zu erstellende oder zu löschende Element die Konfigurationsdatei für die angegebene $ConfigurationScope
.
Definieren Sie TailspinEnsure als Enumeration nach TailspinScope. Sie sollte die Werte Absent
und haben Present
.
enum TailspinEnsure {
Absent
Present
}
Fügen Sie als Nächstes die $Ensure
-Eigenschaft in der -Klasse nach der $ConfigurationScope
-Eigenschaft hinzu. Es sollte ein leeres DscProperty-Attribut haben, und sein Typ sollte TailspinEnsure sein. Der Standardwert sollte sein Present
.
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
Hinzufügen der UpdateAutomatically-Eigenschaft
Um automatische Updates zu verwalten, definieren Sie die $UpdateAutomatically
-Eigenschaft in der -Klasse nach der $Ensure
-Eigenschaft. Das DscProperty-Attribut sollte angeben, dass es obligatorisch und sein Typ boolescher Wert sein sollte.
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
Hinzufügen der UpdateFrequency-Eigenschaft
Um zu verwalten, wie oft TSToy nach Updates suchen soll, fügen Sie die $UpdateFrequency
-Eigenschaft in der -Klasse nach der $UpdateAutomatically
-Eigenschaft hinzu. Es sollte über ein leeres DscProperty-Attribut verfügen, und sein Typ sollte int sein. Verwenden Sie das ValidateRange-Attribut , um die gültigen Werte für $UpdateFrequency
auf 1 bis 90 zu begrenzen.
[DscProperty()] [int] [ValidateRange(1, 90)]
$UpdateFrequency
Hinzufügen der Reasons-Eigenschaft
Da diese DSC-Ressource für die Verwendung mit dem Azure Automanage-Computerkonfigurationsfeature vorgesehen ist, muss sie über die Reasons-Eigenschaft verfügen, die die folgenden Anforderungen erfüllt:
- Sie muss mit der NotConfigurable-Eigenschaft für das DscProperty-Attribut deklariert werden.
- Es muss sich um ein Array von Objekten handeln, die über eine String-Eigenschaft namens Code, eine String-Eigenschaft mit dem Namen Phrase und keine anderen Eigenschaften verfügen.
Die Computerkonfiguration verwendet die Reasons-Eigenschaft , um die Darstellung von Konformitätsinformationen zu standardisieren. Jedes von der Methode für die Get()
Reasons-Eigenschaft zurückgegebene Objekt gibt an, wie und warum eine Instanz der DSC-Ressource nicht kompatibel ist.
Die Computerkonfiguration verwendet die Reasons-Eigenschaft , um die Darstellung von Konformitätsinformationen zu standardisieren. Jedes von der Methode für die Get()
Reasons-Eigenschaft zurückgegebene Objekt identifiziert eine der Eigenschaften der DSC-Ressource, ihren gewünschten Zustand und ihren tatsächlichen Zustand.
Um die Reasons-Eigenschaft zu definieren, müssen Sie eine Klasse dafür definieren. Definieren Sie die ExampleResourcesReason-Klasse nach der TailspinEnsure-Enumeration . Sie sollte die Eigenschaften Code und Phrase als Zeichenfolgen aufweisen. Beide Eigenschaften sollten über das DscProperty-Attribut verfügen.
Um die Gründe während des manuellen Tests lesbarer anzuzeigen, definieren Sie die ToString()
-Methode für die ExampleResourcesReason-Klasse , wie im Codeausschnitt gezeigt.
class ExampleResourcesReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
[string] ToString() {
return "`n$($this.Code):`n`t$($this.Phrase)`n"
}
}
Fügen Sie als Nächstes die $Reasons
-Eigenschaft in der Klasse der DSC-Ressource nach der $UpdateFrequency
-Eigenschaft hinzu. Es sollte das DscProperty-Attribut mit der NotConfigurable
Option angegeben haben, und sein Typ sollte ExampleResourcesReason[] sein.
[DscProperty(NotConfigurable)] [ExampleResourcesReason[]]
$Reasons
Hinzufügen ausgeblendeter Cacheeigenschaften
Fügen Sie als Nächstes zwei ausgeblendete Eigenschaften zum Zwischenspeichern des aktuellen Zustands der Ressource hinzu: $CachedCurrentState
und $CachedData
. Legen Sie den Typ von $CachedCurrentState
auf Tailspin fest, der mit der -Klasse und dem Rückgabetyp für die Get()
-Methode identisch ist. Legen Sie den Typ von $CachedData
auf PSCustomObject fest. Präfixen Sie beiden Eigenschaften das hidden
Schlüsselwort. Geben Sie für beides nicht das DscProperty-Attribut an.
hidden [Tailspin] $CachedCurrentState
hidden [PSCustomObject] $CachedData
Diese ausgeblendeten Eigenschaften werden in den Get()
Methoden und Set()
verwendet, die Sie später definieren.
Überprüfen der Moduldatei
An diesem Punkt ExampleResources.psm1
sollten Sie Folgendes definieren:
- Die Tailspin-Klasse mit den Eigenschaften
$ConfigurationScope
,$Ensure
, ,$UpdateAutomatically
und$UpdateFrequency
- Die TailspinScope-Enumeration mit den Werten
Machine
undUser
- Die TailspinEnsure-Enumeration mit den Werten
Present
undAbsent
- Die minimalen Implementierungen der
Get()
Methoden ,Test()
, undSet()
.
[DscResource()]
class Tailspin {
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
[DscProperty()] [int] [ValidateRange(1,90)]
$UpdateFrequency
[DscProperty(NotConfigurable)] [ExampleResourcesReason[]]
$Reasons
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
}
class ExampleResourcesReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
[string] ToString() {
return "`n$($this.Code):`n`t$($this.Phrase)`n"
}
}
Da die DSC-Ressource nun die Anforderungen erfüllt, können Sie sie verwenden Get-DscResource
, um sie anzuzeigen. Öffnen Sie in VS Code ein neues PowerShell-Terminal.
. ./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: Implementieren der DSC-Ressourcenmethoden
Die Methoden der DSC-Ressource definieren, wie sie den aktuellen Zustand einer DSC-Ressource abrufen, anhand des gewünschten Zustands überprüfen und den gewünschten Zustand erzwingen.
Die Get-Methode
Die Get()
-Methode ruft den aktuellen Zustand der DSC-Ressource ab. Sie wird verwendet, um eine DSC-Ressource manuell zu überprüfen und von der Test()
-Methode aufgerufen.
Die Get()
-Methode verfügt über keine Parameter und gibt eine Instanz der -Klasse als Ausgabe zurück. Für die Tailspin
DSC-Ressource sieht die minimale Implementierung wie folgt aus:
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
return $CurrentState
}
Das einzige, was diese Implementierung tut, ist, eine Instanz der Tailspin-Klasse zu erstellen und zurückzugeben. Sie können die -Methode mit Invoke-DscResource
aufrufen, um dieses Verhalten anzuzeigen.
Invoke-DscResource -Name Tailspin -Module ExampleResources -Method Get -Property @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
Machine Present False 0
Die Eigenschaften des zurückgegebenen Objekts sind alle auf ihren Standardwert festgelegt. Der Wert von $ConfigurationScope
sollte immer der vom Benutzer angegebene Wert sein. Damit die Get()
Methode nützlich ist, muss sie den tatsächlichen Zustand der DSC-Ressource zurückgeben.
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
$CurrentState.ConfigurationScope = $this.ConfigurationScope
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
Die $this
Variable verweist auf die Arbeitsinstanz der DSC-Ressource. Wenn Sie nun erneut verwenden Invoke-DscResource
, $ConfigurationScope
hat sie den richtigen Wert.
Invoke-DscResource -Name Tailspin -Module ExampleResources -Method Get -Property @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
}
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present False 0
Als Nächstes muss die DSC-Ressource ermitteln, ob die Konfigurationsdatei vorhanden ist. Wenn dies der Fall ist, $Ensure
sollte .Present
Wenn dies nicht der Fall ist, $Ensure
sollte .Absent
Der Speicherort der Konfigurationsdateien von TSToy hängt vom Betriebssystem und dem Konfigurationsbereich ab:
- Für Windows-Computer:
- Die
Machine
Konfigurationsdatei lautet%PROGRAMDATA%\TailSpinToys\tstoy\tstoy.config.json
- Die
User
Konfigurationsdatei lautet%APPDATA%\TailSpinToys\tstoy\tstoy.config.json
- Die
- Für Linux-Computer:
- Die
Machine
Konfigurationsdatei lautet/etc/xdg/TailSpinToys/tstoy/tstoy.config.json
- Die
User
Konfigurationsdatei lautet~/.config/TailSpinToys/tstoy/tstoy.config.json
- Die
- Für macOS-Computer:
- Die
Machine
Konfigurationsdatei lautet/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json
- Die
User
Konfigurationsdatei lautet~/Library/Preferences/TailSpinToys/tstoy/tstoy.config.json
- Die
Um diese Pfade zu behandeln, müssen Sie eine Hilfsmethode erstellen, 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
}
}
Um diese neue Methode zu testen, führen Sie die using
-Anweisung aus, um die Klassen und Enumerationen des ExampleResources-Moduls in Ihre aktuelle Sitzung zu laden.
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
Öffnen Sie Helpers.ps1
in VS Code. Kopieren Sie die Pfade für die Konfigurationsdateien, fügen Sie sie in das Skript ein, und weisen Sie sie und zu $TSToyMachinePath
$TSToyUserPath
. Die Datei sollte wie folgt aussehen:
$env:PSModulePath += "<separator>$pwd"
$TSToyMachinePath = '<machine configuration file path>'
$TSToyUserPath = '<user configuration file path>'
Beenden Sie das Terminal in VS Code, und öffnen Sie ein neues Terminal. Punktquelle Helpers.ps1
.
. ./Helpers.ps1
Jetzt können Sie den Rest der Get()
Methode schreiben.
[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
}
$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
}
Nachdem Sie den Pfad der $ConfigurationScope
Konfigurationsdatei festgelegt und ermittelt haben, überprüft die Methode, ob die Datei vorhanden ist. Wenn es nicht vorhanden ist, müssen Sie das Ergebnis auf festlegen $Ensure
Absent
und zurückgeben.
Wenn die Datei vorhanden ist, muss die Methode den Inhalt aus JSON konvertieren, um den aktuellen Zustand der Konfiguration zu erstellen. Als Nächstes überprüft die -Methode, ob die Schlüssel über einen Wert verfügen, bevor sie sie den Eigenschaften des aktuellen Zustands zuweisen. Wenn sie nicht angegeben werden, muss die DSC-Ressource sie als nicht festgelegt und im Standardzustand betrachten.
An diesem Punkt speichert die DSC-Ressource die Daten zwischen. Das Zwischenspeichern der Daten ermöglicht es Ihnen, die Daten während der Entwicklung zu überprüfen und ist bei der Implementierung der Set()
Methode nützlich.
Sie können dieses Verhalten lokal überprüfen.
$GetParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Method = 'Get'
Property = @{
ConfigurationScope = 'User'
}
}
Invoke-DscResource @GetParameters
New-Item -Path $TSToyUserPath -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
Öffnen Sie die User
Bereichskonfigurationsdatei in VS Code.
code $TSToyUserPath
Kopieren Sie diese JSON-Konfiguration in die Datei, und speichern Sie sie.
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
Rufen Sie erneut auf Invoke-DscResource
, und sehen Sie sich die Werte in den Ergebnissen an.
Invoke-DscResource @GetParameters
ConfigurationScope Ensure UpdateAutomatically UpdateFrequency
------------------ ------ ------------------- ---------------
User Present True 30
Die Get()
Methode gibt jetzt genaue Informationen über den aktuellen Zustand der DSC-Ressource zurück.
Behandlungsgründe
Für computerkonfigurationsfähige DSC-Ressourcen muss die Get()
Methode auch die Reasons-Eigenschaft auffüllen. Erstellen Sie zu diesem Zweck die GetReasons()
-Methode. Es sollte ein Array von ExampleResourcesReason-Objekten zurückgeben und ein einzelnes Tailspin-Objekt als Eingabe verwenden.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
return $DefinedReasons
}
Als Nächstes muss die Methode die Gültigkeit jeder konfigurierbaren Einstellung überprüfen. Für jede Einstellung muss die -Methode einen ExampleResourcesReason-Wert zurückgeben, der den Zustand identifiziert und beschreibt.
Die erste zu überprüfende Einstellung ist die $Ensure
-Eigenschaft. Wenn $Ensure
der Zustand nicht vorhanden ist, sind alle anderen Eigenschaften falsch, da die Konfigurationsdatei vorhanden ist, wenn sie nicht oder nicht vorhanden ist, wenn sie sollte.
Die -Methode muss einen Grund mit dem richtigen Code und einem sinnvollen Ausdruck definieren. Der Code hat immer das Format <ResourceName>.<ResourceName>.<PropertyName>
. Der Ausdruck ist immer ein Satz, der die Überprüfung beschreibt, gefolgt von Sätzen, die den erwarteten Zustand und den tatsächlichen Zustand beschreiben.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
return $DefinedReasons
}
Wenn $Ensure
sich der Zustand nicht nicht befindet, sollte die -Methode überprüfen, ob der gewünschte Zustand ist Absent
. Wenn dies der Fall ist, gibt es keine anderen Eigenschaften, die nicht im Zustand sein können, da die Konfigurationsdatei nicht vorhanden ist und nicht vorhanden sein sollte.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $DefinedReasons
}
return $DefinedReasons
}
Wenn $Ensure
ist und die Datei vorhanden ist Present
, muss die Methode die verbleibenden konfigurierbaren Eigenschaften überprüfen.
Die Überprüfung der $UpdateAutomatically
Eigenschaft ist einfach, da es sich um einen obligatorischen und booleschen Wert handelt.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateAutomatically"
Phrase = (@(
"Checked value of the 'updates.automatic' key in the TSToy configuration file."
"Expected boolean value of '$($this.UpdateAutomatically)'"
"Actual boolean value of '$($CurrentState.UpdateAutomatically)'"
) -join "`n`t")
}
return $DefinedReasons
}
Die letzte zu überprüfende Eigenschaft ist $UpdateFrequency
. Diese Überprüfung kann kurzgeschlossen werden, wenn der Wert der -Eigenschaft ist 0
. Wenn die Eigenschaft angegeben ist, liegt sie immer zwischen 1 und 90. Das bedeutet, dass ein Wert von 0
angibt, dass die Eigenschaft nicht verwaltet wird.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateAutomatically"
Phrase = (@(
"Checked value of the 'updates.automatic' key in the TSToy configuration file."
"Expected boolean value of '$($this.UpdateAutomatically)'"
"Actual boolean value of '$($CurrentState.UpdateAutomatically)'"
) -join "`n`t")
}
return $DefinedReasons
# Short-circuit the check; UpdateFrequency isn't defined by caller
if ($this.UpdateFrequency -eq 0) {
return $DefinedReasons
}
}
Schließlich muss die Methode den gewünschten und aktuellen Zustand der $UpdateFrequency
-Eigenschaft vergleichen und einen Grund definieren, wenn sie sich nicht im Zustand befinden.
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateAutomatically"
Phrase = (@(
"Checked value of the 'updates.automatic' key in the TSToy configuration file."
"Expected boolean value of '$($this.UpdateAutomatically)'"
"Actual boolean value of '$($CurrentState.UpdateAutomatically)'"
) -join "`n`t")
}
# Short-circuit the check; UpdateFrequency isn't defined by caller
if ($this.UpdateFrequency -eq 0) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateFrequency"
Phrase = (@(
"Checked value of the 'updates.checkFrequency' key in the TSToy configuration file."
"Expected integer value of '$($this.UpdateFrequency)'."
"Actual integer value of '$($CurrentState.UpdateFrequency)'."
) -join "`n`t")
}
return $DefinedReasons
}
Wenn die GetReasons()
-Methode implementiert ist, muss die Get()
-Methode aktualisiert werden, um sie aufzurufen, bevor der aktuelle Zustand zurückgegeben wird.
[Tailspin] Get() {
$CurrentState = [Tailspin]::new()
$CurrentState.ConfigurationScope = $this.ConfigurationScope
$FilePath = $this.GetConfigurationFile()
if (!(Test-Path -Path $FilePath)) {
$CurrentState.Ensure = [TailspinEnsure]::Absent
$CurrentState.Reasons = $this.GetReasons($CurrentState)
$this.CachedCurrentState = $CurrentState
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
}
$CurrentState.Reasons = $this.GetReasons($CurrentState)
$this.CachedCurrentState = $CurrentState
return $CurrentState
}
Wenn die Implementierung aktualisiert wird, können Sie das Verhalten überprüfen und feststellen, dass die Gründe gemeldet werden:
$SharedParameters = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
Ensure = 'Present'
UpdateAutomatically = $false
}
}
Invoke-DscResource -Method Get @SharedParameters
$SharedParameters.Property.UpdateAutomatically = $true
Invoke-DscResource -Method Get @SharedParameters
$SharedParameters.Property.UpdateFrequency = 1
Invoke-DscResource -Method Get @SharedParameters
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 1
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'False'
Actual boolean value of 'True'
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 1
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 1
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
,
Tailspin.Tailspin.UpdateFrequency:
Checked value of the 'updates.checkFrequency' key in
the TSToy configuration file.
Expected integer value of '1'.
Actual integer value of '1'.
}
Die Testmethode
Wenn die Get()
-Methode implementiert ist, können Sie überprüfen, ob der aktuelle Zustand mit dem gewünschten Zustand kompatibel ist.
Die Test()
minimale Implementierung der Methoden gibt immer zurück $true
.
[bool] Test() {
return $true
}
Sie können dies überprüfen, indem Sie Invoke-DscResource
ausführen.
$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
Sie müssen die Test()
Methode genau angeben, ob sich die DSC-Ressource im gewünschten Zustand befindet. Die Test()
-Methode sollte immer die Get()
-Methode aufrufen, damit der aktuelle Zustand mit dem gewünschten Zustand verglichen werden kann. Überprüfen Sie dann, ob die $Ensure
Eigenschaft richtig ist. Wenn dies nicht der Fall ist, geben Sie sofort zurück $false
. Wenn sich die $Ensure
Eigenschaft außerhalb des gewünschten Zustands befindet, sind keine weiteren Überprüfungen erforderlich.
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
return $true
}
Jetzt können Sie das aktualisierte Verhalten überprüfen.
$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
Überprüfen Sie als Nächstes, ob der Wert von $Ensure
ist Absent
. Wenn die Konfigurationsdatei nicht vorhanden ist und nicht vorhanden sein sollte, gibt es keinen Grund, die verbleibenden Eigenschaften zu überprüfen.
[bool] Test() {
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
return $false
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $true
}
return $true
}
Als Nächstes muss die -Methode den aktuellen Status der Eigenschaften vergleichen, die das Updateverhalten von TSToy verwalten. Überprüfen Sie zunächst, ob sich die $UpdateAutomatically
Eigenschaft im richtigen Zustand befindet. Wenn dies nicht der Fall ist, geben Sie zurück $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
}
Um zu vergleichen $UpdateFrequency
, müssen wir ermitteln, ob der Benutzer den Wert angegeben hat. Da $UpdateFrequency
mit 0
initialisiert wird und das ValidateRange-Attribut der Eigenschaft angibt, dass es zwischen 1
und 90
sein muss, wissen wir, dass der Wert von 0
angibt, dass die Eigenschaft nicht angegeben wurde.
Mit diesen Informationen sollte die Test()
-Methode:
- Zurückgeben
$true
, wenn der Benutzer nicht angegeben hat$UpdateFrequency
- Gibt zurück
$false
, wenn der Benutzer angegeben$UpdateFrequency
hat und der Wert des Systems nicht dem vom Benutzer angegebenen Wert entspricht. - Rückgabe
$true
, wenn keine der vorherigen Bedingungen erfüllt war
[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
}
Test()
Die -Methode verwendet nun die folgende Reihenfolge der Vorgänge:
- Rufen Sie den aktuellen Status der TSToy-Konfiguration ab.
- Gibt zurück
$false
, wenn die Konfiguration vorhanden ist, wenn sie nicht vorhanden sein soll oder nicht vorhanden ist, wenn sie sollte. - Gibt zurück
$true
, wenn die Konfiguration nicht vorhanden ist und nicht vorhanden sein soll. - Gibt zurück
$false
, wenn die Einstellung für die automatische Aktualisierung der Konfiguration nicht mit der gewünschten Einstellung übereinstimmt. - Gibt zurück
$true
, wenn der Benutzer keinen Wert für die Einstellung für die Updatehäufigkeit angegeben hat. - Gibt zurück
$false
, wenn der vom Benutzer für die Einstellung für die Updatehäufigkeit angegebene Wert nicht mit der Einstellung der Konfiguration übereinstimmt. - Gibt zurück
$true
, wenn keine der vorherigen Bedingungen erfüllt war.
Sie können die Test()
Methode lokal überprüfen:
$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
Mit diesem Code kann die Test()
-Methode genau bestimmen, ob sich die Konfigurationsdatei im gewünschten Zustand befindet.
Die Set-Methode
Nachdem die Get()
Methoden und Test()
nun zuverlässig funktionieren, können Sie die Set()
Methode definieren, um den gewünschten Zustand tatsächlich zu erzwingen.
In der minimalen Implementierung bewirkt die Set()
-Methode nichts.
[void] Set() {}
Zunächst muss ermittelt werden, Set()
ob die DSC-Ressource erstellt, aktualisiert oder entfernt werden muss.
[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()
ruft zuerst die Test()
-Methode auf, um festzustellen, ob tatsächlich etwas getan werden muss. Einige Tools wie das Computerkonfigurationsfeature von Azure Automanage stellen sicher, dass die Set()
-Methode nur nach der Test()
-Methode aufgerufen wird. Eine solche Garantie gibt es jedoch nicht, wenn Sie das Invoke-DscResource
Cmdlet verwenden.
Da die Test()
-Methode aufruft Get()
, die den aktuellen Zustand zwischenspeichert, kann die DSC-Ressource auf den zwischengespeicherten aktuellen Zustand zugreifen, ohne die Get()
-Methode erneut aufrufen zu müssen.
Als Nächstes muss die DSC-Ressource zwischen dem Erstellen, Entfernen und Aktualisieren der Konfigurationsdatei unterscheiden. Wenn die Konfigurationsdatei nicht vorhanden ist, wissen wir, dass sie erstellt werden sollte. Wenn die Konfigurationsdatei vorhanden ist und nicht, wissen wir, dass sie entfernt werden muss. Wenn die Konfigurationsdatei vorhanden ist und vorhanden sein sollte, wissen wir, dass sie aktualisiert werden muss.
Erstellen Sie drei neue Methoden, um diese Vorgänge zu verarbeiten, und rufen Sie sie bei Bedarf in der Set()
-Methode auf.
Der Rückgabetyp für alle drei sollte void sein.
[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() {}
Erstellen Sie außerdem eine neue Methode namens ToConfigJson()
. Der Rückgabetyp sollte Zeichenfolge sein. Diese Methode konvertiert die DSC-Ressource in den JSON-Code, den die Konfigurationsdatei erwartet. Sie können mit der folgenden minimalen Implementierung beginnen:
[string] ToConfigJson() {
$config = @{}
return ($config | ConvertTo-Json)
}
Die ToConfigJson-Methode
Die minimale Implementierung gibt ein leeres JSON-Objekt als Zeichenfolge zurück. Damit es nützlich ist, muss die tatsächliche JSON-Darstellung der Einstellungen in der TSToy-Konfigurationsdatei zurückgegeben werden.
Füllen Sie zunächst die $config
Hashtabelle mit der Einstellung für obligatorische automatische Updates vor, indem Sie den Schlüssel mit seinem updates
Wert als Hashtabelle hinzufügen. Die Hashtabelle sollte den automatic
Schlüssel enthalten. Weisen Sie dem Schlüssel den Wert der -Eigenschaft der automatic
Klasse $UpdateAutomatically
zu.
[string] ToConfigJson() {
$config = @{
updates = @{
automatic = $this.UpdateAutomatically
}
}
return ($config | ConvertTo-Json)
}
Dieser Code übersetzt die DSC-Ressourcendarstellung der TSToy-Einstellungen in die Struktur, die die TSToy-Konfigurationsdatei erwartet.
Als Nächstes muss die -Methode überprüfen, ob die -Klasse die Daten aus einer vorhandenen Konfigurationsdatei zwischengespeichert hat. Die zwischengespeicherten Daten ermöglichen es der DSC-Ressource, die definierten Einstellungen zu verwalten, ohne nicht verwaltete Einstellungen zu überschreiben oder zu entfernen.
[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)
}
Wenn die -Klasse die Einstellungen aus einer vorhandenen Konfiguration zwischengespeichert hat, erfolgt Folgendes:
Überprüft die Eigenschaften der zwischengespeicherten Daten und sucht nach Eigenschaften, die von der DSC-Ressource nicht verwaltet werden. Wenn diese gefunden werden, fügt die Methode diese nicht verwalteten Eigenschaften in die
$config
Hashtabelle ein.Da die DSC-Ressource nur die Updateeinstellungen verwaltet, wird jede Einstellung mit Ausnahme von
updates
eingefügt.Überprüft, ob die
checkFrequency
Einstellung inupdates
festgelegt ist. Wenn er festgelegt ist, fügt die Methode diesen Wert in die$config
Hashtabelle ein.Dieser Vorgang ermöglicht es der DSC-Ressource, die
$UpdateFrequency
Eigenschaft zu ignorieren, wenn der Benutzer sie nicht angibt.Schließlich muss die -Methode überprüfen, ob der Benutzer die
$UpdateFrequency
-Eigenschaft angegeben hat, und sie in die$config
Hashtabelle einfügen.
Mit diesem Code ist die -Methode wie folgt ToConfigJson()
:
- Gibt eine genaue JSON-Darstellung des gewünschten Zustands zurück, den die TSToy-Anwendung in ihrer Konfigurationsdatei erwartet.
- Berücksichtigt alle Einstellungen von TSToy, die von der DSC-Ressource nicht explizit verwaltet werden.
- Berücksichtigt den vorhandenen Wert für die Updatehäufigkeit von TSToy, wenn der Benutzer keinen angegeben hat, einschließlich der Nichtdefinition in der Konfigurationsdatei.
Um diese neue Methode zu testen, schließen Sie Ihr VS Code-Terminal, und öffnen Sie ein neues. Führen Sie die using
-Anweisung aus, um die Klassen und Enumerationen des ExampleResources-Moduls in Ihre aktuelle Sitzung zu laden und das Skript zu helpers.ps1
dotieren.
using module ./ExampleResources.psd1
. ./Helpers.ps1
$Example = [Tailspin]::new()
Get-Content -Path $TSToyUserPath
$Example.ConfigurationScope = 'User'
$Example.ToConfigJson()
Bevor die Get()
-Methode aufgerufen wird, ist der einzige Wert in der Ausgabe der ToJsonConfig-Methode der konvertierte Wert für die $UpdateAutomatically
-Eigenschaft.
{
"unmanaged_key": true,
"updates": {
"automatic": false,
"checkFrequency": 30
}
}
{
"updates": {
"automatic": false
}
}
$Example.Get()
$Example.ToConfigJson()
Nachdem Sie aufgerufen Get()
haben, enthält die Ausgabe einen nicht verwalteten Schlüssel der obersten Ebene, unmanaged_key
. Es enthält auch die vorhandene Einstellung in der Konfigurationsdatei für $UpdateFrequency
, da sie nicht explizit für die DSC-Ressource festgelegt wurde.
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : False
UpdateFrequency : 30
Reasons : {}
{
"unmanaged_key": true,
"updates": {
"automatic": false,
"checkFrequency": 30
}
}
$Example.UpdateFrequency = 7
$Example.ToConfigJson()
Nachdem $UpdateFrequency
festgelegt wurde, spiegelt die Ausgabe den angegebenen Wert wider.
{
"unmanaged_key": true,
"updates": {
"automatic": false,
"checkFrequency": 7
}
}
Die Create-Methode
Um die Create()
-Methode zu implementieren, müssen wir die vom Benutzer angegebenen Eigenschaften für die DSC-Ressource in den JSON-Code konvertieren, den TSToy in der Konfigurationsdatei erwartet, und sie in diese Datei schreiben.
[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
}
Die -Methode verwendet die ToConfigJson()
-Methode, um den JSON-Code für die Konfigurationsdatei abzurufen. Es überprüft, ob der Ordner der Konfigurationsdatei vorhanden ist, und erstellt ihn bei Bedarf. Schließlich wird die Konfigurationsdatei erstellt und der JSON-Code in sie geschrieben.
Die Remove-Methode
Die Remove()
-Methode weist das einfachste Verhalten auf. Wenn die Konfigurationsdatei vorhanden ist, löschen Sie sie.
[void] Remove() {
Remove-Item -Path $this.GetConfigurationFile() -Force -ErrorAction Stop
}
Die Update-Methode
Die Update()
Implementierung der Methode ähnelt der Create-Methode . Es muss die vom Benutzer angegebenen Eigenschaften für die DSC-Ressource in den JSON-Code konvertieren, den TSToy in seiner Konfigurationsdatei erwartet, und die Einstellungen in dieser Datei ersetzen.
[void] Update() {
$ErrorActionPreference = 'Stop'
$Json = $this.ToConfigJson()
$FilePath = $this.GetConfigurationFile()
Set-Content -Path $FilePath -Value $Json -Encoding utf8 -Force
}
5: Manuelles Testen einer DSC-Ressource
Nachdem die DSC-Ressource vollständig implementiert ist, können Sie ihr Verhalten jetzt testen.
Schließen Sie vor dem Testen Ihr VS Code-Terminal, und öffnen Sie ein neues Terminal. Punktquelle für das Helpers.ps1
Skript.
Erstellen Sie für jedes Testszenario die Hashtabelle, die $DesiredState
die freigegebenen Parameter enthält, und rufen Sie die Methoden in der folgenden Reihenfolge auf:
-
Get()
, um den Anfangszustand der DSC-Ressource abzurufen -
Test()
, um zu sehen, ob die DSC-Ressource den gewünschten Zustand ansieht -
Set()
, um den gewünschten Zustand zu erzwingen -
Test()
, um zu sehen, ob die DSC-Ressource es als richtig festgelegt betrachtet -
Get()
, um den endgültigen Zustand der DSC-Ressource zu bestätigen
Szenario: TSToy sollte im Benutzerbereich nicht automatisch aktualisiert werden
In diesem Szenario muss die vorhandene Konfiguration im Benutzerbereich so konfiguriert werden, dass sie nicht automatisch aktualisiert wird. Alle anderen Einstellungen sollten unverändert bleiben.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $false
Ensure = 'Present'
}
}
Get-Content -Path $TSToyUserPath
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 $TSToyUserPath
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 30
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'False'
Actual boolean value of 'True'
}
InDesiredState : False
RebootRequired : False
InDesiredState : True
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : False
UpdateFrequency : 30
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'False'
Actual boolean value of 'False'
}
{
"unmanaged_key": true,
"updates": {
"automatic": false,
"checkFrequency": 30
}
}
Szenario: Tailspin sollte nach jedem Zeitplan im Benutzerbereich automatisch aktualisiert werden.
In diesem Szenario muss die vorhandene Konfiguration im Benutzerbereich so konfiguriert werden, dass sie automatisch aktualisiert wird. Alle anderen Einstellungen sollten unverändert bleiben.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
Ensure = 'Present'
}
}
Get-Content -Path $TSToyUserPath
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 $TSToyUserPath
{
"unmanaged_key": true,
"updates": {
"automatic": false,
"checkFrequency": 30
}
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : False
UpdateFrequency : 30
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'False'
}
InDesiredState : False
RebootRequired : False
InDesiredState : True
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 30
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
}
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
Szenario: TSToy sollte im Benutzerbereich täglich automatisch aktualisiert werden.
In diesem Szenario muss die vorhandene Konfiguration im Benutzerbereich so konfiguriert werden, dass sie automatisch und täglich aktualisiert wird. Alle anderen Einstellungen sollten unverändert bleiben.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $true
UpdateFrequency = 1
Ensure = 'Present'
}
}
Get-Content -Path $TSToyUserPath
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 $TSToyUserPath
{
"unmanaged_key": true,
"updates": {
"automatic": true,
"checkFrequency": 30
}
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 30
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
,
Tailspin.Tailspin.UpdateFrequency:
Checked value of the 'updates.checkFrequency' key in
the TSToy configuration file.
Expected integer value of '1'.
Actual integer value of '30'.
}
InDesiredState : False
RebootRequired : False
InDesiredState : True
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 1
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file to exist at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
,
Tailspin.Tailspin.UpdateFrequency:
Checked value of the 'updates.checkFrequency' key in
the TSToy configuration file.
Expected integer value of '1'.
Actual integer value of '1'.
}
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 1,
"automatic": true
}
}
Szenario: TSToy sollte keine Benutzerbereichskonfiguration haben
In diesem Szenario sollte die Konfigurationsdatei für TSToy im Benutzerbereich nicht vorhanden sein. Wenn dies der Fall ist, sollte die DSC-Ressource die Datei löschen.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'User'
UpdateAutomatically = $false
Ensure = 'Absent'
}
}
Get-Content -Path $TSToyUserPath
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 $TSToyUserPath
{
"unmanaged_key": true,
"updates": {
"checkFrequency": 1,
"automatic": true
}
}
ConfigurationScope : User
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 1
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file not to exist at 'C:\Users\ml
ombardi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.j
son'.
The configuration file exists at 'C:\Users\mlombardi\App
Data\Roaming\TailSpinToys\tstoy\tstoy.config.json'.
}
InDesiredState : False
RebootRequired : False
InDesiredState : True
ConfigurationScope : User
Ensure : Absent
UpdateAutomatically : False
UpdateFrequency : 0
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the User scope.
Expected configuration file not to exist at 'C:\Users\ml
ombardi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.j
son'.
The configuration file was not found at 'C:\Users\mlomba
rdi\AppData\Roaming\TailSpinToys\tstoy\tstoy.config.json'
.
}
False
Szenario: TSToy sollte automatisch jede Woche im Computerbereich aktualisiert werden.
In diesem Szenario gibt es keine definierte Konfiguration im Computerbereich. Der Computerbereich muss so konfiguriert werden, dass er automatisch und täglich aktualisiert wird. Die DSC-Ressource sollte die Datei und alle übergeordneten Ordner nach Bedarf erstellen.
. ./Helpers.ps1
$DesiredState = @{
Name = 'Tailspin'
Module = 'ExampleResources'
Property = @{
ConfigurationScope = 'Machine'
UpdateAutomatically = $true
Ensure = 'Present'
}
}
Test-Path -Path $TSToyMachinePath, (Split-Path -Path $TSToyMachinePath)
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 $TSToyMachinePath
False
False
ConfigurationScope : Machine
Ensure : Absent
UpdateAutomatically : False
UpdateFrequency : 0
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the Machine scope.
Expected configuration file to exist at
'C:\ProgramData\TailSpinToys\tstoy\tstoy.config.json'.
The configuration file was not found at
'C:\ProgramData\TailSpinToys\tstoy\tstoy.config.json'.
}
InDesiredState : False
RebootRequired : False
InDesiredState : True
ConfigurationScope : Machine
Ensure : Present
UpdateAutomatically : True
UpdateFrequency : 0
Reasons : {
Tailspin.Tailspin.Ensure:
Checked existence of the TSToy configuration file in
the Machine scope.
Expected configuration file to exist at
'C:\ProgramData\TailSpinToys\tstoy\tstoy.config.json'.
The configuration file exists at
'C:\ProgramData\TailSpinToys\tstoy\tstoy.config.json'.
,
Tailspin.Tailspin.UpdateAutomatically:
Checked value of the 'updates.automatic' key in the
TSToy configuration file.
Expected boolean value of 'True'
Actual boolean value of 'True'
}
{
"updates": {
"automatic": true
}
}
Überprüfung
In diesem Tutorial:
- Erstellen eines Gerüsts für ein PowerShell-Modul und Implementieren der
Tailspin
klassenbasierten DSC-Ressource - Definiert die Eigenschaften der DSC-Ressource zum Verwalten des Updateverhaltens der TSToy-Anwendung im Computer- und Benutzerbereich mit Überprüfung für diese Eigenschaften
- Implementierte Enumerationen für die
$Ensure
Eigenschaften und$ConfigurationScope
- Implementieren der
ExampleResourcesReason
-Klasse zum Melden von Zustandsüberschreitungen einer Ressource in der Computerkonfiguration - Implementierung der
GetConfigurationFile()
Hilfsmethode, um den Speicherort der TSToy-Anwendungskonfiguration im Computer- und Benutzerbereich plattformübergreifend zuverlässig zu ermitteln -
Get()
Die -Methode wurde implementiert, um den aktuellen Zustand der DSC-Ressource abzurufen und zur Verwendung in denTest()
Methoden undSet()
zwischenzuspeichern. -
GetReasons()
Die Hilfsmethode wurde implementiert, um zu überprüfen, ob sich die DSC-Ressource im gewünschten Zustand befindet, und, falls dies nicht der Fall ist, um aufzulisten, wie sich der Zustand nicht befindet. -
Test()
Die -Methode wurde implementiert, um den aktuellen Status des TSToy-Updateverhaltens in einem bestimmten Bereich anhand des gewünschten Zustands zu überprüfen. - Die ToConfigJson-Methode wurde implementiert, um den gewünschten Zustand der DSC-Ressource in das JSON-Objekt zu konvertieren, das die TSToy-Anwendung für ihre Konfigurationsdatei benötigt, wobei nicht verwaltete Einstellungen berücksichtigt werden.
- Implementierung der
Set()
Methode und der Hilfsmethoden Create, Remove und Update , um den gewünschten Zustand für das Updateverhalten von TSToy in einem bestimmten Bereich zu erzwingen, um sicherzustellen, dass die DSC-Ressource keine unerwünschten Nebenwirkungen hat - Manuell getestete gängige Verwendungsszenarien für die DSC-Ressource
Am Ende der Implementierung sieht Ihre Moduldefinition wie folgt aus:
[DscResource()]
class Tailspin {
[DscProperty(Key)] [TailspinScope]
$ConfigurationScope
[DscProperty()] [TailspinEnsure]
$Ensure = [TailspinEnsure]::Present
[DscProperty(Mandatory)] [bool]
$UpdateAutomatically
[DscProperty()] [int] [ValidateRange(1, 90)]
$UpdateFrequency
[DscProperty(NotConfigurable)] [ExampleResourcesReason[]]
$Reasons
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
$CurrentState.Reasons = $this.GetReasons($CurrentState)
$this.CachedCurrentState = $CurrentState
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
}
$CurrentState.Reasons = $this.GetReasons($CurrentState)
$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
}
}
[ExampleResourcesReason[]] GetReasons([Tailspin]$CurrentState) {
[ExampleResourcesReason[]]$DefinedReasons = @()
$FilePath = $this.GetConfigurationFile()
if ($this.Ensure -eq [TailspinEnsure]::Present) {
$Expected = "Expected configuration file to exist at '$FilePath'."
} else {
$Expected = "Expected configuration file not to exist at '$FilePath'."
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Present) {
$Actual = "The configuration file exists at '$FilePath'."
} else {
$Actual = "The configuration file was not found at '$FilePath'."
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.Ensure"
Phrase = @(
"Checked existence of the TSToy configuration file in the $($this.ConfigurationScope) scope."
$Expected
$Actual
) -join "`n`t"
}
if ($CurrentState.Ensure -ne $this.Ensure) {
return $DefinedReasons
}
if ($CurrentState.Ensure -eq [TailspinEnsure]::Absent) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateAutomatically"
Phrase = (@(
"Checked value of the 'updates.automatic' key in the TSToy configuration file."
"Expected boolean value of '$($this.UpdateAutomatically)'"
"Actual boolean value of '$($CurrentState.UpdateAutomatically)'"
) -join "`n`t")
}
# Short-circuit the check; UpdateFrequency isn't defined by caller
if ($this.UpdateFrequency -eq 0) {
return $DefinedReasons
}
$DefinedReasons += [ExampleResourcesReason]@{
Code = "Tailspin.Tailspin.UpdateFrequency"
Phrase = (@(
"Checked value of the 'updates.checkFrequency' key in the TSToy configuration file."
"Expected integer value of '$($this.UpdateFrequency)'."
"Actual integer value of '$($CurrentState.UpdateFrequency)'."
) -join "`n`t")
}
return $DefinedReasons
}
[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
}
class ExampleResourcesReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
[string] ToString() {
return "`n$($this.Code):`n`t$($this.Phrase)`n"
}
}
Bereinigen
Wenn Sie dieses Modul nicht weiter verwenden möchten, löschen Sie den ExampleResources
Ordner und die darin enthaltenen Dateien.
Nächste Schritte
- Erfahren Sie mehr über klassenbasierte DSC-Ressourcen, erfahren Sie, wie sie funktionieren, und überlegen Sie, warum die DSC-Ressource in diesem Tutorial auf diese Weise implementiert ist.
- Informieren Sie sich über das Computerkonfigurationsfeature von Azure Automanage , um zu verstehen, wie Sie damit Ihre Systeme überwachen und konfigurieren können.
- Überlegen Sie, wie diese DSC-Ressource verbessert werden kann. Gibt es Edgefälle oder Features, die nicht verarbeitet werden? Aktualisieren Sie die Implementierung, um sie zu behandeln.