【问题标题】:Desired State Configuration can't get hash table from Script resource Get block所需状态配置无法从脚本资源获取块中获取哈希表
【发布时间】:2017-01-13 21:38:42
【问题描述】:

我已经使用 1.1 和 xScript 5.1.0.0 的内置脚本资源对此进行了测试,并获得了相同的结果。我的 Set 和 Test 块工作正常。我正在使用其他几个非常相似的脚本资源,它们也适用于 get 块。

我尝试了很多不同的语法变化,但结果总是一样。我知道该块正在运行,因为我注释掉了创建的文件被删除的行并且我看到了该文件。我还在 powershell 中将其作为函数运行,并将输出通过管道传输到 Get-Member,可以看到它确实是一个返回的 hastable。

顺便说一句,我真的不喜欢我在这里使用的通过 DSC 管理此设置的方法。我对其他想法持开放态度,只要它仍在 DSC 中。

Script StorePasswordsUsingReversibleEncyption
{
    SetScript   = {
        secedit /export /cfg c:\temp\secpol.cfg
        (gc C:\temp\secpol.cfg).replace("ClearTextPassword = 1", "ClearTextPassword = 0") | Out-File C:\temp\secpol.cfg
        secedit /configure /db c:\windows\security\local.sdb /cfg c:\temp\secpol.cfg /areas SECURITYPOLICY /quiet
        rm -force c:\temp\secpol.cfg -confirm:$false
    } 

    TestScript = {
        secedit /export /cfg c:\temp\secpol.cfg
        $str = (Get-Content 'c:\temp\secpol.cfg' | select-String 'ClearTextPassword' -SimpleMatch).ToString()
        rm -force c:\temp\secpol.cfg -confirm:$false
        if ($str -eq 'ClearTextPassword = 0') {return $true}
        else {return $false}            
    } 

    # Not working yet           
    GetScript   = {
        secedit /export /cfg c:\temp\secpol.cfg
        $str = (Get-Content 'c:\temp\secpol.cfg' | select-String 'ClearTextPassword' -SimpleMatch).ToString()
        rm -force c:\temp\secpol.cfg -confirm:$false
        return @{Result = $str}     
    }    
}

运行 Get-DSCConfiguration 后,控制台返回的输出是这样的:

Get-DscConfiguration : PowerShell DSC resource MSFT_ScriptResource  failed to execute Get-TargetResource functionality 
with error message: Failure to get the results from the script in a hash table format. 
At line:1 char:1
+ Get-DscConfiguration
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (MSFT_DSCLocalConfigurationManager:root/Microsoft/...gurationManager)  
   [Get-DscConfiguration], CimException
    + FullyQualifiedErrorId : ProviderOperationExecutionFailure,Get-DscConfiguration

【问题讨论】:

    标签: powershell hashtable dsc


    【解决方案1】:

    试试这个:

     GetScript   = {
            $null = secedit /export /cfg c:\temp\secpol.cfg
            $str = (Get-Content 'c:\temp\secpol.cfg' | select-String 'ClearTextPassword' -SimpleMatch).ToString()
            rm -force c:\temp\secpol.cfg -confirm:$false
            return @{Result = $str}     
        }    
    

    问题在于,当您调用外部命令(如secedit)时,如果该命令(这很自然),它写入标准输出的所有内容都会作为输出返回。但是,如果不将其捕获到变量中,它将被进一步传递到脚本块的输出。 return statement 也有点误导——它不是说“只返回这个东西”,而是“把这个东西写到输出流,然后返回”。

    这意味着您原来的 GetScript 不会返回单个哈希表,而是返回一个如下所示的数组:

    @(
      "some-output-from-secedit",
      @{ Result = $str }
    )
    

    将外部命令的输出分配给一个变量(在这种情况下我使用$null 表示我想丢弃它)将防止它弄乱你的脚本块的输出。

    另一种方法是将命令的输出重定向到Write-Verbose(如果您有兴趣阅读)或$null(如果您不关心):

    secedit /export /cfg c:\temp\secpol.cfg | write-verbose
    

    【讨论】:

    • 只是一个小评论:我怀疑rmRemove-Item 的别名)会返回任何没有-PassThru 参数的东西。无论如何 +1。
    • 这行得通,但我不完全理解你的解释。您能否将我链接到一些可以帮助我更好地理解的文档?谢谢!
    【解决方案2】:

    您可以尝试像这样修改您的 getscript 块吗:

    GetScript   = {
    
    start-process secedit -ArgumentList '/export /cfg c:\temp\secpol.cfg' -Wait
    $str = (Get-Content 'c:\temp\secpol.cfg' | select-String 'ClearTextPassword' -SimpleMatch).ToString()
    rm -force c:\temp\secpol.cfg -confirm:$false
    return @{Result = $str}     
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 2013-12-11
      • 2013-11-27
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多