Задача разлогинить всех пользователей с фермы rds у которых статус disconnect и определение активного брокера, логирование с очищением логов
# Функция для завершения RDP-сессии function Invoke-RDPSessionLogoff { Param( [parameter(Mandatory=$True, Position=0)][String]$ComputerName, [parameter(Mandatory=$true, Position=1)][String]$SessionID ) $ErrorActionPreference = "Stop" logoff $SessionID /server:$ComputerName /v 2>&1 } # Функция для получения списка залогиненных пользователей Function Get-LoggedOnUser { Param( [parameter(Mandatory=$True, Position=0)][String]$ComputerName="localhost" ) $ErrorActionPreference = "Stop" Test-Connection $ComputerName -Count 1 | Out-Null quser /server:$ComputerName 2>&1 | Select-Object -Skip 1 | ForEach-Object { $CurrentLine = $_.Trim() -Replace "\s+"," " -Split "\s" $HashProps = @{ UserName = $CurrentLine[0] ComputerName = $ComputerName } If ($CurrentLine[2] -eq "Disc") { $HashProps.SessionName = $null $HashProps.Id = $CurrentLine[1] $HashProps.State = $CurrentLine[2] $HashProps.IdleTime = $CurrentLine[3] $HashProps.LogonTime = $CurrentLine[4..6] -join " " $HashProps.LogonTime = $CurrentLine[4..($CurrentLine.GetUpperBound(0))] -join " " } else { $HashProps.SessionName = $CurrentLine[1] $HashProps.Id = $CurrentLine[2] $HashProps.State = $CurrentLine[3] $HashProps.IdleTime = $CurrentLine[4] $HashProps.LogonTime = $CurrentLine[5..($CurrentLine.GetUpperBound(0))] -join " " } New-Object -TypeName PSCustomObject -Property $HashProps | Select-Object -Property UserName, ComputerName, SessionName, Id, State, IdleTime, LogonTime } } # Определение активного брокера подключений $Brokers = @("RDCB02", "RDCB01") $ActiveBroker = $null Write-Host "Определение активного брокера подключений..." try { $HAInfo = Get-RDConnectionBrokerHighAvailability -ConnectionBroker $Brokers[0] if ($HAInfo.ActiveManagementServer) { $ActiveBroker = $HAInfo.ActiveManagementServer Write-Host "Активный брокер: $ActiveBroker" } else { throw "Не удалось определить активный брокер." } } catch { Write-Host "Ошибка при определении активного брокера: $($Error[0].Exception.Message)" -ForegroundColor Red exit } # Логирование $LogRetentionDays = 7 $LogDirectory = "$PSScriptRoot\log" if (-not (Test-Path -Path $LogDirectory)) { New-Item -ItemType Directory -Path $LogDirectory | Out-Null } # Очистка старых логов Write-Host "Очистка логов старше $LogRetentionDays дней..." Get-ChildItem -Path $LogDirectory -Filter "RDS_Log_*.txt" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$LogRetentionDays) } | Remove-Item -Force -ErrorAction SilentlyContinue # Создание имени файла лога на основе текущей даты $LogFile = "$LogDirectory\RDS_Log_$(Get-Date -Format 'yyyyMMdd').txt" # Список пользователей с отключенными сессиями $us = Get-RDUserSession -ConnectionBroker $ActiveBroker | Where-Object {$_.SessionState -eq 'STATE_DISCONNECTED'} # Список серверов, где пользователи не найдены $NotFoundServers = @() Foreach ($u in $us) { $UserLogin = $u.UserName Write-Host "Поиск RDP-сессий пользователя $UserLogin на серверах..." $SessionList = @() $Server = $u.HostServer $TargetSession = $null Write-Host " Опрос сервера $Server" Try { $TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin} } Catch { Write-Host "Ошибка: " $Error[0].Exception.Message -ForegroundColor Red Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Ошибка: Не удалось получить сессии на сервере $Server. Сообщение: $($Error[0].Exception.Message)" Continue } If ($TargetSession) { #Invoke-RDPSessionLogoff -ComputerName $Server -SessionID $TargetSession.ID Write-Host " Сессия пользователя $UserLogin завершена." # Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Завершена сессия пользователя $UserLogin на сервере $Server (Session ID: $($TargetSession.ID))" } Else { Write-Host " Сессий не найдено." Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Сессии пользователя $UserLogin не найдены на сервере $Server" # Добавляем сервер в список, если пользователь не найден $NotFoundServers += $Server } } # Выводим список серверов, где пользователи не найдены Write-Host "Следующие серверы требуют перезагрузки подключений:" $NotFoundServers | Sort-Object -Unique | ForEach-Object { Write-Host " $_" Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Сервер $_ требует перезагрузки подключений" } # Выполняем действия по включению/выключению подключений на серверах foreach ($serv in $NotFoundServers | Sort-Object -Unique) { Write-Host "Обработка сервера $serv..." try { # Отключаем новые подключения Write-Host " Отключение новых подключений..." #Set-RDSessionHost -ConnectionBroker $ActiveBroker -SessionHost $serv -NewConnectionAllowed No Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') На сервере $serv отключены новые подключения" Start-Sleep -Seconds 2 # Включаем новые подключения Write-Host " Включение новых подключений..." #Set-RDSessionHost -ConnectionBroker $ActiveBroker -SessionHost $serv -NewConnectionAllowed Yes Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') На сервере $serv включены новые подключения" Write-Host " Обработка завершена." } catch { Write-Host "Ошибка при обработке сервера $serv : $($Error[0].Exception.Message)" -ForegroundColor Red Add-Content -Path $LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Ошибка при обработке сервера $serv : $($Error[0].Exception.Message)" } }
Similar Posts:
- Как сбросить терминальные сессии на терминальной ферме RDS windows 2012-2016 без прав администратора
- Как делегировать права управления терминальных сессий не давая полные права на сервер в windows 2012/16
- Как сделать плановую перезагрузку серверов RDS host windows 2016, со снятием нагрузки и возвращением её после ребута.
- Как сделать gpo выключение windows 10 пк по бездействию в течение часа.
- Как отключить (отмонтировать) диск User Profile Disks в RDS Windows Server