Quantcast
Channel: PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources: Active Threads
Viewing all articles
Browse latest Browse all 8411

An ASDI interface and Method question.

$
0
0

Hello All

Hello

Can someone please help me with the following question? In some respects it is a little unusual and quirky.  I understand what went wrong and how to fix it, but there is an element I am a bit unclear on (the interesting bit),  I have a hunch but not certain, help most appreciated.

I am dealing with Microsoft Active Directory and the [ADSI] DirectoryServices.DirectoryEntry and [ADSISEARCHER] DirectoryServices.DirectorySearcher interfaces to AD.

Now let’s say I have

 AD Domain called MyDomain.net

Three OU’s called under MyDoamin (Windows 2003 R2)

OU1
OU2
Groups

Under OU1 there are two users
User1
User2

Under OU2 there are two users
User3
User4

Under the Groups OU there are two three groups
Group1
Group2
Group3

Now let’s say the following users are members of the following groups

Group1 members
User1 under OU1
User2 under OU1
User3 under OU2

Therefore the key here is that User3 under OU2 is a member of Group1 alongside Users1 and 2 from OU1

Now I want to remove any users from Group1 “as long as the user is under OU1 and no other OU”, therefore the result should be that Group1 ends up with just User3.

I realise I can do this with the Quest AD cmdlets, but I want to focus on how I initially did it using [ADSI] why it went wrong and how I resolved it, and therein my question (coming later).

So my initial code was

$OU="LDAP://OU=OU1,DC=MyDomain,DC=net"

$ObjectType="(&(objectCategory=Person)(objectClass=User))"

$Searcher= [DirectoryServices.DirectorySearcher]""

$Searcher.SearchRoot=$OU

$Searcher.Filter=$ObjectType

$Users=$Searcher.FindAll()

 

foreach ($userin$Users) {

 

      $GroupNames= ($user.PSBase.Properties.memberof | where {$_-match"CN=Group1"})

 

            foreach ($GroupNamein$GroupNames) {

 

            if ($user.PSBase.Properties.memberof | where {$_-match"CN=Group1"})

                 

                  {

                        $GroupObj=[ADSI]"LDAP://$GroupName"

                        $GroupObj.Remove("LDAP://$user")

 

                  }

            }

      }

 

First off, if you look at the result of $Users

It returns only the users accounts under OU1 as designed, i.e. it returns a collection of object of type System.DirectoryServices.SearchResult which I know are cut down objects and if you want the actual object you need to use the GetDirectoryEntry() method, but I will come to this later.

If I run the above script the result will be that all users (including User3 under OU2) will be removed from the group, and not just the collection of users I am working on in the foreach loop i.e. foreach ($userin$Users) as we know $Users only contains search results from users under OU1, so I am thinking why did it process a user (user3) under OU2 when it was not even in the collection of $Users.

 

So I am thinking perhaps the following line


$GroupObj
.Remove("LDAP://$user")


i.e. the $User part is acting on the Class ‘user’ rather than the particular instance of the class e.g. the user in question under OU1 which is why it removed all users. However I do not see why as the LDAP://$user should pick out and attach to a particular instance as each instance of $user represents a specific user in my collection

 

So then I take a closer look at $user it returns the following to the console

 

 

Path
----                                       

LDAP://CN=User1,OU=OU1,DC=mydomain,DC=net


Properties
----------
{blah blah } 

Path
----                                       

LDAP://CN=User2,OU=OU1,DC=mydomain,DC=net


Properties
----------
{blah blah } 


That looks OK,  again no mention at all of User3

So then I do the following

$OU="LDAP://OU=Users,OU=OU1,DC=MyDomain,DC=net"

$ObjectType="(&(objectCategory=Person)(objectClass=User))"

$Searcher= [DirectoryServices.DirectorySearcher]""

$Searcher.SearchRoot=$OU

$Searcher.Filter=$ObjectType

$Users=$Searcher.FindAll()

 

foreach ($userin$Users) {

 

$GroupNames= ($user.PSBase.Properties.memberof | where {$_-match"CN=Group1"})

 

      foreach ($GroupNamein$GroupNames) {

 

      if ($user.PSBase.Properties.memberof | where {$_-match"CN=Group1"})

     

      {

      $UserObj=$user | % {$_.GetDirectoryEntry()} | % {$_.distinguishedName

      }

 

                                   

                  $GroupObj=[ADSI]"LDAP://$GroupName"

                  $GroupObj.Remove("LDAP://$UserObj")

 

                  }

            }

      }

This time the script works as expected and only removes Users under OU1 (User1 and User1) from Group1 and not users under OU2 (User3).

I realise with the second example I am getting the actual user object (as opposed to a cut down searcher result) from AD with the GetDirectoryEntry() method, but I did not think this was necessary;  as event before invoking the GetDirectoryEntry() method each $user only represents one user and always under OU1 (event if is only a System.DirectoryServices.SearchResult object)

Perhaps without using GetDirectoryEntry() the following might work

$GroupObj.Remove("$($User.path)")

Not tested that one yet.

Any advice on the mechanics of the above and how/why in the first example all users are remove from the group would be most welcome.

Thanks

Ernie

 

 

 

 


Viewing all articles
Browse latest Browse all 8411

Latest Images

Trending Articles



Latest Images