• No results found

147Active Directory groups

In document Exploring PowerShell Automation (Page 154-156)

D Set group scope

147Active Directory groups

We need to consider two final tasks regarding groups to complete our work with Active Directory. One question that will arise is “Which groups is this user a member of?” But before we consider that, we need to be able to find all of the members of a group.

TECHNIQUE 16 Finding group members

Discovering the members of a group can be thought of as two separate problems. We have a problem—the direct group membership—that can be resolved easily. This is the list of members you’d see on the Members tab of the Properties dialog in Active Directory Users and Computers.

The second problem is more complex, in that we want to find all of the members, including those users that are members of a group—members of the group in which we’re interested. The group nesting may occur to any number of levels.

PROBLEM

We need to find all the members of a group. SOLUTION

We solve this problem by creating a function that will list the group members, as shown in listing 5.25. If a member is itself a group, we get the function to call itself using the name of that group. This is known as recursion. The primary goal of this sec- tion is to resolve the nested group membership. But before we review that script, we’ll look at reading the direct membership of a group:

$group = [ADSI]"LDAP://cn=UKPMs,ou=All Groups,dc=manticore,dc=org" $group.member | Sort-Object

After retrieving a directory entry object for the group, we can display the members using $group.member. Piping this into a sort makes the output more readable.

function resolve-group{ param ($group)

foreach ($member in $group.member){ $obj = [ADSI]("LDAP://" + $member)

$global:members += $obj.distinguishedname if ($obj.objectclass[1] -eq 'group'){resolve-group $obj} } } $global:members = @() $ldp = "LDAP://cn=International,ou=All Groups,dc=manticore,dc=org" $group = [ADSI]$ldp resolve-group $group $global:members | Sort-Object -Unique

Alternatively, we can use the Microsoft cmdlet:

Get-ADGroupMember -Identity EngSci | select Name, distinguishedname

The Quest alternative gives us:

Get-QADGroupMember -Identity "cn=USPres,ou=All Groups,dc=manticore,dc=org"

Listing 5.25 Get nested group membership

Loop through members

E

Add to members list

F

G

Call function Define array

B

C

Directory entry

D

Call function

Display all members

H

Discovering the nested group membership is more complicated than retrieving the membership of a single group, as listing 5.25 shows. The script consists of two parts: a function, resolve-group, that reads the group membership, and the main part of the script that gets the group and displays the membership. We start the script by creating an empty array (developers will refer to this as declaring an array)

B

. The point to note here is the way the variable is defined: $global:members. The addition of global: to the variable makes it a variable of global scope, meaning that we can access the same variable in the main part of the script and in the function. This will be important.

ADSI is used to get a directory entry

C

for the group. We then call the resolve- group function

D

, passing in the group as a parameter. The $group within the func- tion is in a different scope than the $group outside the function.

A foreach loop is used to read the group membership

E

from the member prop- erty. A directory entry is created for each member

F

and added to our globally avail- able array. We test the group member, and if it’s a group

G

, we call the resolve- group function using the member as a parameter.

DISCUSSION

Congratulations! You now understand recursion, as the function will keep calling itself as many times as necessary. As the array we created to hold the membership is global in scope, it can be accessed through the various levels of recursion.

Once the function has finished processing the direct and nested membership, we return to the main part of the script. The contents of the array are sorted and the unique values

H

are displayed. Using the -Unique parameter prevents duplicate entries from being displayed, and means that we don’t have to write code to deal with them. This makes the script easier to write and understand.

There’s a simpler way to get this information using the Microsoft cmdlet Get- ADGroupMember. The -Recursive parameter displays nested group membership:

Get-ADGroupMember -Identity international -Recursive | select Name, DistinguishedName

The Quest alternative is to use the –Indirect parameter:

Get-QADGroupMember -Identity 'manticore\international' -Indirect

Having mastered recursion in the previous example, we’ll use it again to determine all of the groups of which a particular user is a member.

TECHNIQUE 17 Finding a user’s group membership

One last Active Directory script and then we’re done. PROBLEM

We need to find all of the groups of which the user is a member. SOLUTION

The memberof attribute holds the groups of which the user is a member. We can recur- sively check those groups for other groups to determine the full list of groups where the user is a member, as shown in listing 5.26. The processing starts by getting a direc-

149 Summary

tory entry for the user

B

. We use the memberof property to find the groups of which the user is a direct member

C

. The group is passed into the function resolve-mem- bership, where the distinguished name is written

D

to screen.

For each of the groups, we get a directory entry

E

and test to see if it’s a member of any groups. If it is, we call the function with the name of each group.

F

Recursion keeps this script compact. It is a topic that many find difficult but the examples in the book should make it easier to use. Once you have worked through a few scripts of your own you’ll be proficient.

function resolve-membership{ param ($group)

Write-Host $group

$group2 = [ADSI]("LDAP://" + $group) if ($group2.memberof -ne $null){

foreach ($group3 in $group2.memberof){ resolve-membership $group3 } }

}

$user = [ADSI]"LDAP://CN=WELLESLEY Arthur,OU=England,DC=Manticore,DC=org" foreach ($group in $user.memberof){resolve-membership $group}

DISCUSSION

I haven’t produced a version using the cmdlets, as there isn’t a built-in way to produce this information, and we just replace the [ADSI] lines

E

and

B

in listing 5.26 with Get-ADGroup/Get-QADGroup and Get-ADUser/Get-QADUser respectively.

5.5

Summary

Automating Active Directory administration involves working with users and groups or performing searches. We can perform these tasks by scripting based on ADSI or by using the AD cmdlets from either Microsoft or Quest .

Creation and modification scripts follow a pattern of getting a directory object, making changes (or creating a child object), and saving back to the database. Search- ing has its own pattern of defining the root of the search, defining the search filter, performing the search, and displaying the results.

There’s useful functionality in the System.DirectoryServices.Accountmanage- ment classes, though a few holes also exist.

After creating and modifying our user account, it’s time to turn our attention to our email system. Email has become a business critical tool, and by combining our mailbox and user account administration techniques, we can automate and stream- line our processes.

Listing 5.26 Get user’s group membership

Write group

D

Group directory entry

E

In document Exploring PowerShell Automation (Page 154-156)