简体   繁体   中英

Powershell Set-ADUser userCertificate parameter type error

I have a script, which essentially does the following:

$user = Get-ADUser $someUserName -Server $someCertServer -Properties *
$user.userCertificate |% { Set-ADUser $someUserName -Certificates @{Add=$_} }

It copies the cert data from a cert-server to the default server. $user.userCertificate is of type Microsoft.ActiveDirectory.Management.ADPropertyValueCollection and $user.userCertificate[0] is of type System.Byte[] . According to the docs , I can pass a Byte[] and be good to go. By using the foreach operator in the above script, I get the Byte[].

However, Powershell fails with the error message

the parameter certificates requires all values in the collection to be of the same type

(and underlines the @{Add=$_} ; the message might not be 100% accurate, since I had to translate it to English). Because of the foreach operator, there is only one type: a Byte[]. What does that error message mean and how can I shove the certificate into the ADUser object?

I also tried to convert the Byte[] to a certificate object, however it ended up with the same error message:

$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($user.userCertificate[0])
Set-ADUser $someUserName -Certificates @{Add=$cert}

The very first issue I see is that you are calling on the wrong property for your example to work.

 $user.userCertificate | ForEach-Object { Set-ADUser $someUserName -Certificates @{Add=$_}} 

While there is a property called userCertificate on that object that contains an collection of [byte[]] . For that code to work the way you want it to you should be using Certificates . Certificates is an collection of Security.Cryptography.X509Certificates.X509Certificate

So making that change I was able to add another users certificate to my own account.

$certUser = Get-Aduser "someGuy" -Properties certificates
$certUser.Certificates | %{ Set-ADUser "ME" -Certificates @{Add=$_}}

Note: It is a better practice to only request the properties you need from AD. Using -properties * is a waste of effort and needless resources

While this exact scenario is not covered there is a nice write-up on the MSDN Blogs about dealing with certs.


Cert as a byte array

Now that we know userCertificate is a collection of byte arrays maybe we can look into how to use that.

I was having issues using the byte array with the certificate parameter for Set-Aduser even though it is supposed to support it. I got the error

 Set-ADUser : Cannot validate argument on parameter 'Certificates'. Values in the argument collection should be of Type: 'System.Security.Cryptography.X509Certificates.X509Certificate' 

I did get this to work but I had to cast the byte array as a cert object first which was redundant considering this appear to be what the Certificates property already is.

$certUser.Usercertificate | ForEach-Object{
    Set-ADUser "ME" -certificate @{Add=[System.Security.Cryptography.X509Certificates.X509Certificate]$_}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM