二进制注册表项的 DSC 语法

Sam*_*gan 2 powershell windows-registry dsc

原本应该是简单的注册表 DSC 配置已经变成了令人有些沮丧的猜测。我正在尝试设置二进制注册表项。我发现不可能找到正确的值数据格式来正确设置密钥。我正在尝试将此注册表文件转换为 DSC:

\n\n
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\DefaultSecurity]\n"SrvsvcShareAdminConnect"=hex:01,00,04,80,64,00,00,00,70,00,00,00,00,00,00,00,\\\n  14,00,00,00,02,00,50,00,03,00,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,\\\n  00,00,05,20,00,00,00,20,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,\\\n  00,05,20,00,00,00,25,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,00,\\\n  05,20,00,00,00,27,02,00,00,01,01,00,00,00,00,00,05,12,00,00,00,01,01,00,00,\\\n  00,00,00,05,12,00,00,00\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经对注册表和 xregistry 资源进行了尝试,并遇到了相同的格式错误(我真的不介意我使用哪个)。我尝试将数据提供为单个字符串、字符串数组、附加 0x 以显示它是十六进制的字符串数组等。我也尝试了这里的建议。

\n\n

我得到的最接近的是下面的配置,它似乎有效:

\n\n
   Registry disableAdminShare {\n            Ensure      = "Present"\n            Key         = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\DefaultSecurity"\n            Force       = $true\n            ValueName   = "SrvsvcShareAdminConnect"\n            ValueData   = @("010004806400000070000000000000001400000002005000030000000000180003000f00010200000000000520000000200200000000180003000f00010200000000000520000000250200000000180003000f0001020000000000052000000027020000010100000000000512000000010100000000000512000000")\n            ValueType   = "Binary"\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

但查看应用时的日志,它似乎将值转换为十进制,导致无效条目:

\n\n
\'HKLM:\\SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\DefaultSecurity\\SrvsvcSha\nreAdminConnect\' to \'(1, 0, 4, 128, 100, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 20,\n0, 0, 0, 2, 0, 80, 0, 3, 0, 0, 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0,\n0, 5, 32, 0, 0, 0, 32, 2, 0, 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0,\n5, 32, 0, 0, 0, 37, 2, 0, 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 5,\n32, 0, 0, 0, 39, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0, 1, 1, 0, 0, 0,\n0, 0, 5, 18, 0, 0, 0)\' of type \'Binary\'\nVERBOSE: [SCDEV-RD-02]: LCM:  [ End    Set      ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我\xe2\x80\x99m 确信对此有一个简单的答案,但我无法\xe2\x80\x99 在文档中找到任何内容。

\n

Mat*_*ore 5

DSCMSFT_Registry二进制类型的格式ValueData是具有连续字节值对的字符串,带有可选的前导“0x”

诀窍是来自 $env:windir\Windows\System32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\DSCResources\MSFT_Registry.psm1 中资源的这段代码。

它通过以下方式解析该值:

    $binaryVal = $null
    $val = $Data[0].TrimStart("0x")
    if ($val.Length % 2 -ne 0)
    {
        $val = $val.PadLeft($val.Length+1, "0")
    }

    try
    {
        $byteArray = [Byte[]]@()

        for ($i = 0 ; $i -lt ($val.Length-1) ; $i = $i+2)
        {
            $byteArray += [Byte]::Parse($val.Substring($i, 2), "HexNumber")                                    
        }

        $ReturnValue.Value = [Byte[]]$byteArray
    }
Run Code Online (Sandbox Code Playgroud)

例子

对输入数据使用轻微的变化:

$reg = "01,00,04,80,64,00,00,00,70,00,00,00,00,00,00,00,
  14,00,00,00,02,00,50,00,03,00,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,
  00,00,05,20,00,00,00,20,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,
  00,05,20,00,00,00,25,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,00,
  05,20,00,00,00,27,02,00,00,01,01,00,00,00,00,00,05,12,00,00,00,01,01,00,00,
  00,00,00,05,12,00,00,00"
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令创建格式正确的字符串:

$val = [String]::Join("",$reg.Split(",").Trim())
Run Code Online (Sandbox Code Playgroud)

在 MOF 中,您会看到:

 ValueData = {
    "010004806400000070000000000000001400000002005000030000000000180003000f00010200000000000520000000200200000000180003000f00010200000000000520000000250200000000180003000f0001020000000000052000000027020000010100000000000512000000010100000000000512000000"
};
Run Code Online (Sandbox Code Playgroud)

这是证明这一点的完整测试示例:

   $reg = "01,00,04,80,64,00,00,00,70,00,00,00,00,00,00,00,
  14,00,00,00,02,00,50,00,03,00,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,
  00,00,05,20,00,00,00,20,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,
  00,05,20,00,00,00,25,02,00,00,00,00,18,00,03,00,0f,00,01,02,00,00,00,00,00,
  05,20,00,00,00,27,02,00,00,01,01,00,00,00,00,00,05,12,00,00,00,01,01,00,00,
  00,00,00,05,12,00,00,00"

$val = [String]::Join("",$reg.Split(",").Trim())

Configuration RegistryTest
{
    param([string] $Path, [string] $Name, [string] $BinaryValue)

    Import-DscResource -ModuleName PSDesiredStateConfiguration    
    Registry test
    {
        Key = $Path
        ValueName = $Name
        ValueData = $val
        ValueType = "Binary"
    }
}

$args = @{ 
    Path = "HKLM:\SOFTWARE\StackOverflow"
    Name = "BinaryTest"
}

Remove-ItemProperty @args
Get-ItemProperty @args -ErrorAction Continue # Nothing up my sleeve!
$o = RegistryTest @args -BinaryValue $val -outputpath $env:temp
Start-DscConfiguration ($o | split-path) -Wait -Verbose -force
Get-ItemProperty @args
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

Get-ItemProperty : Property BinaryTest does not exist at path 
HKEY_LOCAL_MACHINE\SOFTWARE\StackOverflow.
At C:\scratch\test.ps1:30 char:1
+ Get-ItemProperty @args -ErrorAction Continue # Nothing up my sleeve!
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (BinaryTest:String) [Get-ItemProperty], PSArgu 
   mentException
    + FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.Powe 
   rShell.Commands.GetItemPropertyCommand

VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendCo
nfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microso
ft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer STACKOVERFLOW with user sid S-...
VERBOSE: [STACKOVERFLOW]: LCM:  [ Start  Set      ]
VERBOSE: [STACKOVERFLOW]: LCM:  [ Start  Resource ]  [[Registry]test]
VERBOSE: [STACKOVERFLOW]: LCM:  [ Start  Test     ]  [[Registry]test]
VERBOSE: [STACKOVERFLOW]:                            [[Registry]test] Registry key value 'HKLM:\SOFTW
ARE\StackOverflow\BinaryTest' does not exist
VERBOSE: [STACKOVERFLOW]: LCM:  [ End    Test     ]  [[Registry]test]  in 0.2130 seconds.
VERBOSE: [STACKOVERFLOW]: LCM:  [ Start  Set      ]  [[Registry]test]
VERBOSE: [STACKOVERFLOW]:                            [[Registry]test] (SET) Set registry key value 'H
KLM:\SOFTWARE\StackOverflow\BinaryTest' to '(1, 0, 4, 128, 100, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0,
 0, 20, 0, 0, 0, 2, 0, 80, 0, 3, 0, 0, 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 5, 32,
 0, 0, 0, 32, 2, 0, 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 37, 2, 0,
 0, 0, 0, 24, 0, 3, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 39, 2, 0, 0, 1, 1, 0, 0, 0, 
0, 0, 5, 18, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0)' of type 'Binary'
VERBOSE: [STACKOVERFLOW]: LCM:  [ End    Set      ]  [[Registry]test]  in 0.1390 seconds.
VERBOSE: [STACKOVERFLOW]: LCM:  [ End    Resource ]  [[Registry]test]
VERBOSE: [STACKOVERFLOW]: LCM:  [ End    Set      ]
VERBOSE: [STACKOVERFLOW]: LCM:  [ End    Set      ]    in  0.7010 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 0.799 seconds


BinaryTest   : {1, 0, 4, 128...}
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\StackOverflow
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
PSChildName  : StackOverflow
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry
Run Code Online (Sandbox Code Playgroud)

查看运行此命令的 Server 2016 和 Windows 10 计算机,注册表看起来正确。

demo的注册表二进制值