Tag Archive: group membership

Adding/removing members from another forest or domain to groups in Active Directory:


Example of powershell script:
Write-Host “Loading the Quest.ActiveRoles.ADManagement powershell snap-in”
if ( (Get-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue) -eq $null )
Add-PsSnapin Quest.ActiveRoles.ADManagement

Write-Host “”
$rootOU = “DC=mydomain,DC=local”
$date = Get-Date -Format ddMMyyyy
$log = “.\Update-CVS-GroupMembership-$date.txt”
$startscript = Get-Date
$totalgrp = 0
$nceoldgrp = 0
$changes = 0
$KO = 0
Write-Host “”
Write-Host “————————————————————————————————”
Write-Host “”
Get-QADGroup -SearchRoot $rootOU | %{
$members = $null
$groupname = $_.Samaccountname
$members = Get-QADGroupMember -Identity $_.DN -Type group -Name MII_*
if ($members -ne $null) {
foreach ($member in $members) {
$GroupToReplace = $member.Samaccountname
$GroupToFind    = $GroupToReplace -replace (“MII_”,””)
$GroupExist = $null

$GroupExist = Get-QADGroup -SearchRoot “OU=Groups,DC=mydomain,DC=local” -SearchScope OneLevel -SamAccountName $GroupToFind

If ($GroupExist -ne $null)
Add-QADGroupMember -Identity $groupname -Member $GroupExist.DN -proxy
# Remove-QADGroupMember -Identity $groupname -Member $member.DN -proxy
Write-Output “Modification – $GroupToReplace has been replaced by $GroupToFind in the $groupname” | Out-File $log -Append
Write-Output “Error – $groupname unchanged… $GroupToReplace has not a matching group as $GroupToFind”  | Out-File $log -Append
Write-Host “”
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
Write-host “TOTAL “$totalgrp” total groups parsed” -BackgroundColor Yellow -ForegroundColor Black
Write-host “TOTAL “$nceoldgrp” total old MII_xxx groups found” -BackgroundColor Yellow -ForegroundColor Black
Write-host “TOTAL “$changes” total groups changed successfully” -BackgroundColor Yellow -ForegroundColor Black
Write-host “TOTAL “$KO” total groups with no matching” -BackgroundColor Yellow -ForegroundColor Black
Write-Host “”
#Start-Sleep 5
Write-Host “——————-”
Write-Host “– End of Script –”
Write-Host “——————-”
Write-Host “”
$stopscript = Get-Date
Write-Host “Has started at” $startscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “Had finished at” $stopscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “TIME SPENT:” (New-TimeSpan -Start $startscript -End $stopscript).hours “Hours” (New-TimeSpan -Start $startscript -End $stopscript).minutes “Minutes” (New-TimeSpan -Start $startscript -End $stopscript).seconds “Seconds” -BackgroundColor Green -ForegroundColor Black
Write-Host “”
Write-Host “”


How to resolve Foreign security principals with Quest cmdlets for AD?

Get-QADObject -ResolveForeignSecurityPrincipals -Type foreignSecurityPrincipal | select Samaccoutname,Type,DN


How to remove the Foreign security principals from groups:

$log = New-Item -Path c:\output;txt -ItemType File -Force
$group = cmd.exe /c dsquery group “ou=groups,dc=mydomain,dc=com”
Foreach ($g in $group){
 $members = cmd.exe /c dsget group $g -members
 Foreach ($m in $members){
 if ($m -like “*CN=ForeignSecurityPrincipals*”){

write-host “Group $g that contain FSP $m”

# to remove the FSP
# $result = “dsmod group $($g) -rmmbr $($m)”
 Add-Content -Path $log -Value $result  }
 } # end foreach groups
 } # end foreach members



Here is a script to list the Foreign Security Principals and the groups they belong too:

Find all foreign security principals and the groups they are used in.

Find all the foreign security principals in the provided local domain that belong to the provided foreign domain and return their full name and group memberships.

.PARAMETER LocalDomain
Local domain name in which to find foreign security principals.

.PARAMETER ForeignDomain
Foreign domain for which foreign security principals should be returned.

PS D:\> Get-ForeignSecurityPrincipals.ps1 -LocalDomain atl.mydomain.net -ForeignDomain ble.mydomain.net


[CmdletBinding(SupportsShouldProcess = $True)]
param (
[Parameter(Mandatory = $true)]
[Parameter(Mandatory = $true)]

if (!(Get-Module ActiveDirectory))
Import-Module ActiveDirectory

$startscript = Get-Date
Write-Host “”
Write-Host “List foreign security principals on domain $LocalDomain, please wait it can takes time” -BackgroundColor Green -ForegroundColor Black
Write-Host “”
$domainSid = Get-ADDomain $ForeignDomain -ErrorAction SilentlyContinue | select -ExpandProperty DomainSID | select -ExpandProperty Value
if ($domainSid -notmatch ‘^S-\d-\d-\d\d-\d{9,10}-\d{9,10}-\d{9,10}$’)
Write-Error “Unable to determine domain SID for $ForeignDomain”
foreach ($g in (Get-ADObject -Filter “objectClass -eq ‘group'” -Server $LocalDomain -Properties member | ? { $_.member -like “CN=$domainSid*” }))
foreach ($m in $g.member)
if ($m -match “^CN=$domainSid”)
$fspSamAccountName = Get-ADObject -Identity $m -Server $LocalDomain -Properties ‘msDS-PrincipalName’ | select -ExpandProperty ‘msDS-PrincipalName’
$final += @(New-Object –TypeName PSObject -Property @{
GroupName = $g.name
ForeignSecurityPrincipal = $fspSamAccountName

Write-Host “”
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
$final | select GroupName, ForeignSecurityPrincipal | sort GroupName
Write-Host “”
Write-Host “——————-“
Write-Host “– End of Script –“
Write-Host “——————-“
$stopscript = Get-Date
Write-Host “Has started at” $startscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “Had finished at” $stopscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “TIME SPENT:” (New-TimeSpan -Start $startscript -End $stopscript).hours “Hours” (New-TimeSpan -Start $startscript -End $stopscript).minutes “Minutes” (New-TimeSpan -Start $startscript -End $stopscript).seconds “Seconds” -BackgroundColor Green -ForegroundColor Black
Write-Host “”
Write-Host “”

Several methods to retrieve group membership for user and group:
Several methods to retrieve group membership for user and group:

Using Powershell:

Using powershell – for a user samaccountname:

Import-module Activedirectory
(Get-ADUser <samaccountname> -Properties MemberOf | Select-Object MemberOf).MemberOf        ; list of groups the user belongs

Get-QADUser -SamAccountName <samaccountname> | % {$_.MemberOf } | Get-QADGroup | select name    ; idem
(Get-ADUser <samaccountname> -Properties MemberOf | Select-Object MemberOf).MemberOf.Count     ; Display the number of the groups the user belongs

Other useful powershell cmdlet:
get-adprincipalgroupmembership <samaccountname>
(get-adprincipalgroupmembership <samaccountname>).count

Using powershell – for a Group samaccountname:

Import-module Activedirectory
(Get-ADGroup “domain users” -Properties MemberOf | Select-Object MemberOf).MemberOf        ; list of groups the “domain users” group belongs
(Get-ADGroup “domain users” -Properties MemberOf | Select-Object MemberOf).MemberOf.count    ; Display the number of the groups the group “domain users” belongs

Using powershell with Quest cmdlets for AD – for a user samaccountname:

Add-PsSnapin Quest.ActiveRoles.ADManagement

(get-QADGroup -containsmember <samaccountname>)                ; list of groups the user belongs
(get-QADGroup -containsmember <samaccountname>).count            ; Display the number of the groups the user belongs

(get-QADGroup -containsIndirectmember <samaccountname>)            ; list of all nested groups the user belongs
(get-QADGroup -containsIndirectmember <samaccountname>).count        ; Display the number of the groups the user belongs

Using powershell with Quest cmdlets for AD – for a group samaccountname:

Add-PsSnapin Quest.ActiveRoles.ADManagement

(get-QADGroupMember ‘administrators’)                ; list content of administrators group
(get-QADGroupMember ‘administrators’).count            ; count the content

(get-QADGroupMember ‘administrators’ -indirect)            ; list the content with nesting content!
(get-QADGroupMember ‘administrators’ -indirect).count        ; count the full content with nested content!


Using dsquery/dsget:

To display only the MemberOf of a group:

dsquery group -name “domain users” -d <domain> | dsget group -memberof                ; list of groups the “domain users” group belongs

To display only the MemberOf of a user:

dsquery user -samid <samaccountname> | dsget user -memberof | dsget group -samid        ; list of groups the user belongs

WARNING: but this command does not list recursive groups!

dsquery user -samid <samaccountname> | dsget user -memberof -expand | dsget group -samid        ; list of groups the user belongs (including recursive groups)


Technical reference about Kerberos: http://technet.microsoft.com/en-us/library/cc739058(WS.10).aspx

White paper about Kerberos troubleshooting: http://www.microsoft.com/en-us/download/details.aspx?id=21820

Microsoft has published a tool called Tokensz: http://www.microsoft.com/download/en/details.aspx?id=1448

Microsoft has a detailed document about the token-bloat problem, Addressing Problems Due To Access Token Limitation: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=13749)

To step you through remediation on this MS whitepaper, we can read:

Several factors can affect the outcome of the token evaluation process, including the following: · Whether the token is issued for logon purposes or for resource access. · The groups that the principal is a member of, including direct and transitive memberships. · The types of groups involved. There are two types of groups in Active Directory: distribution groups and security groups. Distribution groups are not included in the principal’s token, but all security groups are included. All group scopes (universal, global, domain local, machine local, and built-in) are included in the token evaluation. · The functional level (for Windows Server 2003) or the domain mode (for Windows 2000 Server). The token evaluation process evaluates groups recursively. For example, if User A is a member of Group 1 and Group 1 is a member of Group 2, then a token generated for User A contains SIDs representing both Group 1 and Group 2. In native mode and higher domains, universal, global, and domain local groups are all evaluated recursively. Universal security groups do not exist in mixed mode domains.

MaxTokenSize and Token Bloat: http://blogs.technet.com/b/shanecothran/archive/2010/07/16/maxtokensize-and-kerberos-token-bloat.asp



Updated Guidance and Recommendations

In the past we had guidance that stated you could increase the MaxTokenSize registry entry to 65535. But because of HTTP’s base64 encoding of authentication context tokens limits starting with Windows Server 2012, the default value of the MaxTokenSize registry entry is 48000 bytes. This is why we are recommending that you set the MaxTokenSize no larger than 48000 bytes on any OS version.

How to reduce Kerberos token bloat

First read this very interesting article: https://dirteam.com/sander/2013/05/22/common-challenges-when-managing-active-directory-domain-services-part-2-unnecessary-complexity-and-token-bloat/

  • To reduce the Kerberos Ticket Size you can:
  • Reduce/consolidate group membership
  • Clean up SID History
  • Limit the number of users that are configured to use “trusted for delegation”. The account that are configured to use “trusted   for delegation” the buffer requirements for each SID may double.

To find and to remove SIDHistory:

Web resources:


Remove SIDhistory:


SIDHistory powershell module: https://gallery.technet.microsoft.com/PowerShell-Module-for-08769c67

With AD cmdlets: https://technet.microsoft.com/en-us/library/powershell_remove_sid_history%28WS.10%29.aspx


Token Bloat known issues

How to use Group Policy to add the MaxTokenSize registry entry to multiple computers


New resolution for problems with Kerberos authentication when users belong to many groups

“HTTP 400 – Bad Request (Request Header too long)” error in Internet Information Services (IIS)

Users who are members of more than 1,015 groups may fail logon authentication

Group Policy may not be applied to users belonging to many groups


Recommended settings for IIS and Apache


Reference article: http://support.microsoft.com/kb/2020943


Default values

Value Default Maximum Comment
MaxFieldLength 16384 64 – 65534 (64k – 2) bytes Sets an upper limit for each header. See MaxRequestBytes. This limit translates to approximately 32k characters for a URL.
MaxRequestBytes 16384 256 – 16777216 (16MB) bytes Determines the upper limit for the total size of the Request line and the headers.
Its default setting is 16KB. If this value is lower than MaxFieldLength, the MaxFieldLength value is adjusted.


NOTE: If MaxFieldLength is configured to its maximum value of 64KB, then the MaxTokenSize registry value should be set to 3/4 * 64 = 48KB. For more information on the MaxTokenSize setting, please see the Microsoft knowledge base article KB327825 listed below.

Values recommended: 32768 for MaxFieldLength and MaxRequestBytes values

Note: those settings has been implemented on ADFS IIS servers typically etc.


  • For Apache Http:


#Limit Request to 32Kb because we encounter problem after migraiton GAD related to header limit size (IE only)
LimitRequestFieldSize 32768

<LocationMatch “(/upm/oauth_clients|/upm/oauth/authorize)” >
AuthType Kerberos
KrbServiceName http
Krb5Keytab /etc/krb5.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd on
require valid-user

LoadModule auth_kerb_module /tools/httpd/current/modules/mod_auth_kerb.so

Note: those settings has been implemented on Apache servers etc.





System Event log Event ID 31 on domain controller


Reference technet: http://blogs.technet.com/b/askds/archive/2012/09/12/maxtokensize-and-windows-8-and-windows-server-2012.aspx



The Kerberos enhancements included in Windows 8 and Windows Server 2012 that specifically target large service ticket and MaxTokenSize scenarios. To summarize:

  • Increased default MaxTokenSize from 12k to 48k
  • New Group Policy setting to centrally manage MaxTokenSize
  • New Group Policy setting to write warnings to the system event log when a service ticket exceeds a designated threshold
  • New Resource SID compression to reduce the storage size of SIDs from the resource domain







Powershell Scripts





  1. Using a powershell script to collect all Event ID 31 on all the domain controllers:

Modify the dclist.csv

Then from a powershell in admin mode: .\Dump-DC-KerberosEventID31.ps1


  1. Using a powershell script to make a assessment on a specific user samaccountname:

.\CheckMaxTokenSize -Principals <enter a samaccountname> -Details $true

i.e .\CheckMaxTokenSize -Principals jdalbera -Details $true


Event Viewer – Xpath query to search all event ID 31 last day:



<Query Id=”0″ Path=”System”>

<Select Path=”System”>*[System[(Level=3) and (EventID=31) and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]</Select>