{"id":86542,"date":"2019-10-23T01:00:59","date_gmt":"2019-10-23T09:00:59","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/scripting\/?p=86542"},"modified":"2019-10-23T02:47:41","modified_gmt":"2019-10-23T10:47:41","slug":"copy-multi-valued-active-directory-attributes-from-one-user-to-another-with-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/copy-multi-valued-active-directory-attributes-from-one-user-to-another-with-powershell\/","title":{"rendered":"Copy multi-valued Active Directory attributes from one user to another with PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Using -Replace parameter with Set-ADUser to copy Active Directory multi-valued attributes<\/p>\n<p>Q: Hey, Doctor Scripto!<\/p>\n<p>We are in the middle of an Active Directory migration and need to copy the multi-valued attribute \u201cProxyAddresses\u201d from old user accounts to new ones. Can you do with a few lines of code?<\/p>\n<p>\u2014ND<\/p>\n<p>A: Hello ND,<\/p>\n<p>Hello everyone, your good friend Doctor Scripto is here with Walid, one of our PFEs who really likes mixing PowerShell with Active Directory. Walid, what do you think of this one?<\/p>\n<p>Well, Doctor Scripto, it makes a lot of sense to try and automate this type of tasks. Who likes to manually copy information from one place to another for a whole night?<\/p>\n<p>The Active Directory module for PowerShell has a command called Set-ADUser, we can use the -Replace parameter to provide new values of any attribute, like ProxyAddresses for example. The -Replace parameter takes a hashtable, so we can use it to enter several attributes at once. See example below,<\/p>\n<pre class=\"lang:ps decode:true\">Set-ADUser -Identity \"MyTestUser\" -Replace @{ Title = \"CEO\" Description = \"Chief Executive Officer\" }<\/pre>\n<p>This will replace what ever value in the Title and Description attributes with the information above.<\/p>\n<p>Now, when it comes to multi-valued attributes, we can use the -Replace, but fort the value, we need to provide an array. See this example,<\/p>\n<pre class=\"lang:ps decode:true\">Set-ADUser -Identity \"MyTestUser\" -Replace @{ ProxyAddresses = @(\"Address1\",\"Address2\",\"Address3\")}<\/pre>\n<p>Here we provided an array of strings. This is how it looks in AD,<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-86546 size-medium\" src=\"http:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/scripto-adattribute-282x300.png\" alt=\"\" width=\"282\" height=\"300\" srcset=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/scripto-adattribute-282x300.png 282w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/scripto-adattribute.png 362w\" sizes=\"(max-width: 282px) 100vw, 282px\" \/><\/p>\n<p>Now to our main task, copying from one user to the another. The first step would be to get the value from the old user,<\/p>\n<pre class=\"lang:ps decode:true \">$OldUserProxyAddresses = (Get-ADUser -Identity \"OldUser\" -Properties \"ProxyAddresses\").ProxyAddresses<\/pre>\n<p>However, if we look at the object type of the extracted data, it is a collection, not an array. So we cannot directly use it.<\/p>\n<p><img decoding=\"async\" width=\"694\" height=\"89\" class=\"wp-image-86544\" src=\"http:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-11.png\" srcset=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-11.png 694w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-11-300x38.png 300w\" sizes=\"(max-width: 694px) 100vw, 694px\" \/><\/p>\n<p>One trick PowerShell has is its ability to cast a specific type, we can use this to quickly convert the ProxyAddresses into an Array using [Array] before the variable name,<\/p>\n<p><img decoding=\"async\" width=\"545\" height=\"77\" class=\"wp-image-86545\" src=\"http:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-12.png\" srcset=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-12.png 545w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/word-image-12-300x42.png 300w\" sizes=\"(max-width: 545px) 100vw, 545px\" \/><\/p>\n<p>Now we can use it to copy into the new user,<\/p>\n<pre class=\"lang:ps decode:true \">Set-ADUser -Identity \"NewUser\" -Replace ([Array] $OldUserProxyAddresses)<\/pre>\n<p>To sum it up, if we want to this for many users quickly we can use a CSV with a list of old and new users,<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>OldSamAccountName<\/strong><\/td>\n<td><strong>NewSamAccountName<\/strong><\/td>\n<\/tr>\n<tr>\n<td>OldUser1<\/td>\n<td>NewUser1<\/td>\n<\/tr>\n<tr>\n<td>OldUser2<\/td>\n<td>NewUser2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>Then use PowerShell to automate the whole process,<\/p>\n<pre class=\"lang:default decode:true \">$UserList = Get-Content \"C:\\Temp\\UsersToCopyProxyAddresses.CSV\"\r\n\r\nforeach ($User in $UserList)\r\n{\r\n     $OldUserProxyAddresses = (Get-ADUser -Identity ($User.OldSamAccountName) -Properties \"ProxyAddresses\").ProxyAddresses\r\n     Set-ADUser -Identity ($User.NewSamAccountName) -Replace ([Array] $OldUserProxyAddresses)\r\n}<\/pre>\n<p>That\u2019s it, 4 lines. Hope this saves you some time ND.<\/p>\n<p>So that is all there is to copying multi-valued attributes in Active Directory.\u00a0 Pop by next week as we put on our detective hats to uncover a cool puzzle in Azure.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\">Official Scripting Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Your good friend, Doctor Scripto<\/strong><\/p>\n<p>PowerShell, Doctor Scripto, Active Directory, Walid Moselhy<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Using -Replace parameter with Set-ADUser to copy Active Directory multi-valued attributes Q: Hey, Doctor Scripto! We are in the middle of an Active Directory migration and need to copy the multi-valued attribute \u201cProxyAddresses\u201d from old user accounts to new ones. Can you do with a few lines of code? \u2014ND A: Hello ND, Hello [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2641,1739,1738,685],"tags":[7,1740,377,2642],"class_list":["post-86542","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-active-directory","category-doctor-scripto","category-powershell","category-scripting-techniques","tag-active-directory","tag-doctor-scripto","tag-powershell","tag-walid-moselhy"],"acf":[],"blog_post_summary":"<p>Summary: Using -Replace parameter with Set-ADUser to copy Active Directory multi-valued attributes Q: Hey, Doctor Scripto! We are in the middle of an Active Directory migration and need to copy the multi-valued attribute \u201cProxyAddresses\u201d from old user accounts to new ones. Can you do with a few lines of code? \u2014ND A: Hello ND, Hello [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86542","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=86542"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86542\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=86542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=86542"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=86542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}