Перейти к содержимому

Как удалить группы из коллекции rds rdp windows

Ошибки на ферме

Error: Exception calling «Translate» with «1» argument(s): «Some or all identity references could not be translated

Unable to retrieve the session collection properties. Some or all identity references could not be translated.

Failed: Unable to retrieve the session collection properties. Some or all identity references could not be translated.

Не публикуется  новое приложение в коллекцию rds rdp windows

Сначала проверим коллекции .\Check-RDSAccessGroups.ps1 -ConnectionBroker «HWRDCB02.adminbd.ru»

<#
.SYNOPSIS
    Аудит групп доступа RDS (Session Collection + RemoteApp) с проверкой их наличия в AD.
 
.DESCRIPTION
    Скрипт перебирает все Session Collections на RDS-ферме, получает список групп,
    назначенных на саму коллекцию и на каждое опубликованное RemoteApp-приложение,
    после чего проверяет каждую группу в Active Directory:
      - если группа резолвится по имени -> OK
      - если группа хранится как "битый" SID (осиротевшая ссылка) -> помечается как ошибка
      - если группа не найдена в AD вообще -> помечается как отсутствующая
 
.NOTES
    Запускать на сервере с ролью RDS Connection Broker (или там, где доступен модуль RemoteDesktop),
    с правами администратора и доступом к модулю ActiveDirectory (RSAT).
#>
 
[CmdletBinding()]
param(
    [string]$ConnectionBroker = $env:COMPUTERNAME
)
 
Import-Module RemoteDesktop -ErrorAction Stop
Import-Module ActiveDirectory -ErrorAction Stop
 
function Resolve-DeletedADObject {
    <#
        Пытается найти в AD Recycle Bin / tombstone исходное имя удалённого объекта по SID.
        Работает только если объект ещё физически не вычищен (не истёк tombstone lifetime,
        обычно 180 дней) и включён/доступен просмотр удалённых объектов.
    #>
    param([string]$SidString)
 
    try {
        $deleted = Get-ADObject -Filter "objectSid -eq '$SidString'" -IncludeDeletedObjects -Properties objectClass, whenChanged -ErrorAction Stop
        if ($deleted) {
            $cleanName = $deleted.Name -replace "`0ADEL:.*$", '' -replace "\x0ADEL:.*$", ''
            return [PSCustomObject]@{
                Found       = $true
                Name        = $cleanName
                ObjectClass = $deleted.objectClass
                DeletedWhen = $deleted.whenChanged
            }
        }
    }
    catch {
        # Нет доступа к Deleted Objects, либо Recycle Bin не включён, либо объект уже вычищен
    }
    return [PSCustomObject]@{ Found = $false; Name = $null; ObjectClass = $null; DeletedWhen = $null }
}
 
function Test-ADGroupExists {
    param([string]$GroupRef)
 
    $result = [PSCustomObject]@{
        GroupRef   = $GroupRef
        ResolvedAs = $null
        Status     = $null
    }
 
    # --- Случай 1: ссылка выглядит как SID (осиротевшая ссылка, не резолвится штатно) ---
    if ($GroupRef -match '^S-1-\d+(-\d+)+$') {
        try {
            $sid = New-Object System.Security.Principal.SecurityIdentifier($GroupRef)
            $adGroup = Get-ADGroup -Identity $sid -ErrorAction Stop
            $result.ResolvedAs = $adGroup.SamAccountName
            $result.Status     = "OK (найдена по SID)"
            return $result
        }
        catch {
            # Группа не резолвится штатно -> пробуем достать исходное имя из удалённых объектов
            $deletedInfo = Resolve-DeletedADObject -SidString $GroupRef
            if ($deletedInfo.Found) {
                $result.ResolvedAs = "$($deletedInfo.Name) [удалён $($deletedInfo.DeletedWhen), класс: $($deletedInfo.ObjectClass)]"
                $result.Status     = "ОШИБКА: осиротевший SID, объект удалён из AD (исходное имя найдено)"
            } else {
                $result.ResolvedAs = $null
                $result.Status     = "ОШИБКА: осиротевший SID, объект удалён из AD (имя не восстановить — tombstone истёк или нет доступа к Deleted Objects)"
            }
            return $result
        }
    }
 
    # --- Случай 2: ссылка по имени (DOMAIN\Name или просто Name) ---
    $shortName = ($GroupRef -split '\\')[-1]
 
    # 2a. Пробуем как группу
    try {
        $adGroup = Get-ADGroup -Identity $shortName -ErrorAction Stop
        $result.ResolvedAs = $adGroup.SamAccountName
        $result.Status     = "OK"
        return $result
    }
    catch { }
 
    try {
        $adGroup = Get-ADGroup -Filter "SamAccountName -eq '$shortName'" -ErrorAction Stop
        if ($adGroup) {
            $result.ResolvedAs = $adGroup.SamAccountName
            $result.Status     = "OK"
            return $result
        }
    }
    catch { }
 
    # 2b. Это не группа -> может, это пользователь (RDS иногда хранит и юзеров в UserGroups)
    try {
        $adUser = Get-ADUser -Identity $shortName -ErrorAction Stop
        $result.ResolvedAs = $adUser.SamAccountName
        $result.Status     = "ПРЕДУПРЕЖДЕНИЕ: это пользователь, а не группа (объект существует в AD)"
        return $result
    }
    catch { }
 
    try {
        $adUser = Get-ADUser -Filter "SamAccountName -eq '$shortName'" -ErrorAction Stop
        if ($adUser) {
            $result.ResolvedAs = $adUser.SamAccountName
            $result.Status     = "ПРЕДУПРЕЖДЕНИЕ: это пользователь, а не группа (объект существует в AD)"
            return $result
        }
    }
    catch { }
 
    # 2c. Может, это компьютер
    try {
        $adComputer = Get-ADComputer -Identity $shortName -ErrorAction Stop
        $result.ResolvedAs = $adComputer.SamAccountName
        $result.Status     = "ПРЕДУПРЕЖДЕНИЕ: это компьютерная учётка, а не группа"
        return $result
    }
    catch { }
 
    # 2d. Нигде не нашли -> пробуем поискать среди удалённых объектов по имени
    try {
        $deleted = Get-ADObject -Filter "name -like '$shortName*'" -IncludeDeletedObjects -Properties objectClass, whenChanged -ErrorAction Stop |
                   Select-Object -First 1
        if ($deleted) {
            $result.ResolvedAs = "$($deleted.Name) [удалён $($deleted.whenChanged), класс: $($deleted.objectClass)]"
            $result.Status     = "ОШИБКА: объект удалён из AD (найден в Deleted Objects)"
            return $result
        }
    }
    catch { }
 
    $result.Status = "ОШИБКА: объект не найден в AD (не группа, не пользователь, не компьютер, не в Deleted Objects)"
    return $result
}
 
$report = New-Object System.Collections.Generic.List[Object]
 
Write-Host "Получаю список коллекций..." -ForegroundColor Cyan
$collections = Get-RDSessionCollection -ConnectionBroker $ConnectionBroker
 
foreach ($col in $collections) {
    $colName = $col.CollectionName
    Write-Host "`n=== Коллекция: $colName ===" -ForegroundColor Yellow
 
    # --- Группы на уровне коллекции ---
    try {
        $colGroups = (Get-RDSessionCollectionConfiguration -CollectionName $colName -UserGroup -ConnectionBroker $ConnectionBroker).UserGroup
    }
    catch {
        Write-Warning "Не удалось получить UserGroup для коллекции '$colName': $($_.Exception.Message)"
        $colGroups = @()
    }
 
    foreach ($g in $colGroups) {
        $check = Test-ADGroupExists -GroupRef $g
        $report.Add([PSCustomObject]@{
            Collection = $colName
            Scope      = "Collection"
            RemoteApp  = ""
            GroupRef   = $check.GroupRef
            ResolvedAs = $check.ResolvedAs
            Status     = $check.Status
        })
    }
 
    # --- Группы на уровне каждого RemoteApp ---
    try {
        $apps = Get-RDRemoteApp -CollectionName $colName -ConnectionBroker $ConnectionBroker
    }
    catch {
        Write-Warning "Не удалось получить RemoteApp для коллекции '$colName': $($_.Exception.Message)"
        $apps = @()
    }
 
    foreach ($app in $apps) {
        # UserGroups может быть пустым (значит наследует группы коллекции) либо содержать список через ';'
        if ([string]::IsNullOrWhiteSpace($app.UserGroups)) {
            $report.Add([PSCustomObject]@{
                Collection = $colName
                Scope      = "RemoteApp"
                RemoteApp  = $app.DisplayName
                GroupRef   = "(наследует группы коллекции)"
                ResolvedAs = ""
                Status     = "-"
            })
            continue
        }
 
        $appGroups = $app.UserGroups -split ';' | Where-Object { $_ -ne '' }
        foreach ($g in $appGroups) {
            $check = Test-ADGroupExists -GroupRef $g
            $report.Add([PSCustomObject]@{
                Collection = $colName
                Scope      = "RemoteApp"
                RemoteApp  = $app.DisplayName
                GroupRef   = $check.GroupRef
                ResolvedAs = $check.ResolvedAs
                Status     = $check.Status
            })
        }
    }
}
 
Write-Host "`n=== ИТОГОВЫЙ ОТЧЁТ ===" -ForegroundColor Green
$report | Format-Table -AutoSize
 
$errorRows = $report | Where-Object { $_.Status -like "ОШИБКА*" }
if ($errorRows) {
    Write-Host "`nНайдены проблемные группы (не резолвятся в AD):" -ForegroundColor Red
    $errorRows | Format-Table -AutoSize
} else {
    Write-Host "`nВсе найденные группы успешно резолвятся в AD." -ForegroundColor Green
}
 
# Экспорт в CSV для дальнейшего анализа
$csvPath = "$PSScriptRoot\RDS-AccessGroups-Report.csv"
$report | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
Write-Host "`nОтчёт сохранён: $csvPath" -ForegroundColor Cyan

после удалить битые группы .\Repair-RDSAccessGroups.ps1 -ConnectionBroker «RDCB02.» -OnlyCollections «Farm Fxlogixs»  для проверки после запустить .\Repair-RDSAccessGroups.ps1 -ConnectionBroker «WRDCB02.» -OnlyCollections «Farm Fxlogixs» -Apply

Similar Posts:

Добавить комментарий

Яндекс.Метрика