===== 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~~