Skip to content

Commit 9d4a0a7

Browse files
authored
Create createADObjectGroupTokenExport.ps1
1 parent f3db1b7 commit 9d4a0a7

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<#PSScriptInfo
2+
.VERSION 2021.10
3+
.GUID 368f7248-347a-46d9-ba35-3ae42890daed
4+
.AUTHOR Chad.Cox@microsoft.com
5+
https://blogs.technet.microsoft.com/chadcox/
6+
https://github.com/chadmcox
7+
.COMPANYNAME
8+
.COPYRIGHT This Sample Code is provided for the purpose of illustration only and is not
9+
intended to be used in a production environment. THIS SAMPLE CODE AND ANY
10+
RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
11+
EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant You a
13+
nonexclusive, royalty-free right to use and modify the Sample Code and to
14+
reproduce and distribute the object code form of the Sample Code, provided
15+
that You agree: (i) to not use Our name, logo, or trademarks to market Your
16+
software product in which the Sample Code is embedded; (ii) to include a valid
17+
copyright notice on Your software product in which the Sample Code is embedded;
18+
and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and
19+
against any claims or lawsuits, including attorneys` fees, that arise or result
20+
from the use or distribution of the Sample
21+
.Note
22+
23+
#>
24+
$reportpath = "$env:USERPROFILE\Downloads"
25+
cd $reportpath
26+
$searchbase = @()
27+
$default_err_log = "$reportpath\err.txt"
28+
$time_log = "$reportpath\runtime.csv"
29+
30+
31+
#https://gist.githubusercontent.com/bill-long/43ea5863469f7585fbba/raw/360ea41e1a0786c22762bf1b8276b6ab1d8f54d2/Get-TokenGroups.ps1
32+
33+
function gettokengroups{
34+
[cmdletbinding()]
35+
param($gcName, $adobject)
36+
$dn = $adobject.distinguishedname
37+
Add-Type @"
38+
using System;
39+
public class TokenEntry {
40+
public string SID;
41+
public string Name;
42+
}
43+
"@
44+
45+
$searchRoot = [ADSI]("GC://" + $gcName + "/" + $dn)
46+
$searcher = New-Object System.DirectoryServices.DirectorySearcher($searchRoot, "(objectClass=*)", @("tokenGroups"), [System.DirectoryServices.SearchScope]::Base)
47+
$result = $searcher.FindOne()
48+
if ($result -eq $null)
49+
{
50+
return
51+
}
52+
53+
""
54+
$result.Path
55+
foreach ($sidBytes in $result.Properties["tokenGroups"])
56+
{
57+
$translated = $null
58+
$sid = New-Object System.Security.Principal.SecurityIdentifier($sidbytes, 0)
59+
try {
60+
$translated = $sid.Translate("System.Security.Principal.NTAccount").ToString()
61+
}
62+
catch {
63+
try {
64+
$adObject = ([ADSI]("LDAP://<SID=" + $sid.ToString() + ">"))
65+
$translated = $adObject.Properties["samAccountName"][0].ToString()
66+
}
67+
catch { }
68+
}
69+
70+
$tokenEntry = New-Object TokenEntry;
71+
$tokenEntry.SID = $sid.ToString();
72+
$tokenEntry.Name = $translated;
73+
$tokenEntry | select @{name='group';expression={$_.Name}}, @{name='object';expression={$adobject.samaccountname}}, `
74+
@{name='objectclass';expression={$adobject.objectclass}} | export-csv .\ADGroupMemberExport.csv -NoTypeInformation -Append
75+
$tokenEntry
76+
}
77+
}
78+
Function createADSearchBase{
79+
[cmdletbinding()]
80+
param()
81+
$hash_domain = @{name='Domain';expression={$domain}}
82+
$searchbase_list = "$reportpath\tmpADSearchBaseList.csv"
83+
try{Get-ChildItem $searchbase_list | Where-Object { $_.LastWriteTime -lt $((Get-Date).AddDays(-5))} | Remove-Item -force}catch{}
84+
write-host "Generating Search Base List"
85+
If (!(Test-Path $searchbase_list)){
86+
foreach($domain in (get-adforest).domains){
87+
write-debug "Gathering OUs"
88+
try{Get-ADObject -ldapFilter "(objectclass=organizationalunit)" `
89+
-Properties "msds-approx-immed-subordinates" -server $domain -ResultPageSize 500 -ResultSetSize $null | `
90+
where {$_."msds-approx-immed-subordinates" -ne 0} | select `
91+
$hash_domain, DistinguishedName | export-csv $searchbase_list -append -NoTypeInformation}
92+
catch{"function CollectionADSearchBase - $domain - $($_.Exception)" | out-file $default_err_log -append}
93+
try{Get-ADObject -ldapFilter "(objectclass=domainDNS)" `
94+
-Properties "msds-approx-immed-subordinates" -server $domain -ResultPageSize 500 -ResultSetSize $null | `
95+
where {$_."msds-approx-immed-subordinates" -ne 0} | select `
96+
$hash_domain, DistinguishedName | export-csv $searchbase_list -append -NoTypeInformation}
97+
catch{"function CollectionADSearchBase - $domain - $($_.Exception)" | out-file $default_err_log -append}
98+
try{Get-ADObject -ldapFilter "(objectclass=builtinDomain)" `
99+
-Properties "msds-approx-immed-subordinates" -server $domain -ResultPageSize 500 -ResultSetSize $null | `
100+
where {$_."msds-approx-immed-subordinates" -ne 0} | select `
101+
$hash_domain, DistinguishedName | export-csv $searchbase_list -append -NoTypeInformation}
102+
catch{"function CollectionADSearchBase - $domain - $($_.Exception)" | out-file $default_err_log -append}
103+
try{(get-addomain $domain).UsersContainer | Get-ADObject -server $domain | select `
104+
$hash_domain, DistinguishedName | export-csv $searchbase_list -append -NoTypeInformation}
105+
catch{"function CollectionADSearchBase - $domain - $($_.Exception)" | out-file $default_err_log -append}
106+
try{(get-addomain $domain).ComputersContainer | Get-ADObject -server $domain | select `
107+
$hash_domain, DistinguishedName | export-csv $searchbase_list -append -NoTypeInformation}
108+
catch{"function CollectionADSearchBase - $domain - $($_.Exception)" | out-file $default_err_log -append}
109+
}
110+
}
111+
else{
112+
Write-host "Reusing Existing Searchbase List"
113+
}
114+
$searchbase = import-csv $searchbase_list
115+
$searchbase
116+
}
117+
118+
function exportadobjects{
119+
[cmdletbinding()]
120+
param()
121+
if(!($searchbase)){
122+
$searchbase = createADSearchBase
123+
}
124+
foreach($sb in $searchbase){$domain = $sb.domain
125+
write-host "exporting objects $($sb.distinguishedname)"
126+
get-adobject -ldapFilter "(&(memberof=*)(|(objectCategory=person)(objectCategory=group)))" -SearchBase $sb.distinguishedname -SearchScope OneLevel `
127+
-Server $sb.domain -Properties samaccountname,objectSid | select `
128+
@{n='domain';e={$sb.domain}}, distinguishedname, objectclass, samaccountname,objectSid
129+
}
130+
}
131+
function createreports{
132+
[cmdletbinding()]
133+
param()
134+
try{Get-ChildItem .\ADGroupMemberExport.csv | Remove-Item -force}catch{}
135+
$count = (import-csv "$reportpath\tmpADObjectList.csv").count
136+
import-csv "$reportpath\tmpADObjectList.csv" -pv ado | foreach{$i++
137+
write-host "exporting $i / $count groups for $($ado.distinguishedname)"
138+
$ado | select @{n='domain';e={$ado.domain}},
139+
@{n='samaccountname';e={$ado.samaccountname}}, `
140+
@{n='objectclass';e={$ado.objectclass}}, `
141+
@{n='tokenGroupCount';e={(gettokengroups -gcName $dc -adobject $ado | measure-object).count}}
142+
}
143+
}
144+
$dc = (get-addomaincontroller -Discover).hostname
145+
exportadobjects | export-csv .\tmpADObjectList.csv -NoTypeInformation
146+
createreports | export-csv .\ADObjectGroupTokenSummary.csv -NoTypeInformation
147+
write-host "Results found here: $reportpath"

0 commit comments

Comments
 (0)