Поддержка исправной, корректной работы компьютеров и ПО обычных пользователей — рутина сотрудников техподдержки и/или администраторов. Если компания небольшая, а все находятся в одной-двух комнатах, обычно нетрудно подойти самому и решить проблему или проверить то, что нужно.
Но что делать, если компания большая, а пользователь находится на другой площадке/в другом городе/стране?

Один из классических инструментов для такой работы — удаленное подключение (с помощью 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.
