Skip to content

Commit f624c3d

Browse files
committed
Merge pull request #46 from Meatballs1/group_recursion
Group recursion
2 parents f727369 + 5472233 commit f624c3d

File tree

1 file changed

+128
-127
lines changed

1 file changed

+128
-127
lines changed

PowerView/powerview.ps1

Lines changed: 128 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,155 +3217,156 @@ function Get-NetGroup {
32173217
# otherwise try to connect to the DC for the target domain
32183218
$GroupSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"LDAP://$dn")
32193219
}
3220-
# samAccountType=805306368 indicates user objects
3221-
$GroupSearcher.filter = "(&(objectClass=group)(name=$GroupName))"
3220+
3221+
if ($Recurse) {
3222+
$GroupDN = (Get-NetGroups -GroupName $GroupName -Domain $Domain -FullData).distinguishedname
3223+
if ($GroupDN) {
3224+
$GroupSearcher.filter = "(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=$GroupDN))"
3225+
$GroupSearcher.PropertiesToLoad.AddRange(('distinguishedName','samaccounttype','lastlogon','lastlogontimestamp','dscorepropagationdata','objectsid','whencreated','badpasswordtime','accountexpires','iscriticalsystemobject','name','usnchanged','objectcategory','description','codepage','instancetype','countrycode','distinguishedname','cn','admincount','logonhours','objectclass','logoncount','usncreated','useraccountcontrol','objectguid','primarygroupid','lastlogoff','samaccountname','badpwdcount','whenchanged','memberof','pwdlastset','adspath'))
3226+
} else {
3227+
Write-Error "Unable to find GroupName"
3228+
}
3229+
} else {
3230+
$GroupSearcher.filter = "(&(objectClass=group)(name=$GroupName))"
3231+
}
32223232
}
32233233
catch{
32243234
Write-Warning "The specified domain $Domain does not exist, could not be contacted, or there isn't an existing trust."
32253235
}
3226-
}
3227-
else{
3228-
$Domain = (Get-NetDomain).Name
3236+
} else {
3237+
$Domain = (Get-NetDomain).Name
32293238

3230-
# otherwise, use the current domain
3239+
if ($Recurse) {
3240+
$GroupDN = (Get-NetGroups -GroupName $GroupName -Domain $Domain -FullData).distinguishedname
3241+
if ($GroupDN) {
3242+
$GroupSearcher = [adsisearcher]"(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=$GroupDN))"
3243+
$GroupSearcher.PropertiesToLoad.AddRange(('distinguishedName','samaccounttype','lastlogon','lastlogontimestamp','dscorepropagationdata','objectsid','whencreated','badpasswordtime','accountexpires','iscriticalsystemobject','name','usnchanged','objectcategory','description','codepage','instancetype','countrycode','distinguishedname','cn','admincount','logonhours','objectclass','logoncount','usncreated','useraccountcontrol','objectguid','primarygroupid','lastlogoff','samaccountname','badpwdcount','whenchanged','memberof','pwdlastset','adspath'))
3244+
} else {
3245+
Write-Error "Unable to find GroupName"
3246+
}
3247+
} else {
32313248
$GroupSearcher = [adsisearcher]"(&(objectClass=group)(name=$GroupName))"
3249+
}
32323250
}
3251+
if ($GroupSearcher) {
32333252

3234-
if ($GroupSearcher){
3235-
$GroupSearcher.PageSize = 200
3253+
$GroupSearcher.PageSize = 200
3254+
3255+
if ($Recurse) {
3256+
$members = $GroupSearcher.FindAll()
3257+
$GroupFoundName = $GroupName
3258+
} else {
32363259
$GroupSearcher.FindAll() | % {
3237-
try{
3238-
if (!($_) -or !($_.properties) -or !($_.properties.name)) { continue }
3239-
3240-
$GroupFoundName = $_.properties.name[0]
3241-
$members = @()
3242-
3243-
if ($_.properties.member.Count -eq 0) {
3244-
$finished = $false
3245-
$bottom = 0
3246-
$top = 0
3247-
while(!$finished) {
3248-
$top = $bottom + 1499
3249-
$memberRange="member;range=$bottom-$top"
3250-
$bottom += 1500
3251-
$GroupSearcher.PropertiesToLoad.Clear()
3252-
[void]$GroupSearcher.PropertiesToLoad.Add("$memberRange")
3253-
try {
3254-
$result = $GroupSearcher.FindOne()
3255-
if ($result) {
3256-
$rangedProperty = $_.Properties.PropertyNames -like "member;range=*"
3257-
$results = $_.Properties.item($rangedProperty)
3258-
if ($results.count -eq 0) {
3259-
$finished = $true
3260-
} else {
3261-
$results | % {
3262-
$members += $_
3263-
}
3264-
}
3265-
} else {
3260+
try {
3261+
if (!($_) -or !($_.properties) -or !($_.properties.name)) { continue }
3262+
3263+
$GroupFoundName = $_.properties.name[0]
3264+
$members = @()
3265+
3266+
if ($_.properties.member.Count -eq 0) {
3267+
$finished = $false
3268+
$bottom = 0
3269+
$top = 0
3270+
while(!$finished) {
3271+
$top = $bottom + 1499
3272+
$memberRange="member;range=$bottom-$top"
3273+
$bottom += 1500
3274+
$GroupSearcher.PropertiesToLoad.Clear()
3275+
[void]$GroupSearcher.PropertiesToLoad.Add("$memberRange")
3276+
try {
3277+
$result = $GroupSearcher.FindOne()
3278+
if ($result) {
3279+
$rangedProperty = $_.Properties.PropertyNames -like "member;range=*"
3280+
$results = $_.Properties.item($rangedProperty)
3281+
if ($results.count -eq 0) {
32663282
$finished = $true
3283+
} else {
3284+
$results | % {
3285+
$members += $_
32673286
}
3268-
} catch [System.Management.Automation.MethodInvocationException] {
3269-
$finished = $true
32703287
}
3288+
} else {
3289+
$finished = $true
32713290
}
3272-
} else {
3273-
$members = $_.properties.member
3291+
} catch [System.Management.Automation.MethodInvocationException] {
3292+
$finished = $true
32743293
}
3294+
}
3295+
} else {
3296+
$members = $_.properties.member
3297+
}
3298+
} catch {
3299+
write-verbose $_
3300+
}
3301+
}
3302+
}
32753303

3276-
$members | ForEach-Object {
3277-
# for each user/member, do a quick adsi object grab
3278-
if ($PrimaryDC){
3279-
$properties = ([adsi]"LDAP://$PrimaryDC/$_").Properties
3280-
}
3281-
else {
3282-
$properties = ([adsi]"LDAP://$_").Properties
3283-
}
3284-
3285-
# check if the result is a user account- if not assume it's a group
3286-
if ($properties.samAccountType -ne "805306368"){
3287-
$isGroup = $True
3288-
}
3289-
else{
3290-
$isGroup = $False
3291-
}
3292-
3293-
$out = New-Object psobject
3294-
$out | add-member Noteproperty 'GroupDomain' $Domain
3295-
$out | Add-Member Noteproperty 'GroupName' $GroupFoundName
3296-
3297-
if ($FullData){
3298-
$properties.PropertyNames | % {
3299-
# TODO: errors on cross-domain users?
3300-
if ($_ -eq "objectsid"){
3301-
# convert the SID to a string
3302-
$out | Add-Member Noteproperty $_ ((New-Object System.Security.Principal.SecurityIdentifier($properties[$_][0],0)).Value)
3303-
}
3304-
elseif($_ -eq "objectguid"){
3305-
# convert the GUID to a string
3306-
$out | Add-Member Noteproperty $_ (New-Object Guid (,$properties[$_][0])).Guid
3307-
}
3308-
else {
3309-
if ($properties[$_].count -eq 1) {
3310-
$out | Add-Member Noteproperty $_ $properties[$_][0]
3311-
}
3312-
else {
3313-
$out | Add-Member Noteproperty $_ $properties[$_]
3314-
}
3315-
}
3316-
}
3317-
}
3318-
else {
3319-
$MemberDN = $properties.distinguishedName[0]
3320-
# extract the FQDN from the Distinguished Name
3321-
$MemberDomain = $MemberDN.subString($MemberDN.IndexOf("DC=")) -replace 'DC=','' -replace ',','.'
3322-
3323-
if ($properties.samAccountType -ne "805306368"){
3324-
$isGroup = $True
3325-
}
3326-
else{
3327-
$isGroup = $False
3328-
}
3304+
$members | ForEach-Object {
3305+
# for each user/member, do a quick adsi object grab
3306+
if ($Recurse) {
3307+
$properties = $_.Properties
3308+
} else {
3309+
if ($PrimaryDC){
3310+
$properties = ([adsi]"LDAP://$PrimaryDC/$_").Properties
3311+
}
3312+
else {
3313+
$properties = ([adsi]"LDAP://$_").Properties
3314+
}
3315+
}
33293316

3330-
if ($properties.samAccountName){
3331-
# forest users have the samAccountName set
3332-
$MemberName = $properties.samAccountName[0]
3333-
}
3334-
else {
3335-
# external trust users have a SID, so convert it
3336-
try {
3337-
$MemberName = Convert-SidToName $properties.cn[0]
3338-
}
3339-
catch {
3340-
# if there's a problem contacting the domain to resolve the SID
3341-
$MemberName = $properties.cn
3342-
}
3343-
}
3344-
$out | add-member Noteproperty 'MemberDomain' $MemberDomain
3345-
$out | add-member Noteproperty 'MemberName' $MemberName
3346-
$out | add-member Noteproperty 'IsGroup' $IsGroup
3347-
$out | add-member Noteproperty 'MemberDN' $MemberDN
3348-
}
3317+
# check if the result is a user account- if not assume it's a group
3318+
$isGroup = $properties.samaccounttype[0] -ne "805306368"
33493319

3350-
$out
3320+
$out = New-Object psobject
3321+
$out | add-member Noteproperty 'GroupDomain' $Domain
3322+
$out | Add-Member Noteproperty 'GroupName' $GroupFoundName
33513323

3352-
if($Recurse) {
3353-
# if we're recursiving and the returned value isn't a user account, assume it's a group
3354-
if($IsGroup){
3355-
if($FullData){
3356-
Get-NetGroup -Domain $Domain -PrimaryDC $PrimaryDC -FullData -Recurse -GroupName $properties.SamAccountName[0]
3357-
}
3358-
else {
3359-
Get-NetGroup -Domain $Domain -PrimaryDC $PrimaryDC -Recurse -GroupName $properties.SamAccountName[0]
3360-
}
3361-
}
3362-
}
3363-
}
3324+
if ($FullData){
3325+
$properties.PropertyNames | % {
3326+
# TODO: errors on cross-domain users?
3327+
if ($_ -eq "objectsid"){
3328+
# convert the SID to a string
3329+
$out | Add-Member Noteproperty $_ ((New-Object System.Security.Principal.SecurityIdentifier($properties[$_][0],0)).Value)
3330+
}
3331+
elseif($_ -eq "objectguid"){
3332+
# convert the GUID to a string
3333+
$out | Add-Member Noteproperty $_ (New-Object Guid (,$properties[$_][0])).Guid
3334+
}
3335+
else {
3336+
if ($properties[$_].count -eq 1) {
3337+
$out | Add-Member Noteproperty $_ $properties[$_][0]
3338+
}
3339+
else {
3340+
$out | Add-Member Noteproperty $_ $properties[$_]
3341+
}
3342+
}
3343+
}
3344+
}
3345+
else {
3346+
$MemberDN = $properties.distinguishedname[0]
3347+
# extract the FQDN from the Distinguished Name
3348+
$MemberDomain = $MemberDN.subString($MemberDN.IndexOf("DC=")) -replace 'DC=','' -replace ',','.'
3349+
if ($properties.samaccountname) {
3350+
# forest users have the samAccountName set
3351+
$MemberName = $properties.samaccountname[0]
3352+
} else {
3353+
# external trust users have a SID, so convert it
3354+
try {
3355+
$MemberName = Convert-SidToName $properties.cn[0]
33643356
}
33653357
catch {
3366-
write-verbose $_
3358+
# if there's a problem contacting the domain to resolve the SID
3359+
$MemberName = $properties.cn
33673360
}
3361+
}
3362+
$out | add-member Noteproperty 'MemberDomain' $MemberDomain
3363+
$out | add-member Noteproperty 'MemberName' $MemberName
3364+
$out | add-member Noteproperty 'IsGroup' $IsGroup
3365+
$out | add-member Noteproperty 'MemberDN' $MemberDN
33683366
}
3367+
3368+
$out
3369+
}
33693370
}
33703371
}
33713372
}

0 commit comments

Comments
 (0)