{"id":949,"date":"2014-07-25T00:01:00","date_gmt":"2014-07-25T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/07\/25\/transforming-the-active-directory-cmdlets-part-5\/"},"modified":"2022-06-13T14:27:40","modified_gmt":"2022-06-13T21:27:40","slug":"transforming-the-active-directory-cmdlets-part-5","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/transforming-the-active-directory-cmdlets-part-5\/","title":{"rendered":"Transforming the Active Directory Cmdlets: Part 5"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Learn how to translate between ADSI, Quest, and Windows PowerShell cmdlets for creating users.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>\u00a0Hey, Scripting Guy!<\/p>\n<p>Today I&#8217;m translating a script for modifying user properties and I could really use some help. There are so many parameters to work with. Where do I start?<\/p>\n<p>\u2014LC<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>\u00a0Hello LC,<\/p>\n<p>Honorary Scripting Guy, Sean Kearney, here. I&#8217;m finishing up this week where I have been discussing switching between the various forms of Active Directory cmdlets.** **<\/p>\n<p><strong>Note<\/strong> This is the final post in a series. For more, see:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/transforming-the-active-directory-cmdlets-part-1\/\" target=\"_blank\" rel=\"noopener\">Transforming to<b> <\/b>Active Directory Cmdlets: Part 1<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/transforming-the-active-directory-cmdlets-part-2\/\" target=\"_blank\" rel=\"noopener\">Transforming to<b> <\/b>Active Directory Cmdlets: Part <\/a>2<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/transforming-the-active-directory-cmdlets-part-3\/\" target=\"_blank\" rel=\"noopener\">Transforming to<b> <\/b>Active Directory Cmdlets: Part 3<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/transforming-the-active-directory-cmdlets-part-4\/\" target=\"_blank\" rel=\"noopener\">Transforming to<b> <\/b>Active Directory Cmdlets: Part 4<\/a><\/li>\n<\/ul>\n<p>Funny enough, LC, Kevin had the same issue. He actually had an older ADSI script that he was trying to modify to both Quest and Windows PowerShell versions. The original script looked like this:<\/p>\n<p style=\"margin-left:30px\">\n  $ModifyList=Import-CSV $ModifyList.csv\n<\/p>\n<p style=\"margin-left:30px\">\n  Foreach {$User in $ModifyList)\n<\/p>\n<p style=\"margin-left:30px\">\n  {\n<\/p>\n<p style=\"margin-left:30px\">\n  $Parent=&#8217;OU=Grok,DC=Contoso,DC=Local&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $Class=&#8221;user&#8221;\n<\/p>\n<p style=\"margin-left:30px\">\n  $Connection=[ADSI]&#8221;LDAP:\/\/$Parent&#8221;\n<\/p>\n<p style=\"margin-left:30px\">\n  $Name=&#8217;CN=&#8217;+$User.Name\n<\/p>\n<p style=\"margin-left:30px\">\n  $Phone=$User.Phone\n<\/p>\n<p style=\"margin-left:30px\">\n  $Email=$User.Email\n<\/p>\n<p style=\"margin-left:30px\">\n  $Description=$User.Description\n<\/p>\n<p style=\"margin-left:30px\">\n  $SetUser=$Connection.($invokeGet(Class, $Name)\n<\/p>\n<p style=\"margin-left:30px\">\n  $SetUser.put(&#8220;description&#8221;,$user.Description)\n<\/p>\n<p style=\"margin-left:30px\">\n  $SetUser.put(&#8220;mail&#8221;,$user.email)\n<\/p>\n<p style=\"margin-left:30px\">\n  $Setuser.put(&#8220;telephoneNumber&#8221;,$user.phone)\n<\/p>\n<p style=\"margin-left:30px\">\n  }\n<\/p>\n<p>Kevin was in small quandary, &#8220;The cmdlets are easy to use. The issue I am having is trying to sort out the parameters with all the names\u2014there are sooo many.&#8221;<\/p>\n<p>By looking at <strong>Get-Help<\/strong> for both cmdlets for setting user information, you can see Kevin&#8217;s issue. Check out the sheer number of parameters!<\/p>\n<p>First the Quest cmdlet:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/04350.1.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/04350.1.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Then the Windows PowerShell cmdlet:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0763.2.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0763.2.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>&#8220;Using them is actually pretty easy to figure out. Pass the name and give the parameter and value. But I have to try to find the <strong>one<\/strong> parameter to match the value I&#8217;m looking for. If only there was a way to list the parameters so I could find the name with a search.&#8221;<\/p>\n<p>Kevin began eyeing the shiny spot when I pointed out, &#8220;There is a way&#8230;and an easy one at that.&#8221;<\/p>\n<p>&#8220;We get that information by using <strong>Get-Command<\/strong>. IT can tell us information about the cmdlet and its properties.&#8221;<\/p>\n<p style=\"margin-left:30px\">\n  GET-Command SET-ADUser | GET-Member\n<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/7242.3.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/7242.3.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>I then showed Kevin how to pull up a list of parameters for the <strong>Set-ADUser<\/strong> cmdlet:<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-ADUser).parameters\n<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/6204.4.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/6204.4.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>&#8220;Ooooooo!&#8221; His eyes lit up, &#8220;So can I pass this information to <strong>Where-Object<\/strong> to filter on?&#8221;<\/p>\n<p>He immediately sat down to try to find the parameter for &#8220;email&#8221; with <strong>Set-ADUser<\/strong>:<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-ADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*mail*&#8217; }\n<\/p>\n<p>He found that the parameter name is <strong>EmailAddress<\/strong>, and he began putting together the rest of the command for the <strong>Set-ADUser<\/strong> Windows PowerShell cmdlet:<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-ADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*description*&#8217; }\n<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-ADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*phone*&#8217; }\n<\/p>\n<p>And then he wrote the following for the Quest version:<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-QADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*mail*&#8217; }\n<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-QADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*description*&#8217; }\n<\/p>\n<p style=\"margin-left:30px\">\n  (GET-Command SET-QADUser).parameters | Select-Object -ExpandProperty Keys | where { $_ -like &#8216;*phone*&#8217; }\n<\/p>\n<p>In most cases, Kevin found a one-to-one match, for example, <strong>Description<\/strong>. In some cases, he got a few extras, for example, <strong>HomePhone<\/strong>, <strong>MobilePhone<\/strong>, and <strong>PhoneNumber<\/strong>.<\/p>\n<p>&#8220;But this is way easier. Now that I can see the most likely parameters to use, I can easily convert this script. First, a version for our modern environment with Windows Server\u00a02012\u00a0R2:&#8221;<\/p>\n<p style=\"margin-left:30px\">\n  $ModifyList=Import-CSV $ModifyList.csv\n<\/p>\n<p style=\"margin-left:30px\">\n  Foreach {$User in $ModifyList)\n<\/p>\n<p style=\"margin-left:30px\">\n  {\n<\/p>\n<p style=\"margin-left:30px\">\n  $Parent=&#8217;OU=Grok,DC=Contoso,DC=Local&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $Name=$User.Name\n<\/p>\n<p style=\"margin-left:30px\">\n  $Phone=$User.Phone\n<\/p>\n<p style=\"margin-left:30px\">\n  $Email=$User.Email\n<\/p>\n<p style=\"margin-left:30px\">\n  $Description=$User.Description\n<\/p>\n<p style=\"margin-left:30px\">\n  SET-ADUser $Name \u2013emailaddress $email \u2013OfficePhone $phone \u2013description $Description\n<\/p>\n<p style=\"margin-left:30px\">\n  }\n<\/p>\n<p>&#8220;And now the exact script for the Quest <strong>Set-QADUser<\/strong> cmdlet:&#8221;<\/p>\n<p style=\"margin-left:30px\">\n  $ModifyList=Import-CSV $ModifyList.csv\n<\/p>\n<p style=\"margin-left:30px\">\n  Foreach {$User in $ModifyList)\n<\/p>\n<p style=\"margin-left:30px\">\n  {\n<\/p>\n<p style=\"margin-left:30px\">\n  $Parent=&#8217;OU=Grok,DC=Contoso,DC=Local&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $Name=$User.Name\n<\/p>\n<p style=\"margin-left:30px\">\n  $Phone=$User.Phone\n<\/p>\n<p style=\"margin-left:30px\">\n  $Email=$User.Email\n<\/p>\n<p style=\"margin-left:30px\">\n  $Description=$User.Description\n<\/p>\n<p style=\"margin-left:30px\">\n  SET-QADUser $Name \u2013email $email \u2013Phonenumber $phone \u2013description $Description\n<\/p>\n<p style=\"margin-left:30px\">\n  }\n<\/p>\n<p>Kevin noted that all three commands (ADSI, Quest, and Windows PowerShell) seemed to have their place, &#8220;I found that the Quest cmdlets were easiest to use, but they have a .NET Framework requirement that I can&#8217;t use sometimes\u2014depending on restrictions in the environment. The older <strong>[ADSI]<\/strong> accelerator is more involved, but it works all the time.&#8221;<\/p>\n<p>&#8220;True,&#8221; I nodded, &#8220;But the coolest thing you may not have realized about the Microsoft Active Directory cmdlets is that they do not require firewall ports to be open for WMI and RPC. They leverage a web service.&#8221;<\/p>\n<p>Jaw drop time. &#8220;Do you mean the network guys won&#8217;t freak on me as much when I spin up a domain controller? WooHooo!&#8221;<\/p>\n<p>And after this day, a small paper lay on the desk:<\/p>\n<p style=\"margin-left:30px\">\n  &#8220;Here lay the &#8216;Shiny Spot&#8217;\u2014a place of frustration, venting, and head butting\u2014until Kevin learned Windows PowerShell. The &#8216;Shiny Spot&#8217; is no more.&#8221;\n<\/p>\n<p>LC, that is all there is to converting the basic Active Directory user cmdlets. You know? I think tomorrow is Saturday! That means time for the Weekend Scripter! WooHoooo!<\/p>\n<p>I invite you to follow The Scripting Guys on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send an email to The Scripting Guys at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then remember eat your cmdlets each and every day with a dash of creativity.<\/p>\n<p>**Sean Kearney, **Windows PowerShell MVP and Honorary Scripting Guy<span style=\"font-size:12px\">\u00a0<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to translate between ADSI, Quest, and Windows PowerShell cmdlets for creating users. \u00a0Hey, Scripting Guy! Today I&#8217;m translating a script for modifying user properties and I could really use some help. There are so many parameters to work with. Where do I start? \u2014LC \u00a0Hello LC, Honorary Scripting Guy, Sean Kearney, here. [&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":[1],"tags":[7,56,3,154,45],"class_list":["post-949","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-guest-blogger","tag-scripting-guy","tag-sean-kearney","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to translate between ADSI, Quest, and Windows PowerShell cmdlets for creating users. \u00a0Hey, Scripting Guy! Today I&#8217;m translating a script for modifying user properties and I could really use some help. There are so many parameters to work with. Where do I start? \u2014LC \u00a0Hello LC, Honorary Scripting Guy, Sean Kearney, here. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/949","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=949"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/949\/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=949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}