TechnoGist

gist (jst)# The central idea; the essence…

Archive for the ‘Get-QADGroup’ tag

AD and Kerberos Token Bloat – Analyzing Group Nesting

with one comment

How To: Analyze Nested AD Groups.

I am working on a Kerberos Token size issue (Token Bloat) and need to accurately depict a groups nested members for token size analysis and remediation.

Brief Token Bloat Explanation:

Token Bloat is where due to several factors including deep group nesting the Kerberos token utilized in AD for resource authentication bloats towards the set limit or even beyond. This can cause larger logon times to resources and even issues in applications like Exchange 2003 that can only exist on a 32Bit OS.

I came across this article on the “Microsoft Active Directory Group PowerShell” blog, it has a great script for analysing nested group memberships. Unfortunately to use the PowerShell script you need to be running Windows 2008 servers for the Active Directory cmdlets to be available. The environment that I required the script for was not W2008 so I converted the script to use the Quest cmdlets available with the Quest Active Roles Management PSSnapIn.

You will need to have these installed before using this script.

The script originally written by the MS AD PowerShell team, provides a visual tree view of the groups and their nested levels, a ‘MaxNestingLevel’ value and a ‘NestedGroupMembershipCount’.

Example:

PS C:\> Get-QADGroupNesting.ps1 group-name

Or

PS C:\> Get-QADGroupNesting.ps1 group-name -ShowTree

The above example not only displays group statistics it also plots the structure of the group in a tree format.

Download Script at PoshCode.org

Code:

##########Copy the below script into a new file called Get-ADGroupNesting.ps1
 
Param (
    [Parameter(Mandatory=$true,
        Position=0,
        ValueFromPipeline=$true,
        HelpMessage="DN or ObjectGUID of the AD Group."
    )]
    [string]$groupIdentity,
    [switch]$showTree
    )
#Validate Quest PSSnapin is loaded
Add-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$global:numberOfRecursiveGroupMemberships = 0
$lastGroupAtALevelFlags = @() 
 
function Get-GroupNesting ([string] $identity, [int] $level, [hashtable] $groupsVisitedBeforeThisOne, [bool] $lastGroupOfTheLevel)
{
    $group = $null
    $group = Get-QADGroup -Identity $identity -SizeLimit 0
    if($lastGroupAtALevelFlags.Count -le $level)
    {
        $lastGroupAtALevelFlags = $lastGroupAtALevelFlags + 0
    }
    if($group -ne $null)
    {
        if($showTree)
        {
            for($i = 0; $i -lt $level - 1; $i++)
            {
                if($lastGroupAtALevelFlags[$i] -ne 0)
                {
                    Write-Host -ForegroundColor Blue -NoNewline "  "
                }
                else
                {
                    Write-Host -ForegroundColor Blue -NoNewline "│ "
                }
            }
            if($level -ne 0)
            {
                if($lastGroupOfTheLevel)
                {
                    Write-Host -ForegroundColor Blue -NoNewline "└─"
                }
                else
                {
                    Write-Host -ForegroundColor Blue -NoNewline "├─"
                }
            }
            Write-Host -ForegroundColor Blue $group.Name
        }
        $groupsVisitedBeforeThisOne.Add($group.DN,$null)
        $global:numberOfRecursiveGroupMemberships ++
        $groupMemberShipCount = $group.memberOf.Count
        if ($groupMemberShipCount -gt 0)
        {
            $maxMemberGroupLevel = 0
            $count = 0
            foreach($groupDN in $group.memberOf)
            {
                $count++
                $lastGroupOfThisLevel = $false
                if($count -eq $groupMemberShipCount){$lastGroupOfThisLevel = $true; $lastGroupAtALevelFlags[$level] = 1}
                if(-not $groupsVisitedBeforeThisOne.Contains($groupDN)) #prevent cyclic dependancies
                {
                    $memberGroupLevel = Get-GroupNesting -Identity $groupDN -Level $($level+1) -GroupsVisitedBeforeThisOne $groupsVisitedBeforeThisOne -lastGroupOfTheLevel $lastGroupOfThisLevel
                    if ($memberGroupLevel -gt $maxMemberGroupLevel){$maxMemberGroupLevel = $memberGroupLevel}
                }
            }
            $level = $maxMemberGroupLevel
        }
        else #we've reached the top level group, return it's height
        {
            return $level
        }
        return $level
    }
}
$global:numberOfRecursiveGroupMemberships = 0
$groupObj = Get-QADGroup -Identity $groupIdentity -SizeLimit 0
if($groupObj)
{
    [int]$maxNestingLevel = Get-GroupNesting -Identity $groupIdentity -Level 0 -GroupsVisitedBeforeThisOne @{} -lastGroupOfTheLevel $false
 Add-Member -InputObject $groupObj -MemberType NoteProperty  -Name MaxNestingLevel -Value $maxNestingLevel -Force
 Add-Member -InputObject $groupObj -MemberType NoteProperty  -Name NestedGroupMembershipCount -Value $($global:numberOfRecursiveGroupMemberships - 1) -Force
 $groupObj | Select-Object Name,DN,MaxNestingLevel,NestedGroupMembershipCount | Format-List
}

Hope this helps
All information is provided on an AS-IS basis, with no warranties and confers no rights.

Written by Paul Brice

January 25th, 2010 at 8:33 pm

Searching for DL's with Exchange Expansion Servers

without comments

Question:

Do we have any Email enabled groups in Active Directory that have an Exchange 2003 expansion server explicitly specified in its properties and who manages them? 

Expansion Server:

“Exchange server dedicated to expanding the members of a specific mail enabled group (distribution list)”

Answer:

So I would need to look at  Active Directory for all email enabled distribution lists that have the attribute ‘msExchExpansionServerName’ (which only exists when a group is mail enabled), and that it’s value is not blank. If the attribute is blank the distribution list is set to default which is ‘Any server in the organization’. The value can be viewed on the ‘Exchange Advanced’ TAB on the groups properties in ADUC.

Here is the PowerShell one line command that I used. I am utilizing the Quest Active Roles Management cmdlets.

You will need the following:

  1. DN, GUID or Canonical Name of the Domain or Container where you wish to search for groups. (The example quotes a DN for the group container)
  2. Quest Active Roles Management Shell snapin.
Get-QADGroup -SearchRoot 'OU=GrouOU,DC=company,DC=com' -SizeLimit 0 -LdapFilter '(msExchExpansionServerName=*)' -IncludeAllProperties | Select-Object name,msexchexpansionservername,managedby

If you need any assistance in using the Quest Active Roles Management cmdlets see this article.

Note:

I use the ‘-IncludeAllProperties’property of the ‘Get-QADGroup’ cmdlet to ensure the ‘msExchExpansionServerName’ attribute is returned into the local cached object result set, by default this would not be returned, for more information see this article..

Hope this helps.

All information is provided on an AS-IS basis, with no warranties and confers no rights.

Written by Paul Brice

June 8th, 2009 at 1:43 am

Quest AD Management Shell – Get-QADGroup

without comments

In my previous blog entry “Getting Started” I went over downloading and installing the Quest AD Management shell, registering the snapins and running some basic commands using the Get-QADUser CmdLet.

Today I will be looking at the Get-QADGroup CmdLet.
This allows easy access to Active Directory “Group” objects.

As before open a PowerShell Shell window and add in your snapins.

add-pssnapin Quest.ActiveRoles.ADManagement

Getting the number of members in a group.

(Get-QADGroup "GroupName").members.count

Export out the members of a group to a formatted table including the name,displayname,mail(SMTP) and office for each member.

Function Get-MemberName()
{
Process
{
ForEach($Member In $_)
{
Get-QADUser –ObjectAttributes @{distinguishedName=$Member}
}
}
}
(Get-QADGroup "GroupName").members | Get-MemberName | Format-Table name,displayname,mail,office

I often have to clean up groups by looking for disabled users.
To do this you can just add the “accountisdisabled” property to the script above.

E.g.

(Get-QADGroup "GroupName").members | Get-MemberName | Format-Table name,displayname,mail,office,accountisdisabled

Export out the members of a group to a CSV file with all properties.

Function Get-MemberName()
{
Process
{
ForEach($Member In $_)
{
Get-QADUser –ObjectAttributes @{distinguishedName=$Member}
}
}
}
(Get-QADGroup "GroupName").members | Get-MemberName | Export-Csv "C:\GroupMembers.csv"

Above are some useful examples of using Quest AD CmdLets to enumerate Active Directory Group objects.

Hope this helps.

All information is provided on an AS-IS basis, with no warranties and confers no rights.

Written by Paul Brice

April 21st, 2009 at 10:45 am