DSC Script 资源

适用于:Windows PowerShell 4.0 和 Windows PowerShell 5.x

Windows PowerShell Desired State Configuration (DSC) 中的 Script 资源提供了在目标节点上运行 Windows PowerShell 脚本的机制。 Script 资源使用 GetScriptSetScriptTestScript 属性,这些属性包含定义以执行相应的 DSC 状态操作的脚本块。

提示

在可能的情况下,最佳做法是使用定义的 DSC 资源,而不是此资源。 资源的 Script 缺点使测试、维护和预测更加困难。

与其他 DSC 资源不同,资源的每个属性 Script 都是一个键属性,并且此资源的 Get 方法只能返回当前状态的单个字符串。 无法保证此资源以幂等方式实现,也不能保证它会在任何系统上按预期方式工作,因为它使用自定义代码。 如果不在目标系统上调用,则无法对其进行测试。

在使用 Script 资源之前,请考虑是否可以 改为创作资源 。 使用定义完善的 DSC 资源可使配置更具可读性和可维护性。

注意

此 DSC 资源的文档介绍了 PowerShell 版本 7.2 之前包含的版本。 PSDscResources 模块包含 Microsoft 正式支持的新的和更新的 DSC 资源。 PowerShell 库中提供了 PSDscResources 模块。

有关详细信息和更新的文档,请参阅 PSDscResources 参考文档

语法

Script [string] #ResourceName
{
    GetScript = [string]
    SetScript = [string]
    TestScript = [string]
    [ Credential = [PSCredential] ]
    [ DependsOn = [string[]] ]
    [ PsDscRunAsCredential = [PSCredential] ]
}

注意

GetScriptTestScriptSetScript 块存储为字符串。

属性

属性 说明
GetScript 一个返回节点当前状态的脚本块。
SetScript 一个脚本块,DSC 使用该脚本块在节点未处于所需状态时强制实施合规性。
TestScript 一个用于确定节点是否处于所需状态的脚本块。
凭据 指示要用于运行此脚本的凭据(如果需要凭据)。

公共属性

properties 说明
DependsOn 指示必须先运行其他资源的配置,再配置此资源。
PsDscRunAsCredential 设置用于运行整个资源的身份的凭据。

注意

在 WMF 5.0 中添加了 PsDscRunAsCredential 公共属性,用于允许在其他凭据上下文中运行任何 DSC 资源。 有关详细信息,请参阅将凭据与 DSC 资源配合使用

其他信息

GetScript

DSC 不使用 Get-DscConfiguration cmdlet 执行的GetScript输出GetScript来检索节点的当前状态。 如果指定返回值,则不需要返回 GetScript 值,它必须是包含 结果 键的哈希表,其值为 String。

TestScript

执行 TestScript DSC 以确定是否 SetScript 应运行。 如果 TestScript 返回 $false,则 DSC 执行 SetScript 以使节点恢复到所需的状态。 它必须返回一个布尔值。 的结果 $true 指示节点符合要求且 SetScript 不应执行。

Test-DscConfiguration cmdlet 执行TestScript以检索节点与Script资源的符合性。 但是,在这种情况下,无论哪个TestScript块返回,SetScript都不会运行。

注意

TestScript 的所有输出都是其返回值的一部分。 PowerShell 将未压缩的输出解释为非零输出,这意味着无论节点的状态如何,都会 TestScript 返回 $true 。 这会导致不可预测的结果和误报,并导致在故障排除时出现问题。

SetScript

SetScript 修改节点以强制执行所需的状态。 如果脚本块返回 ,TestScriptDSC 将$false调用 SetScriptSetScript 应该没有返回值。

示例

示例 1:使用脚本资源编写示例文本

此示例测试每个节点上是否存在 C:\TempFolder\TestFile.txt。 如果不存在,则使用 SetScript创建它。 返回 GetScript 文件的内容,并且不使用其返回值。

Configuration ScriptTest
{
    Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

    Node localhost
    {
        Script ScriptExample
        {
            SetScript = {
                $sw = New-Object System.IO.StreamWriter("C:\TempFolder\TestFile.txt")
                $sw.WriteLine("Some sample string")
                $sw.Close()
            }
            TestScript = { Test-Path "C:\TempFolder\TestFile.txt" }
            GetScript = { @{ Result = (Get-Content C:\TempFolder\TestFile.txt) } }
        }
    }
}

示例 2:使用脚本资源比较版本信息

此示例从创作计算机上的文本文件中检索符合的版本信息,并将其存储在 $version 变量中。 在生成节点的 MOF 文件时,DSC 将每个脚本块中的 $using:version 变量替换为 $version 变量的值。 在执行期间,符合的版本存储在每个节点上的文本文件中,并在后续执行时进行比较和更新。

$version = Get-Content 'version.txt'

Configuration ScriptTest
{
    Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

    Node localhost
    {
        Script UpdateConfigurationVersion
        {
            GetScript = {
                $currentVersion = Get-Content (Join-Path -Path $env:SYSTEMDRIVE -ChildPath 'version.txt')
                return @{ 'Result' = "$currentVersion" }
            }
            TestScript = {
                # Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
                $state = [scriptblock]::Create($GetScript).Invoke()

                if( $state.Result -eq $using:version )
                {
                    Write-Verbose -Message ('{0} -eq {1}' -f $state.Result,$using:version)
                    return $true
                }
                Write-Verbose -Message ('Version up-to-date: {0}' -f $using:version)
                return $false
            }
            SetScript = {
                $using:version | Set-Content -Path (Join-Path -Path $env:SYSTEMDRIVE -ChildPath 'version.txt')
            }
        }
    }
}

示例 3:使用脚本资源中的参数

此示例通过使用 using 范围,从脚本资源中访问参数。 可以通过类似方式访问 ConfigurationData。 与示例 2 一样,实现要求将版本存储在目标节点上的本地文件中。 本地路径和版本都是可配置的,将代码与配置数据分离。

Configuration ScriptTest
{
    param
    (
        [Version]
        $Version,

        [string]
        $FilePath
    )

    Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

    Node localhost
    {
        Script UpdateConfigurationVersion
        {
            GetScript = {
                $currentVersion = Get-Content -Path $using:FilePath
                return @{ 'Result' = "$currentVersion" }
            }
            TestScript = {
                # Create and invoke a scriptblock using the $GetScript automatic variable,
                # which contains a string representation of the GetScript.
                $state = [scriptblock]::Create($GetScript).Invoke()

                if( $state['Result'] -eq $using:Version )
                {
                    Write-Verbose -Message ('{0} -eq {1}' -f $state['Result'],$using:version)
                    return $true
                }

                Write-Verbose -Message ('Version up-to-date: {0}' -f $using:version)
                return $false
            }
            SetScript = {
                Set-Content -Path $using:FilePath -Value $using:Version
            }
        }
    }
}

生成的 MOF 文件包含通过 using 范围访问的变量及其值。 它们将注入到每个使用变量的 scriptblock 中。 为简洁起见,删除了测试和设置脚本:

instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
{
 GetScript = "$FilePath ='C:\\Config.ini'\n\n $currentVersion = Get-Content -Path $FilePath\n return @{ 'Result' = \"$currentVersion\" }\n";
 TestScript = ...;
 SetScript = ...;
};

已知限制

  • 使用拉取或推送服务器模型时,在脚本资源中传递的凭据并不总是可靠的。 在这种情况下,请使用完整资源,而不是使用脚本资源。