TechnoGist

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

Archive for the ‘AD’ Category

Quest AD Management Shell – Moving AD User Objects

without comments

Code Snippet: Moving disable user objects in Active Directory using PowerShell and Quest Management cmdlets.Task:

Task: Moving all disabled users in the ‘/Users’ OU to the /Users/Disabled OU.

Code:

Add-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$Users = Get-QADUser -SearchRoot 'ad.domain.com/Users/' -Disabled
Write-Host "Moving $Users.Count Users."
ForEach($User In $Users){
Move-QADObject $User.DN -NewParentContainer 'ad.domain.com/Users/Disabled'}

Hope this helps

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

Written by Paul Brice

January 28th, 2010 at 7:00 pm

Posted in AD,PowerShell,Quest

Tagged with , ,

Exchange 2010 on a Windows 2008 R2 Domain Controller

with one comment

Issue: “Service ‘MSExchangeTransport’ failed to reach  status ‘Running’ on this server.”

I am building my virtual lab using VMWare Fusion at home, It consists of a Windows 2008 R2 server with AD Domain Services installed and Exchange 2010.

Please Note:

I am running AD (Global Catalog) and Exchange 2010 on the same server and this is not a recommended configuration by Microsoft.

Possible Issues

After the installation of Windows 2008 R2 and AD Domain Services, I have installed all prerequisites for Exchange 2010 and performed the Exchange 2010 install using the install wizard. I chose to install Exchange Management Tools, Hub, CAS and Mailbox to have a nice contained environment.

However during the install of the ‘Hub Transport Role’ I got this failure;

The execution of: “$error.Clear(); if ($RoleStartTransportService) { start-SetupService -ServiceName MSExchangeTransport }”, generated the following error: “Service ‘MSExchangeTransport’ failed to reach  status ‘Running’ on this server.”

And this error appeared in the Application Event log.

Source: MSExchange ADAccess
Event ID: 2114
Task Category: Topology
Level: Error
Description:
Process MSEXCHANGEADTOPOLOGYSERVICE.EXE (PID=1784). Topology discovery failed, error 0x80040a02 (DSC_E_NO_SUITABLE_CDC). Look up the Lightweight Directory Access Protocol (LDAP) error code specified in the event description. To do this, use Microsoft Knowledge Base article 218185, “Microsoft LDAP Error Codes.” Use the information in that article to learn more about the cause and resolution to this error. Use the Ping or PathPing command-line tools to test network connectivity to local domain controllers.

After finding several mentions of security changes and group membership alterations including domain policy issues I found this article from ‘Rui Silver’ in his blog. He experienced the very same issue while installing Exchange 2007 on Windows 2008 and it was a result of Exchange requiring IPv6. I had disabled it on the interface properties while building my Windows 2008 R2 server believing I would not need it.

After I re-enabled IPv6 on the interface and left it to obtain an IPv6 address automatically by default, rebooted the system and like magic the exchange services could start and I could complete the installation of all Exchange 2010 roles.

You can disable IPv6 permanently before installing Exchange and there are several articles out there. (I have not tested either of these.)

  1. Windows Server Forums
  2. Exchange Server Share

Resources:

  1. Windows 2008 R2 Server
  2. Active Directory Domain Services
  3. Exchange 2010 Prerequisites

Please note that this is a basic overview of my server and it is not intended as a recommendation or standard to be used by anyone else.

Hope this helps

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

Written by Paul Brice

January 27th, 2010 at 10:59 pm

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