Reputation: 942
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}
Upvotes: 1
Views: 4581
Reputation: 46710
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.
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]$_}
}
Upvotes: 1