none
PowerShell Set-ADUser Cannot write Multi-Value Octet String Values RRS feed

  • Question


  • My requirement is to copy values from 4 Multi-Value Octet String attributes to new, schema extended Multi-Value Octet String attributes. Here I'm trying to copy the 5 byte list values in AttributeCertificateAttribute to jpegPhoto.

    This throws no errors, but nothing happens either:

    Import-Module ActiveDirectory
    $UserName = Read-Host "Enter UserName"
    $ActiveUsers = Get-ADUser -Filter { Name -eq $UserName } -Properties attributeCertificateAttribute, jpegPhoto
    foreach ($User in $ActiveUsers)
    {
    	$AttrCertAttr = $User.attributeCertificateAttribute
    	Set-ADUser $UserName -Replace @{ jpegPhoto = $AttrCertAttr }
    }

    After much anguish and searching I finally pieced together something that semi-works, but only for the first octet string (byte list) of 5:

    Import-Module ActiveDirectory
    $UserName = Read-Host "Enter UserName"
    $ActiveUsers = Get-ADUser -Filter { Name -eq $UserName } -Properties attributeCertificateAttribute, jpegPhoto
    foreach ($User in $ActiveUsers)
    {
    	$AttrCertAttr = $User.attributeCertificateAttribute
    	If ($AttrCertAttr -ne $Null)
    	{
    		Set-ADUser $UserName -Clear jpegPhoto
    		
    		foreach ($arNum in $AttrCertAttr)
    		{
    			$Count = $arNum.Count
    			$UBound = $arNum.GetUpperBound(0)
    			$ByteList = New-Object byte[] $Count
    			For ($b = 0; $b -le $UBound; $b++)
    			{
    				$ByteList[$b] = $arNum[$b]
    			}
    			Set-ADUser $UserName -Add @{ jpegPhoto = $Bytelist }
    		}
    	}
    }

    The first byte list write works, but the subsequent 4 writes throw: 

    Set-ADUser : Invalid type 'System.Management.Automation.PSObject'.
    Parameter name: jpegPhoto
    At P:\^AD\CopyADUserAttributesToIPD-DemoJpg.ps1:53 char:5
    +                 Set-ADUser $UserName -Add @{ jpegPhoto = $Bytelist }
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (mbarker:ADUser) [Set-ADUser], ArgumentException
        + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Comm
       ands.SetADUser

    Then I tried to use -Replace with an array of Octet Strings (byte lists):

    Import-Module ActiveDirectory
    $UserName = Read-Host "Enter UserName"
    $ActiveUsers = Get-ADUser -Filter { Name -eq $UserName } -Properties attributeCertificateAttribute, jpegPhoto
    foreach ($User in $ActiveUsers)
    {
    	$arByteLists = @()
    	$AttrCertAttr = $User.attributeCertificateAttribute
    	If ($AttrCertAttr -ne $Null)
    	{
    		Set-ADUser $UserName -Clear jpegPhoto
    		
    		foreach ($arNum in $AttrCertAttr)
    		{
    			$Count = $arNum.Count
    			$UBound = $arNum.GetUpperBound(0)
    			$ByteList = New-Object byte[] $Count
    			For ($b = 0; $b -le $UBound; $b++)
    			{
    				$ByteList[$b] = $arNum[$b]
    			}
    			$arByteLists += $ByteList
    		}
    		Set-ADUser $UserName -Replace @{ jpegPhoto = $arByteLists }
    	}
    }

    I get this error (Even though the value does NOT already exist):

    Set-ADUser : The specified value already exists
    At P:\^AD\CopyADUserAttributesToJpg-Demo-Array.ps1:44 char:3
    +         Set-ADUser $UserName -Replace @{ jpegPhoto = $arByteLists }
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (mbarker:ADUser) [Set-ADUser], ADException
        + FullyQualifiedErrorId : ActiveDirectoryServer:8323,Microsoft.ActiveDirectory.Management.Commands.SetADUser

    Thanks in Advance for any ideas.

    -Mitch


    • Edited by Mitchell Barker Tuesday, April 9, 2019 5:23 PM Fix: code now in tool
    • Moved by Bill_Stewart Wednesday, September 4, 2019 9:04 PM Abandoned
    Tuesday, April 9, 2019 3:07 AM

All replies

  • Why is it that no one can read the forum rules on posting code.  Please edit your post and post the code using the code posting tool provided.  WHat you have posted is unreadable in most browsers.

    All technical forums have code posting tools and require that you use them so code can be easily rad and copied.  Please try to fix this.

    To copy any attribute just get the attributs and set it on the new account object.  Use "Replace" and not "Add".


    \_(ツ)_/


    • Edited by jrv Tuesday, April 9, 2019 3:33 AM
    Tuesday, April 9, 2019 3:29 AM
  • Thanks for the quick reply.

    I'm new, sorry I didn't know about, or use your nice Code Block tool. I just edited and fixed my post.

    As for your suggestion, now that you can read my code, you can see that I DID try a simple replace first, and nothing happens. No attribute gets written at all, but no errors.

    Thanks,

    -Mitch

    Tuesday, April 9, 2019 5:27 PM
  • You cannot use a cert byte array to add to a photo.  It is the wrong kind of object.  Why would you want to do that anyway?


    \_(ツ)_/

    Tuesday, April 9, 2019 5:31 PM
  • I just used jpegphoto as a demo. 

    Our 2 factor authentication software has been successfully using 4 native AD multi-valued octet string attributes: audio, jpegPhoto, extensionData, attributeCertificateAttribute to store data of this type. Obviously not an elegant solution, so now we have extended the schema with 4 new custom multi-valued octet string attributes, and simply want to copy the data over to the new attributes, but it fails.

    It wouldn't make sense for me to show you a demo of copying to an attribute no else has, nor has heard of. hence I used jpegphoto for these demos, which fails in the same way. They are both the same data type, so it should work. I know how to read msdn articles and use PowerShell fairly well. I see nothing in Google on this topic. There is some info on multi-value string copying and manipulation, but nothing on multi-value octet string. It really seems to me like PowerShell is incapable of doing this. I'm certainly willing to be proven wrong, and would love to know how to do this if there is a way. 

    Thanks again,

    Mitch

    Tuesday, April 9, 2019 6:20 PM
  • The value you are copying is not a simple value.  Why not just assign one to the other directly. 

    Without a real example that is not trying to copy a cert to a phot this will behard to understand.

    To assign a byte array from one attribute to another just assign it.

    Also the folloing is not a byte array.

    $arByteLists = @()

    A byte array is:

    [byte[]]$bytes

    Your method creates an array of objects.

    PS C:\WINDOWS\system32> $arByteLists = @()
    PS C:\WINDOWS\system32> $arByteLists.GetType().Name
    Object[]
    PS C:\WINDOWS\system32>


    \_(ツ)_/


    • Edited by jrv Tuesday, April 9, 2019 6:28 PM
    Tuesday, April 9, 2019 6:28 PM
  • Here is how to copy one attribute to another of the same type:

    Set-ADUser $UserName -Replace @{ YourAttribute = $User.attributeCertificateAttribute }


    \_(ツ)_/

    Tuesday, April 9, 2019 6:30 PM
  • I know that should work, and it was the first thing I tried, but it really does not do anything on this data type.

    I have tried it on various User objects, trying to copy various multi-valued octet string values, and it always completes without error, but no values are copied.

    Can someone else please try this and see what the results are? Just need to find a multi-valued octet string that has data in it, and try to copy it to another.

    Thanks,

    Wednesday, April 10, 2019 6:38 PM
  • Is it a byte array or an octet string.  They are incompatible types.  You have to be explicit.  "jpeg" takes a byte array.  Other attributes take an octet string. What are you trying to do?

    Remember that an object array cannot be stored into an attribute that takes a byte array.


    \_(ツ)_/

    Wednesday, April 10, 2019 8:44 PM