{"id":56023,"date":"2008-03-12T00:13:00","date_gmt":"2008-03-12T00:13:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/03\/12\/hey-scripting-guy-how-can-i-use-windows-powershell-to-add-a-domain-user-to-a-local-group\/"},"modified":"2008-03-12T00:13:00","modified_gmt":"2008-03-12T00:13:00","slug":"hey-scripting-guy-how-can-i-use-windows-powershell-to-add-a-domain-user-to-a-local-group","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-use-windows-powershell-to-add-a-domain-user-to-a-local-group\/","title":{"rendered":"Hey, Scripting Guy! How Can I Use Windows PowerShell to Add a Domain User to a Local Group?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! I recently came across <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct04\/hey1008.mspx\"><b>your article<\/b><\/a> where you showed people how to use VBScript to add a domain user to a local group. How can I do that same task using Windows PowerShell?<\/p>\n<p>&#8212; KE<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, KE. Before we begin we thought we should mention that the Scripting Guy who writes this column has a new favorite TV commercial. He\u2019s not even sure what the commercial is advertising (other than some car maker) but it shows two identical cars (with identical drivers and passengers) driving parallel roads. When the two roads merge together, the cars magically merge together as well, and the two cars seamlessly become one car. <\/p>\n<p>Admittedly, that\u2019s not that big of a deal. Instead, what\u2019s <i>really<\/i> cool about the commercial isn\u2019t the commercial itself, but the disclaimer that accompanies it:<\/p>\n<table class=\"dataTable\" id=\"EGD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\">Professional driver on closed course. Do not attempt.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>To be honest, that\u2019s extremely good advice. For example, suppose you\u2019ve had yourself cloned, and both you and your clone drive identical cars. Should you drive down parallel roads and then smash the cars into one another, assuming that the two cars will seamlessly merge into one? No, you should not.<\/p>\n<p>Well, not unless both you and your clone happen to be professional drivers on a closed course. Then it\u2019s OK. <\/p>\n<p>Or at least that\u2019s what they tell you on TV. To tell you the truth, though, it doesn\u2019t look all that hard to us. Why don\u2019t you give it a try and let us know how it goes?<\/p>\n<table class=\"dataTable\" id=\"ERD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. At the risk of giving the poor old Scripting Editor a heart attack, we take that back: <i>don\u2019t<\/i> give this a try, even if you <i>are<\/i> a professional driver on a closed course. And no, not even if your clone is also a professional driver.<\/p>\n<p>Oh, and a word of advice: to the best of our knowledge, no court in the world will accept \u201cThe Scripting Guys <i>told<\/i> me to do it\u201d as a legitimate excuse for doing something stupid.<\/p>\n<p>Nor should they.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>But don\u2019t worry; this doesn\u2019t mean that only professional drivers on closed courses get to have any fun. Granted, you can\u2019t smash two cars together to see if you can somehow get them to merge into one car. (Although, then again \u2026 no, never mind. Don\u2019t even <i>think<\/i> about it. Or, at the least, don\u2019t tell anyone that the Scripting Guys <i>told<\/i> you to think about it.) But who cares? Believe it or not, you can still have fun without smashing two cars together. For example, you don\u2019t need to be a professional driver on a closed course in order to write a Windows PowerShell script that adds a domain user to a local group. Instead, all you have to do is put together something similar to this:<\/p>\n<pre class=\"codeSample\">$objUser = [ADSI](\"WinNT:\/\/fabrikam\/kenmyer\")\n$objGroup = [ADSI](\"WinNT:\/\/atl-fs-001\/Administrators\")\n\n$objGroup.PSBase.Invoke(\"Add\",$objUser.PSBase.Path)\n<\/pre>\n<p>So what\u2019s going on here? Good question. In the first line, we\u2019re using the <b>[ADSI]<\/b> type adapter to create an object reference to an Active Directory user account; more specifically, we\u2019re creating an object reference to the fabrikam\\kenmyer user account. So what <i>is<\/i> the [ADSI] type adapter? That\u2019s also a good question. In order to make certain operations a little easier for, and a little more relevant to, system administrators, PowerShell includes several \u201ctype adapters\u201d such as [ADSI]; in this case, the type adapter makes it easier to connect to ADSI, regardless of whether you\u2019re using ADSI to manage Active Directory or to manage local accounts. If it wasn\u2019t for the type adapter, you\u2019d need to go through the .NET Framework and conjure up an instance of the System.DirectoryServices.DirectoryEntry class in order to work with ADSI. The type adapter simply creates that instance for you.<\/p>\n<p>Hmmm, that\u2019s another good question: if this is Active Directory why did we use the <b>WinNT<\/b> provider; aren\u2019t you supposed to use the LDAP provider when working with Active Directory?<\/p>\n<p>Yes, you are, <i>provided<\/i> that you are working exclusively with Active Directory. In this case, however, we aren\u2019t working exclusively with Active Directory; instead we\u2019re working with local accounts as well. Local accounts require the use of the WinNT provider, and the WinNT provider doesn\u2019t know how to work with OUs and other Active Directory components. Because of that, we have to use the old-fashioned <i>domain\/username<\/i> syntax. <\/p>\n<p>After we create an object reference to the user account we repeat the process to create a second object reference, this one to our local group. For our sample script, that\u2019s the Administrators group on the computer atl-fs-001:<\/p>\n<pre class=\"codeSample\">$objGroup = [ADSI](\"WinNT:\/\/atl-fs-001\/Administrators\")\n<\/pre>\n<p>Once we\u2019ve done that we can add the domain user Ken Myer to our local Administrators group by using the following line of code:<\/p>\n<pre class=\"codeSample\">$objGroup.PSBase.Invoke(\"Add\",$objUser.PSBase.Path)\n<\/pre>\n<p>Yet <i>another<\/i> good question: what the heck is that <b>PSBase<\/b> stuff? Well, when you use Windows PowerShell to connect to an object, PowerShell will often decide, in advance, which methods and properties will be exposed to you. That\u2019s usually fine, except that sometimes PowerShell guesses wrong; sometimes it fails to show the property or method you really need. That\u2019s the case here; if you bind to a local group account (like the Administrator account) PowerShell exposes only a handful of methods and properties:<\/p>\n<pre class=\"codeSample\">Name                        MemberType\n----                        ----------\nConvertDNWithBinaryToString CodeMethod\nConvertLargeIntegerToInt64  CodeMethod\nDescription                 Property\ngroupType                   Property\nName                        Property\nobjectSid                   Property\n<\/pre>\n<p>That\u2019s where the PSBase object comes in. PSBase lets you get at the \u201craw\u201d object behind the object PowerShell exposes by default; in other words, PSBase lets you get at all the properties and methods of the object:<\/p>\n<pre class=\"codeSample\">Name                      MemberType\n----                      ----------\nClose                     Method\nCommitChanges             Method\nCopyTo                    Method\nCreateObjRef              Method\nDeleteTree                Method\nDispose                   Method\nEquals                    Method\nGetHashCode               Method\nGetLifetimeService        Method\nGetType                   Method\nInitializeLifetimeService Method\nInvoke                    Method\nInvokeGet                 Method\nInvokeSet                 Method\nMoveTo                    Method\nRefreshCache              Method\nRename                    Method\nToString                  Method\nAuthenticationType        Property\nChildren                  Property\nContainer                 Property\nGuid                      Property\nName                      Property\nNativeGuid                Property\nNativeObject              Property\nObjectSecurity            Property\nOptions                   Property\nParent                    Property\nPassword                  Property\nPath                      Property\nProperties                Property\nSchemaClassName           Property\nSchemaEntry               Property\nSite                      Property\nUsePropertyCache          Property\nUsername                  Property\n<\/pre>\n<p>In this case, PSBase exposes the <b>Invoke<\/b> method. In turn, we can then call Invoke, passing it the <b>Add<\/b> parameter and the <b>Path<\/b> property containing the user account in Active Directory. What will <i>that<\/i> do for us? You got it: it will add the user in question (fabrikam\\kenmyer) to the local Administrators group on atl-fs-001.<\/p>\n<table class=\"dataTable\" id=\"EDG\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. By the way, you might notice that, when calling the Invoke method, we had to use the PSBase object of our user account: $objUser.PSBase.Path. That\u2019s because, by default, we don\u2019t have access to the object Path. The only way to get to that is to use PSBase.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Believe it or not, KE, that\u2019s all you have to do. Run this script, and Ken Myer\u2019s Active Directory account will be added to the local Admins account. Give it a try and see for yourself.<\/p>\n<p>Remember, though, <i>don\u2019t<\/i> try smashing two cars together for yourself. For that matter, don\u2019t try smashing two anythings together. Several years ago, the Scripting Guys tried an experiment in which we had Peter Costantini and Dean Tsaltas run as fast as they can and then smash together. The hope was that, by combining the two, we would produce some sort of Super Scripting Guy. So what <i>did<\/i> we end up with instead? Peter and Dean, exactly as they are today.<\/p>\n<p>Let that be a warning to you all.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I recently came across your article where you showed people how to use VBScript to add a domain user to a local group. How can I do that same task using Windows PowerShell? &#8212; KE Hey, KE. Before we begin we thought we should mention that the Scripting Guy who writes this [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[7,168,44,3,45],"class_list":["post-56023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-domains","tag-groups","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I recently came across your article where you showed people how to use VBScript to add a domain user to a local group. How can I do that same task using Windows PowerShell? &#8212; KE Hey, KE. Before we begin we thought we should mention that the Scripting Guy who writes this [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56023","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=56023"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56023\/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=56023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=56023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=56023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}