Aracılığıyla paylaş


PowerShell sınıfları ile özel bir DSC kaynağı yazma

Şunun için geçerlidir: Windows PowerShell 5.0

Windows PowerShell 5.0'da PowerShell sınıflarının kullanıma sunulmasıyla, artık bir sınıf oluşturarak bir DSC kaynağı tanımlayabilirsiniz. sınıfı hem şemayı hem de kaynağın uygulamasını tanımlar, bu nedenle ayrı bir MOF dosyası oluşturmanıza gerek yoktur. DSCResources klasörü gerekli olmadığından, sınıf tabanlı bir kaynağın klasör yapısı da daha basittir.

Sınıf tabanlı bir DSC kaynağında şema, özellik türünü belirtmek için özniteliklerle değiştirilebilen sınıfın özellikleri olarak tanımlanır. Kaynak, Get(), Set()ve Test() yöntemleri (betik kaynağındaki Get-TargetResource, Set-TargetResourceve Test-TargetResource işlevlerine eşdeğerdir) tarafından uygulanır.

Bu makalede, belirtilen yolda bir dosyayı yöneten NewFile adlı basit bir kaynak oluşturacağız.

DSC kaynakları hakkında daha fazla bilgi için bkz. Özel Windows PowerShell İstenen Durum Yapılandırma Kaynakları oluşturma

Not

Genel koleksiyonlar sınıf tabanlı kaynaklarda desteklenmez.

Sınıf kaynağı için klasör yapısı

PowerShell sınıfına sahip bir DSC özel kaynağı uygulamak için aşağıdaki klasör yapısını oluşturun. sınıfı MyDscResource.psm1 ve modül bildirimi MyDscResource.psd1içinde tanımlanır.

$env:ProgramFiles\WindowsPowerShell\Modules (folder)
    |- MyDscResource (folder)
        MyDscResource.psm1
        MyDscResource.psd1

Sınıfı oluşturma

Bir PowerShell sınıfı oluşturmak için class anahtar sözcüğünü kullanırsınız. Sınıfın bir DSC kaynağı olduğunu belirtmek için DscResource() özniteliğini kullanın. sınıfının adı DSC kaynağının adıdır.

[DscResource()]
class NewFile {
}

Özellikleri bildirme

DSC kaynak şeması sınıfının özellikleri olarak tanımlanır. Üç özelliği aşağıdaki gibi bildiririz.

[DscProperty(Key)]
[string] $path

[DscProperty(Mandatory)]
[ensure] $ensure

[DscProperty()]
[string] $content

[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons

Özelliklerin öznitelikler tarafından değiştirildiğine dikkat edin. Özniteliklerin anlamı aşağıdaki gibidir:

  • DscProperty(Anahtar): özelliği gereklidir. özelliği bir anahtardır. Anahtar olarak işaretlenmiş tüm özelliklerin değerleri, yapılandırma içindeki bir kaynak örneğini benzersiz olarak tanımlamak için birleştirilmelidir.
  • DscProperty(Zorunlu): Özelliği gereklidir.
  • DscProperty(NotConfigurable): Özelliği salt okunurdur. Bu öznitelikle işaretlenmiş özellikler bir yapılandırma tarafından ayarlanamaz, ancak mevcut olduğunda Get() yöntemiyle doldurulur.
  • DscProperty(): Özelliği yapılandırılabilir, ancak gerekli değildir.

$Path ve $SourcePath özellikleri her iki dizedir. $CreationTime bir DateTime özelliğidir. $Ensure özelliği, aşağıdaki gibi tanımlanan bir numaralandırma türüdür.

enum Ensure
{
    Absent
    Present
}

Sınıfları ekleme

Kaynağınızda kullanabileceğiniz tanımlı özelliklere sahip yeni bir tür eklemek isterseniz, yukarıda açıklandığı gibi özellik türlerine sahip bir sınıf oluşturmanız yeter.

class MyDscResourceReason {
    [DscProperty()]
    [string] $Code

    [DscProperty()]
    [string] $Phrase
}

Not

MyDscResourceReason sınıfı burada modülün adı ön ek olarak bildirilir. Katıştırılmış sınıflara herhangi bir ad verebilirsiniz, ancak iki veya daha fazla modül aynı ada sahip bir sınıf tanımlarsa ve her ikisi de bir yapılandırmada kullanılırsa PowerShell bir özel durum oluşturur.

DSC'de ad çakışmalarından kaynaklanan özel durumları önlemek için, katıştırılmış sınıflarınızın adlarını modül adıyla ön ekleyin. Katıştırılmış sınıfınızın adı zaten çakışma olasılığı düşükse, bunu ön ek olmadan kullanabilirsiniz.

DSC Kaynağınız Azure Automanage'ın makine yapılandırma özelliğiyle kullanılmak üzere tasarlanmışsa, Nedenler özelliği için her zaman oluşturduğunuz eklenmiş sınıfın adını önekleyin.

Genel ve Özel işlevler

Aynı modül dosyasında PowerShell işlevleri oluşturabilir ve bunları DSC sınıf kaynağınızın yöntemleri içinde kullanabilirsiniz. İşlevlerin genel olarak bildirilmesi gerekir, ancak bu ortak işlevlerin içindeki betik blokları özel işlevleri çağırabilir. Tek fark, bunların modül bildiriminin FunctionsToExport özelliğinde listelenip listelenmedikleridir.

<#
   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
}

Yöntemleri uygulama

Get(), Set()ve Test() yöntemleri, betik kaynağındaki Get-TargetResource, Set-TargetResourceve Test-TargetResource işlevlerine benzer.

En iyi yöntem olarak, sınıf uygulaması içindeki kod miktarını en aza indirin. Bunun yerine kodunuzun büyük bölümünü modüldeki genel işlevlere taşıyın. Bu işlev bağımsız olarak test edilebilir.

<#
    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
}

Dosyanın tamamı

Tam sınıf dosyası aşağıdaki gibidir.

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
    }
}

Bildirim oluşturma

Sınıf tabanlı bir kaynağı DSC altyapısının kullanımına açmak için bildirim dosyasına modülün kaynağı dışarı aktarmasını belirten bir DscResourcesToExport deyimi eklemeniz gerekir. Bildirimimiz şu şekilde görünür:

@{

    # 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

    }
}

Kaynağı test edin

Sınıf ve bildirim dosyalarını daha önce açıklandığı gibi klasör yapısına kaydettikten sonra, yeni kaynağı kullanan bir yapılandırma oluşturabilirsiniz. DSC yapılandırması çalıştırma hakkında bilgi için bkz.yapılandırmaları . Aşağıdaki yapılandırma, /tmp/test.txt dosyasının var olup olmadığını ve içeriğin 'Content' özelliği tarafından sağlanan dizeyle eşleşip eşleşmediğini denetler. Aksi takdirde, dosyanın tamamı yazılır.

Configuration MyConfig
{
    Import-DSCResource -ModuleName NewFile
    NewFile testFile
    {
        Path = "/tmp/test.txt"
        Content = "DSC Rocks!"
        Ensure = "Present"
    }
}
MyConfig

PsDscRunAsCredential'ı destekleme

[Not] PsDscRunAsCredential PowerShell 5.0 ve sonraki sürümlerde desteklenir.

PsDscRunAsCredential özelliği, kaynağın belirtilen kimlik bilgileri kümesi altında çalıştırılması gerektiğini belirtmek için DSC yapılandırmalarında kaynak bloğunda kullanılabilir. Daha fazla bilgi için bkz.kullanıcı kimlik bilgileriyle DSC çalıştırma .

Kaynağınız için PsDscRunAsCredential gerektirme veya izin verme

özniteliği RunAsCredentialisteğe bağlı bir parametre alır. Bu parametre üç değerden birini alır:

  • Optional PsDscRunAsCredential bu kaynağı çağıran yapılandırmalar için isteğe bağlıdır. Bu varsayılan değerdir.
  • Mandatory PsDscRunAsCredential bu kaynağı çağıran tüm yapılandırmalar için kullanılmalıdır.
  • bu kaynağı çağıran NotSupported Yapılandırmaları PsDscRunAsCredentialkullanamaz.
  • Default Optionalile aynıdır.

Örneğin, özel kaynağınızın PsDscRunAsCredentialkullanılmasını desteklemediğini belirtmek için aşağıdaki özniteliği kullanın:

[DscResource(RunAsCredential=NotSupported)]
class NewFile {
}

Modülde birden çok sınıf kaynağı bildirme

Modül, birden çok sınıf tabanlı DSC kaynağı tanımlayabilir. Yalnızca aynı .psm1 dosyasındaki tüm sınıfları bildirmeniz ve her adı .psd1 bildirimine eklemeniz gerekir.

$env:ProgramFiles\WindowsPowerShell\Modules (folder)
     |- MyDscResource (folder)
        |- MyDscResource.psm1
           MyDscResource.psd1

Kullanıcı bağlamını erişme

Özel bir kaynağın içinden kullanıcı bağlamlarına erişmek için $global:PsDscContextotomatik değişkenini kullanabilirsiniz.

Örneğin aşağıdaki kod, kaynağın çalıştığı kullanıcı bağlamını ayrıntılı çıkış akışına yazar:

if (PsDscContext.RunAsUser) {
    Write-Verbose "User: $global:PsDscContext.RunAsUser";
}

Ayrıca Bkz.

Özel Windows PowerShell İstenen Durum Yapılandırma Kaynakları oluşturma