• ↓
  • ↑
  • ⇑
 
Записи с темой: scripting (список заголовков)
20:29 

UMRA - User Manager Resource Administrator

В Dash'e под Chronostasis'ом.
Программирование без goto - Клац!
Я не случайно начал эту запись со ссылки на один из холиваров мира программирования - стоит ли использовать оператор goto при построении кода? Сам стараюсь его не употреблять ни в каком виде, благо, средств проверки условий и переходов по результату проверки достаточно. Но не в этот раз.
Довелось сегодня править код формы в этом самом UMRA. Форма работала, но после перегруппировки каталогов Active Directory работоспособность резко упала до нуля ;) Ожидаемый результат, который надо исправлять. Чем и занялся.
Итак, что представляет из себя редактор кода в этой консоли? Это достаточно прямолинейный список из заранее подготовленных команд, которые можно передать службе UmraSvc, и она уже будет их выполнять. Команд не так уж много, но и немало. Даже конструкция if... then... else поддерживается, которую я очень активно собирался использовать. Не тут-то было! Да, этот заранее заготовленный блок может проверять довольно много параметров (хотя и там нашлось, к чему придраться), но в качестве действий после проверки условия можно назначить только одно единственное! Угадайте, какое именно. Правильно - пресловутый goto!
Представить все это "великолепие" в виде псевдокода можно следующим образом:

variable1 = 5
if variable1 < 10 then goto label1 else goto label2
label1: action1
goto end
label2: action2
goto end
end:

И вот таким макаром проверять кучу условий. Повторюсь, в блоке then кроме тупого перехода к метке поставить ничего нельзя, вообще. Все дело в том, что код формы редактируется не в виде исходного кода как такового, где где угодно можно записать что угодно, а через самый что ни на есть GUI - отдельная формочка для ввода всех параметров блока if... then... else. Одним словом - такого кошмара я давно не встречал, если встречал где-то вообще.
Код этой несчастной формы в итоге был выправлен, но времени на отладку в итоге ушло куда больше, чем планировалось.
И на вкусное. Механизм проверки условий UMRA, как выяснилось, совершенно не может проверить какое-либо поле формы на непустое значение. На пустое - пожалуйста, можно выбрать тип проверки null or not present, но вот not null там не поставишь. Пришлось изгаляться с вариантом if var is null then end else blah-blah-blah. Тоже не добавило радости, если честно.

@музыка: Ryan Farish - Perfect Clarity

@темы: Scripting, Этот безумный мир

22:25 

Script run time

В Dash'e под Chronostasis'ом.
Время выполнения скрипта. Весьма важный показатель производительности системы. Ни с того ни с сего некоторые сотрудники начали жаловаться, что при загрузке компьютера уж очень много времени уходит на стадию "Выполнение сценариев запуска". Сценариев этих вообще-то к компьютерам привязано довольно много, и тот факт, что нужное на их выполнение время исчисляется далеко не секундами, а их парой-тройкой десятков - это норма. Но не 10 минут же! К тому же 10 минут - это deadline для системы, по достижении которого она (система) просто прекратит обработку сценариев и продолжит загружаться. Нужно узнать, какой из скриптов тормозит процесс.
Есть два варианта. Первый применим в том случае, если в домене не включена параллельная обработка сценариев - каждый следующий скрипт будет запускаться только по окончании выполнения предыдущего (это настройка по-умолчанию). В этом случае можно просто открыть консоль GPMC, взять интересующую нас систему и собрать с нее результирующий набор политик. Дальше на вкладке с перечисленными параметрами, которые применяются к системе из политик, можно раскрыть раздел сценраиев запуска и просто посмотреть, когда в последний раз был запущен тот или иной скрипт. Учитывая, что запускаются они последовательно - можно сразу увидеть, где узкое место.
Второй метод может пригодиться там, где параллельная обработка сценариев уже включена (это ускоряет процесс загрузки, по понятным причинам). Но для этого придется каждый выполняемый сценарий немного изменить - повесить на него "рамку":
sсript run time
Эта рамка выведет время выполнения сценария в текстовый файл. Его расположение задается в блоке set output file name - в профиле пользователя (если измеряем производительность скрипта входа пользователя), либо в папке %SystemRoot% - если интересует скрипт загрузки самого компьютера. Естественно, эти пути можно и поменять под свой вкус.
Блок sсript body понятен и без объяснений.
Можно, конечно, обойтись и простым выводом на экран, а не в файл. Однако, учитывая, что лично мне придется эти изменения вносить в боевые версии сценариев, лучше лишний раз пользователям не докучать и выполнять все действия в фоне.

@музыка: El DeBarge - Who's Johnny

@темы: Scripting

22:28 

Localization is EVIL (part 2)

В Dash'e под Chronostasis'ом.
Продолжение истории, рассказанной вот тут.
Да, да, снова возня с сетевыми адресами, снова очень хочется обеспечить абсолютную прозрачность для пользователей. В предыдущей истории пришли к выводу, что psexec можно заставить понимать русский текст в названии сетевого соединения, но каждый раз набирать команды в окне DNTU - все же удручает. Вот если бы написать скрипт.
Размышляя над этой задачкой, вспомнил, что нечто подобное мне уже делать доводилось, нужно было написать сценарий для работы исключительно в DOS-окне, в котором русский текст воспринимался так же отвратно, как и в psexec. Вспомнил и метод решения этой задачи - скрипт был написан в редакторе AkelPad. Эта штука полезна тем, что кодировок знает неисчислимое множество, в том числе и пресловутый OEM 866 Russian, в которой и писался тот скрипт.
Стащить AkelPad из сети - дело нехитрое, набросать в нем заветные строки в нужной кодировке - тоже. Получаем вот такое:

netsh interface IP set dns "Подключение по локальной сети" static %PRIMARY-DNS% primary
netsh interface IP add dns "Подключение по локальной сети" %SECONDARY-DNS% index=2
netsh interface ip set address "Подключение по локальной сети" static %ADDRESS% %MASK% %GATEWAY% 1

А вот как это выглядит, если просматривать в том же Lister из Total Commander'a:

netsh interface IP set dns "Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" static %PRIMARY-DNS% primary
netsh interface IP add dns "Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" %SECONDARY-DNS% index=2
netsh interface ip set address "Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" static %ADDRESS% %MASK% %GATEWAY% 1

Да, мы видим все те же самые "кракозябы", которые уже совершенно спокойно будут восприняты программой psexec. Дело за малым - прописать в файле нужные параметры, сохранить, скопировать на удаленную систему, после чего:
psexec \\%TARGET-SYSTEM% -s c:\changeIP.cmd
(подразумеваем, что скрипт называется changeIP.cmd и скопирован в корень диска С:)

Кто-то может задать резонный вопрос - а почему не резервирование по DHCP, оно же куда проще? Абсолютно корректное замечание, и сетевому отделу было об этом сказано. Но... гремлинов среди гоблинов всегда хватает ;) (с)

@музыка: Within Temptation - Faster

@настроение: А сайт и софт от MSI - все равно зло.

@темы: Scripting

00:05 

Localization is EVIL.

В Dash'e под Chronostasis'ом.
Меня иногда спрашивают, мол, почему я с пренебрежением отношусь к русской версии Windows XP. Все просто. Я - админ. Человек, который с консолью подчас работает гораздо больше, чем с графическим интерфейсом, который при многократном выполнении одной операции проигрывает консоли прежде всего по скорости. Еще один плюс консоли - она работает скрытно, пользователь, компьютер которого подвергается настройке, ничего не видит и даже не догадывается, что систему потрошат.
Однако, есть проблема. Такие замечательные программы, как psexec, netsh и подобные, очень, ОЧЕНЬ плохо работают с русским языком. Вместо нормальных диагностических сообщений выводится сплошная абракадабра, кодировка страдает (ниже будет пример). А эта диагностика ох, как важна. Ради примера - текущая задача: необходимо на некоторой выборке компьютеров перенастроить DNS серверы в свойствах сетевого соединения. В связи со сменой IP адресов этих самых серверов. Кто-то может возразить, мол, а как же DHCP? Возразит, и будет прав, но лишь отчасти. Потому что есть ситуации, где DHCP просто отсутствует.
Продолжаем перечислять исходные данные. Сетевое соединение на всех тех компьютерах называется вот так: "Подключение по локальной сети". Ну и номер в конце, где-то он есть, где-то его нет.
Собственно, на этом все.
Сценарий работы, по идее, весьма прост. При помощи psexec подключиться к удаленной системе, открыть там сеанс cmd и в нем вбить следующее:

netsh interface ip set dns name="Подключение по локальной сети" source=static addr=a.a.a.a
netsh interface ip add dns name="Подключение по локальной сети" b.b.b.b index=2

Первая команда сносит текущие настройки и ставит первый DNS, вторая добавляет еще одну запись.
Но не тут-то было. psexec просто не примет русскоязычное название сетевого интерфейса. Что делать? Пытаться воспользоваться ключом -r в самом netsh, но и тут засада - при работе в удаленном сеансе netsh не поддерживаются команды настройки DNS, только просмотр. По вполне понятным причинам. Опять таки, что делать?
Решением стало следующее. Поскольку на предприятии используется пакет DNTU, открываем его, открываем тамошний RCmd в режиме Open View, цепляемся к удаленной машине и смотрим на то, как будет обозвано сетевое соединение в этой консоли (помним, что оно называется "Подключение по локальной сети")
Консоль выдаст следующее:
"Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ"

Да, да и еще раз ДА! Именно так это соединение и будет называться. Кучей иероглифов. Если бы оно называлось английскими символами, 90% тех неприятностей, которые мы имеем сейчас, просто бы не возникли. Что ж, главный фокус. В командной строке открываем контекст netsh:

netsh interface ip, жмем Enter.

А дальше поочередно вбиваем вот такие конструкции:

set dns name="Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" source=static addr=a.a.a.a
add dns name="Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" b.b.b.b index=2

И это сработает.
А теперь сравните, чем можно было бы обойтись, будь соединение с англоязычным именем:

C:\psexec \\x.x.x.x cmd
netsh interface ip set dns name="LAN" source=static addr=a.a.a.a
netsh interface ip add dns name="LAN" b.b.b.b index=2
Никаких иероглифов, никаких лишних в данном случае DNTU, только то, что нужно.

Вас еще интересует вопрос, почему же я отдаю предпочтение английским версиям ОС?

На вкусное, как переименовать русскоязычное соединение в удобоваримый вариант:
netsh interface set interface name="Џ®¤Є«о祭ЁҐ Ї® «®Є «м­®© бҐвЁ" newname="NewLan"

@музыка: Tomoko Tane - Let Me hear

@темы: Scripting

23:50 

Chain of Earth -> Stone Shock.

В Dash'e под Chronostasis'ом.

Да, да, именно шок.
Преамбула - поставлена задача: найти, кто сидел за конкретным компьютером в определенный промежуток при условии, что сотрудники могут пересаживаться. Казалось бы, что сложного, открываем журнал Security и смотрим логи. Проблема в том, что требуемый промежуток - это уже довольно дальнее прошлое, в текущих логах уже давным давно стертое. Ладно, есть бекапы. Открываем их, лезем в заветную папку %windir%\system32\config, ищем там secevents.evt... и понимаем, что в полном бекапе контроллера домена этого лога нет. Как нет и любого другого из системного журнала событий. Вдумчивое ковыряние гугла подтверждает мысль - ntbackup даже при полном резервном копировании не сохраняет логи. Это касается Windows 2003 Server, платформу 2008 на это еще не тестировали (есть повод создать новую виртуальную машину и поиздеваться над ней).
Что ж, задачу удалось решить, но несколько иным и довольно кривым методом, но осадок остался. Одновременно с этим встал вопрос - что делать с бекапом логов. В итоге был найден и доработан напильником вот такой скрипт:
Backup Security Events.vbs

Далее - Планировщик задач и задача по созданию резервной копии журнала на регулярной основе.

@музыка: Alice in Videoland - Ladykiller

@темы: Security, Scripting

17:00 

Cached Files

В Dash'e под Chronostasis'ом.
Кэш. Не тот, что наличный, а тот, что временное хранилище файлов. Хорошая вещь, помогающая сэкономить на трафике, но только в том случае, если за ним следить. А пользователи, как правило, вообще не в курсе, что это такое, зачем оно нужно. Более того, они не в курсе, что он вообще существует. Но обязанности следить за ним это не отменяет.
Если не ограничивать в размерах временные папки - они склонны раздуваться, раздуваться и раздуваться. Плодитесь и размножайтесь, так вроде было? Значит, нужно как-то эти папки чистить, потому что пользователя не допросишься это делать.
Основные два рассадника "времянки" - браузер и почтовый клиент - IE и Outlook. И если в первом еще можно размер обозначить, то второй чрезвычайно любит покушать. Суть идеи проста - удалять содержимое этих хранилищ когда пользователь выходит из системы. Расположения кэшей известны:
C:\Documents and Settings\%username%\Local Settings\Temporary Internet Files\Content.IE5\ - браузер
C:\Documents and Settings\%username%\Local Settings\Temporary Internet Files\Content.Outlook\ - Outlook 2007
C:\Documents and Settings\%username%\Local Settings\Temporary Internet Files\OLK*\ - Outlook 2003

Имея все эти данные, можно набросать небольшой сценарий выхода из системы, после чего подцепить его к групповой политике. Сам cmd-файл будет выглядеть следующим образом:
Clean Cache.cmd

Одним из плюсов постоянной очистки, по крайней мере, кэша браузера видится тот факт, что это позволит стирать с жестких дисков пользователей всякую вредоносную дрянь, которая сидит в Temporary Internet Files, и запускается c User-level правами на старте системы. Антивирус все же не панацея.

@музыка: Moya Brennan - Tara

@темы: Scripting

21:05 

IE 6,7,8

В Dash'e под Chronostasis'ом.
Гром таки грянул. Сколько пришлось попариться для того, чтобы обновить IE на компьютерах домена до версии выше, чем 6 - почти все напрасно. Выяснилось, что один из компонентов используемого бизнес-приложения стабильно работать может только в версии 6. Во всех других он может завесить браузер намертво, что приводит к лишнему расстройству, потери набранных в форму данных (браузер нужно будет перезапустить без сохранения состояния). В общем, обещается много-много неприятного. В связи с чем встал вопрос - как бы версии 7+ снести с порядочного количества компьютеров максимально быстро и по возможности без лишних телодвижений и звонков. Немного ковыряния в предметной области показало, что у приложения Windows Internet Explorer 7/8 есть так называемая строка деинсталляции (в общем и целом, эта строка есть почти у всех продуктов, которые прописываются в апплете "Установка и удаление программ"). Оно и понятно, системе ведь нужно что-то запускать для процесса удаления ненужного приложения.
Что ж, это радикально меняет дело. Строка известна, стало быть нам нужен еще один скрипт, который будет запускаться на нужных компьютерах. В итоге получается следующий vbs-файл:

'Internet Exploer 7,8 Uninstallation
on error resume next
Set WshShell = CreateObject("WScript.Shell")
'Uninstall IE 8
WshShell.Run "C:\WINDOWS\ie8\spuninst\spuninst.exe /quiet /norestart",1,true

'Uninstall IE 7
WshShell.Run "C:\WINDOWS\ie7\spuninst\spuninst.exe /quiet /norestart",1,true

Вот такой небольшой сценарий.
Последний момент - после удаления всех старших версий компьютер нужно перезапустить. Проблема в том, что пользователи на это чаще всего забивают. Что делать? Выход прост - этот скрипт нужно выполнить в момент завершения работы компьютера.
Таким образом получаем довольно простой сценарий: групповая политика, область действия - выбранные компьютеры (а они известны), параметры политики - Shutdown sсript, именно туда нужно будет подставить указанный выше сценарий. Дело за малым, перезагрузить машины - и задача выполнена.

@музыка: Clannad - From Your Heart

@настроение: Scripts are my best friends

@темы: Scripting

10:15 

Oneliners

В Dash'e под Chronostasis'ом.

Oneliner - сценарий, состоящий из одной строки (one line). Их удобство в том, что для решения какой-то задачи достаточно открыть консоль, набрать нужную команду, запустить ее на выполнение и получить результат. Нет необходимости писать текст скрипта, сохранять его, затем писать команду на вызов этого сохраненного файла. Все просто.

Недавно понял, что нужно привести в порядок в нашем домене ограничения на максимальный размер передаваемого через почту сообщения. У кого-то стоит одно, у кого-то другое, у некоторых вообще десятое. Это неправильно. Два параметра (размер входящего письма и размер исходящего письма) хранятся непосредственно в записях Active Directory, следовательно, вытащить их достаточно просто. Вариантов довольно много, но в итоге я остановился на Powershell и его сторонней оснастке Quest Management Shell. Quest - это отдельный набор команд, облегчающих работу с Active Directory и делающих ее более прозрачной, чем обычные команды Powershell. Сами параметры зовутся так:
SubmissionContLength - размер исходящего сообщения;
DelivContLength - размер входящего сообщения.

После непродолжительного чтения справки удалось набросать сценарий, шаблон которого выглядит так:

foreach ($name in get-qaduser -searchroot 'INSERT_ROOT_OF_SEARCH') {set-qaduser $name -objectattributes @{SubmissionContLength='INSERT_VALUE';DelivContLength='INSERT_VALUE'}}

Пара слов о том, что он делает.
foreach - это команда, которая выполняет определенный набор действий с каждым объектом какой-либо выборки. в общем случае она записывается так:
foreach (selection) {sсriрt}
где selection - это выборка, а sсript - то самое действие (или несколько действий), которые нужно произвести с объектами выборки.
$name - переменная, хранящая в себе имя пользователя.
get-qaduser - одна из ключевых команд сценария. она вытаскивает из Active Directory полную информацию о пользователе, чье имя хранится в переменной $name
-searchroot - модификатор, задающий область поиска. Сюда нужно подставить путь к ветке в Active Directory, в которой сценарий будет искать нужного нам пользователя. Формат записи: 'OU=TestOU,DC=Domain,DC=com'

Таким образом, первая часть сценария создает выборку объектов Active Directory, у которой нужно будет сменить пару свойств. Непосредственно сменой свойств занимается вторая часть скрипта, заключенная в фигурные скобки.
set-qaduser $name - изменить параметры учетной записи, имя которой указано в переменной $name,
-objectattributes @{SubmissionContLength='INSERT_VALUE';DelivContLength='INSERT_VALUE'} - здесь задается, что именно меняеть, как раз те самые два параметра. Следует обратить внимание, что набор параметров заключается в фигурные скобки.

@темы: MS Exchange, PowerShell, Scripting

15:34 

Ключи...

В Dash'e под Chronostasis'ом.

... от квартиры, где деньги лежат.
Нет, на самом деле речь пойдет о ключах другого рода, лицензионных. Первое, что приходится учитывать компаниям, это ключи на ОС и офисный пакет, если используется MS Office. И может сложиться такая ситуация, когда нужно быстро собрать информацию о ключах на довольно большом количестве машин. Как это сделать?
На помощь может прийти утилита под названием Produkey. Свободно распространяемое мелкое приложение, которое позволяет узнать ключи Windows, MS Office и некоторых других пакетов. Сама эта утилита содержит в себе возможность сканирования удаленных машин с целью сбора информации о лизензиях. Но есть один момент - компьютер для этого должен быть включен. Другой же вариант решения проблемы - запустить Produkey в момент запуска компьютера. Это можно сделать сценарием запуска машины.
Групповые политики, Параметры компьютера, Сценарии запуска. Сюда нужно будет положить сценарий, шаблон которого представлен ниже: GetKeys.vbs

Что делает этот сценарий? При загрузке компьютера из папки \\NETWORK-SHARE\ вызывается программа produkey.exe с определенным набором параметров. Результатом ее выполнения будет созданный в корне диска С: файл с информацией об установленном на компьютере ПО (в той части, которую "распознает" produkey). Далее этот файл копируется в сетевую папку "\\REPORTS-FOLDER-SHARE\", после чего из корня диска С: файл будет удален. Таким образом в папке "\\REPORTS-FOLDER-SHARE\" создается набор файлов, каждый из которых соответствует одному компьютеру. Этот набор файлов уже можно анализировать в спокойной обстановке.
Отдельно об анализе этого набора файлов. Например, требуется узнать, что творится с ключами ОС (типичная в России ситуация для нового системного администратора на предприятии). Известно, что в отчетах produkey информация об ОС идет первой строкой. Значит, задача сводится к тому, чтобы пробежать по всему набору отчетов, вытащить из каждого отчета первую строку и внести ее в файл итоговой таблицы. Эту задачу можно легко решить при помощи Powershell, например:

$ReportPath = "\\REPORTS-FOLDER-SHARE\"
foreach ($name in ls $ReportPath) {get-content $ReportPath\$name -totalcount 1 | Out-file winkeys.txt -append}

Этот нехитрый сценарий пройдет по всем файлам в папке \\REPORTS-FOLDER-SHARE\, прочитает по одной строке из каждого файла в ней, после чего результат скинет в файл winkeys.txt, находящийся в домашней папке пользователя. Работать с единой таблицей же куда проще, чем с набором файлов.

@музыка: Stone Age - Maribrengall

@темы: Security, Scripting, PowerShell

Записная книжка

главная