Поддержка исправной, корректной работы компьютеров и ПО обычных пользователей — рутина сотрудников техподдержки и/или администраторов. Если компания небольшая, а все находятся в одной-двух комнатах, обычно нетрудно подойти самому и решить проблему или проверить то, что нужно.
Но что делать, если компания большая, а пользователь находится на другой площадке/в другом городе/стране?
Один из классических инструментов для такой работы — удаленное подключение (с помощью RDP, ПО вроде TeamViewer/Skype с демонстрацией рабочего стола и так далее). Однако он не лишен принципиальных недостатков:
- в любом случае конечный пользователь будет отвлекаться от своей работы (в некоторых случаях — даже не видя своего рабочего стола)
- эти инструменты не всегда будут работать, если на удаленном компьютере есть ошибки
- установка стороннего ПО (в том числе проприетарного, в случае TeamViewer) далеко не всегда приветствуется политикой компании
- способ практически не автоматизируется
Наконец — такой подход используется, когда инцидент уже произошел (сложно представить себе, чтобы администратор время от времени "профилактически" подключался к каждому пользователю). Именно поэтому важен механизм контроля (мониторинга) удаленных компьютеров.
Одним из возможных решений — использование удаленного доступа к реестру Windows. Он хранит данные в виде иерархической базы данных, что позволяет их быстро получать и компактно хранить. Используют реестр для хранения собственных настроек и параметров как ОС и встроенные службы, так и большинство сторонних программ. Поэтому содержание реестра во многом влияет на работу системы.
Исходя из этого, реестр вполне может использоваться как "индикатор" для контроля (можно обнаружить ошибку, если она связана с некорректными параметрами в реестре или смоделировать у себя проблемную ситуацию).
Еще одна возможность, которую дает такое решение — возможность административного контроля пользователей (например, удаленное чтение позволяет увидеть факты установок нежелательных программ и внесение изменений в настройки) — не стоит забывать о влиянии "человеческого фактора" на работу системы. На практике это пригодилось в рамках проекта SkypeTime, где было нужно отследить исправление настроек в Skype for Business.
Но реестр содержит тысячи записей, проконтролировать всех их крайне сложно. Поэтому прежде всего следует ограничить предмет контроля — определить, какие именно параметры нам интересны, и узнать, в каких именно ветках реестра находятся соответствующие значения. Как правило, последнее не составляет труда найти в документации / Интернете, или определить самостоятельно исходя из названий ключей.
Определившись с предметом контроля, можно переходить к непосредственной настройке удаленного доступа. Для этого необходимо активировать службу Remote Procedure Call на удаленных компьютерах и нужным образом настроить firewall, что удобно сделать с помощью групповых политик. С учетом требований безопасности, для доступа необходимы права доменного администратора или локального администратора на каждом из устройств.
Для активации самой службы, в разделе Computer Configuration > Preferences > Control Panel Settings > Services задаем для службы RpcSs параметры, как на скрин-шоте
Осталось добавить соответствующие исключения Firewall. В этой же политике в разделе Computer Configuration > Policies > Windows Settings > Security Settings > Windows Firewall with Advanced Security > Inbound Rules создаем New Rule:
Rule Type – Custom
В качестве пути программы указываем – %SystemRoot%\system32\svchost.exe
Из дополнительных настроек в разделе Службы (Services) задаем Применять к службе со следующим кратким именем – Winmgmt
На следующих страницах задаем TCP без указания конкретных портов и для всех адресов
и разрешаем подключение (Allow the Connection) для доменного профиля
Однако контролировать вручную реестр десятков и сотен компьютеров "вручную" (пусть даже по нескольким записям) — дело неблагодарное и бессмысленное. К счастью, этот процесс достаточно просто автоматизировать с помощью скриптов. Например, следующий скрипт на PowerShell позволяет узнать, кто из пользователей изменял параметры AwayThreshold и IdleThreshold (время перехода в состояние "Нет на месте" и "Неактивен") для Skype for Business.
Param (
[alias("c")]
[string]$FromFileComputers,
[alias("r")]
[string]$OutputRPCErrorsFile,
[alias("u")]
[string]$FromFileUsers,
[alias("o")]
[string]$OutputFile="output.csv",
[alias("a")]
[int]$MinAway,
[alias("i")]
[int]$MinIdle
)
$RPCErrorsArray = @()
$result = @()
$HKU = 2147483651
$RegistryForCheckArray = "SOFTWARE\Microsoft\Office\13.0\Lync","SOFTWARE\Microsoft\Office\14.0\Lync","SOFTWARE\Microsoft\Office\15.0\Lync","SOFTWARE\Microsoft\Office\16.0\Lync","SOFTWARE\Microsoft\Communicator"
$CurrentComputerNumber = 0;
if(![string]::IsNullOrEmpty($FromFileUsers))
{
$Users = Get-Content $FromFileUsers;
}
if(![string]::IsNullOrEmpty($FromFileComputers))
{
$Comps = Get-Content $FromFileComputers;
}
else
{
$date = (get-date).AddMonths(-1)
$Comps = Get-ADComputer -filter { lastlogontimestamp -ge $date } | select name | ForEach-Object {$_.name}
#$Comps = "NB_CY"
}
$ServersCount = ($Comps).Count;
Foreach ($Comp in $Comps) {
$CurrentComputerNumber++
try
{
Write-Host "Checking: $Comp [$CurrentComputerNumber/$ServersCount]";
$profiles = Get-WmiObject Win32_UserProfile -filter "Loaded=$true and special=$false" -ComputerName $Comp -ErrorAction Stop
$reg = [wmiclass]"\\$Comp\root\default:stdregprov"
Foreach ($profile in $profiles)
{
$username = Split-Path $profile.LocalPath -Leaf
if(![string]::IsNullOrEmpty($FromFileUsers))
{
if(!$Users.Contains($username))
{
continue;
}
}
Foreach( $registry in $RegistryForCheckArray)
{
$hkey = "$($profile.sid)\$registry"
#Write-Host "KEY: $hkey"
$away = $reg.GetDWORDValue($hku,$hkey,"AwayThreshold").uValue
$idle = $reg.GetDWORDValue($hku,$hkey,"IdleThreshold").uValue
$sip = $reg.GetStringValue($hku,$hkey,"ServerSipUri").sValue
if([string]::IsNullOrEmpty($away) -and [string]::IsNullOrEmpty($idle))
{
continue;
}
if(($MinAway -gt 0 -and $away -lt $MinAway) -or ($MinIdle -gt 0 -and $idle -lt $MinIdle))
{
continue;
}
$result += New-Object PsObject -Property @{
"PC" = $Comp
"Username" = $username
"SIP" = $sip
"SFB_Away" = $away
"SFB_Idle" = $idle
}
}
}
}
catch
{
if ($_.Exception.GetType().Name -eq "COMException") {
$RPCErrorsArray += $Comp;
}
Write-Host "Error: ($_.Exception.GetType().Name)";
$_.Exception
}
}
$result | Export-csv -Path $OutputFile
$result | Format-Table -Property PC,Username,SIP,SFB_Away,SFB_Idle -AutoSize
Write-Host "Saved to: $OutputFile"
if(![string]::IsNullOrEmpty($OutputRPCErrorsFile))
{
$RPCErrorsArray | out-file $OutputRPCErrorsFile
Write-Host "RPC errors saved to: $OutputRPCErrorsFile"
}
Для большего удобства, скрипт может быть запущен с параметрами:
-c путь к файлу со списком hostname компьютеров для проверки, если не задано — получает компьютеры из AD с активностью за 30 дней.
-r путь к файлу, в который будут записаны hostname компьютеров у которых была ошибка RPC.
-u путь к файлу со списком юзеров (login), если не задано — проверяет всех.
-o путь к файлу, в котором будет результат выполнения скрипта, по умолчанию output.csv.
-a минимальное значение для параметра AwayThreshold, записи со значением, меньше указанного, не попадут результат выполнения скрипта.
-i минимальное значение для параметра IdleThreshold, записи со значением, меньше указанного, не попадут результат выполнения скрипта.
Далее запуск скрипта можно автоматизировать, добавив в Планировщик заданий Windows (Task Scheduler) или через функционал Sheduled Job в PowerShell.