На терминальных серверах существует проблема с автоматическим удалением перемещаемых профилей (roaming profiles), если в терминальной сессии происходил сбой какой-нибудь программы - временные файлы программы блокируют удаление профиля с терминального сервера. При следующем входе в терминальную сессию для пользователя создастся новый профиль с каким-то суфиксом, так как старый неудаленный профиль не даст корректно переместить профиль с файлового сервера на терминальный. Со временем таких неудаленных профилей накопится очень много, что замусорит систему.
Для решения вышеописанной проблемы рекомендую использовать скрипт удаления профилей с терминального сервера, который должен быть запущен сразу же после перезагрузки сервера, когда терминальные сессии к серверу еще не установлены, то есть когда на сервере по определению не может быть профилей пользователей.
Ниже приведен код скрипта удаления профилей Remove-Profiles.ps1.
# Получение пути к скрипту $ScriptFolder = $MyInvocation.MyCommand.Path.SubString(0,($MyInvocation.MyCommand.Path.Length - ` $MyInvocation.MyCommand.Name.Length)) # Формирование пути к лог-файлу $LogFile = $ScriptFolder + $MyInvocation.MyCommand.Name.SubString(0,($MyInvocation.MyCommand.Name.Length ` - 4)) + ".log" # Создание лог-файла Out-File -FilePath $LogFile # Указание папки профилей $ProfileFolder = "C:\Users" # Указание служебных папок $ExcludedProfiles = "Default", "Default User", "Public", "All Users", "Administrator" # Получение объектов из папки профилей $SubDirs= Get-ChildItem $ProfileFolder -Force # Обработка объектов из папки профилей ForEach ($Dir in $SubDirs) { $LogMessage = $Nothing # Проверка, что объект существует и это папка If (Test-Path $Dir.FullName -PathType Container) { # Проверка, что профиль - это не служебная папка $NotDeleteFlag = $False ForEach ($ExcludedProfile in $ExcludedProfiles) { If ($Dir.Name -eq $ExcludedProfile) { $NotDeleteFlag = $True } } # Удаление профиля If ($NotDeleteFlag -eq $False) { # Формирование события для лога $LogMessage = get-date -uformat "%d.%m.%Y %H:%M:%S" $LogMessage += "`t" $LogMessage += $Dir.FullName + " is deleted." # Удаление папки #Remove-Item -Path $Dir.FullName -Force -Recurse $CmdLine = "cmd /c RD /S /Q """ + $Dir.FullName + """" Invoke-Expression -command $CmdLine } Else { # Формирование события для лога $LogMessage = get-date -uformat "%d.%m.%Y %H:%M:%S" $LogMessage += "`t" $LogMessage += $Dir.FullName + " is skipped as a service folder." } } Else { # Формирование события для лога $LogMessage = get-date -uformat "%d.%m.%Y %H:%M:%S" $LogMessage += "`t" $LogMessage += $Dir.FullName + " is skipped as a file." } # Запись события в лог-файл $LogMessage | Out-File -FilePath $LogFile -Append }
Обращаю внимание, что в скрипте закомментирована строка удаления папок средствами PowerShell
Remove-Item -Path $Dir.FullName -Force -Recurse
Это сделано по причине того, что PowerShell не может удалить папки, на которые у пользователя нет прав, даже если оболочка запущена с повышенными административными правами. Проблема решается вызовом обычной командной строки с командой RD, которая не имеет указанной проблемы.
$CmdLine = "cmd /c RD /S /Q """ + $Dir.FullName + """" Invoke-Expression -command $CmdLine
Перед использованием скрипта на сервере нужно разрешить выполнение неподписанных сценариев командой
Set-ExecutionPolicy -ExecutionPolicy "RemoteSigned"
Проверить текущую политику выполнения сценариев можно командой
Get-ExecutionPolicy
Чтобы корректно удалять профили, нужно чтобы все сессии этих профилей были завершены и перемещаемые профили вернулись на файловый сервер, если это возможно. Форсировать завершение сессий и отправку профилей на файловый сервер можно перезагрузкой сервера. В планировщике заданий Windows нужно поставить 2 задачи:
- задачу на перезагрузку сервера раз в неделю перед началом рабочего дня;
- задачу на выполнение скрипта от имени системы с повышенными административными правами при загрузке сервера.
Запуск скрипта лучше осуществлять через командный файл
powershell.exe "%~DP0Remove-Profiles.ps1"
После выполнения сценария все профили, которые зависли на терминальном сервере будут стерты. А копии профилей с правильной конфигурацией останутся на файловом сервере. То есть при входе в терминальную сессию пользователь получит последнюю правильную копию своего профиля.