Поиск компьютера в AD по содержимому атрибута Description с последующей передачей в окно «Предложение удаленной помощи» имени найденного компьютера

В предыдущих постах я разместил скрипты на VBScript и на PowerShell, которые записывают в атрибут Description объекта computer в AD имя «залогоненого» на этом компьютере пользователя. Если в вашей организации пользователи не часто меняют компьютер на своем рабочем месте (а в большинстве организаций именно так и происходит), то, запуская эти скрипты время от времени, вы всегда будете знать, за каким компьютером работает тот или иной пользователь. Вы можете легко найти компьютер нужного вам пользователя при помощи оснастки Active Directory Users and Computers, команд dsquery /?, dsget /? в командной строке windows, например

dsquery computer | dsget computer -samid –desc | find /i "username"

 или при помощи командлетов Get-QADComputer в PowerShell, например

Get-QADComputer | where {$_.description -like "*username*"}

Для чего это нужно? Ну, например, как я уже писал ранее, для того, чтобы быстро найти компьютер, за которым работает пользователь, обратившийся к вам за помощью и, затем, подключиться к этому компьютеру. Подключение к сеансу пользователя я выполнял при помощи страницы «Центр справки и поддержки» «Предложение удаленной помощи». Но, если открыть окно с этой страницей можно быстро с помощью URL , например, так

Start ->Run -> hcp://cn=microsoft%20corporation,l=redmond,s=washington,c=us/Remote%20Assistance/Escalation/Unsolicited/unsolicitedrcui.htm

 то для передачи в это окно имени целевого компьютера приходилось заниматься CopyPaste’ом, что совсем не православно и ничуть не доставляет ;). Очень хотелось бы научиться передавать имя компьютера прямо из скрипта автоматически.

 Да, кстати, а знаете ли вы, где взять URL для вызова окна «Предложение удаленной помощи»? Может быть вам не интересно, но я все  равно расскажу. ;) Все на самом деле очень просто. Сначала надо добраться до самой страницы. Делаем так: <Win>+<F1> -> «Использование служебных программ для просмотра информации о компьютере и диагностики неполадок» – «Предложение удаленной помощи». Затем, щелкаем правой кнопкой мышки по открытой в окне странице и (в выпашем контекстном меню) выбираем пункт «Свойства».

 

 В результате перед нами откроется окно, содержащее (вы не поверите ;)) свойства  этой страницы.

  

Среди прочих – в окне свойств имеется и нужный нам Адрес (URL), который мы легко можем скопировать при помощи «мыши».

 Хорошо, URL нашли, но где же сам файл, который открывается при вызове этого URL? Если поискать файл, указанный в URL (unsolicitedrcui.htm), на компьютере, то мы  найдем его в папке “C:\WINDOWS\pchealth\helpctr\Vendors\CN=Microsoft Corporation,L=Redmond,S=Washington,C=US\Remote Assistance\Escalation\Unsolicited” Да-да, это именно имя папки, которая на самом деле существует на вашем компьютере. Для тех, кто не верит, покажу скриншот

Т.к. хотелось бы добиться быстрого результата малой кровью, то проще всего было бы внести небольшие изменения в уже готовый код, чем делать все с нуля.

Поэтому откроем найденный файл и подумаем, как мы могли бы передать в него имя компьютера, к которому мы хотим осуществить подключение?

 Мы видим, что код на писан на JScript и использует объект SAFRemoteDesktopConnection.  В тексте файла меня заинтересовали следующие строки:

<INPUT type=text class="sys-font-body sys-color-body MaxWidth" name="idComputerName" id="idComputerName" onkeypress="onEnter()" title="Введите или скопируйте имя компьютера или IP-адрес" size=47 tabindex=1>

и строки в функции onConnect():

…
try
{
g_oSAFRemoteConnectionData = g_oSAFRemoteDesktopConnection.ConnectRemoteDesktop(idComputerName.value);
}
…

Если посмотреть на них, то становиться понятно, что для того, чтобы добиться результата и передать в текстовое поле idComputerName формы «Предложение удаленной помощи» имя компьютера, необходимо задать значение текстового поля idComputerName.value. Сделать это можно, например, в функции onLoad(), которая, очевидно, вызывается при загрузке страницы.

Да, но как передать в функцию onLoad() имя целевого компьютера? Т.к. мы собрались вызывать форму «Предложение удаленной помощи» из скрипта при помощи URL, то логично было бы передавать имя компьютера в этом же самом URL, а уже внутри формы выделять имя компьютера из этого URL. Проделать это, как выяснилось, не сложно.

Если мы добавим имя компьютера к URL страницы, разделив их знаком вопроса,

 hcp://CN=Microsoft%20Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Escalation/Unsolicited/UnsolicitedRCui+.htm?computer_name

  то сможем поступить следующим образом: URL получим при помощи объекта window.location. У этого объекта имеется свойство search, которое вернет нам ту часть URL, которая начинается со знака вопроса. Осталось отбросить сам знак вопроса, который нам совсем не нужен. Т.к. window.location.search вернет нам строку (объект типа String  Jscript), то для того, чтобы отбросить первый символ (знак вопроса), можно использовать метод substring объекта String. Т.о. выделить имя компьютера из следующего URL

hcp://CN=Microsoft%20Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Escalation/Unsolicited/UnsolicitedRCui+.htm?computer_name

 можно при помощи одной строчки кода: window.location.search.substring(1)

 В конечном итоге, все, что нам нужно сделать, чтобы добиться поставленной цели, это добавить в функцию onLoad() строку idComputerName.value = window.location.search.substring(1); :

function onLoad()
{
;
;
try
{///////////
/// add by shs
///////////
idComputerName.value = window.location.search.substring(1);
///////
setTimeout(&quot;idComputerName.focus(),250);
g_oSAFRemoteDesktopConnection = oSAFClassFactory.CreateObject_RemoteDesktopConnection();
}
…

 эта строка кода запишет в поле формы имя компьютера, которое мы укажем в URL при вызове страницы «Предложение удаленной помощи».

Модифицированный вышеописанным способом файл unsolicitedrcui.htm, я сохранил в ту же папку, что и исходный, изменив его имя на unsolicitedrcui+.htm

 Уф-ф-ф… Ну, а теперь пришло время самого скрипта, который будет осуществлять поиск компьютера по имени пользователя, которое мы  заранее записали в атрибут Description для каждого объекта компьютер в AD.

####################################################################################
# RemAssist.ps1 PowerShell ShS 20091207
#
# Поиск целевого компьютера по содержимому атрибута Description (с последующим
# вызовом окна "Центр справки и поддержки" и передачей в параметрах вызова
# имени целевого компьютера)
####################################################################################
#
#Проверяем, что в командной строке запуска скрипта присутствовали аргументы вызова
if ($Args.Count -gt 0) {
    $args[0]
    #Зададим маску поиска
    #(будем искать вхождение первого аргумента)
    $mask="*$($args[0])*"
    #производим поиск компьютера, согласно заданой маске , по атрибуту Description
    $comps=@(Get-QADComputer -SizeLimit 0 | ?{$_.Description -like $mask})
    #
    $i=1
    #Если было найдено более одного компьютера, то...
    if ($comps.length -gt 1) {
        cls
        #...сформируем и выведем на экран нумерованный список найденных компьютеров
        for (;$comp=$comps[$i-1];$i++) {
            "[$i]" + " $comp`t"+$comp.Description+"`n"
        }
        #допрос пользователя
        $i=[int](Read-Host "Введите номер компьютера из списка или 0 - для завершения работы")
    }
    #Если пользователь указал правильный номер компьютера...
    if (($i -gt 0) -and ($i -le $comps.length)) {
        $comp=$comps[$i-1]
        #...произведем вызов окна "Центр справки и поддержки"
        #в URL вызова передадим имя найденного компьютера
        &"$env:windir\PCHEALTH\HELPCTR\Binaries\HelpCtr.exe" -url (
        "hcp://CN=Microsoft%20Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Escalation/Unsolicited/UnsolicitedRCui+.htm?"+
        $comp.Name)
    }
    "$comp`t"+$comp.Description
} else {
#если скрипт был вызван без аргументов, печатаем краткую справку
"`n" + $MyInvocation.MyCommand.Name + " PoSh ShS 20090709"
"`nUsage :`n"
$MyInvocation.MyCommand.Name + " <part_of_ComputerDescription>"+$Args
}

Т.к. он написан на PoSh и снабжен подробными комментариями, то пояснять здесь особенно нечего, кроме того, что для вызова URL, который начинается с префикса hcp://, необходимо использовать helpctr.exe

Upd. Пример работы скрипта. Если мы хотим подключиться к компьютеру пользователя, чье имя содержит подстроку “bo”, то нам нужно будет запустить скрипт следующим образом:

PS > .\RemAssist.ps1 bo

В результате получим:

[1] DOMAIN\ORG-20071018-1$ DOMAIN\BorisovaIrina

[2] DOMAIN\ORG-20080201-1$ DOMAIN\BogachevaTatyana

[3] DOMAIN\ORG-20061211-1$ DOMAIN\BogolyubovaSvetlana

[4] DOMAIN\ORG-20071008-1$ DOMAIN\bondarchukIvan

Введите номер компьютера из списка или 0 - для завершения работы: 4
DOMAIN\ORG-20071008-1$ DOMAIN\ bondarchukIvan
PS >

Как видно из вышеприведенного примера, я выбрал компьютер с четвертым порядковым номером из предложенного скриптом списка и, как результат, получил в консоле запись DOMAIN\ORG-20071008-1$ DOMAIN\ bondarchukIvan, подтверждающую мой выбор, и окно “Предложение удаленной помощи” с именем компьютера, которое было подставлено в него скриптом.

5 Comments

  1. Несколько удивил код

    Get-QADComputer | where {$_.description -like &quot;*username*&quot;}
    

    Мне кажется – слегка жестоко. А применять фильтрацию непосредственно в командлете, чтобы фильтр “ушёл в ldap запрос”? по типу

    Get-QADComputer -Filter {description -like &quot;*username*&quot;}
    

    ???

    • вы правы: фильтр командлета всегда будет работать быстрее, чем фильтрация при помощи отдельного командлета where-object

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.