Archive for the ‘Quest’ Category
Quest AD Management Shell – Moving AD User Objects
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.
AD and Kerberos Token Bloat – Analyzing Group Nesting
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.
Scanning Active Directory for SMTP Addresses
How To: Scanning Active Directory for SMTP Addresses.
When an object in AD is mail enabled it is assigned an SMTP address. Sometimes these addresses are assigned incorrectly to objects or a requested address is already in use on a object and you need to find the object that it is assigned to. I come across this situation sometimes and the simplest way is to query AD for the SMTP address. The SMTP addresses are stored in an AD attribute called “proxyAddresses” this holds all addresses including SMTP. Using the QUEST PowerShell PSSnapIn, you can query AD for this attribute using an LDAP filter.
Querying AD using Quest cmdlets and LDAP query.
Get-QADObject -LdapFilter "(proxyAddresses=*$Address*)" -IncludedProperties "proxyAddresses"
Using the above command with perform the filter, however you will only pull back the default cached set of attributes for the object so I add the ‘-includeallproperties’ switch to pull all attributes available for the object back into the cache.
I also set the ‘-SizeLimit 0′ so the result set isn’t limited to the standard 1000 returned objects.
The below code turns the basic shell command into a ‘Function’ called ‘Get-ProxyAddress.ps1′.
Instructions:
- Copy the below code into a file called ‘Get-ProxyAddress.ps1′
- Open the PowerShell shell and traverse to the directory that hosts the above file
- Run the script using this syntax, “./Get-ProxyAddress.ps1 address@domain.com”
- address@domain.com being the SMTP address you are searching for.
The output details either that the SMTP address is not found in AD or the below attributes are listed for the object that own the SMTP address.
- Name
- DisplayName
- ObjectClass
- AccountisDisabled
- AccountisLockedOut
- MailNickName
- LegacyExchangeDN
Download Script from PoshCode.org
Code:
Param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, HelpMessage="Enter SMTP address to search for in Active-Directory." )] [string]$objSMTP ) Function Get-ProxyAddresses ([string]$Address){ $objAD = $null $objAD = Get-QADObject -LdapFilter "(proxyAddresses=*$Address*)" -IncludeAllProperties -SizeLimit 0 -ErrorAction SilentlyContinue Write-Output $objAD }#Close Function #Validate Quest PSSnapin is loaded Add-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue #Run Function to search AD for SMTP address $Results = $null $Results = Get-ProxyAddresses -Address $objSMTP | Select-Object Name,DisplayName,ObjectClass,Email,AccountisDisabled,AccountisLockedOut,MailNickName,LegacyExchangeDN -ErrorAction SilentlyContinue IF($Results -eq $null){ Write-Host "" Write-Host "No Object Found with .attribute[proxyAddress] containing $objSMTP."} Else{$Results | Format-List *} #End
Hope this helps.
All information is provided on an AS-IS basis, with no warranties and confers no rights.
Exporting 2003 Mailbox Data to CSV
I have been using this code for a while and thought I would post it.
I manage several Exchange 2003 servers, this PowerShell code will allow you to pull Mailbox data from each server into their own .CSV file.
It uses a built Array for the server list and parses the Array to get Mailbox data from each server.
$Mailboxes = $Null $Computers = "Server1","Server2","Server3","Server4" ForEach($Computer in $Computers) { $Mailboxes = Get-WmiObject -NameSpace Root\MicrosoftExchangeV2 -Class Exchange_Mailbox -Computer $Computer $Mailboxes | Export-Csv "C:\Mailboxes_$Computer.csv" -NoTypeInformation }
You can combine this with ADSI code to discover all your Exchange 2003 servers in your Directory.
This would give you Mailbox data on all of your Exchange 2003 servers without the need for a manual Array.
[Array]$ExchSrvs = @("") [String]$StrFilter = “(objectCategory=msExchExchangeServer)” $objRootDSE = [ADSI]“LDAP://RootDSE” [String]$strContainer = $objRootDSE.configurationNamingContext $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = New-object System.DirectoryServices.DirectoryEntry(”LDAP://$strContainer”) $objSearcher.PageSize = 1000 $objSearcher.Filter = $strFilter $objSearcher.SearchScope = “Subtree” $colServers = $objSearcher.FindAll() ForEach($objServer in $colServers) { [String]$Server = $objResult.Properties.name $ExchSrvs += $Server } $ExchSrvs.Count
Your final script would look something like this.
[Array]$ExchSrvs = @("") [String]$StrFilter = “(objectCategory=msExchExchangeServer)” $objRootDSE = [ADSI]“LDAP://RootDSE” [String]$strContainer = $objRootDSE.configurationNamingContext $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = New-object System.DirectoryServices.DirectoryEntry(”LDAP://$strContainer”) $objSearcher.PageSize = 1000 $objSearcher.Filter = $strFilter $objSearcher.SearchScope = “Subtree” $colServers = $objSearcher.FindAll() ForEach($objServer in $colServers) { [String]$Server = $objResult.Properties.name $Mailboxes = $Null $Mailboxes = Get-WmiObject -NameSpace Root\MicrosoftExchangeV2 -Class Exchange_Mailbox -Computer $Server $Mailboxes | Export-Csv "C:\Mailboxes_$Server.csv" -NoTypeInformation }
Hope this helps.
All information is provided on an AS-IS basis, with no warranties and confers no rights.
Searching for DL's with Exchange Expansion Servers
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:
- 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)
- 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.
