撰寫單一實例 DSC 資源
注意
本文說明定義只允許 DSC 組態中單一實例的 DSC 資源的最佳作法。 沒有內建的 DSC 功能可執行這項操作。 這在未來可能會變更。
在某些情況下,您不想允許 DSC 資源在 DSC 設定中多次使用。 例如,在先前的 xTimeZone DSC 資源實作中,DSC 組態可以多次呼叫 DSC 資源,並將時區設定為每個 DSC 資源區塊中的不同設定:
Configuration SetTimeZone {
param (
[String[]]$NodeName = $env:COMPUTERNAME
)
Import-DSCResource -ModuleName xTimeZone
Node $NodeName {
xTimeZone TimeZoneExample {
TimeZone = 'Eastern Standard Time'
}
xTimeZone TimeZoneExample2 {
TimeZone = 'Pacific Standard Time'
}
}
}
這是因為 DSC 資源 金鑰 屬性的運作方式。 DSC 資源必須至少有一個 Key 屬性。 如果所有 索引鍵 屬性值的組合是唯一的,DSC 資源實例就會被視為唯一的。
在其先前的實作中, xTimeZone DSC 資源只有一個屬性--TimeZone,也就是 Key。 因此,範例 DSC 組態已編譯並執行,而不會發出警告。 xTimeZone
每個 DSC 資源區塊都被視為唯一的。 這會導致 DSC 組態重複套用至系統,並來回循環時區。
為了確保 DSC 組態只能設定系統一次的時區,DSC 資源已更新為新增第二個屬性 IsSingleInstance,成為 Key 屬性。 IsSingleInstance 限制為單一值 Yes
。 DSC 資源的舊 MOF 架構為:
[ClassVersion("1.0.0.0"), FriendlyName("xTimeZone")]
class xTimeZone : OMI_BaseResource
{
[Key, Description("Specifies the TimeZone.")] String TimeZone;
};
DSC 資源的更新 MOF 架構為:
[ClassVersion("1.0.0.0"), FriendlyName("xTimeZone")]
class xTimeZone : OMI_BaseResource
{
[Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance;
[Required, Description("Specifies the TimeZone.")] String TimeZone;
};
DSC 資源的實作已更新為使用新的參數。 以下是其變更方式:
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([Hashtable])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)
#Get the current TimeZone
$CurrentTimeZone = Get-TimeZone
$returnValue = @{
TimeZone = $CurrentTimeZone
IsSingleInstance = 'Yes'
}
#Output the target resource
$returnValue
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)
#Output the result of Get-TargetResource function.
$CurrentTimeZone = Get-TimeZone
Write-Verbose -Message "Replace the System Time Zone to $TimeZone"
try
{
if($CurrentTimeZone -ne $TimeZone)
{
Write-Verbose -Verbose "Setting the TimeZone"
Set-TimeZone -TimeZone $TimeZone
}
else
{
Write-Verbose -Verbose "TimeZone already set to $TimeZone"
}
}
catch
{
$ErrorMsg = $_.Exception.Message
Write-Verbose -Verbose $ErrorMsg
}
}
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet('Yes')]
[String]
$IsSingleInstance,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$TimeZone
)
#Output from Get-TargetResource
$CurrentTimeZone = Get-TimeZone
if($TimeZone -eq $CurrentTimeZone)
{
return $true
}
else
{
return $false
}
}
Function Get-TimeZone {
[CmdletBinding()]
param()
& tzutil.exe /g
}
Function Set-TimeZone {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[System.String]
$TimeZone
)
try
{
& tzutil.exe /s $TimeZone
}
catch
{
$ErrorMsg = $_.Exception.Message
Write-Verbose $ErrorMsg
}
}
Export-ModuleMember -Function *-TargetResource
請注意, TimeZone 屬性不再是 Key 屬性。 現在,如果 DSC 組態嘗試設定時區兩次, (具有不同 TimeZone 值的兩個不同xTimeZone
區塊) ,則嘗試編譯 DSC 組態會導致錯誤:
Write-Error:
Line |
289 | Test-ConflictingResources $keywordName $canonicalizedValue $k …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| A conflict was detected between resources '[xTimeZone]TimeZoneExample (C:\code\dsc\DscExample.ps1::9::10::xTimeZone)' and '[xTimeZone]TimeZoneExample2 (C:\code\dsc\DscExample.ps1::14::10::xTimeZone)' in node 'DESKTOP-KFLGVVP'. Resources have identical key properties but there are differences in the following non-key properties: 'TimeZone'. Values 'Eastern Standard Time' don't match values 'Pacific Standard Time'. Please update these property values so that they are identical in both cases.
InvalidOperation: Errors occurred while processing configuration 'SetTimeZone'.
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應