{"id":3261,"date":"2019-03-14T14:57:07","date_gmt":"2019-03-14T12:57:07","guid":{"rendered":"https:\/\/www.msb365.blog\/?p=3261"},"modified":"2019-04-29T14:59:41","modified_gmt":"2019-04-29T12:59:41","slug":"net-assemblies-in-powershell-part-2-manage-active-directory-group-members-and-user-accounts","status":"publish","type":"post","link":"https:\/\/www.msb365.blog\/?p=3261","title":{"rendered":".NET Assemblies In PowerShell &#8211; Part 2: Manage Active Directory group members and user accounts"},"content":{"rendered":"<p>In the <a href=\"https:\/\/www.msb365.blog\/?p=1776\">first part<\/a> of this series, I described how you can add and remove members to and from Active Directory groups in PowerShell, without using the <em>ActiveDirectory<\/em> module, but just by using the .Net namespace <em>System.DirectoryServices.AccountManagement.<\/em><\/p>\n<p>In this part I want to show how you can work with the members of a group, as well as with Active Directory accounts in general using this namespace in PowerShell. For the prerequisites, please check out the <a href=\"https:\/\/www.msb365.blog\/?p=1776\">first part<\/a> of this series.<\/p>\n<h4><strong>The members property<\/strong><\/h4>\n<p>In the last article, we created a <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.groupprincipal?view=netframework-4.7.2\"><em>GroupPrincipal<\/em><\/a> object for an Active Directory group. One cool thing about this object type: you can easily work with any of the group members by accessing the <em>Members<\/em> property (type <em><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.principalcollection?view=netframework-4.7.2\">PrincipalCollection<\/a><\/em><em>)<\/em> of the group object<em>.<\/em><\/p>\n<p>By calling the&nbsp;<em>Members<\/em> property, a list of all group members will be shown, in which any group member is presented as a <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.principalcontext?view=netframework-4.7.2\">PrincipalContext<\/a> object.<\/p>\n<p>In the following example, we&#8217;re accessing the <em>Members <\/em>property of a group that contains two user accounts.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-delay:false nums:false nums-toggle:false lang:ps decode:true\" title=\"Members property - get members\">PS C:\\Users&gt; $group.Members\r\n\r\n\r\nGivenName                         : Test\r\nMiddleName                        : \r\nSurname                           : 001\r\nEmailAddress                      : Test.001@lab.com\r\nVoiceTelephoneNumber              : \r\nEmployeeId                        : \r\nAdvancedSearchFilter              : System.DirectoryServices.AccountManagement.AdvancedFilters\r\nEnabled                           : True\r\nAccountLockoutTime                : \r\nLastLogon                         : 02.05.2018 11:52:56\r\nPermittedWorkstations             : {}\r\nPermittedLogonTimes               : {255, 255, 255, 255...}\r\nAccountExpirationDate             : \r\nSmartcardLogonRequired            : False\r\nDelegationPermitted               : True\r\nBadLogonCount                     : 0\r\nHomeDirectory                     : \\\\FileServer01\\TEST001$\r\nHomeDrive                         : H:\r\nScriptPath                        : \r\nLastPasswordSet                   : \r\nLastBadPasswordAttempt            : 02.05.2018 11:51:39\r\nPasswordNotRequired               : False\r\nPasswordNeverExpires              : True\r\nUserCannotChangePassword          : False\r\nAllowReversiblePasswordEncryption : False\r\nCertificates                      : {}\r\nContext                           : System.DirectoryServices.AccountManagement.PrincipalContext\r\nContextType                       : Domain\r\nDescription                       : 001 Test\r\nDisplayName                       : 001 Test\r\nSamAccountName                    : TEST001\r\nUserPrincipalName                 : Test.001@lab.com\r\nSid                               : S-1-5-21-4025995969-482537669-3923321509-3972\r\nGuid                              : de16cf7f-79c4-4257-9de7-adb687ba5fe7\r\nDistinguishedName                 : CN=001 Test,OU=Standard,OU=Users,DC=lab,DC=com\r\nStructuralObjectClass             : user\r\nName                              : 001 Test\r\n\r\nGivenName                         : TEST0500\r\nMiddleName                        : \r\nSurname                           : TestAccount\r\nEmailAddress                      : TEST0500@lab.com\r\nVoiceTelephoneNumber              : \r\nEmployeeId                        : \r\nAdvancedSearchFilter              : System.DirectoryServices.AccountManagement.AdvancedFilters\r\nEnabled                           : True\r\nAccountLockoutTime                : \r\nLastLogon                         : \r\nPermittedWorkstations             : {}\r\nPermittedLogonTimes               : {255, 255, 255, 255...}\r\nAccountExpirationDate             : \r\nSmartcardLogonRequired            : False\r\nDelegationPermitted               : True\r\nBadLogonCount                     : 0\r\nHomeDirectory                     : \r\nHomeDrive                         : \r\nScriptPath                        : \r\nLastPasswordSet                   : \r\nLastBadPasswordAttempt            : \r\nPasswordNotRequired               : False\r\nPasswordNeverExpires              : False\r\nUserCannotChangePassword          : False\r\nAllowReversiblePasswordEncryption : False\r\nCertificates                      : {}\r\nContext                           : System.DirectoryServices.AccountManagement.PrincipalContext\r\nContextType                       : Domain\r\nDescription                       : \r\nDisplayName                       : TestAccount TEST0500\r\nSamAccountName                    : TEST0500\r\nUserPrincipalName                 : \r\nSid                               : S-1-5-21-4025995969-482537669-3923321509-16697\r\nGuid                              : 45e85f63-3d47-452f-b071-0572f423aa99\r\nDistinguishedName                 : CN=TestAccount TEST0500,OU=Standard,OU=Users,DC=lab,DC=com\r\nStructuralObjectClass             : user\r\nName                              : TestAccount TEST0500<\/pre>\n<p>Well, this is really nice. First, we see a lot more of the members&#8217; attributes than the <em>Get-ADGroupMember<\/em> cmdlet provides and second, we can directly work with these objects from here on. In my opinion, this is a great advantage over the <em>ActiveDirectory <\/em>PowerShell module<em>.<\/em>&nbsp;<\/p>\n<h4><strong>The group members&nbsp;<\/strong><\/h4>\n<p>Through the <em>Members<\/em> property we are not only able to list and manage who the members of a group are, we can even directly modify some attributes of the members (all attributes that are properties of the <em>UserPrincipal<\/em> class).<\/p>\n<p>This could make some daily business tasks way easier for us.<\/p>\n<p>For example: Let&#8217;s say you want to change the description for all members of a specific Active Directory group to &#8220;Test account&#8221;. Using the PowerShell <em>ActiveDirectory<\/em> module cmdlets, you would have to do something like this:&nbsp;<\/p>\n<ol>\n<li>Run the <em>Get-ADGroupMembers<\/em> cmdlet.<br \/>\n2. Iterate through the result.<br \/>\n3. Pass each item of the result to the <em>Set-ADUser<\/em> cmdlet.&nbsp;<\/li>\n<\/ol>\n<p>Of course, you could also just pipe the result of the <em>Get-ADGroupMember<\/em> cmdlet to <em>Set-ADUser<\/em>.<\/p>\n<p>Using the <em>System.DirectoryServices.AccountManagement<\/em> namespace, the steps would be the following:<\/p>\n<p>First, let&#8217;s check the the current description of the group members (optional):<\/p>\n<pre class=\"theme:powershell toolbar-overlay:false toolbar-delay:false nums:false nums-toggle:false lang:ps decode:true\" title=\"list group members\">PS C:\\Users&gt; $group.Members | select SAMAccountName,Description\r\n\r\nSamAccountName Description    \r\n-------------- -----------    \r\nTEST001        Something      \r\nTEST0500       Something else<\/pre>\n<p>Now, let&#8217;s change it (this is actually all we need to do):<\/p>\n<pre class=\"theme:powershell-ise toolbar-overlay:false toolbar-delay:false nums:false lang:ps decode:true\" title=\"Edit group members\">foreach ($user in $group.Members)\r\n{\r\n    #Set the new description\r\n    $user.Description = \"Test account\"\r\n    #Save the user to the Active Directory\r\n    $user.Save()\r\n}<\/pre>\n<p>There will be no confirmation if the task was successful. In this case, no news is good news.<\/p>\n<p>Finally, if we want to verify the effects of our command, we can just run the first command again (optional):<\/p>\n<pre class=\"theme:powershell toolbar-overlay:false toolbar-delay:false nums:false nums-toggle:false lang:ps decode:true\">PS C:\\Users&gt; $group.Members | select SAMAccountName,Description\r\n\r\nSamAccountName Description \r\n-------------- ----------- \r\nTEST001        Test account\r\nTEST0500       Test account<\/pre>\n<p>As we can see, the description of all group members was successfully changed to &#8220;Test account&#8221;. Pretty cool, huh?<\/p>\n<p>Hint: Instead of using a For Each loop, we can even save some lines by calling the <i>ForEach&nbsp;<\/i>method of the <em>Members<\/em> property. See the following example:<\/p>\n<pre class=\"theme:powershell-ise nums:false nums-toggle:false lang:ps decode:true \">$group.Members.ForEach({$_.Description = \"Test account\"})\r\n$group.Members.ForEach({$_.Save()})\r\n<\/pre>\n<h4>Speed<\/h4>\n<p>Again, I was curious about how the execution times would compete against the cmdlets of the <em>ActiveDirectory<\/em> module. Here are the results of my measuring:<\/p>\n<pre class=\"nums:false lang:ps decode:true\" title=\"Edit group members - speed test 1\">#Using \"Get-ADGroupMember\" and \"Set-ADUser\"\r\nPS C:\\&gt; Measure-command {Get-ADGroupMember test-group001 |%{Set-ADUser $_ -Description \"Test account\"}}\r\n\r\n\r\nDays              : 0\r\nHours             : 0\r\nMinutes           : 0\r\nSeconds           : 0\r\nMilliseconds      : 213\r\nTicks             : 2131780\r\nTotalDays         : 2.46733796296296E-06\r\nTotalHours        : 5.92161111111111E-05\r\nTotalMinutes      : 0.00355296666666667\r\nTotalSeconds      : 0.213178\r\nTotalMilliseconds : 213.178\r\n\r\n#Using the \"Members\" property and a for each loop\r\nPS C:\\&gt; Measure-Command {$group.Members |%{$_.Description = \"Test account\";$_.Save()}}\r\n\r\n\r\nDays              : 0\r\nHours             : 0\r\nMinutes           : 0\r\nSeconds           : 0\r\nMilliseconds      : 69\r\nTicks             : 695725\r\nTotalDays         : 8.05237268518518E-07\r\nTotalHours        : 1.93256944444444E-05\r\nTotalMinutes      : 0.00115954166666667\r\nTotalSeconds      : 0.0695725\r\nTotalMilliseconds : 69.5725\r\n\r\n#Using the \"Members\" property and the \"ForEach\" method of the group object\r\nPS C:\\&gt; Measure-command {$group.Members.ForEach({$_.Description = \"Test account\"});$group.Members.ForEach({$_.Save()})}\r\n\r\n\r\nDays              : 0\r\nHours             : 0\r\nMinutes           : 0\r\nSeconds           : 0\r\nMilliseconds      : 41\r\nTicks             : 414158\r\nTotalDays         : 4.79349537037037E-07\r\nTotalHours        : 1.15043888888889E-05\r\nTotalMinutes      : 0.000690263333333333\r\nTotalSeconds      : 0.0414158\r\nTotalMilliseconds : 41.4158<\/pre>\n<p>Sure, we already had the group object created before.<\/p>\n<p>Ok, then let&#8217;s see how the creation of the group object will affect the execution time:<\/p>\n<pre class=\"nums:false lang:ps decode:true\" title=\"Edit group members - speed test 2\">#Create the group object first\r\n#then run the command\r\n\r\nPS C:\\&gt; Measure-Command {\r\n$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($pc, \"test-group001\")\r\n$group.Members |% {$_.Description = \"Test account\";$_.Save()}\r\n}\r\n\r\n\r\n\r\nDays              : 0\r\nHours             : 0\r\nMinutes           : 0\r\nSeconds           : 0\r\nMilliseconds      : 67\r\nTicks             : 678370\r\nTotalDays         : 7.85150462962963E-07\r\nTotalHours        : 1.88436111111111E-05\r\nTotalMinutes      : 0.00113061666666667\r\nTotalSeconds      : 0.067837\r\nTotalMilliseconds : 67.837\r\n\r\n#Create all necessary objects and add the assembly\r\nPS C:\\&gt; Measure-Command {\r\n$am = Add-Type -AssemblyName System.DirectoryServices.AccountManagement\r\n$pc = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::`\r\nDomain)\r\n$IDType = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName\r\n$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($pc, \"test-group001\")\r\n$group.Members |% {$_.Description = \"Test account\";$_.Save()}\r\n}\r\n\r\n\r\nDays              : 0\r\nHours             : 0\r\nMinutes           : 0\r\nSeconds           : 0\r\nMilliseconds      : 97\r\nTicks             : 979199\r\nTotalDays         : 1.13333217592593E-06\r\nTotalHours        : 2.71999722222222E-05\r\nTotalMinutes      : 0.00163199833333333\r\nTotalSeconds      : 0.0979199\r\nTotalMilliseconds : 97.9199<\/pre>\n<p>And&#8230;we have a winner. Even including all necessary code, we were still more than double as fast as the cmdlets of the <em>ActiveDirectory<\/em> module are.<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>The UserPrincipal object<\/strong><\/h4>\n<p>Alright. Now, we know how to modify attributes of users that are members of a specific group. But, how do we work with an Active Directory user directly?<\/p>\n<p>For this, we first need to create an object for the user which we want to manage.<\/p>\n<p>This is done in the same way as for a group, except that we&#8217;re now using the <em><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.userprincipal?view=netframework-4.7.2\">UserPrincipal<\/a><\/em> class of the <em>System.DirectoryServices.AccountManagement <\/em>namespace, instead of the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.groupprincipal?view=netframework-4.7.2\"><em>GroupPrincipal<\/em> <\/a>class. Following, an example how to create such an object.<\/p>\n<pre class=\"theme:powershell-ise nums:false lang:ps decode:true\" title=\"UserPrincipal object - get user\">#load the assembly (will NOT throw any error if already loaded)\r\n$am = Add-Type -AssemblyName System.DirectoryServices.AccountManagement\r\n#create the PrincipalContext object\r\n$pc = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::`\r\nDomain)\r\n#Set the username (SAMAccountName)\r\n$username = \"TEST001\"\r\n#load the user from AD \/ create the user object \r\n$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($pc,$username) \r\n<\/pre>\n<p>And, here&#8217;s our user:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - show user\">PS C:\\&gt; $user\r\n\r\n\r\nGivenName                         : Test\r\nMiddleName                        : \r\nSurname                           : 001\r\nEmailAddress                      : Test.001@lab.com\r\nVoiceTelephoneNumber              : \r\nEmployeeId                        : \r\nAdvancedSearchFilter              : System.DirectoryServices.AccountManagement.AdvancedFilters\r\nEnabled                           : False\r\nAccountLockoutTime                : \r\nLastLogon                         : 02.05.2018 11:52:56\r\nPermittedWorkstations             : {}\r\nPermittedLogonTimes               : {255, 255, 255, 255...}\r\nAccountExpirationDate             : \r\nSmartcardLogonRequired            : False\r\nDelegationPermitted               : True\r\nBadLogonCount                     : 0\r\nHomeDirectory                     : \\\\fileserver1\\TEST001$\r\nHomeDrive                         : H:\r\nScriptPath                        : \r\nLastPasswordSet                   : \r\nLastBadPasswordAttempt            : 02.05.2018 11:51:39\r\nPasswordNotRequired               : False\r\nPasswordNeverExpires              : True\r\nUserCannotChangePassword          : False\r\nAllowReversiblePasswordEncryption : False\r\nCertificates                      : {}\r\nContext                           : System.DirectoryServices.AccountManagement.PrincipalContext\r\nContextType                       : Domain\r\nDescription                       : Test account\r\nDisplayName                       : 001 Test\r\nSamAccountName                    : TEST001\r\nUserPrincipalName                 : Test.001@lab.com\r\nSid                               : S-1-5-21-4025995969-482537669-3923321509-3972\r\nGuid                              : de16cf7f-79c4-4257-9de7-adb687ba5fe7\r\nDistinguishedName                 : CN=001 Test,OU=Users,DC=lab,DC=com\r\nStructuralObjectClass             : user\r\nName                              : 001 Test \r\n<\/pre>\n<p>Once created, we can access any of the <em>UserPrincipal<\/em> object&#8217;s properties and methods by using the PowerShell standard \u201c.\u201d notation<strong><em>.<\/em><\/strong><\/p>\n<p>Here&#8217;s an example how you can display only the DisplayName of the user object:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - show single properties\">PS C:\\&gt; $user.DisplayName\r\n001 Test<\/pre>\n<p>And here&#8217;s how you can change it:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - change properties\">#Set a new display name\r\nPS C:\\&gt; $user.DisplayName = \"001 Test \/ msb365\"\r\n#save the user object to Active Directory\r\nPS C:\\&gt; $user.Save() \r\n<\/pre>\n<p>Display the new value:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - get user and show single property\">#Do a fresh load of the user from AD\r\nPS C:\\&gt; $user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($pc,$username)\r\n#Show the DisplayName property\r\nPS C:\\&gt; $user.DisplayName\r\n001 Test \/ msb365 \r\n<\/pre>\n<p>Keep in mind: For any changes of properties to take effect, the object has to be saved by using the <em>Save<\/em> method.<\/p>\n<h4>MemberOf<\/h4>\n<p>To list all Active Directory groups that a user is a member of, the <em>UserPrincipal<\/em> object provides the methods: <em>GetGroups <\/em>and <em>GetAuthorizationGroups<\/em>.<\/p>\n<p>For a listing of groups of which the user is a direct member, we can use the <em>GetGroups <\/em>method, as shown below:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - get MemberOf\">PS C:\\&gt; $user.GetGroups()\r\n\r\n\r\nIsSecurityGroup       : True\r\nGroupScope            : Global\r\nMembers               : {Administrator, DefaultAccount, AdminIIEM, krbtgt...}\r\nContext               : System.DirectoryServices.AccountManagement.PrincipalContext\r\nContextType           : Domain\r\nDescription           : All domain users\r\nDisplayName           : \r\nSamAccountName        : Domain Users\r\nUserPrincipalName     : \r\nSid                   : S-1-5-21-4025995969-482537669-3923321509-513\r\nGuid                  : 0c8e9be6-0271-4c93-a670-8a081a87406b\r\nDistinguishedName     : CN=Domain Users,CN=Users,DC=iamlab,DC=net\r\nStructuralObjectClass : group\r\nName                  : Domain Users\r\n\r\nIsSecurityGroup       : True\r\nGroupScope            : Global\r\nMembers               : {001 Test, TEstACCName TEST0500}\r\nContext               : System.DirectoryServices.AccountManagement.PrincipalContext\r\nContextType           : Domain\r\nDescription           : \r\nDisplayName           : \r\nSamAccountName        : test-group001\r\nUserPrincipalName     : \r\nSid                   : S-1-5-21-4025995969-482537669-3923321509-16717\r\nGuid                  : 924c1135-80c0-4e29-aeae-b6ff5f42c9bf\r\nDistinguishedName     : CN=test-group001,OU=GROUPS,DC=iamlab,DC=net\r\nStructuralObjectClass : group\r\nName                  : test-group001\r\n<\/pre>\n<p>We see that the user is a member of the two groups \u201cDomain Users\u201d and \u201ctest-group001\u201d. To make the output more readable, we can use the dot notation to show only the SAMAccountNames of those groups:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\">PS C:\\&gt; $user.GetGroups().samaccountname\r\nDomain Users\r\ntest-group001 \r\n<\/pre>\n<p>We can also include indirect memberships; groups in which the user is member of by group nesting.<\/p>\n<p>For this, we need to use the <em>GetAuthorizationGroups<\/em> method. See the example below:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - MemberOf recursive\">PS C:\\&gt; $user.GetAuthorizationGroups().samaccountname\r\nEveryone\r\nAuthenticated\r\nUsersDomain \r\nUsers\r\ntest-group001\r\nUsers<\/pre>\n<p>Now, the list contains some more groups. The additional groups are groups of which the user is a indirect member of. For example, we see the built-in group \u201cUsers\u201d here, because the user is a member of the &#8220;Domain Users&#8221; group, which again is a member of the group &#8220;Users&#8221;.<\/p>\n<h4>Other useful methods<\/h4>\n<p>The <em>UserPrincipal<\/em> object provides some more pretty useful methods for daily business tasks on Active Directory user accounts. Following, there&#8217;s a brief description of some of them.<\/p>\n<h5>Check if an account is a member of a specific group<\/h5>\n<p>For this, we first need to create a <em>GroupPrincipal <\/em>object for the Active Directory group that we want to check. Once we&#8217;ve created it, we can check if the user is a member of that group, by calling the <em>IsMemberOf<\/em> method of the <em>UserPrincipal<\/em> object and passing the <em>GroupPrincipal<\/em> as an overload. Return values are &#8220;True&#8221;, or &#8220;False&#8221; (type Boolean).<\/p>\n<pre class=\"nums:false nums-toggle:false lang:ps decode:true\" title=\"UserPrincipal object - Check if in group\">#create the group object\r\nPS C:\\&gt; $group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($pc, \"test-group001\")\r\n#Call the MemberOf method with the group object as overload\r\nPS C:\\&gt; $user.IsMemberOf($group)\r\nTrue \r\n<\/pre>\n<h5>Check if an account is locked out<\/h5>\n<p>Return values: &#8220;True&#8221;, or &#8220;False&#8221; (type Boolean).<\/p>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true \">PS C:\\&gt; $user.IsAccountLockedOut()\r\nFalse<\/pre>\n<h5>Unlock an account<\/h5>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">PS C:\\&gt; $user.UnlockAccount()<\/pre>\n<h5>Refresh an expired password<\/h5>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">PS C:\\&gt; $user.RefreshExpiredPassword()<\/pre>\n<h5>Set a user&#8217;s password to expired<\/h5>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">PS C:\\&gt; $user.ExpirePasswordNow()<\/pre>\n<h5>Set a new password<\/h5>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">PS C:\\&gt; $user.SetPassword('NewP@$$w0rd')<\/pre>\n<h5>Delete a user account<\/h5>\n<p>Careful! There will be no confirmation question, or second approval option. It just deletes the account right away.<\/p>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true \">PS C:\\&gt; $user.Delete()<\/pre>\n<p>&nbsp;<\/p>\n<h4>Further info<\/h4>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement?view=netframework-4.7.2\" target=\"_blank\" rel=\"noopener noreferrer\">&#8220;System.DirectoryServices.AccountManagement&#8221; namespace<\/a><\/p>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.accountmanagement.principalcontext?view=netframework-4.7.2\" target=\"_blank\" rel=\"noopener noreferrer\">PrincipalContext class<\/a><\/p>\n<p>The&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.utility\/add-type?view=powershell-5.0\" target=\"_blank\" rel=\"noopener noreferrer\">Add-Type cmdlet<\/a><\/p>\n<p><a href=\"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/11\/11\/use-powershell-to-work-with-the-net-framework-classes\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to work with .Net classes in PowerShell<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>In the next parts of this series, I will focus on creating Active Directory objects. So, stay tuned \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the first part of this series, I described how you can add and remove members to and from Active Directory groups in PowerShell, without using the ActiveDirectory module, but just by using the .Net namespace System.DirectoryServices.AccountManagement. In this part I want to show how you can work with the members of a group, as [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":3403,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[685,3],"tags":[],"class_list":["post-3261","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-active-directory","category-powershell"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/posts\/3261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3261"}],"version-history":[{"count":36,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions"}],"predecessor-version":[{"id":3492,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions\/3492"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=\/wp\/v2\/media\/3403"}],"wp:attachment":[{"href":"https:\/\/www.msb365.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.msb365.blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}