I would suggest you start over and really review what information you need in order to break down this task into simple steps.
Before we begin, let's review the token size formula:
TokenSize = 1200 + 40d + 8s
This formula uses the following values:
d:
The number of domain local groups a user is a member of plus the
number of universal groups outside the user's account domain that the
user is a member of plus the number of groups represented in security
ID (SID) history.
s:
The number of security global groups that a user
is a member of plus the number of universal groups in a user's account
domain that the user is a member of.
1200: The estimated value for
ticket overhead. This value can vary, depending on factors such as DNS
domain name length, client name, and other factors.
Assuming that you have the computer name already (potentially from user input), what we need is:
- Retrieve the computer account object, with its sid history
- Find all its group memberships (recursively)
- Split the groups into two buckets based on domain and scope
So, let's get to work.
Since you have the ActiveDirectory
module handy, finding the computer is easy:
# Define computer name
$ComputerName = "computer01"
# Find the computer in the directory
$Computer = Get-ADComputer -LDAPFilter "(&(name=$ComputerName))" -Properties PrimaryGroup,SidHistory
Now, we could use the Get-ADPrincipalGroupMembership
cmdlet to retrieve all the group memberships, but it doesn't support recursive searches, so I would use the IN_CHAIN query rule control in an LDAP filter with Get-ADGroup
:
# Locate a Global Catalog server
$GC = Get-ADDomainController -Discover -Service GlobalCatalog
# Search the global catalog using our recursive ldap filter
$Groups = Get-ADGroup -LDAPFilter "(&(member:1.2.840.113556.1.4.1941:=$($Computer.DistinguishedName)))" -Server "$($GC.HostName):3268"
# Don't forget the primary group
$Groups = @($Groups; Get-ADGroup -Identity $Computer.PrimaryGroup)
Now we just need to split the groups into two sets, one containing Domain Local groups and foreign Universal Groups, and one containing Global groups and local Universal groups:
# These are the "d" groups from the original formula
$LargeGroups = @($Groups |Where-Object {$_.GroupScope -eq 'DomainLocal' -or ($_.GroupScope -eq 'Universal' -and $_.DistinguishedName -notlike "*,DC=$($GC.Domain -split '\.' -join ',DC=')")})
# These are the "s" groups from the original formula
$SmallGroups = @($Groups |Where-Object {$_.GroupScope -eq 'Global' -or ($_.GroupScope -eq 'Universal' -and $_.DistinguishedName -like "*,DC=$($GC.Domain -split '\.' -join ',DC=')")})
Now just calculate according to the formula:
# Calculate TokenSize based on groups
$TokenSize = 1200 + (40 * $LargeGroups.Count) + (8 * $SmallGroups.Count)
# Factory in SIDHistory principals
if($Computer.SIDHistory){
$TokenSize += 40 * $Computer.SIDHistory.Count
}
And we're done :-)