How can you set an arbitrary AD attribute with PowerShell?
Of course Get-QADUser
and Set-QADUser
have a set of default most common attributes the cmdlets retrieve and operate. Thus, for example moving me to marketing could be as simple as:
Set-QADUser "Dmitry Sotnikov" -Department Marketing
However, sometimes (extended schema or necessity to operate a not-so-common sets of attributes) makes you want to go beyond the most common parameters.
In a few recent posts I’ve blogged about:
- Getting a full list of user attributes from AD schema,
- Retrieving and manipulating arbitrary AD attributes,
- Optimizing retrieval by memory and performance.
Now let’s (hopefully) finish the series by talking about how you can set any attribute in AD.
In most cases, when you need to set any of the attributes beyond the default scope, you can do that using the -ObjectAtributes
parameter.
For example:
Set-QADUser jsmith -ObjectAttributes @{l=’New York’;description='Reallocated Jan 1'}
changes city
and description
attributes for user jsmith
.
Or
Set-QADUser ‘mycompany.com/usersOU/User1′ -objectAttributes @{otherTelephone=@(’555-34-67′,’555-34-68′)}
sets multivalued otherTelephone
attribute to values 555-34-67 and 555-34-68.
Or
[Collections.DictionaryEntry] $de = new-object Collections.DictionaryEntry -argumentList ‘Append, @(’555-34-
67′,’555-34-68′)’
Set-QADUser User1 -objectAttributes @{otherTelephone=$de}
Appends multivalued otherTelephone
attribute with values 555-34-67 and 555-34-68.
In some cases you might also need to make sure you supply data in right format because -ObjectAttributes
does not convert values of attributes before passing them to AD. For INTEGER8
attributes like accountExpires
this
means you must pass only values of types accepted by Microsoft LDAP ADSI:
IADsLargeInteger
, string
or int
.
This means that you would need to do the conversion manually with something like this:
$dateOfExpiration = (get-date -year 2007 -month 10 -day
15).ToFileTime().ToString()
set-qaduser user1 -ObjectAttributes @{accountExpires =
$dateOfExpiration}
Hope this helps (and hope that in most cases the default set of attributes will be more than enough so you won’t need all these advanced tricks).
Dmitry
Tags: AD cmdlets, cmdlets, oneliner, one-liner, AD, Active Directory, Examples
I am attempting to add a new attribute to “proxyAddresses”, which is a mult-valued AD attribute. I am able to write the data, but it replaces the existing addresses. Reading this post, it says that I should be using Collections.DictionaryEntry. I can not get this to work.
My overall goal is to read the sAMAccountName from a CSV file. For each user, I want it to ADD or APPEND a new proxyAddresses x500 address. Below is the current state of my script. If I remove the line for the Collections.DictionaryEntry and replace the value for $de to point to my spreadsheet, the script works. However, it REPLACES the existing data and only writes the new address.
—– My PowerShell Script —–
Connect-QADService -service ‘domain.company.net’ -Credential ( Get-Credential )
$list = import-csv “c:\test.csv”
foreach ($name in $list)
{
[Collections.DictionaryEntry] $de = new-object Collections.DictionaryEntry -argumentList ‘Append, @(‘”X500:/O=My Company, Inc./OU=Corporate/cn=Recipients/cn=testmigrate8attempt3″‘)’
Get-QADUser -SamAccountName $name.sAMAccountName | Set-QADUser -ObjectAttributes @{proxyAddresses=$de}
}
Disconnect-QADService
—– My PowerShell Script —–
I receive the following message:
DefaultNamingContext Type
——————– —-
DC=domain,DC=company,DC=net ActiveDirectory
A parameter cannot be found that matches parameter name ‘X500:/O=My Company, Inc./OU=Corporate/cn=Recipients/cn=testmigrate8attempt3’.
At line 6, position 0
{
Do you have a suggestion on how I can change my script? Is there a cmdlet that will let me import the existing multivalued data and then append a new entry to it?
Thank you,
Dustin
Dustin,
I don’t currently have access to my lab to troubleshoot the script. Could you post the question to the AD PowerShell forum at: http://powergui.org/forum.jspa?forumID=173
The folks there are very helpful.
Dmitry
why not use Add-QADProxyAddress, Set-QADProxyAddress, Remove-QADProxyAddress
These did not exist when I was posting this in 2007 🙂
On Tue, Jan 22, 2013 at 12:04 AM, Dmitry’s PowerBlog: PowerShell and beyond
Hi Dmitry,
Thanks for pointing me to the correct forum. I was able to do some more research and it appears to be working now. I’m posting my latest script just for your reference. I hope it helps others looking to perform a similar task.
#This script reads from a CSV file. It uses the sAMAccountName column in the CSV to find the user. Then it reads the proxyAddresses attribute and appends the proxyAddresses data from the CSV. This is needed because proxyAddresses is a multivalued attribute.
Connect-QADService -service ‘domain.company.net’ -Credential ( Get-Credential )
$list = import-csv “c:\test.csv”
foreach ($name in $list)
{
$UserInfo = Get-QADUser -SamAccountName $name.sAMAccountName
#The following line should only be used for multivalued attributes. It reads from the existing attributes and adds additional data from the CSV file.
Get-QADUser -SamAccountName $name.sAMAccountName | Set-QADUser -ObjectAttributes @{proxyAddresses=$UserInfo.proxyAddresses +=$name.proxyAddresses}
Write-Host $UserInfo.ProxyAddresses
}
Disconnect-QADService
Thank you,
Dustin Hollenback
Senior Consultant
Ensynch
Hi,
I want to do this script :
Search atttribu user departement to AD and :
if objUser.Get(“departement”) = “%variable%” then
add group “%variable%”
group=”cn=%variable%”
ouGroups=”ou=NoIAM,ou=%variable%,”
ouMoveUser=”ou=%variable%”
Have you an idea ?.
Thank.
Ben, this code of yours is definitely not PowerShell. Come join our side and we’ll be here to help. 😉
PowerGUI.org has a pretty good AD Management forum (but again for PowerShell only)
Could be a newbee question but it’s more than two days that i looking around for a solution.I want to append a value to a multi-valued AD attribute such as userworkstations and as the help example I use:
PS C:\> [Collections.DictionaryEntry] $de = new-object Collections.DictionaryEntry -argumentList Append, @(‘srvr-ica6’)
PS C:\> set-QADUser ‘CN=TestUser2,CN=Users,DC=test,DC=pippo,DC=com’ -objectAttributes @{userworkstations=$de}
but immediatly i recieve this error message:
Set-QADUser : L’attributo o valore specificato per il servizio directory esiste già. (Eccezione da HRESULT: 0x8007200D)
At line:1 char:12
+ set-QADUser <<<< ‘CN=TestUser2,CN=Users,DC=test,DC=pippo,DC=com’ -objectAttributes @{userworkstations=$de}
Any suggestion?
Riccardo, I think you already found the solution with other folks at the forum: http://powergui.org/thread.jspa?threadID=7844&tstart=0
I couldn’t get the code above to work either until I added the “includeallproperties” to both “GET-QADUSER” statements (see below).
This script will currently die if it encounters a duplicate X500 address and will not continue on to the next user. I am a 2 hour newbie into powershell and I think fixing this issue would be pretty helpful.
$list = import-csv “c:\test.csv”
foreach ($name in $list)
{
$UserInfo = Get-QADUser -SamAccountName $name.sAMAccountName -IncludeAllProperties
#The following line should only be used for multivalued attributes. It reads from the existing attributes and adds additional data from the CSV file.
Get-QADUser -SamAccountName $name.sAMAccountName -IncludeAllProperties | Set-QADUser -ObjectAttributes @{proxyAddresses=$UserInfo.proxyAddresses +=$name.proxyAddresses}
Write-Host $UserInfo.proxyAddresses
}
Really? This is weird… Could you post that to the AD PowerShell forum at: http://powergui.org/forum.jspa?forumID=173 so the engineers confirm/troubleshoot the behavior?
Dmitry
Upon looking at your code once again, I can see why you needed all properties in the first call – proxyAddresses attribute is not retrieved by default (still a more efficient way is to do: -IncludedProperties proxyAddresses). For the second one – I don’t think you need it. Even more, you actually do not need the second get at all. You can use the samAccountName as the identity parameter right in the set.
$list = import-csv “c:\test.csv”
foreach ($name in $list)
{
$UserInfo = Get-QADUser -SamAccountName $name.sAMAccountName -IncludedProperties proxyAddresses
#The following line should only be used for multivalued attributes. It reads from the existing attributes and adds additional data from the CSV file.
Set-QADUser $name.sAMAccountName -ObjectAttributes @{proxyAddresses=$UserInfo.proxyAddresses +=$name.proxyAddresses}
Write-Host $UserInfo.proxyAddresses
}
Sorry, i’ve forgot to post the solution here.
Your last comment was really helpfull!
Thanks Dmitry!
Nice…I just ran my script today and it took about 2.5 hours for 4000 records. I am guessing that your tightened up code would reduce this time.
Thanks
Complete Newbie here….
I want to search our users for those with a Particular Company attribute, and then change them to have a different company attribute… Any help would be great!!…..
Ian,
Is the attribute among the ones exposed Get-QADUser and Set-QADUser parameters?
If yes, then it is trivial, e.g.:
Get-QADUser -City “Chicago” | Set-QADUser “Mumbai”
If not, then use the ObjectAttributes parameter:
Get-QADUser -ObjectAttributes @{l=’Chicago’} | Set-QADUser -ObjectAttributes @{l=’Mumbai’}
Please ask any questions at our PowerShell support forums: http://powergui.org/forumindex.jspa?categoryID=55 – the guys over there are normally much faster to respond than I am. 🙂
Dmitry
Hi,
how can clear the attribute “msrassavedframedipaddress”? When I try to use:
Get-QADUser USERNAME| Set-QADUser -ObjectAttributes @{msrassavedframedipaddress=$null}
I do get an access denied error. The user performing the command is a domain administrator.
Thomas
Hi,
What is the easiest way with Powershell to add/append a period “.” to current Middle Initials in AD that don’t have it. Forexample:
I <<<wrong
I. <<<correct
Thank You,
Dima
Dima,
This is relatively easy. Could you post this to the Active Directory and PowerShell forum: http://powergui.org/forum.jspa?forumID=173 – so we can discuss there rather than in blog comments?
Dmitry
Thanks. This was really useful for me today.
Hi
I would like to change CN attribute of an user object.
When I change for example firstname, I would like also update the “displayName” used in ADUC to reflect this change.
I believe that changing CN would do that.
In VBS I could use move object with a new full name and use the samu OU to acomplish this, but move in PS seems to take only OU for destination (or I did something wrong).
Does anyone have a sollution?
Thanl you in advance
Herbert,
Rename-QADObject [http://wiki.powergui.org/index.php/Rename-QADObject] to change object CN / DN.
To change Display Name, simply use Set-QADUser -DisplayName [http://wiki.powergui.org/index.php/Set-QADUser]
If you still have questions, post these to our PowerShell and AD forum here: http://powergui.org/forum.jspa?forumID=173
Dmitry
I have a situation where I need to read SAMAccountName from a file and populate extension attribute 15 for each user. The SAMAccountName value would go into extension attribute 15. What is the best way to do that? Thank you in advance.
John, I guess this will be along the lines of:
Get-Content “c:\samaccountnames.txt” | ForEach-Object { Set-QADUser $_ -ObjectAttributes @{extensionattribute1=$_}}
I do not have a lab handy to test this. If this does not work, try asking in the forums at powergui.org
Great read, thanks you. I am really new to powershell and am Trying to update a custom attribute called s-commisionclass it in bulk.
Import-csv “massupdates.csv” | ForEach{ Set-QADuser $name.SamAccountName -ObjectAttributes @{“s-commissionclass”=$name.repcode}}
In my massupdates.csv I have a SamAccountName and a repcode column but it doesn’t like it. Any suggestions?
Set-QADuser : Cannot validate argument on parameter ‘Identity’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
Variable $name is not initialized in your script anywhere. It is $null – hence the issue.
Oh geez,
I thought that would pull SamAccountName and repcode coulmns. I’m not sure what I need to do to get to that point. I see now that was a mistake. $name needs to equal something, not sure why I thought otherwise. Would you be able to help me understand what I need to do?
Use ForEach and $_. as shown for example here: https://dmitrysotnikov.wordpress.com/2010/04/19/import-file-to-change-group-membership/
I might have it now, i’ll need to test it more tomorrow though
Import-csv “massupdates.csv” | ForEach-Object {
set-QADUser $_.samAccountName -ObjectAttributes @{“s-commissionclass”=($_.s-commissionclass);}}
In my massupdates.csv I’ll have a SamAccountName and a s-commissionclass column. I want it to add the commission class codes to each samacocunt s-commissionclass custom attribute.
like this
Samacocunt s-commissionclass
ssmith GEN.0123
jsmith USR.0154
jtroy CST.1111
Hopefully i’m making sense.