Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Van toepassing op: Windows PowerShell 5.0
Met de introductie van PowerShell-klassen in Windows PowerShell 5.0 kunt u nu een DSC-resource definiëren door een klasse te maken. De klasse definieert zowel het schema als de implementatie van de resource, dus u hoeft geen afzonderlijk MOF-bestand te maken. De mappenstructuur voor een op klassen gebaseerde bron is ook eenvoudiger, omdat een DSCResources-map niet nodig is.
In een DSC-resource op basis van een klasse wordt het schema gedefinieerd als eigenschappen van de klasse die kan worden gewijzigd met kenmerken om het eigenschapstype op te geven. De resource wordt geïmplementeerd door Get(), Set(), en Test() methoden (gelijk aan de Get-TargetResource, Set-TargetResource, en Test-TargetResource functies in een scriptresource.
In dit artikel maken we een eenvoudige resource met de naam NewFile die een bestand in een opgegeven pad beheert.
Zie Aangepaste Windows PowerShell-configuratiebronnen voor gewenste status bouwen voor meer informatie over DSC-bronnen
Notitie
Algemene verzamelingen worden niet ondersteund in op klassen gebaseerde resources.
Mapstructuur voor een klasseresource
Als u een aangepaste DSC-resource wilt implementeren met een PowerShell-klasse, maakt u de volgende mapstructuur.
De klasse is gedefinieerd in MyDscResource.psm1 en het modulemanifest is gedefinieerd in MyDscResource.psd1.
$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
MyDscResource.psm1
MyDscResource.psd1
De klasse maken
U gebruikt het trefwoord klasse om een PowerShell-klasse te maken. Gebruik het DscResource() kenmerk om op te geven dat een klasse een DSC-resource is. De naam van de klasse is de naam van de DSC-resource.
[DscResource()]
class NewFile {
}
Eigenschappen declareren
Het DSC-resourceschema wordt gedefinieerd als eigenschappen van de klasse. We declareren drie eigenschappen als volgt.
[DscProperty(Key)]
[string] $path
[DscProperty(Mandatory)]
[ensure] $ensure
[DscProperty()]
[string] $content
[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons
U ziet dat de eigenschappen worden gewijzigd door kenmerken. De betekenis van de kenmerken is als volgt:
- DscProperty(Key): De eigenschap is vereist. De eigenschap is een sleutel. De waarden van alle eigenschappen die als sleutels zijn gemarkeerd, moeten worden gecombineerd om een resource-exemplaar in een configuratie uniek te identificeren.
- DscProperty(Verplicht): De eigenschap is verplicht.
-
DscProperty(NotConfigurable): De eigenschap is alleen-lezen. Eigenschappen die met dit kenmerk zijn gemarkeerd, kunnen niet worden ingesteld door een configuratie, maar worden ingevuld door de
Get()methode indien aanwezig. - DscProperty(): De eigenschap is configureerbaar, maar is niet vereist.
De $Path eigenschappen en $SourcePath zijn beide tekenreeksen. Het $CreationTime is een DateTime-eigendom . De $Ensure eigenschap is een opsommingstype, dat als volgt wordt gedefinieerd.
enum Ensure
{
Absent
Present
}
Klassen insluiten
Als u een nieuw type wilt opnemen met gedefinieerde eigenschappen die u in uw resource kunt gebruiken, maakt u een klasse met eigenschapstypen zoals hierboven beschreven.
class MyDscResourceReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
Notitie
De MyDscResourceReason klasse wordt hier gedeclareerd met de naam van de module als voorvoegsel. Hoewel u ingesloten klassen een willekeurige naam kunt geven, als twee of meer modules een klasse met dezelfde naam definiëren en beide worden gebruikt in een configuratie, genereert PowerShell een uitzondering.
Als u uitzonderingen wilt voorkomen die worden veroorzaakt door naamconflicten in DSC, moet u de namen van uw ingesloten klassen vooraf laten gaan door de modulenaam. Als de naam van uw ingesloten klasse al niet conflicteert, kunt u deze gebruiken zonder voorvoegsel.
Als uw DSC-resource is ontworpen voor gebruik met de configuratie van Azure-machines, moet u altijd de naam van de ingesloten klasse die u maakt voor de eigenschap Reasons voorafgaan.
Openbare en privéfuncties
U kunt PowerShell-functies maken in hetzelfde modulebestand en deze gebruiken in de methoden van uw DSC-klasseresource. De functies moeten als openbaar worden gedeclareerd, maar de scriptblokken binnen deze openbare functies kunnen functies aanroepen die privé zijn. Het enige verschil is of ze worden vermeld in de FunctionsToExport eigenschap van het modulemanifest.
<#
Public Functions
#>
function Get-File {
param(
[ensure]$ensure,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$fileContent = [MyDscResourceReason]::new()
$fileContent.code = 'file:file:content'
$filePresent = [MyDscResourceReason]::new()
$filePresent.code = 'file:file:path'
$ensureReturn = 'Absent'
$fileExists = Test-path $path -ErrorAction SilentlyContinue
if ($true -eq $fileExists) {
$filePresent.phrase = "The file was expected to be: $ensure`nThe file exists at path: $path"
$existingFileContent = Get-Content $path -Raw
if ([string]::IsNullOrEmpty($existingFileContent)) {
$existingFileContent = ''
}
if ($false -eq ([string]::IsNullOrEmpty($content))) {
$content = $content | ConvertTo-SpecialChars
}
$fileContent.phrase = "The file was expected to contain: $content`nThe file contained: $existingFileContent"
if ($content -eq $existingFileContent) {
$ensureReturn = 'Present'
}
}
else {
$filePresent.phrase = "The file was expected to be: $ensure`nThe file does not exist at path: $path"
$path = 'file not found'
}
return @{
ensure = $ensureReturn
path = $path
content = $existingFileContent
Reasons = @($filePresent,$fileContent)
}
}
function Set-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
Remove-Item $path -Force -ErrorAction SilentlyContinue
if ($ensure -eq "Present") {
New-Item $path -ItemType File -Force
if ([ValidateNotNullOrEmpty()]$content) {
$content | ConvertTo-SpecialChars | Set-Content $path -NoNewline -Force
}
}
}
function Test-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$test = $false
$get = Get-File @PSBoundParameters
if ($get.ensure -eq $ensure) {
$test = $true
}
return $test
}
<#
Private Functions
#>
function ConvertTo-SpecialChars {
param(
[parameter(Mandatory = $true,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$string
)
$specialChars = @{
'`n' = "`n"
'\\n' = "`n"
'`r' = "`r"
'\\r' = "`r"
'`t' = "`t"
'\\t' = "`t"
}
foreach ($char in $specialChars.Keys) {
$string = $string -replace ($char,$specialChars[$char])
}
return $string
}
De methoden implementeren
De Get(), Set(), en Test() methoden zijn analoog aan de Get-TargetResource, Set-TargetResource, en Test-TargetResource functies in een scriptresource.
Minimaliseer als best practice de hoeveelheid code binnen de klasse-implementatie. Verplaats in plaats daarvan het merendeel van uw code naar openbare functies in de module, die vervolgens onafhankelijk kunnen worden getest.
<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate
resources. This method returns an instance of this class with the
updated key properties.
#>
[NewFile] Get() {
$get = Get-File -ensure $this.ensure -path $this.path -content $this.content
return $get
}
<#
This method is equivalent of the Set-TargetResource script function.
It sets the resource to the desired state.
#>
[void] Set() {
$set = Set-File -ensure $this.ensure -path $this.path -content $this.content
}
<#
This method is equivalent of the Test-TargetResource script
function. It should return True or False, showing whether the
resource is in a desired state.
#>
[bool] Test() {
$test = Test-File -ensure $this.ensure -path $this.path -content $this.content
return $test
}
Het volledige bestand
Het volledige klassebestand volgt.
enum ensure {
Absent
Present
}
<#
This class is used within the DSC Resource to standardize how data
is returned about the compliance details of the machine. Note that
the class name is prefixed with the module name - this helps prevent
errors raised when multiple modules with DSC Resources define the
Reasons property for reporting when they're out-of-state.
#>
class MyDscResourceReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
<#
Public Functions
#>
function Get-File {
param(
[ensure]$ensure,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$fileContent = [MyDscResourceReason]::new()
$fileContent.code = 'file:file:content'
$filePresent = [MyDscResourceReason]::new()
$filePresent.code = 'file:file:path'
$ensureReturn = 'Absent'
$fileExists = Test-path $path -ErrorAction SilentlyContinue
if ($true -eq $fileExists) {
$filePresent.phrase = "The file was expected to be: $ensure`nThe file exists at path: $path"
$existingFileContent = Get-Content $path -Raw
if ([string]::IsNullOrEmpty($existingFileContent)) {
$existingFileContent = ''
}
if ($false -eq ([string]::IsNullOrEmpty($content))) {
$content = $content | ConvertTo-SpecialChars
}
$fileContent.phrase = "The file was expected to contain: $content`nThe file contained: $existingFileContent"
if ($content -eq $existingFileContent) {
$ensureReturn = 'Present'
}
}
else {
$filePresent.phrase = "The file was expected to be: $ensure`nThe file does not exist at path: $path"
$path = 'file not found'
}
return @{
ensure = $ensureReturn
path = $path
content = $existingFileContent
Reasons = @($filePresent,$fileContent)
}
}
function Set-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
Remove-Item $path -Force -ErrorAction SilentlyContinue
if ($ensure -eq "Present") {
New-Item $path -ItemType File -Force
if ([ValidateNotNullOrEmpty()]$content) {
$content | ConvertTo-SpecialChars | Set-Content $path -NoNewline -Force
}
}
}
function Test-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$test = $false
$get = Get-File @PSBoundParameters
if ($get.ensure -eq $ensure) {
$test = $true
}
return $test
}
<#
Private Functions
#>
function ConvertTo-SpecialChars {
param(
[parameter(Mandatory = $true,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$string
)
$specialChars = @{
'`n' = "`n"
'\\n' = "`n"
'`r' = "`r"
'\\r' = "`r"
'`t' = "`t"
'\\t' = "`t"
}
foreach ($char in $specialChars.Keys) {
$string = $string -replace ($char,$specialChars[$char])
}
return $string
}
<#
This resource manages the file in a specific path.
[DscResource()] indicates the class is a DSC resource
#>
[DscResource()]
class NewFile {
<#
This property is the fully qualified path to the file that is
expected to be present or absent.
The [DscProperty(Key)] attribute indicates the property is a
key and its value uniquely identifies a resource instance.
Defining this attribute also means the property is required
and DSC will ensure a value is set before calling the resource.
A DSC resource must define at least one key property.
#>
[DscProperty(Key)]
[string] $path
<#
This property indicates if the settings should be present or absent
on the system. For present, the resource ensures the file pointed
to by $Path exists. For absent, it ensures the file point to by
$Path does not exist.
The [DscProperty(Mandatory)] attribute indicates the property is
required and DSC will guarantee it is set.
If Mandatory is not specified or if it is defined as
Mandatory=$false, the value is not guaranteed to be set when DSC
calls the resource. This is appropriate for optional properties.
#>
[DscProperty(Mandatory)]
[ensure] $ensure
<#
This property is optional. When provided, the content of the file
will be overwridden by this value.
#>
[DscProperty()]
[string] $content
<#
This property reports the reasons the machine is or is not compliant.
[DscProperty(NotConfigurable)] attribute indicates the property is
not configurable in DSC configuration. Properties marked this way
are populated by the Get() method to report additional details
about the resource when it is present.
#>
[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons
<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate
resources. This method returns an instance of this class with the
updated key properties.
#>
[NewFile] Get() {
$get = Get-File -ensure $this.ensure -path $this.path -content $this.content
return $get
}
<#
This method is equivalent of the Set-TargetResource script function.
It sets the resource to the desired state.
#>
[void] Set() {
$set = Set-File -ensure $this.ensure -path $this.path -content $this.content
}
<#
This method is equivalent of the Test-TargetResource script
function. It should return True or False, showing whether the
resource is in a desired state.
#>
[bool] Test() {
$test = Test-File -ensure $this.ensure -path $this.path -content $this.content
return $test
}
}
Een manifest maken
Als u een op klasse gebaseerde resource beschikbaar wilt maken voor de DSC-engine, moet u een DscResourcesToExport instructie opnemen in het manifestbestand waarin de module wordt geïnstrueerd om de resource te exporteren. Ons manifest ziet er als volgt uit:
@{
# Script module or binary module file associated with this manifest.
RootModule = 'NewFile.psm1'
# Version number of this module.
ModuleVersion = '1.0.0'
# ID used to uniquely identify this module
GUID = 'fad0d04e-65d9-4e87-aa17-39de1d008ee4'
# Author of this module
Author = 'Microsoft Corporation'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = ''
# Description of the functionality provided by this module
Description = 'Create and set content of a file'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Functions to export from this module
FunctionsToExport = @('Get-File','Set-File','Test-File')
# DSC resources to export from this module
DscResourcesToExport = @('NewFile')
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @(Power Plan, Energy, Battery)
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
}
}
De resource testen
Nadat u de klasse- en manifestbestanden in de mapstructuur hebt opgeslagen zoals eerder is beschreven, kunt u een configuratie maken die gebruikmaakt van de nieuwe resource. Zie Configuraties uitvoeren voor meer informatie over het uitvoeren van een DSC-configuratie. De volgende configuratie controleert of het bestand bestaat /tmp/test.txt en of de inhoud overeenkomt met de tekenreeks die wordt geleverd door de eigenschap 'Inhoud'. Zo niet, dan wordt het hele bestand geschreven.
Configuration MyConfig
{
Import-DSCResource -ModuleName NewFile
NewFile testFile
{
Path = "/tmp/test.txt"
Content = "DSC Rocks!"
Ensure = "Present"
}
}
MyConfig
Ondersteuning voor PsDscRunAsCredential
[Opmerking] PsDscRunAsCredential wordt ondersteund in PowerShell 5.0 en hoger.
De eigenschap PsDscRunAsCredential kan worden gebruikt in het resourceblok DSC-configuraties om op te geven dat de resource moet worden uitgevoerd onder een opgegeven set referenties. Zie DSC uitvoeren met gebruikersreferenties voor meer informatie.
PsDscRunAsCredential vereisen of weigeren voor uw resource
Het DscResource() kenmerk heeft een optionele parameter RunAsCredential. Deze parameter heeft een van de drie waarden:
-
OptionalPsDscRunAsCredential is optioneel voor configuraties die deze resource aanroepen. Dit is de standaardwaarde. -
MandatoryPsDscRunAsCredential moet worden gebruikt voor elke configuratie die deze resource aanroept. -
NotSupportedConfiguraties die deze resource aanroepen, kunnen geen gebruik maken van PsDscRunAsCredential. -
DefaultHetzelfde alsOptional.
Gebruik bijvoorbeeld het volgende kenmerk om op te geven dat uw aangepaste resource geen ondersteuning biedt voor het gebruik van PsDscRunAsCredential:
[DscResource(RunAsCredential=NotSupported)]
class NewFile {
}
Meerdere klassebronnen declareren in een module
Een module kan meerdere DSC-resources op basis van klassen definiëren. U hoeft alleen maar alle klassen in hetzelfde .psm1 bestand te declareren en elke naam in het .psd1 manifest op te nemen.
$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
|- MyDscResource.psm1
MyDscResource.psd1
Toegang tot de gebruikerscontext
Als u toegang wilt krijgen tot de gebruikerscontext vanuit een aangepaste resource, kunt u de automatische variabele $global:PsDscContextgebruiken.
Met de volgende code wordt bijvoorbeeld de gebruikerscontext geschreven waaronder de resource wordt uitgevoerd naar de uitgebreide uitvoerstroom:
if (PsDscContext.RunAsUser) {
Write-Verbose "User: $global:PsDscContext.RunAsUser";
}
Zie ook
Aangepaste Windows PowerShell-bronnen voor gewenste statusconfiguratie bouwen