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.
Platí pro: Windows PowerShell 5.0
Po zavedení tříd PowerShellu ve Windows PowerShellu 5.0 teď můžete definovat prostředek DSC vytvořením třídy. Třída definuje schéma i implementaci prostředku, takže není nutné vytvořit samostatný soubor MOF. Struktura složek pro prostředek založený na třídách je také jednodušší, protože složka DSCResources není nutná.
V prostředku DSC založeném na třídě je schéma definováno jako vlastnosti třídy, které lze upravit pomocí atributů pro určení typu vlastnosti. Prostředek je implementován metodami Get(), Set(), a Test() (ekvivalentní Get-TargetResourcefunkcím , Set-TargetResource, a Test-TargetResource v prostředku skriptu.
V tomto článku vytvoříme jednoduchý prostředek s názvem NewFile , který spravuje soubor v zadané cestě.
Další informace o prostředcích DSC najdete v tématu Vytvoření vlastních prostředků konfigurace požadovaného stavu prostředí Windows PowerShell.
Poznámka
Obecné kolekce nejsou podporovány v prostředcích založených na třídách.
Struktura složek pro prostředek třídy
Pokud chcete implementovat vlastní prostředek DSC s třídou PowerShellu, vytvořte následující strukturu složek.
Třída je definována v MyDscResource.psm1 a manifest modulu je definován v MyDscResource.psd1.
$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
MyDscResource.psm1
MyDscResource.psd1
Vytvoření třídy
Klíčové slovo třídy použijete k vytvoření třídy PowerShellu. Chcete-li určit, že třída je prostředkem DSC, použijte atribut.DscResource() Název třídy je název prostředku DSC.
[DscResource()]
class NewFile {
}
Deklarace vlastností
Schéma prostředků DSC je definováno jako vlastnosti třídy. Deklarujeme tři vlastnosti následujícím způsobem.
[DscProperty(Key)]
[string] $path
[DscProperty(Mandatory)]
[ensure] $ensure
[DscProperty()]
[string] $content
[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons
Všimněte si, že vlastnosti jsou upraveny atributy. Význam atributů je následující:
- DscProperty(Key): Vlastnost je povinná. Vlastnost je klíč. Hodnoty všech vlastností označených jako klíče musí být kombinovány, aby bylo možné jedinečně identifikovat instanci prostředku v rámci konfigurace.
- DscProperty(Povinné): Vlastnost je povinná.
-
DscProperty(NotConfigurable): Vlastnost je jen pro čtení. Vlastnosti označené tímto atributem nelze nastavit konfigurací, ale jsou naplněny metodou
Get(), pokud je k dispozici. - DscProperty(): Vlastnost je konfigurovatelná, ale není vyžadována.
Vlastnosti $Path a $SourcePath jsou oba řetězce. Jedná $CreationTime se o vlastnost DateTime . Vlastnost $Ensure je typ výčtu, definovaný následovně.
enum Ensure
{
Absent
Present
}
Vložené třídy
Pokud chcete zahrnout nový typ s definovanými vlastnostmi, které můžete použít v rámci prostředku, stačí vytvořit třídu s typy vlastností, jak je popsáno výše.
class MyDscResourceReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
Poznámka
Třída MyDscResourceReason je zde deklarována s názvem modulu jako prefixem. I když můžete vloženým třídám dát libovolný název, pokud dva nebo více modulů definují třídu se stejným názvem a používají se v konfiguraci, PowerShell vyvolá výjimku.
Abyste se vyhnuli výjimkám způsobeným konflikty názvů v DSC, předpona názvů vložených tříd nahraďte názvem modulu. Pokud je název vložené třídy pravděpodobně konfliktní, můžete ho použít bez předpony.
Pokud je váš prostředek DSC navržený pro použití s konfigurací počítače Azure, vždy před název vložené třídy, kterou vytvoříte, přidejte předponu pro vlastnost Reasons .
Veřejné a soukromé funkce
Funkce PowerShellu můžete vytvořit v rámci stejného souboru modulu a použít je uvnitř metod prostředku třídy DSC. Funkce musí být deklarovány jako veřejné, ale bloky skriptu v rámci těchto veřejných funkcí mohou volat funkce, které jsou soukromé. Jediný rozdíl je v tom, zda jsou uvedeny ve FunctionsToExport vlastnosti manifestu modulu.
<#
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
}
Implementace metod
Metody Get(), Set(), a Test() jsou analogické funkcím Get-TargetResource, Set-TargetResource, a Test-TargetResource v prostředku skriptu.
Osvědčeným postupem je minimalizovat množství kódu v rámci implementace třídy. Místo toho přesuňte většinu kódu na veřejné funkce v modulu, které je pak možné nezávisle testovat.
<#
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
}
Úplný soubor
Kompletní soubor třídy následuje.
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
}
}
Vytvoření manifestu
Chcete-li zpřístupnit prostředek založený na třídě pro modul DSC, musíte do souboru manifestu zahrnout DscResourcesToExport příkaz, který dává modulu pokyn k exportu prostředku. Náš manifest vypadá takto:
@{
# 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
}
}
Otestování prostředku
Po uložení souborů třídy a manifestu ve struktuře složek, jak je popsáno výše, můžete vytvořit konfiguraci, která používá nový prostředek. Informace o tom, jak spustit konfiguraci DSC, najdete v tématu Uzákonění konfigurací. Následující konfigurace zkontroluje, zda soubor at /tmp/test.txt existuje a zda obsah odpovídá řetězci poskytnutému vlastností 'Content'. Pokud ne, zapíše se celý soubor.
Configuration MyConfig
{
Import-DSCResource -ModuleName NewFile
NewFile testFile
{
Path = "/tmp/test.txt"
Content = "DSC Rocks!"
Ensure = "Present"
}
}
MyConfig
Podpora psDscRunAsCredential
[Poznámka] PsDscRunAsCredential je podporován v PowerShellu 5.0 a novějším.
Vlastnost PsDscRunAsCredential lze použít v bloku prostředků konfigurace DSC k určení, že prostředek má být spuštěn pod zadanou sadou přihlašovacích údajů. Další informace najdete v tématu Spuštění DSC s přihlašovacími údaji uživatele.
Vyžadovat nebo zakázat PsDscRunAsCredential pro váš prostředek
Atribut DscResource() přebírá volitelný parametr RunAsCredential. Tento parametr má jednu ze tří hodnot:
-
OptionalPsDscRunAsCredential je volitelný pro konfigurace, které volají tento prostředek. Toto je výchozí hodnota. -
MandatoryPsDscRunAsCredential musí být použit pro jakoukoli konfiguraci, která volá tento prostředek. -
NotSupportedKonfigurace, které volají tento prostředek, nemohou používat PsDscRunAsCredential. -
Defaultstejné jakoOptional.
Pomocí následujícího atributu můžete například určit, že váš vlastní prostředek nepodporuje použití PsDscRunAsCredential :
[DscResource(RunAsCredential=NotSupported)]
class NewFile {
}
Deklarování více prostředků třídy v modulu
Modul může definovat více prostředků DSC založených na třídách. Stačí deklarovat všechny třídy ve stejném .psm1 souboru a zahrnout každý název do manifestu .psd1 .
$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
|- MyDscResource.psm1
MyDscResource.psd1
Přístup k kontextu uživatele
Chcete-li získat přístup ke kontextu uživatele z vlastního zdroje, můžete použít automatickou proměnnou $global:PsDscContext.
Například následující kód zapíše kontext uživatele, pod kterým je prostředek spuštěný do podrobného výstupního datového proudu:
if (PsDscContext.RunAsUser) {
Write-Verbose "User: $global:PsDscContext.RunAsUser";
}
Viz také
Sestavení vlastních prostředků konfigurace požadovaného stavu prostředí Windows PowerShell