Записи с темой: scripting (список заголовков)
22:16 

Powershell - Resize Image #2

Stance Dance

Давняя история, начало которой аж вот тут: Клац!

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

- обрабатывать пофайлово (параметр Identity). Скормил ему прямо имя файла, он его и обработал. Скормил через запятую пару-тройку файлов - обработает и их, например, d:\1.jpg,D:\2.jpg.
- обрабатывать пакетно целые каталоги (параметры Path и Mask). В этом случае используется имя каталога, в котором лежат нужные нам картинки, и маски расширений. Маски можно указывать через запятую, например, *.jpg,*.png
- задавать произвольные размеры картинкам (параметры Width и Height). Указываем прямо нужный размер, и он будет применен ко всем выбранным файлам.
- задавать размер с учетом соотношения длин большей и меньшей стороны (параметр Size). Указываем нужный нам размер большей стороны. Меньшая будет вычислена автоматически. Какая сторона больше - определяется также автоматически для каждого обрабатываемого изображения.

Использовать одновременно параметры Identity и Path/Mask нельзя. Хотя, возможно, я это в дальнейшем поменяю.
Параметры Path и Mask работают только в паре, по-отдельности - нельзя.

Результирующие файлы будут лежать там же, где и исходные, в имя будет добавлен суффикс _new.

@музыка: Gandalf - Titapatawa

@темы: Scripting, PowerShell

16:21 

Powershell + Yandex.Music #5 - Final

Stance Dance

Ну, поглядев на заголовок, подумал, что хочется верить, что это финал :)

Отличия от прошлой версии:
- добавил забытый(sic!) блок очистки временного каталога
- убрал работу с cookies (бесполезны)
- отказался от простой конструкции $source=@(), явно указав, что это динамический массив. Как следствие - System.StringSplitOptions больше не нужны в таком адовом количестве.
- раскидал комментарии.

Для тех, кто все же заинтересовался, как это работает, пояснение ниже.

Вся конструкция для вытаскивания музыки с сервиса Yandex.Music состоит из трех частей: этого скрипта, программки Youtube-DL, которая является "ломовой лошадью" и еще одной программки ID3.exe. С ее помощью мы развешиваем теги к стащенным песням.

В качестве исходных данных скрипт использует ссылку/-и на песни и/или альбомы на самой Яндекс.Музыке. И берет он их даже не из файла или веб-страницы, а из буфера обмена. Пример 1 - в буфере у нас лежит вот такая строка:

Это выкачает одну песенку.

Пример 2 - в буфере лежит подобная ссылка:

Будет стащен весь альбом.

Пример 3 - в буфер загнали больше, чем одну строку:

Будет стащена сначала песня по первой ссылке, затем альбом по второй.

Как "готовить"?

В блоке переменных нужно прописать три пути: путь к папке, где будет храниться скачанная музыка, путь к файлу Youtube-dl.exe, путь к файлу ID3.exe. Естественно, эти файлы у нас уже должны быть. На этом подготока закочена. Копируем в буфер обмена интересующую нас ссылку или группу ссылок и выполняем скрипт.

Текст финальной версии - ниже.

@музыка: Sergey Eybog - Afterword

@темы: Scripting, PowerShell

10:29 

Powershell + Yandex.Music #4 - Full Batch

Stance Dance

Подумалось тут - а чего бы не обучить свой скриптик таскать и альбомы, и треки разом? Собрал в буфере обмена целый список того, что нужно, надавил кнопочку "Download", а умная машинка сама поймет, что от нее хотят.

Теперь скрипт работает так. Скармливаем ему через буфер обмена данные. Первое, что будет сделано - попытка разбить эти данные на строки. Одна строка там будет на выходе или несколько - неважно, они будут потом поочередно обработаны и распознаны - ведет ссылка в этой строке на трек, или же она ведет на альбом. Если на трек, в список загрузки будет добавлена сама эта ссылка, если же на альбом - как и в предыдущей версии - скрипт стащит ссылки на треки этого альбома и уже их добавит в список загрузки.

Ну а в финале - пробежка по списку загрузки и, собственно, скачка нужного.

На удивление часто пришлось играться с System.StringSplitOptions::RemoveEmptyLines, как-то нервно Powershell со строками работает.

@музыка: Sergey Eybog - Get to know me better (Как перестать гореть???)

@настроение: клац-клац-клац

@темы: PowerShell, Scripting

01:35 

Powershell + Yandex.Music #3 - Album Download

Stance Dance

OST "Бесконечного лета" стал последней каплей. Я давно уже собирался обучить мой скрипт загрузки треков с Яндекс.Музыки работе с целыми альбомами, но все духу не хватало. Хотя дел там не так уж и много. Но пройти мимо этой жемчужины я физически не смог, БЛ просто обязан поселиться на моем телефоне целиком.

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

Похоже, что музыкой БЛ я буду болеть еще очень и очень долго. Похоже, она стала именно тем, что я давно для себя искал...

@музыка: Sergey Eybog - Went Fishing, Caught A Girl (я ржу с названия этой композиции)

@настроение: после открытия хорошего рута Лены - уже лучше

@темы: Scripting, PowerShell

09:34 

XPath - боль

Stance Dance

Впервые довелось воспользоваться XPath-фильтром при работе с логами Windows. Это кусок боли, причем с двух сторон. Сначала взвыл, поглядев на структуру сообщений об удалении файлов с ресурсов севрера. Обычно же как:

C этим все просто и понятно. А вот фигвам! Имеем вот такой шаблон:

Энто ж как же, вашу мать, извиняюсь, понимать? (с) бессмертный Филатов.

Повторюсь, с простыми нодами все хорошо, они скриптуются на ура. С нодами при поддержке аттрибутов тоже особых проблем нет. Но вот ноды с аттрибутами и значениями. Каким синтаксисом их утрамбовывать? Как оказалось, в Xpath можно использовать два варианта - через квадратные скобки и через слэши. Второй вариант мне ближе, так что пишем:

Это выберет сообщения, в которых есть указанная нода с указанным аттрибутом и нужным значением этой ноды.

Выбирать можно и по аттрибутам:

Проверяется только значение attribute1, без значения самой ноды, если такого, например, нет вовсе.

Само собой, логические операторы тоже поддерживаются:


Вроде бы и ничего особо сложного, но только когда хоть малость привыкнешь. А до тех пор - bite the bullet, как говорится. А я еще, помнится, на вычисляемые поля в select-object ругался. Тоже долго с тамошнему синтаксису привыкал, со всеми скобочками, точками с запятой, кавычками. Удобная штука, эти вычисляемые поля, не спорю, но прописывать их запаришься.

В общем, основное правило при работе с XPath - вложенные ноды - через слэш, аттрибут рассматриваемой ноды - в квадратные скобки через comm-at - @.

@музыка: David Arkenstone - Ah*Nee*Mah Project - The White Feather

@настроение: привидение выспалось, привидение довольно...

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

16:02 

DPM - Available Tapes #3 - Case Closed

Stance Dance

В топку. В топку тот скрипт, который мне дался таким потом и кровью. А все почему - потому что с точки зрения управления лентами чере Powershell DPM еще та дрянь. Простой пример: лента с одной (всего одной) точкой восстановления, для которой назначено больше чем одна Recovery Goal (ну то есть для данной точки восстановления есть бекап бекапа - вторая копия этой информации). Powershell для этой ленты говорит: Recovery Point status - Expired. Открываем содержимое той же самой ленты в GUI-консоли - бааа, да эта лента сдохнет только через пару недель. И самое паскудное - верная информация все же в консоли.

Короче, как я уже и сказал - в топку. Придется использовать встроенный в сам DPM отчет о ротации лент. Не так удобно, как мой скрипт, но данным можно будет верить, это важнее.

@музыка: Iron maiden - Heaven can wait

@настроение: не самое безоблачное, столько сил впустую

@темы: Scripting, PowerShell, DPM

09:02 

Powershell Functions

Stance Dance

На самом деле такие моменты надо собирать, запоминать и ценить. Они как раз и показывают, что не напрасно занимаешься тем, чем занимаешься.

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

Каждый раз заходить для этого на сервер - лениво. Даже воспользоваться mmc-оснастокй Services - тоже лениво. А самая главная засада в том, что даже если работать через любимый Powershell - имеющаяся там встроенная команда Start-Service не принимает в качестве параметра имя удаленного сервера, она работает только с локальной системой. Потому была написана простенькая функция, которая вызывается вообще без параметров и запускает на жестко забитом сервере жестко заданную по имени службу, используя механизм Invoke-Command. Примерно так:

И она работала себе, жрать не просила.

В какой-то момент я понял, что неплохо бы было расширить ее с таким расчетом, чтобы запускать любую службу на любом сервере, куда можно дотянуться при помощи PS. Удобно же, закинул ее в личный модуль, повесил какой-нибудь короткий алиас, и все. Пара нажатых кнопок, пара имен. И не надо ждать, пока прогрузится либо полностью весь сеанс, либо оснастка. Консоль же PS у меня запущена всегда, это удобно.

Получилось нечто вот такое. Решил, что пора бы осваивать Advanced Functions и встроенный в них man. Заодно обучил функцию работать не только с именами служб, но и с их отображаемыми подписями, так что службу идентифицировать можно разными способами.

И показал ее своему коллеге. Посмотрел он на нее, после чего в чат выдал вот такое:
- Эээ... Get-service -ComputerName %SERVERNAME% -Name %SERVICENAME% | Start-Service

После чего настал мой черед выдать:
- @#$...

И дружно ржем. Потому что весь мой велосипед реально умещается в одну строку кода, если отказаться от проверки DisplayName.

И самая мякотка - того коллегу на Powershell именно я и подсадил где-то год назад :)

@музыка: Nicholas Gunn - Flight over North Rim

@настроение: клац-клац-клац

@темы: PowerShell, Scripting

10:02 

Check DNS addresses

Stance Dance

Частенько бывает необходимо проверить сразу десяток-другой имен узлов в DNS: есть они там, нет их там, если есть - под какими адресами значатся. Каждый раз вбивать nslookup %hostname% руками - утомляет безумно. Потому набросал простенькую конструкцию:

Если узел в DNS есть - будет выведено его имя и его адрес. Если узла нет, или в процессе просмотра вылезла какая-нибудь ошибка - будет выведено только имя.

@музыка: Silence

@настроение: клац-клац-клац

@темы: Scripting, PowerShell

22:44 

DPM - Active Tasks List

Stance Dance

MS DPM - штука такая, за ней глаз да глаз нужен. Точнее, не за ней самой, а за одним типом задач - System State Protection. Частенько бывает так, что такая задача зависнет на пять-шесть часов, и только почем зря занимает ресурсы сервера. Обычно в таком случае мы просто прерываем ее и запускаем заново. Полчаса - и бекап состояния системы готов. Но для того, чтобы задачу перезапустить, ее надо увидеть. А для этого нужно зайти на сам сервер DPM. А... Согласен, слишком много "А", но тем не менее: а консоль DPM - штука очень неторопливая, да и самих серверов далеко не одна штука. Заходить на каждый и смотреть, что там творится - да проще убиться веником. Powershell to the rescue!

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

@музыка: E-Mantra - I shall not care

@настроение: Neutral

@темы: Scripting, PowerShell, DPM

18:11 

DFSR Backlog - Все сразу

Stance Dance

Про Backlog в DFSR уже давно доводилось писать. Возникла нужда снова воспользоваться именно этим способом наблюдения за репликацией, только уже для значительно большего числа групп реплик. А потому хочется уж написать скрипт так, чтобы он работал и для текущих групп, и для всех новосозданных, если такие будут.

А уж что делать с табличкой, утрамбованной в переменную $output - на усмотрение конечного пользователя.

@музыка: Project Blue Sun - Besame (Radio Edit)

@настроение: а за окном дожди и хмарь...

@темы: Scripting, PowerShell

00:08 

Printer Ports and SNMP

Stance Dance

Поступила задача - на большой-пребольшой куче принтерных портов включить галку SNMP Enabled, исключая те, к которым подключены принтеры модели HP 577. При создании всех тех принтеров мы как-то пропустили тот факт, что она не ставится автоматом. Для новых объектов поправили, а что делать с уже имеющимися? Первая мысль: ну не вопрос, в одну руку порт, в другую Set-PrinterPort... Hey, cousin, it doesn't happen! (c) Командлета Set-PrinterPort не существует в природе. Ладно, но есть жабросли WMI:

Хотя и знаю, что правильнее было бы использовать Get-WmiObject -Class win32_TCPIPPrinterPort -filter 'бла-бла-бла', а не Get-WMIObject | where {бла-бла-бла}, но есть затык. В фильтр я так и не смог загнать переменную. А жаль.

@музыка: Sabaton - Blood of Bannockburn

@темы: Scripting, PowerShell

19:15 

Data Protection Manager - Backup Statistics

Stance Dance

Идея вертелась уже черт знает сколько. Наконец-то руки дошли до реализации.
Мысль проста - прийти на рабочее место в начале недели, открыть файлик и посмотреть, что у нас с бекапами. Когда и для какой группы защиты и источника данных была создана последняя точка восстановления. Шастать каждый раз для этого в монструозную консоль DPM - увольте, я успею напиться кофе, пока она откроется. Так что в первом приближении все будет выглядеть вот так:

Task Scheduler, все дела. Затем создается связь в Excel на полученный txt-файл, и дело сделано. При желании можно расширить и на несколько площадок, чтобы вообще всю статистику получить.

@музыка: Philippe Alexandre Belisle - Impovisation

@настроение: клац-клац-клац

@темы: PowerShell, DPM, Scripting

00:00 

Lostfilm RSS

Stance Dance

Враги-лостфильмовцы с переходом на новую версию сайта допустили то, чего я опасался больше всего - RSS уложили отдохнуть. Не работает загрузка через нее больше. Спасибо добрым людям - дали ссылку на топик старого сайта, где рассказали, что делов-то всего - получить старую RSS, заменить одно на другое, после чего скормить полученное торренту. Закавыка всего одна - торрент в принципе не работает с локальными файлами, из чего следует, что исправленную ленту нужно заливать на какой-нибудь сайт. Ну и предлагалось использовать PHP для модификации. Вот только PHP я не люблю, да и держать его не на чем.

Хм... но никто же не мешает поднять IIS. Хотя любви к PHP это не прибавит, но можно и без него обойтись. Главное, что будет куда выкладывать новую ленту.

Итак, имеем следующее.
Исходная лента доступна по адресу

В полученном xml-документе мы должны найти все вхождения

и заменить их на


Как поднять IIS и проверить, что она работает - мануалов тонны. Дальше в дело вступает Powershell:


Файл-результат будет сохранен сразу в веб-каталог IIS. Соответственно, нужны права на запись в него тому пользователю, от чьего имени будет выполняться это задание.

Дальнейшее - тривиально. Task Scheduler, запуск этого скрипта с заданным интервалом под нужной учеткой. Как только увидели, что нужный файл сформировался в каталоге IIS - натравливаем на него torrent-клиент ровно с теми же параметрами, что ранее были заданы для обычной ленты RSS LostFilm.

Готово! Можно кушать :)

@темы: PowerShell, Scripting

17:59 

Powershell Libraries...

Stance Dance

Вот раньше как было?


И это спокойно себе работало.

С недавнего времени отказало. Точнее - работает, но только если этот код вызывается из ISE. Там куча всяких библиотек подгружается в фоне. Проверяем:


Поменяли подгрузку в 5.1 Теперь приходится ручками писать:


Предупреждать надо!

@музыка: John Marting - Anywhere gor you

@темы: Scripting, PowerShell

14:53 

Powershell + Yandex.Music + MP3 Tags #2

Stance Dance

Гость натолкнул на интересную мысль. --add-metadata - штука хорошая, но требует наличия на компьютере какого-нибудь, ну хоть плохонького, но энкодера. А поставить его бывает возможность не всегда. Но мысль заключается в следующем - сохранять метаданные можно не только напрямую в результирующий mp3, но и просто в файл. Так почему бы и нет? Уж распарсить получаемый на выходе json powershell сможет всегда. А рядом с тем же youtube-dl положить маленький любимый id3.exe - и вовсе не проблема.
Остальные условия те же - ссылку для скачивания скрипт берет прямо из буфера обмена.
Поехали!

@музыка: Years & Years - King

@темы: Scripting, PowerShell

19:17 

Poweshell - Fixing Printer Group Policy

Stance Dance

Очередной день, очередные тесты. Вводим в тестовую среду виртуалку с Win 7 в качестве клиентской ОС и начинаем править скрипт таким образом, чтобы результирующие файлы были в нужной кодировке и читались как серверами, так и клиентами.
Смотрим на исходные файлы "живых" политик:
Printers.xml - UTF8
GPT.ini - Windows-1251.

Лезем скрипт, находим там строку

После чего меняем ее на вот такую конструкцию:

Через Stream Writer мы запишем Printers.xml в нужной кодировке - UTF8. Она НЕ равна Unicode, в котором Powershell соберется записать файл по-умолчанию.
С GPT.ini все проще. В инструкции

просто добавляем требуемую кодировку:

После чего gpupdate на клиентах, и наблюдаем красивые безошибочные журналы System и Application.
Дело за проверкой в боевых условиях. Нужна тестовая политика уже там.

@музыка: Ryan Farish - Sunshine in the Rain

@темы: PowerShell, Scripting

20:32 

Powershell - Printer Policy Complete

Stance Dance

Сделано. Решение "влоб" отменяется. MS XML оказался намного проще, чем я полагал все это время.
На вход - csv c полем Name (в нашем случае - ищется файл printers.csv в папке Документов текущего пользователя), где будут перечислены отображаемые имена принтеров. На выходе - заполненные политики по разливке этих принтеров пользователям на основе групп доступа. Принтеры будут расставляться членам групп с именами, равными названиям принтеров.
Политик две. Предполагается, что принтеры на первой площадке попадают в политику Map-Printers-01 и крутятся на принт-сервере ps1, принтеры второй площадки разливаются через политику Map-Printers-02 и сидят на сервере с названием ps2.
Если вдруг скрипт обнаружит, что для какого-то принтера не создана группа доступа, скажет об этом и пропустит принтер.
Если будет обнаружено, что в целевой политике уже есть запись для добавляемого принтера - будет предложено ее (или их, если их много - бывает и так) пересоздать. Если отказаться от этого - принтер будет пропущен.
И важный момент. Обе политики уже должны существовать, и в них должен быть заведен хотя бы один принтер. В противном случае в каталоге политики в SYSVOL будет отсутствовать файл Printers.xml, а создавать его политика не обучена (мне было лень).
Поехали!

@музыка: Joe Satriani - Speed of Light

@настроение: Getting the things done!

@темы: PowerShell, Scripting

23:21 

Lucifer, Maze, Powershell

Stance Dance

Повод для этой записи для меня необычен. На дайриках полно заметок, где народ всякие гифки выкладывает с полюбившимися им киноперсонажами. Вот эта напасть и меня не миновала. Знакомьтесь: Мейзикин (Мейз) из Люцифера.

Вот казалось бы, чего такого - простой поворот и наклон головы. Но именно на этот жест я залип. Да крепко так. Настолько, что пришлось все же освоить науку создания этих ваших гифочек. VirtualDub не подкачал, но пока-а-а-а я смог скормить ему все 63 кадра разом, а до этого еще и руками нарезать эти кадры, потому что формат MKV мало кто способен понять и сделать раскадровку.
С кормежкой VirtualDub вообще азаза получилось. До этого я вовсе ни разу с программкой не работал (как-то не было нужды), потому о том, каким образом ему подсовывать цепочку картинок, не имел ни малейшего понятия. А в окне выбора файлов можно выбрать только один. И как же быть? Да вот так и быть - файлы должны иметь номер в конце. Ну то есть:
File1.jpg
File2.jpg
File3.jpg
...
Ок, не вопрос:

Но и после этого VirtualDub не захотел кушать всю цепочку. Что ж не так? А вот что. MPC HC, которым я резал кадры, сохраняет их с вымученным названием, например,
Lucifer.S02E05.1080p.rus.LostFilm.TV.mkv_snapshot_11.19_[2016.10.30_23.16.35].jpg
В общем и целом, благодаря квадратным скобкам и тому, что между ними, VDub не расценивал эти файлы как часть цепочки. Кстати, сами квадратные скобки еще в Powershell попортили немного крови, пришлось воспользоваться ключом -literalpath при переименовании, иначе PSH эти файлы в упор не видел.
Ладно, тот же скрипт, но вместо $file.basename ставим "LuciferS2-E5-" - и все стало просто замечательно.

@музыка: E-Mantra - Kaleidoscope Clouds

@настроение: А все же залип... Впрочем, Мейз и без этого хороша, особенно в действии :)

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

01:30 

Powershell - Complete Printers Info

Stance Dance

Бессонные ночи того стоили. Однозначно (с)
Хотя нет. Бессонные ночи - это автоматизация настройки принтеров на DHCP и принт-серверах, и это только часть общего дела. Есть и другая часть, не менее муторная, если не более - учет этих самых принтеров. И ведется он, как бы так помягче сказать - из рук вон плохо. Поскольку в Excel-файлы, хранящие в себе сведения по разным офисам данные о добавленных или убранных принтерах вносит куча народа, неизбежны ошибки. А кто-то вообще забудет это сделать. Чего уж там, скорее всего и я в этих файликах тоже косячил.

И в итоге вся отчетность плывет.

Отныне это должно измениться, потому что вся отчетность будет создаваться автоматом на основе реальных данных DHCP и PS: сценарий сформирует сводный csv-файл с кучей информации по резервированным адресам на DHCP серверах и принт-серверах, а сделанная и сохраненная excel-таблица (роль которой - сугубо удобное представление данных) будет кормиться как раз из полученного csv.

Но прежде, чем переходить к самому скрипту, хотелось бы положить в запись ссылку на следующую страницу:

Join-Object - Technet

Скрипт Join-Object фактически реализует такие интереснейшие вещи из мира баз данных, как Join'ы. Именно FULL JOIN позволит нам связать сведения от DHCP-серверов и серверов печати. Прекраснейший скрипт, за который огромное спасибо ребятам из команды MS Powershell. Ну а подключить его к основному сценарию достаточно просто - через dot-source - прямо в первой строке нашего сценария. Что ж, поехали:

Окинув взглядом получившуюся в Excel мега-таблицу увидел в ней сто-о-о-о-о-олько интересного! :)

@музыка: Mark Farina - Sexy Fire (Factory Boom Boom Mix)

@настроение: Overall progress - 50% - nice!

@темы: Scripting, PowerShell

14:35 

Powershell - Continue

Stance Dance

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

Суть кода - в switch проверяется значение переменной $i. Если оно равно 8, пишется предупреждение, вызывается оператор Continue, и скрипт переходит к итерации под номером 9. Во всех остальных случаях switch не делает ничего, и сценарий выполняет следующую за switch инструкцию "напиши мне значение переменной $i. А вот что мы получаем на самом деле:

С другой стороны, исправь мы код совсем чуть-чуть, получим ровно то, что требовалось:

Получается, что continue тоже считает switch за цикл? Это засада.

@музыка: Sandra - Hi! Hi! Hi!

@темы: PowerShell, Scripting

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

главная