===== PowerShell скрипт сравнения разрешений двух подразделений (OU) в Active Directory =====
{{:powershell:active-directory:pasted:20180909-144237.png }} Приводим пример **PowerShell** скрипта, который сравнивает разрешения двух организационных подразделений (**OU**) в службе каталогов **Active Directory** и выдаёт информацию о расхождениях, то есть показывает уникальные разрешения для OU:
<#
.SYNOPSIS
Compares permissions between two OUs in Active Directory.
.DESCRIPTION
This script compares ACLs of two specified OUs and shows differences.
Output is in Russian.
#>
param(
[Parameter(Mandatory=$true)]
[string]$FirstOU,
[Parameter(Mandatory=$true)]
[string]$SecondOU
)
# Set UTF-8 encoding for output
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
# Check ActiveDirectory module
if (-not (Get-Module -Name ActiveDirectory -ErrorAction SilentlyContinue)) {
try {
Import-Module ActiveDirectory -ErrorAction Stop
}
catch {
Write-Error "Failed to load ActiveDirectory module. Ensure RSAT is installed."
exit 1
}
}
function Get-OUPermissionDifferences {
param(
[System.DirectoryServices.ActiveDirectorySecurity]$Acl1,
[System.DirectoryServices.ActiveDirectorySecurity]$Acl2,
[string]$Acl1Name,
[string]$Acl2Name
)
$differences = @()
# Collect all unique SIDs from both ACLs
$allSids = @()
$Acl1.Access | ForEach-Object { $allSids += $_.IdentityReference }
$Acl2.Access | ForEach-Object { $allSids += $_.IdentityReference }
$uniqueSids = $allSids | Select-Object -Unique
foreach ($sid in $uniqueSids) {
$acl1Entries = $Acl1.Access | Where-Object { $_.IdentityReference -eq $sid }
$acl2Entries = $Acl2.Access | Where-Object { $_.IdentityReference -eq $sid }
# If SID exists in first ACL but not in second
if ($acl1Entries -and -not $acl2Entries) {
foreach ($entry in $acl1Entries) {
$differences += [PSCustomObject]@{
Identity = $sid
Rights = $entry.ActiveDirectoryRights
Inheritance = $entry.InheritanceType
AccessType = $entry.AccessControlType
Source = $Acl1Name
Status = "Missing in $Acl2Name"
}
}
}
# If SID exists in second ACL but not in first
elseif ($acl2Entries -and -not $acl1Entries) {
foreach ($entry in $acl2Entries) {
$differences += [PSCustomObject]@{
Identity = $sid
Rights = $entry.ActiveDirectoryRights
Inheritance = $entry.InheritanceType
AccessType = $entry.AccessControlType
Source = $Acl2Name
Status = "Missing in $Acl1Name"
}
}
}
# If SID exists in both ACLs, compare permissions
else {
foreach ($entry1 in $acl1Entries) {
$found = $false
foreach ($entry2 in $acl2Entries) {
if ($entry1.ActiveDirectoryRights -eq $entry2.ActiveDirectoryRights -and
$entry1.InheritanceType -eq $entry2.InheritanceType -and
$entry1.AccessControlType -eq $entry2.AccessControlType) {
$found = $true
break
}
}
if (-not $found) {
$differences += [PSCustomObject]@{
Identity = $sid
Rights = $entry1.ActiveDirectoryRights
Inheritance = $entry1.InheritanceType
AccessType = $entry1.AccessControlType
Source = $Acl1Name
Status = "Different in $Acl2Name"
}
}
}
}
}
return $differences
}
try {
# Get ACLs for both OUs
Write-Host "[INFO] Получение разрешений для первого OU: $FirstOU" -ForegroundColor Cyan
$ou1 = Get-ADOrganizationalUnit -Identity $FirstOU
$acl1 = Get-Acl -Path "AD:\$FirstOU"
Write-Host "[INFO] Получение разрешений для второго OU: $SecondOU" -ForegroundColor Cyan
$ou2 = Get-ADOrganizationalUnit -Identity $SecondOU
$acl2 = Get-Acl -Path "AD:\$SecondOU"
# Compare permissions
$differences = Get-OUPermissionDifferences -Acl1 $acl1 -Acl2 $acl2 -Acl1Name $ou1.Name -Acl2Name $ou2.Name
# Display results
if ($differences.Count -eq 0) {
Write-Host "[RESULT] Разрешения идентичны для обоих OU." -ForegroundColor Green
}
else {
Write-Host "[RESULT] Найдены различия в разрешениях:" -ForegroundColor Yellow
# Prepare Russian column names
$output = $differences | Select-Object @{
Name="Пользователь/Группа"; Expression={$_.Identity}
}, @{
Name="Разрешения"; Expression={$_.Rights}
}, @{
Name="Наследование"; Expression={$_.Inheritance}
}, @{
Name="Тип доступа"; Expression={$_.AccessType}
}, @{
Name="Источник"; Expression={$_.Source}
}, @{
Name="Статус"; Expression={$_.Status -replace "Missing in","Отсутствует в" -replace "Different in","Отличается в"}
}
$output | Format-Table -AutoSize -Wrap
# Optional: export to CSV
$exportPath = "OUPermissionsComparison_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$output | Export-Csv -Path $exportPath -NoTypeInformation -Encoding UTF8
Write-Host "[EXPORT] Результаты сохранены в $exportPath" -ForegroundColor Cyan
}
}
catch {
Write-Error "[ERROR] Ошибка выполнения: $_"
exit 1
}
**Инструкция по использованию:**
- Скопируйте скрипт в файл с расширением .ps1 (например, Compare-OUPermissions.ps1) в кодировке UTF-8
- Запустите PowerShell от имени администратора
- Выполните скрипт, указав DistinguishedName двух OU для сравнения:
.\Compare-OUPermissions.ps1 -FirstOU "OU=Sales,DC=domain,DC=com" -SecondOU "OU=Marketing,DC=domain,DC=com"
**Особенности скрипта:**
* Показывает различия в разрешениях, типах наследования и контроле доступа
* Форматирует вывод в удобочитаемую таблицу
* Поддерживает экспорт результатов в CSV файл
* Требует PS-модуль ActiveDirectory (часть RSAT)
Для работы скрипта необходимо иметь права на чтение разрешений в сравниваемых OU.
----
Проверено на следующих конфигурациях:
^ Версия ОС ^ Версия Powershell ^
| Microsoft Windows 11 Pro 24H2 10.0.26100 | PowerShell 5.1.26100.2161 |
----
{{:user:blogroot.png?50&nolink |}} Автор первичной редакции:\\ [[user:blogroot|Алексей Максимов]] \\ Время публикации: 22.05.2025 14:50
{{tag>PowerShell ADDS OU ACL "Active Directory" }}
~~DISCUSSION~~