共用方式為


撰寫MOF型 DSC 資源

本文說明如何撰寫架構並開發腳本模組來管理 IIS 網站,以建立MOF型 DSC 資源。

重要

從 DSC 3.0 開始,不支援以 MOF 為基礎的 DSC 資源。 如果您要撰寫新的 DSC 資源,並想要使用未來的版本,請改為撰寫 以類別為基礎的 DSC 資源

建立 MOF 結構描述

MOF 型 DSC 資源必須具有架構 (.mof) 檔案,以定義軟體元件的可管理設定。

建立必要的資料夾結構

建立下列資料夾結構。 架構定義於 檔案 Demo_IISWebsite.schema.mof中,而且必要的函式定義於 中 Demo_IISWebsite.psm1。 您可以選擇性地 () .psd1 檔案建立模組指令清單。

$env:ProgramFiles\WindowsPowerShell\Modules (folder)
    |- MyDscResources (folder)
        |- MyDscResources.psd1 (file, Required)
        |- DSCResources (folder)
            |- Demo_IISWebsite (folder)
                |- Demo_IISWebsite.psd1 (file, optional)
                |- Demo_IISWebsite.psm1 (file, required)
                |- Demo_IISWebsite.schema.mof (file, required)

注意

您必須在模組的最上層資料夾下建立名為 DSCResources 的資料夾。 每個 DSC 資源的資料夾名稱必須與 DSC 資源相同。

MOF 檔案的內容

以下是描述 DSC 資源網站屬性的 MOF 檔案範例。 若要遵循此範例,請將此架構儲存至名為 的 Demo_IISWebsite.schema.mof檔案。

[ClassVersion("1.0.0"), FriendlyName("Website")]
class Demo_IISWebsite : OMI_BaseResource
{
  [Key] string Name;
  [Required] string PhysicalPath;
  [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure;
  [write,ValueMap{"Started","Stopped"},Values{"Started", "Stopped"}] string State;
  [write] string Protocol[];
  [write] string BindingInfo[];
  [write] string ApplicationPool;
  [read] string ID;
};

前列程式碼請注意下列事項:

  • FriendlyName 會定義可用來參考此 DSC 資源的名稱。 在這裡範例中, FriendlyNameWebsite
  • DSC 資源的 類別必須衍生自 OMI_BaseResource
  • 屬性上的類型限定符 [Key]表示此屬性可唯一識別資源實例。 每個 DSC 資源都必須至少有一個 [Key] 屬性。
  • [Required]限定符表示使用這個 DSC 資源時,屬性是必要的。
  • [write]限定符表示這個屬性是選擇性的。
  • [read]限定符表示屬性無法由 DSC 資源設定,而且僅供報告之用。
  • 會將可指派給 屬性的值限制為 ValueMap 中定義的值清單。 如需詳細資訊,請參閱 ValueMap and Value Qualifiers (ValueMap 和值限定詞)
  • 針對使用者可以在系統中新增和移除的 DSC 資源,建議在 DSC 資源中包含名為 Ensure 的值 PresentAbsent 屬性。
  • 為您的 DSC 資源命名架構檔案,如下所示: <classname>.schema.mof,其中 <classname> 是架構定義中關鍵詞後面的 class 標識碼。

撰寫腳本模組

MOF 型 DSC 資源的腳本模組會實作 DSC 資源的邏輯。 這個模組中必須包含三個函式,它們是:Get-TargetResourceSet-TargetResourceTest-TargetResource。 這三個函式都必須採用與 DSC 資源架構中所定義之屬性集相同的參數集。 將這三個函式儲存在名為 的 <ResourceName>.psm1檔案中。 在下列範例中,函式會儲存在名為 的 Demo_IISWebsite.psm1檔案中。

注意

當您使用 Invoke-DscResource 多次使用相同的屬性來設定所需的狀態時,您應該不會收到任何錯誤,而且系統應該保持與第一次使用時相同的狀態。 若要這樣做,請確定 您的 Get-TargetResourceTest-TargetResource 函式會保持不變,而且在 Set-TargetResource 具有相同參數值的序列中叫用函式多次,一律與叫用一次相同。

在函式實作中 Get-TargetResource ,使用提供做為參數的 Key 屬性值,來驗證 DSC 資源指定實例的狀態。 此函式必須傳回哈希表,其中會將所有 DSC 資源屬性列為索引鍵,以及這些屬性的實際值當做對應的值。 範例請見下列程式碼。

# The Get-TargetResource function is used to retrieve the current state of a
# website on the system.
function Get-TargetResource {
    param(
        [ValidateSet("Present", "Absent")]
        [string]$Ensure = "Present",

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$PhysicalPath,

        [ValidateSet("Started", "Stopped")]
        [string]$State = "Started",

        [string]$ApplicationPool,

        [string[]]$BindingInfo,

        [string[]]$Protocol
    )

        $getTargetResourceResult = $null;

        <#
          Insert logic that uses the mandatory parameter values to get the
          website and assign it to a variable called $Website Set $ensureResult
          to "Present" if the requested website exists and to "Absent" otherwise
        #>

        # Add all Website properties to the hashtable
        # This example assumes that $Website is not null
        $getTargetResourceResult = @{
            Name            = $Website.Name
            Ensure          = $ensureResult
            PhysicalPath    = $Website.physicalPath
            State           = $Website.state
            ID              = $Website.id
            ApplicationPool = $Website.applicationPool
            Protocol        = $Website.bindings.Collection.protocol
            Binding         = $Website.bindings.Collection.bindingInformation
        }

        $getTargetResourceResult
}

根據使用者為 DSC 資源屬性指定的值, Set-TargetResource 必須執行下列其中一項:

  • 新增網站
  • 更新現有的網站
  • 拿掉現有的網站

下列範例將說明這點。

# The Set-TargetResource function is used to add, update, or remove a website
# on the system.
function Set-TargetResource {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [ValidateSet("Present", "Absent")]
        [string]$Ensure = "Present",

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$PhysicalPath,

        [ValidateSet("Started", "Stopped")]
        [string]$State = "Started",

        [string]$ApplicationPool,

        [string[]]$BindingInfo,

        [string[]]$Protocol
    )

    <#
        If Ensure is set to "Present" and the website specified in the mandatory
          input parameters doesn't exist, then add it using the specified
          parameter values
        Else, if Ensure is set to "Present" and the website does exist, then
          update its properties to match the values provided in the
          non-mandatory parameter values
        Else, if Ensure is set to "Absent" and the website does not exist, then
          do nothing
        Else, if Ensure is set to "Absent" and the website does exist, then
          delete the website
    #>
}

最後,Test-TargetResource 函式必須和 Get-TargetResourceSet-TargetResource 使用相同的參數集。 在您的 實作 中 Test-TargetResource,根據參數集中指定的值,確認系統的目前狀態。 如果目前狀態不符合所需的狀態,則傳回 $false。 否則,傳回 $true

下列程式碼會實作 Test-TargetResource 函式。

function Test-TargetResource {
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param(
        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure,

        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $PhysicalPath,

        [ValidateSet("Started","Stopped")]
        [System.String]
        $State,

        [System.String[]]
        $Protocol,

        [System.String[]]
        $BindingData,

        [System.String]
        $ApplicationPool
    )

    # Get the current state
    $getParameters = @{
        Ensure          = $Ensure 
        Name            = $Name 
        PhysicalPath    = $PhysicalPath 
        State           = $State 
        ApplicationPool = $ApplicationPool 
        BindingInfo     = $BindingInfo 
        Protocol        = $Protocol
    }
    $currentState = Get-TargetResource @getParameters

    # Write-Verbose "Use this cmdlet to deliver information about command processing."

    # Write-Debug "Use this cmdlet to write debug information while troubleshooting."

    # Include logic to
    $result = [System.Boolean]
    # Add logic to test whether the website is present and its status matches the supplied
    # parameter values. If it does, return true. If it does not, return false.
    $result
}

注意

為方便偵錯,請在前述三個函式實作中使用 Write-Verbose Cmdlet。 這個 Cmdlet 會將文字寫入詳細資訊訊息串流中。 根據預設,不會顯示詳細資訊訊息數據流,但您可以藉由變更變數的值 $VerbosePreference 或使用 Verbose 參數搭配 Invoke-DscResource來顯示它。

建立模組資訊清單

最後,使用 New-ModuleManifest Cmdlet 來定義 <ResourceName>.psd1 DSC 資源模組的檔案。 使用腳本模組 (.psm1 上一節所述的) 檔案作為 NestedModules 參數的值。 包含 Get-TargetResourceSet-TargetResourceTest-TargetResource 作為 FunctionsToExport 參數的值。

$ManifestParameters = @{
    Path              = 'Demo_IISWebsite.psd1'
    NestedModules     = 'Demo_IISWebsite.psm1'
    FunctionsToExport = @(
        'Get-TargetResource'
        'Set-TargetResource'
        'Test-TargetResource'
    )
}
New-ModuleManifest @ManifestParameters
@{

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
GUID = '6AB5ED33-E923-41d8-A3A4-5ADDA2B301DE'

# Author of this module
Author = 'Contoso'

# Company or vendor of this module
CompanyName = 'Contoso'

# Copyright statement for this module
Copyright = 'Contoso. All rights reserved.'

# Description of the functionality provided by this module
Description = 'Create and configure IIS websites with DSC.'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '7.2'

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
    'WebAdministration'
)

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = @(
    'Demo_IISWebsite.psm1'
)

# Functions to export from this module
FunctionsToExport = @(
    'Get-TargetResource'
    'Set-TargetResource'
    'Test-TargetResource'
)

}

重新啟動系統

如果函 Set-TargetResource 式中所採取的動作需要重新啟動,您可以使用全域旗標來告知呼叫端重新啟動系統。

在您 Set-TargetResource 函式的內部,請新增下列這行程式碼。

# Include this line if the system requires a reboot.
$global:DSCMachineStatus = 1