PowerShell新ADComputer二进制属性
我是PowerShell的新手,我有一个一次性任务要执行,必须使用PowerShell完成。这也涉及到Active Directory。我需要在我们的广告中添加一个新的计算机对象,我必须在创建时设置一个16字节的二进制值。我得到一个字符串作为输入,它是我必须为属性设置的值的十六进制表示形式 我试图输入值,但它不起作用。我试着用反斜杠转义每个字节,但也不起作用 我应该如何格式化此输入以使用新的ADComputer命令?我正在成功设置一系列其他属性。当我从传递给-OtherAttributes选项的哈希表中删除这个二进制项时,它工作得很好。所以,显然是一个格式问题。我没有发现这些属性的预期格式 有什么提示吗?蒂亚 编辑2018-06-05 19:44美国东部时间: 我尝试将字符串转换为字节数组,如下所示:PowerShell新ADComputer二进制属性,powershell,active-directory,binary-data,Powershell,Active Directory,Binary Data,我是PowerShell的新手,我有一个一次性任务要执行,必须使用PowerShell完成。这也涉及到Active Directory。我需要在我们的广告中添加一个新的计算机对象,我必须在创建时设置一个16字节的二进制值。我得到一个字符串作为输入,它是我必须为属性设置的值的十六进制表示形式 我试图输入值,但它不起作用。我试着用反斜杠转义每个字节,但也不起作用 我应该如何格式化此输入以使用新的ADComputer命令?我正在成功设置一系列其他属性。当我从传递给-OtherAttributes选项的
Function Convert-Hex2ByteArray {
[cmdletbinding()]
param(
[parameter(Mandatory=$true)]
[String]
$HexString
)
[byte[]] $Bytes = @(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
For($i=0; $i -lt $HexString.Length; $i+=2) {
$Bytes[$i/2] = [convert]::ToByte($HexString.Substring($i, 2), 16)
}
$Bytes
}
(...)
$netbootGUID = Convert-Hex2ByteArray($args[$indiceArgs])
$otherAttributes.add( "netbootGUID", $netbootGUID )
(...)
New-ADComputer -Credential $cred -Server $ADhost -Path "CN=Computers,$baseDN" -SAMAccountName $sAMAccountName -Name $name-Instance 4 -OtherAttributes $otherAttributes
这导致了以下错误(我为自己的翻译道歉,因为原文是用法语显示的):
为只能有一个属性的属性指定了多个值
解决的问题:
$netbootGUID = New-Object Guid $args[$indiceArgs]
$otherAttributs.add( "netbootGUID", $netbootGUID )
成功了。对于二进制存储,通常需要将字符串转换为字节数组:
$String = '3c6ef75eaa2c4b23992bbd65ac891917'
$ByteArray = [byte[]]$(for ($i = 0; $i -lt $String.Length; $i+=2) { [Convert]::ToByte($String.Substring($i,2), 16) })
要将其转换回:
$NewString = -join $(foreach($Byte in $ByteArray) { $Byte.ToString('x2') })
如果需要大写字符,请指定'X2'
而不是'X2'
因为您存储的是16字节的值,所以我要注意,如果您存储的是GUID,可能需要更改存储顺序,因为GUID的字符串表示形式中的字节顺序与x86系统上GUID的字节表示形式中的字节顺序不匹配。幸运的是,有一些内置函数可以使用内置的
System.Guid
数据类型处理此转换:
$GUID = 'f8d89eb2b49c4bfeab44a85ccdc4191a'
$ByteArray = [Guid]::new($GUID).ToByteArray()
以及用于转换回的构造函数:
$NewGUID = [Guid]::new($ByteArray)
您是否应该使用此方法取决于您正在更新的确切属性,以及将使用相关属性的应用程序是否正确处理GUID,或者它们是否只是将GUID存储为原始字节(这是不正确的,但并不奇怪)。您必须通过查看应用程序看到的GUID并将其与Active Directory中的字节数组进行比较来进行测试,以验证其正确性
有关字节顺序的详细信息,请参阅:
请注意,返回字节数组中的字节顺序不同于Guid值的字符串表示形式。开始的四字节组和接下来的两个两字节组的顺序相反,而最后两个两字节组和结束的六字节组的顺序相同。该示例提供了一个示例
x86计算机是一种小端系统。通常,对于二进制存储,您需要将字符串转换为字节数组:
$String = '3c6ef75eaa2c4b23992bbd65ac891917'
$ByteArray = [byte[]]$(for ($i = 0; $i -lt $String.Length; $i+=2) { [Convert]::ToByte($String.Substring($i,2), 16) })
要将其转换回:
$NewString = -join $(foreach($Byte in $ByteArray) { $Byte.ToString('x2') })
如果需要大写字符,请指定'X2'
而不是'X2'
因为您存储的是16字节的值,所以我要注意,如果您存储的是GUID,可能需要更改存储顺序,因为GUID的字符串表示形式中的字节顺序与x86系统上GUID的字节表示形式中的字节顺序不匹配。幸运的是,有一些内置函数可以使用内置的
System.Guid
数据类型处理此转换:
$GUID = 'f8d89eb2b49c4bfeab44a85ccdc4191a'
$ByteArray = [Guid]::new($GUID).ToByteArray()
以及用于转换回的构造函数:
$NewGUID = [Guid]::new($ByteArray)
您是否应该使用此方法取决于您正在更新的确切属性,以及将使用相关属性的应用程序是否正确处理GUID,或者它们是否只是将GUID存储为原始字节(这是不正确的,但并不奇怪)。您必须通过查看应用程序看到的GUID并将其与Active Directory中的字节数组进行比较来进行测试,以验证其正确性
有关字节顺序的详细信息,请参阅:
请注意,返回字节数组中的字节顺序不同于Guid值的字符串表示形式。开始的四字节组和接下来的两个两字节组的顺序相反,而最后两个两字节组和结束的六字节组的顺序相同。该示例提供了一个示例
x86计算机是一个小小的endian系统。您的代码在哪里?问题很简单。代码不会增加任何进一步的理解,因为问题是如何将二进制值传递给新的ADComputer,以便正确更新AD。下面是相关的代码行:新的ADComputer-Credential$cred-Server$host-Path“CN=Computers,$baseDN”-SAMAccountName$SAMAccountName-Name$wsName-实例4-OtherAttributes$OtherAttributes,其中$OtherAttributes是包含七个属性的哈希表,其中一个是二进制属性。当我从hastable中删除binary属性时,一切正常。什么属性以及为什么需要以这种特殊方式设置?我没有设计我必须更新的AD对象。我只知道它是一个16字节的二进制值。我不想讨论这个设计是好是坏,还有别的路要走。它已经存在很多年了,现在我必须与它交互。你的代码在哪里?问题很简单。代码不会增加任何进一步的理解,因为问题是如何将二进制值传递给新的ADComputer,以便正确更新AD。下面是相关的代码行:新的ADComputer-Credential$cred-Server$host-Path“CN=Computers,$baseDN”-SAMAccountName$SAMAccountName-Name$wsName-实例4-OtherAttributes$OtherAttributes,其中$OtherAttributes是包含七个属性的哈希表,其中一个是二进制属性。当我从hastable中删除binary属性时,一切都正常。什么属性以及为什么需要在这个表中设置它