-
Notifications
You must be signed in to change notification settings - Fork 2
/
Get-UserOUPermissions.ps1
166 lines (137 loc) · 5.82 KB
/
Get-UserOUPermissions.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$JsonOutputPath = "C:\Temp\UserOUPermissions.json"
)
# Check if Active Directory module is available
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
Write-Host "Active Directory module not found. Please install RSAT or run on a domain controller." -ForegroundColor Red
exit
}
# Import the Active Directory module
Import-Module ActiveDirectory
# Start timer
$startTime = Get-Date
# Get all OUs in the domain
Write-Host "Retrieving Organizational Units..." -ForegroundColor Yellow
$OUs = Get-ADOrganizationalUnit -Filter * -Properties DistinguishedName | Select-Object -ExpandProperty DistinguishedName
$endTime = Get-Date
$duration = $endTime - $startTime
Write-Host "Retrieved $($OUs.Count) OUs in $($duration.TotalSeconds) seconds." -ForegroundColor Green
# Initialize the hashtable to store permissions per user/group
$UserPermissions = @{}
# Define the GUID for group object class
$GroupGUID = "bf967a9c-0de6-11d0-a285-00aa003049e2"
$TotalOUs = $OUs.Count
$Counter = 0
foreach ($OU_DN in $OUs) {
$Counter++
if ($Counter % 100 -eq 0) {
Write-Host "Processed $Counter out of $TotalOUs OUs..." -ForegroundColor Cyan
}
Write-Verbose "Processing OU ${Counter}: $OU_DN"
try {
# Get the ACL of the OU
$acl = Get-ACL -Path "AD:\$OU_DN"
$Owner = $acl.Owner
# Ensure the Owner is in the hashtable
if (-not $UserPermissions.ContainsKey($Owner)) {
$UserPermissions[$Owner] = @{
"Owner" = @()
"Full Control" = @()
"Create Groups" = @()
}
Write-Verbose "Added new entity: $Owner"
}
# Add the OU to the Owner's "Owner" list, if not already present
if (-not ($UserPermissions[$Owner]["Owner"] -contains $OU_DN)) {
$UserPermissions[$Owner]["Owner"] += $OU_DN
Write-Verbose "Added OU to $Owner's Owner list: $OU_DN"
}
# Get the ACLs for the OU
$ACLs = $acl.Access
foreach ($ACE in $ACLs) {
# Process only Allow ACEs
if ($ACE.AccessControlType -eq "Allow") {
$Identity = $ACE.IdentityReference.Value
# Ensure the Identity is in the hashtable
if (-not $UserPermissions.ContainsKey($Identity)) {
$UserPermissions[$Identity] = @{
"Owner" = @()
"Full Control" = @()
"Create Groups" = @()
}
Write-Verbose "Added new entity: $Identity"
}
# Check for Full Control (GenericAll)
if (($ACE.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::GenericAll) -ne 0) {
if (-not ($UserPermissions[$Identity]["Full Control"] -contains $OU_DN)) {
$UserPermissions[$Identity]["Full Control"] += $OU_DN
Write-Verbose "Added OU to $Identity's Full Control list: $OU_DN"
}
}
# Check for Create Groups (CreateChild on group objects)
if (($ACE.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::CreateChild) -ne 0) {
# Check if ObjectType matches group object GUID
if ($ACE.ObjectType -eq $GroupGUID) {
if (-not ($UserPermissions[$Identity]["Create Groups"] -contains $OU_DN)) {
$UserPermissions[$Identity]["Create Groups"] += $OU_DN
Write-Verbose "Added OU to $Identity's Create Groups list: $OU_DN"
}
}
}
}
}
}
catch {
Write-Warning "Failed to process OU: $OU_DN. Error: $_"
}
}
# Now, output the results to the console
Write-Host "Processing complete. Generating console output...`n" -ForegroundColor Yellow
foreach ($User in $UserPermissions.Keys) {
Write-Host "Entity: $User" -ForegroundColor Cyan
foreach ($PermissionType in @("Full Control", "Create Groups", "Owner")) {
$OUsList = $UserPermissions[$User][$PermissionType]
if ($OUsList -and $OUsList.Count -gt 0) {
Write-Host "- ${PermissionType}:"
foreach ($OU in $OUsList | Sort-Object) {
Write-Host " - $OU"
}
}
}
Write-Host
}
# Convert the hashtable to a structured object for JSON serialization
Write-Host "Generating JSON output..." -ForegroundColor Yellow
# Create an array to hold each entity's permissions in a structured format
$JsonOutput = @()
foreach ($User in $UserPermissions.Keys) {
$Entity = [PSCustomObject]@{
"Entity" = $User
"Permissions" = [PSCustomObject]@{
"Full Control" = $UserPermissions[$User]["Full Control"]
"Create Groups" = $UserPermissions[$User]["Create Groups"]
"Owner" = $UserPermissions[$User]["Owner"]
}
}
$JsonOutput += $Entity
}
# Convert to JSON with proper formatting
$JsonString = $JsonOutput | ConvertTo-Json -Depth 4 -Compress:$false
# Output JSON to file
try {
# Ensure the directory exists
$JsonDir = Split-Path -Path $JsonOutputPath
if (-not (Test-Path -Path $JsonDir)) {
New-Item -Path $JsonDir -ItemType Directory -Force | Out-Null
}
# Write the JSON string to the specified file
Set-Content -Path $JsonOutputPath -Value $JsonString -Encoding UTF8
Write-Host "JSON output successfully written to: $JsonOutputPath" -ForegroundColor Green
}
catch {
Write-Warning "Failed to write JSON output to file: $JsonOutputPath. Error: $_"
}
$TotalDuration = (Get-Date) - $startTime
Write-Host "Total script execution time: $($TotalDuration.TotalSeconds) seconds." -ForegroundColor Green