• ↓
  • ↑
  • ⇑
 
Записи с темой: powershell (список заголовков)
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

11:51 

Shared Printers and Group Policy

Stance Dance

It is done!
Последнее, что мне никак в моей опупее по автоматизации развертывания принтеров не давалось, так это подстановка новых принтеров в групповую политику. Среди всех команд Powershell, работающих с GPO, нет ни одного, который бы позволял менять GPPreferences. Точнее, есть, но работают они несколько не с тем, что нужно.
А недавно стукнуло в голову - описания принтеров, которые раскатываются на рабочие места, это ни что иное, как XML файл, лежащий в SYSVOL по вполне себе известному пути. А что если выправить непосредственно этот XML файл, а потом посмотреть, что будет.

Как водится, разъяснения, что тут и как.
В качестве входных параметров в этом коде присутствуют имя принтера, который будет прописывать в политику, имя принтсервера, на котором живет общий ресурс этого принтера, и имя политики, которую будем менять. Все остальное вычисляется автоматом на основании этих данных. В финальном виде входными данными будет только имя принтера, но это уже за рамками данной записи.
Скрипт предполагает, что группа, членам которой будет подключаться этот принтер, уже создана, а ее имя совпадает с именем принтера. При желании проверка на наличие этой группы в AD прописывается очень просто.
Отдельно пара слов о блоке Raise Version of policy. Номер версии групповой политики никак не влияет на репликацию самих файлов политики, а вот для клиентских рабочих станций он может иметь большое значение. Именно поэтому данный блок и введен. Как рассчитывается и как хранится номер версии - в сети материала полно, от себя лишь скажу, что это было весьма интересно.
P.S. Согласен, что сборка XML структуры в виде текста - решение "в лоб". Но как показывает практика, иногда именно такие решения работают надежнее всего.

@музыка: Stellardrone - Comet Halley

@темы: Scripting, PowerShell

17:36 

DX:MD - Scripts

Stance Dance

Ссылки. В прошлой записи ссылок на картинки было под пять десятков. Прописывать все это руками, конвертируя то, что отдает imgur.com - да проще было бы убиться. Ну а поскольку в моей жизни еще не все дела переделаны, убиваться рано (вот разве что кого-то убить... ой, что-то я не туда полез...).

В общем и целом. Есть куча однотипных ссылок на картинки. Нужно отконвертировать их в ссылки с поддержкой мелких (или не очень мелких) превьюшек. Скажем, если ссылка имеет такой вид:

то приобрести она должна вот такой:

Создается обертка в виде тега "a href" и немного меняется путь к той картинке, которая будет выступать в виде превью: в ее имя перед расширением добавляется буква "l".
От копипаста исходных ссылок с imgur ничто не спасет, ну не нашел я там функции экспорта линков. А вот все дальнейшее прекрасно в итоге автоматизируется:

В файл d:\links.txt закидываем imgur'овские ссылки по одной в строку, а полученное на выходе вставляем в форму новой записи на дайриках и разбавляем комментариями. Сделано!

@музыка: Sascha Dikiciyan - DXMD - 101 Trailer

@темы: PowerShell, Scripting

21:23 

Powershell + Yandex.Music + MP3 Tags

Stance Dance

Скажу сразу - на данный момент Яндекс.Музыка похоронила эту идею, но вдруг найдется обходное решение.
Ну не хочу я ставить себе на телефон клиент ЯМ для того, чтобы иметь доступ к своей подборке музыки. В то же время есть консольная утилитка youtube-dl, которая вполне себе поддерживает загрузку треков оттуда. Одно плохо, mp3-файлы, формируемые на выходе, лишены всяческих тегов. Ни исполнителя, ни названия, ни уж тем более альбома и года. А хотелось бы. В то же время все эти данные есть на страницах треков в ЯМ. И их можно распарсить.

А вот что делать с полученными данными - уже на усмотрение конечного пользователя. Можно передать в тот же старый добрый id3.exe, можно что-то иное придумать...

Но с другой стороны, даже несмотря на неработоспособность youtube-dl в полупакетном режиме, все эти игры с ЯМ даром не прошли. Откопалось тут:


P.S. Как выяснилось, Powershell по-дефолту очень жаден (greedy) до регекспов. В будущем это стоит учитывать.

@музыка: Kim Wilde - Game Over

@настроение: прорвемся!

@темы: PowerShell, Music

00:08 

Вызов

Stance Dance
Читая некоторые книги серии FR на английском (переведенного варианта просто нет в природе) неоднократно натыкаюсь на два термина: evocation и invocation. Оба они относятся к призыву чего-то потустороннего. Либо каких-то тайных сил, либо каких-то сущностей вида демонов, небесных существ, а то и вовсе дьявола или бога/богов. Но есть и различие. Весьма подробно оно раскрыто вот тут:
Difference between invocation and evocation

А пока ехал в автобусе, мелькнул в мозгах один из командлетов Powershell: Invoke-Command. Позволяет выполнить другую цепочку команд на локальном или удаленном компьютере с выводом результатов в текущую консоль. Что ж, все сходится, это таки invocation :)

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

@темы: PowerShell, Forgotten Realms

18:09 

Колобки

Stance Dance

При всей моей нелюбви к графическим смайлам существует в природе ровно один набор оных, который мне все же нравится. Да, да, старый добрый "Колобок", известный еще со времен старого QIP и позднее перекочевавший и сюда, в дайрики. Случайно набрел на сайт, целиком и полностью посвященный этим картинкам. Вот он: www.kolobok.us/index.php
Там же можно стащить полный пак смайликов. Одна проблема - ну стащил ты его, а дальше что? Одному открывать их либо в IE по-умолчанию, либо во внешнем вьювере, если он стоит. Сейчас у меня на компе нет практически ничего, почти голая система. Ставить что-либо лишнее почему-то влом. А почему бы не показать все эти картинки разом на одной странице? Есть же стандартный HTML. А вывод какой-либо информации в html-файл освоен уже давно и вовсю используется в том числе и на работе еженедельно. Как уже повелось - ISE в зубы:

Просто и быстро:

Конечно, можно было бы заморочиться с таблицей в несколько колонок, а путь выводить в теге ALT, но мне было лень :)

@музыка: Yanni - Echo of the Dream

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

23:42 

Квоты #3 - Final

Stance Dance

А теперь все и разом - шаблоны, авто-квоты и простые квоты. Сервером назначения является FS2.
Правила игры таковы:
1. Не может быть нескольких шаблонов с одним и тем же именем. Следовательно, если на сервере-истонике есть шаблон квоты на 100 Мб под именем "Шаблон1", а на сервере назначения есть шаблон на 200 Мб под тем же именем, шаблон перенесен не будет.
2. Нельзя назначить несколько авто-квот на один и тот же путь. Это же правило действует для простых квот.
3. Исходим из того, что пути к каталогам, на которые развешиваются квоты, одинаковы что на источнике, что на цели.
Поехали:

@музыка: Enigma - The Child in Us

@темы: PowerShell, Scripting

01:41 

Квоты #2

Stance Dance

Все таки все вышло гораздо интереснее, чем казалось.
Можно. Можно посредством Powershell мигрировать квоты между серверами. Главное - чтобы совпадали имена дисков и путей. А теперь более развернуто.

Сначала камнем преткновения стал параметр -SoftLimit. Синтаксис его таков:
для задания мягкой квоты: New-FSRMQuota -path "blah" -size "blah" -softlimit
для задания жесткой квоты: New-FSRMQuota -path "blah" -size "blah"
то есть если нужен хардкор - параметр не указывается вовсе. Черт, а ведь я хотел бы более привычное -softLimit $True/$False. И как же это побороть? Читаем описание самого параметра и видим:

Accept Pipeline Input? True (ByPropertyName)

А это означает, что весь командлет New-FSRMQuota можно натравить на трубу, через которую будет передан объект, описывающей имеющуюся на сервере источнике квоту. будет примерно так:

Get-FSRMQuota | New-FSRMQuota

Произойдет следующее. Команда Get-... занесет в память объект с кучей свойств, в том числе будет и свойство -SoftLimit. Все это добро будет передано по трубе команде New-..., которая, зная, какие свойства в новом объекте надо заполнить, будет их по имени искать в переданном объекте. Найдет - подставит, не найдет - пропустит. Отлично, с этими разобрались.

Следующее: если в командлете New-FSRMQuota нет параметра вида -ComputerName, который бы сказал, где именно запускать процесс, то каким образом можно:
1. ухитриться запустить на удаленной машине
2. передать параметры квоты на эту самую удаленную машину.
Ответом на первый вопрос стал параметр -CIMSession. Идентификатор сессии, который можно предварительно задать при помощи командлета New-CIMSession. Этот параметр выступит полным аналогом так нужного мне -ComputerName. А со вторым оказалось все до боли просто - та же самая труба. То есть получаем вот такую конструкцию:

$session = New-CimSession -ComputerName FS2
Get-FSRMQuota | new-fsrmquota -CimSession $session

В итоге команда Get-... выполнится в локальной сессии, а New-... - в удаленной, при этом в качестве входных параметров будет использован объект, полученный в локальной сессии. Удобно!

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

А сама особенность заключается в следующем. Если в переносимой квоте не задан шаблон, то при выполнении конструкции Get-FSRMQuota | new-fsrmquota -CimSession $session команда New-... попытается создать новую квоту с параметром -Template, равным пустой строке. Логично, шаблон ведь не задан. И именно на этом моменте она выкинет ошибку. Если команда New-... вызывается с указанием параметра -Template, а в нашем случае он будет указан по-дефолту, то этот параметр просто обязан не быть равным пустой строке. Получается, еще до выполнения New-... нам придется анализировать, а была ли квота подвязана к шаблону, и если не была - то на вход команды New-... нужно передавать уже другой объект, в котором были бы все свойства исходного, кроме -Template. Ну что же, это выполнимо (в переменной $quota как раз хранится объект, описывающий квоту):


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

@музыка: Koan - After the Guiding Venus

@настроение: много кофе ночью на работе...

@темы: Scripting, PowerShell

23:51 

Powershell + Яровая

Stance Dance

WTF, спросите вы, глядя на заголовок. Внезапно, объединение необъединимого - политоты и Powershell, отвечу я. WTF дважды, зададите вопрос вы?

Для начала идем сюда: vote.duma.gov.ru/vote/95967
Тут лежит поименный список тех, кто голосовал (или не голосовал) по "пакету Яровой" и как. Пакет принят, ок, мы это уже знаем. Фильтруем этот список по фракции ЕР. Бегло просматриваем результаты, и убеждаемся, что практически вся эта фракция голосовала "За" (Романов Антон Васильевич - тебя и твой единственный голос разума мы будем помнить). Учитывая, что Яровая как раз из ЕР - что это было? Приказ сверху? Впрочем, интересует не это. Интересуют цифры.

Копипаст всей отфильтрованной таблицы в обычный текстовый файл, сохраняем его под именем file.txt, после чего в консоли Powershell даем следующее:

get-content d:\file.txt | select-string "ЗА" | measure-object


На выходе получаем искомое число: 235. Мы отсекли одного проголосовавшего "Против" (см. выше) и еще двоих - один не голосовал, второй - воздержался. А теперь еще раз смотрим на страницу с поименным голосованием и ищем там строчку Кворум. И смотрим значение - 226.

Господа! У нас просто не было шансов. НИ. ЕДИНОГО. ШАНСА.

P.S. Только сейчас заметил, что на той странице уже выложена процентовка по голосовавшим, по фракциям в том числе. Ну да ладно, лишний повод запустить консоль для тренировки лишним не будет :)

@настроение: предлагаю догадаться самостоятельно...

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

10:50 

Printers - mass rename and reconnect

Stance Dance

Относительно недавно на работе была открыта новая площадка. Назовем ее Loc-05 (Location-05), где 05 - ее индекс, пятая по счету. Все шло хорошо, туда даже сотрудники уже заехали, оборудование поставили, принтеров много-много завезли. Об этих-то принтерах речь и пойдет.

Схема их подключения такова. Все это - МФУ, сетевые устройства. Они все заведены на принтсервер, им включен общий доступ, и они опубликованы в AD. Конечным пользователям все эти принтеры подключаются через групповую политику, раздел Group Policy Extensions - Control Panel, Printers.

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

Принтеры были заведены с именами Loc-05-.....

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

Начинаем разбираться.

Что нужно сделать с каждым из этих принтеров?
1. Снять публикацию принтера в AD, убить общий доступ.
2. Переименовать принтер на принт-сервере.
3. Включить общий доступ под новым именем, опубликовать заново принтер в AD.

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

Тут все просто - переименовываем ее, и дело с концом. Попутно меняем атрибут SAMAccountName, чтобы он совпадал с новым именем группы. При переименовании через GUI система автоматом предлагает это сделать, но имеем это в виду.

Последний участник этого балета - политика. Вот тут сложнее всего. Править ее ручками в редакторе политик на все 100+ принтеров - это ж можно упариться. Но политика - это обычный текстовый файл, который можно обрабатывать как текст в любом редакторе. Учтем и это.

Приступаем к реализации плана.

1. Переименование принтеров на принтсервере. Примем во внимание, что принтсервер у нас основан на Win2012 - вся мощь Powershell в наших руках, так что прямо на этом принтсервере выполняем следующее:

Код выберет на принтсервере все объекты принтеров, имя которых содержит в себе Loc-05, после чего сделает все ранее описанные действия, в том числе и переименование самого принтера. Новым именем будет Loc-06.

2. Переименование групп. Тоже ничего сложного. Разве что нужно убедиться, что на компьютере, где будет запускаться код, установлен модуль ActiveDirectory для Powershell. Единственное, что нужно будет сделать, это поменять OU, где скрипт будет искать нужные нам группы.


3. Действия с политикой. Получить текстовый файл можно двумя путями. Либо мы лезем в каталог sysvol и блуждаем там в дебрях каталогов, либо мы просто выполняем бекап этой политики к себе в папочку. Второй метод проще.

Примечание. \\PS - это имя моего "ручного" принтсервера. EXAMPLE\ - имя такого же "ручного" домена. В рабочей среде эти имена будут другими.

Получив к себе в распоряжение текстовик, начинаем в нем копаться. Нас интересуют строки вот такого вида:

Именно они и определяют принтеры. Что и где нам придется поменять?
name="Loc-05-PDF24" - это очевидно - имя принтера. В нашем случае меняется на name="Loc-06-PDF24"
status="Loc-05-PDF24" - в ту же степь, что и имя принтера. Меняется на status="Loc-06-PDF24"
path="\\PS\Loc-05-PDF24" - здесь показано имя общего устройства, меняем на нужное. Меняем на path="\\PS\Loc-06-PDF24"
name="EXAMPLE\Loc-05-PDF24" - имя той самой группы безопасности, членам которой этот принтер будет подключаться. Меняем на name="EXAMPLE\Loc-06-PDF24"

Очевидно, что все эти изменения можно сделать одной операцией в Блокноте:
Ctrl+H, Loc-05 -> Loc-06

Но это еще не все. Остался последний этап, нужно заставить эту же самую политику отключить на компьютерах пользователей сетевой принтер с уже недействительным именем Loc-05*
Для этого берем строку, определяющую принтер, копируем ее в буфер обмена и вставляем прямо под исходной. А теперь меняем ее так, чтобы она удаляла старый принтер. Ниже я приведу список тех атрибутов, которые нужно поменять.

name="Loc-05-PDF24" - оставляем старое имя принтера
status="Loc-05-PDF24" - см. выше.
path="\\PS\Loc-05-PDF24" - см. выше.
name="EXAMPLE\Loc-05-PDF24" - поскольку мы теперь применяем это действие к членам уже переименованной группы, ставим новое имя - name="EXAMPLE\Loc-06-PDF24"
changed="2016-05-20 12:45:45" - очень интересный параметр, показывает, когда был изменен этот элемент политики. В новой строке меняем его так, чтобы показанная в нем дата была больше, чем в исходной строке. Не знаю, может быть это совпадение, может быть еще что-то, но до тех пор, пока я не изменил этот атрибут, старые принтеры у меня не отключались. Предполагаю, что имел место некий конфликт между записью о подключении принтера и записью о его удалении. Поставим туда текущую дату, которая будет заведомо больше, чем дата подключения: changed="2016-05-21 12:45:45"
image="2" - это картинка, которая высвечивается в редакторе политик. Значение 2 покажет желтый треугольник, значок действия Update. Значение 3 покажет красный крест, значок действия Delete. Ставим 3.
action="U" - само действие. U - Update, нам же нужно D - Delete.

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

И вот так - для каждого принтера.
В конце концов мы сохраняем полученный текстовик, восстанавливаем политику AD из этого текстовика. После этого, в тот момент, когда пользователь, перечисленный в группе EXAMPLE\Loc-06-PDF24, войдет на свой компьютер, ему тут же подключится новый принтер, а старый - будет удален.

Problem solved.

UPD. Вторичная и последующие проверки показала, что параметр changed="..." можно не трогать, все работает из без его изменения.

@музыка: Need for Speed - Most Wanted, RAP Sheet

@настроение: побольше бы таких задач...

@темы: PowerShell, Scripting

07:22 

Poweshell + SNMP

Stance Dance

Все гораздо проще. Не нужны никакие сторонние библиотеки - все уже украдено до нас написано, и давно.
Учитывая, что нам нужно только читать знаничения OIDов, можно воспользоваться самым базовым функционалом, придуманным еще для принтеров, и доступным аж с ванильной Win 7.

Все! Дальнейшие обвязки этого ядра скрипта - вопрос личных предпочтений.

@музыка: Iron Maiden - Can I play with madness

@темы: Scripting, PowerShell

16:33 

Powershell + Registry

Stance Dance

Запись, скорее, из разряда "Getting the things done".
Про шутки с настройками сетевых адаптеров для онлайн-игрушек я знаю давно. Да все руки не доходили заскриптовать одну из настроек, которая, по понятным причинам, сносилась в дефолт после очередной переустановки системы (а в те времена это было частое явление). Что ж, не знаю, пригодится когда-нибудь кому-нибудь, но пусть будет.

Суть изложена вот тут: support.microsoft.com/en-us/kb/328890

А скрипт, который ищет нужный куст реестра, и прописывает там требуемое значение - ниже. Ориентируемся на IP адрес, отданный домашним DHCP.

@музыка: Nigel Stanford - Far Centaurus

@темы: PowerShell, Scripting

14:44 

[Unresolved] Time switch

Stance Dance

Казалось бы, все хорошо. Прихожу домой с очередной ночной смены, тыкаю в клавиатуру, чтобы монитор проснулся. Вроде все хорошо, система работает, байты летают, синхронизация всего и всея тоже в порядке. Вскипятил чай, сижу, читаю, попиваю себе. И вдруг взгляд падает на часы. А там швах - время почему-то на час больше, и я уже опаздываю. Ничего не понимаю, не мог час так быстро пробежать, в конце концов, я не в DMC 4 сидел.

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

Ок, логи. Расскажите мне, что случилось:
get-winevent system | where {$_.message -like "*clock*"} | select -first 1 | fl *

И получаем просто прекрасное:



Так. Система попыталась синхронизироваться с аппаратными часами, а это BIOS. Черт побери, он не обновлялся уже лет этак несколько (MSI, я век вам буду помнить ту бета-прошивку, где вы хотели виртуализацию включить). Настроек часовых поясов там нет. Но проверить надо. Рестарт, экран BIOS, прошерстить все. Нет. Ничего нет.

Загрузка системы, беглое ковыряние гугла. Гугл подсказывает, что подобные пляски со временем начинаются, когда система запускает задачу на синхронизацию времени и пояса. За это отвечают две задачи, забитые в планировщик: SynchronizeTime и SynchronizeTimeZone. Проверил, когда они в последний раз запускались. Не то, они выполнялись два дня назад. Ладно, может быть я что-то упускаю?

get-scheduledtask | get-scheduledtaskinfo | sort lastruntime | ft taskname,Lastruntime



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

@музыка: Shamis Khassenov - Orhon

@настроение: задумался...

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

01:18 

Powershell Finder

Stance Dance

Надоело мне. На-до-е-ло. Использовать сторонние средства для работы с файлами на рабочем месте нельзя, все только через Проводник. А уж как Проводник может задумываться, когда даешь ему задание найти чего-нибудь файловое, думаю, знают все. Как стало модным говорить - хватит это терпеть.
Проверяем, где у нас лежит файл профиля Powershell:
$profile
После чего открываем показанный файл (или создаем, если его не существует) и вносим в него следующий код:

Перезапускаем консоль и наслаждаемся поиском файлов через Powershell.

Ну и куда же в наше время без комментариев. А комментарии таковы. Объявленная функция будет заниматься поиском файлов в текущем каталоге рекурсивно. Маску поиска мы задаем прямо при вызове самой фукнции, например
find-item "games"
Эта команда найдет в текущем каталоге все папки и файлы, в имени которых встречается games.

В функции объявлены ключи -table, -list, -clip. С ними по порядку.

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

-table говорит консоли, что результат нужно представить в виде таблицы:


-list заставит консоль вывести данные в виде списка:


Одновременное использование -table и -list приведет к ошибке:


-clip интереснее. По-умолчанию функция ищет файлы и папки в текущем каталоге. Но что, если у нас нужный путь скопирован в буфер обмена? -clip именно оттуда его и возьмет. После чего отдаст функции, и она будет искать файлы уже в другом каталоге. Пример:
В буфере обмена находится "C:\Program Files"


Ну а если в буфере обмена не содержится правильного пути, функция отдаст ошибку и успокоится на этом:
В буфере обмена находится "C:\Program Files111"


Посмотрим, как покажет себя этот код в боевых условиях...

@музыка: Shamis Khassenov - Orhon

@темы: PowerShell, Scripting

14:40 

Powershell and Firewall

Stance Dance

По мотивам спонтанно возникшего обсуждения файрволлов и их правил.
Лезем разбираться со встроенным файром в Windows 8+. В Powershell наконец-то сделали целый набор команд, который позволяет управлять правилами местного межсетевого экрана. Как и все остальное, эти правила базируются на простых словах: New-/Get-/Set-/Remove-/Enable-/Disable-NetFirewallRule с соотвествующим набором ключей. Но как же "интересно" это все работает.
Итак, для примера создадим через Powershell сетевое правило для Блокнота (да, знаю, что бред, но убивали и за меньшее некоторые люди и на Калькуляторе файры тестировали ;) ):

new-netfirewallrule -name "Test Rule" -displayname "Test Rule" -program "c:\windows\system32\notepad.exe" -direction outbound -protocol tcp -localport 11223 -remoteport 25 -group "Test Group"

Правило будет создано, автоматом будет включено, и, согласно последнему ключу, будет помещено в группу Test Group.

Казалось бы, все хорошо. Да не тут-то было:

В частности, будет начисто заблокирована возможность менять путь к контролируемой программе и порты, по которым она сможет общаться с сетью. В то же время если создать такое же правило в GUI руками - все работает. DAFUQ?

Проверяем одну маленькую догадку. Удаляем все созданные правила и создаем его заново:

new-netfirewallrule -name "Test Rule" -displayname "Test Rule" -program "c:\windows\system32\notepad.exe" -direction outbound -protocol tcp -localport 11223 -remoteport 25

То есть не записываем новое правило в какую-либо группу. На выходе получаем полностью редактируемое любыми средствами правило.

Проверяем еще одно предположение. Удаляем теперь уже нормальное правило, создаем заново правило в группе, используя самую первую команду, чтобы получить заблокированное. А потом даем следующее:

set-netfirewallrule -name "Test Rule" -remoteport 30

После чего обновляем GUI консоль с правилами и лезем в настройки. Удаленный порт, который изначально стоял равным 25, принял значение 30. То есть получается, что Windows (в данном случае 2012) все правила, добавленные в какие-либо группы, считает созданными ей же по-умолчанию, и ничего не дает менять через графику, но спокойно позволяет менять что-либо через черный ход Powershell. Чудны дела твои, MS, хотя подобный подход уже был реализован, например, в Exchange, где через графику даже видно далеко не все.

Ради интереса попробовал поиграться с группой, в которую это правило было утрамбовано. Нифига. Единственным методом исправить группу или удалить правило из группы - удалить правило и создать его в другой группе или вообще без нее, если нужно именно это. Более того, среди всех команд Powershell нет вообще ничего, что работало бы именно с группами, а не правилами. Печально это. Выходит, что старый netsh еще не совсем вышел из моды, а вот с ним мне подружиться так и не удалось :(

@музыка: Sandra - Around my Heart (2006 edition)

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

01:32 

Network configuration

Stance Dance

Тот самый случай, когда понимаешь, что Powershell не всесилен. Точнее не так: не во всех операциях он однозначно и безусловно удобнее, чем опостылевший GUI. Да, речь о настройках сетевых адаптеров.
Конечно, в случае энтерпрайзов начальные настройки сетевух серверы получают посредством DHCP, и это правильно. А как уже дальше будет настроен тот или иной сервер - дело десятое. Но попадаются случаи, где DHCP нет, а сервер поднять надо. Если он поднят в редации Full - проблем не возникает, пощелкал мышкой, вбил требуемое, закрыл окна. А если это Core?

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

Итак. Делается настройка сети в несколько этапов.
Этап первый. Получаем индекс того сетевого адаптера, над которым будем производить все действия. По дефолту первый (с которым чаще всего и приходится работать) адаптер обладает индексом 12. Все последующие шаги будут проводиться именно над ним.
Этап второй. Сбрасываем информацию об уже имеющемся адресе. В условиях отсутствия DHCP там будет стоять APIPA-адрес.
Этап третий. Назначаем адаптеру новый адрес и маску подсети. Внимательные люди сразу спросят - а как же шлюз по-умолчанию? Он же в той же группе контролов в GUI, что и адрес с маской. А вот шлюз будет задан позже и совершенно другой командой.
Этап четвертый. Сбрасываем информацию о шлюзе по-умолчанию, если она имеется. На свежеустановленном сервере с APIPA-адресом ее не будет, но мало ли. Интересно, что среди всех команд powershell есть команда set-netroute, но применить ее именно к шлюзу по-умолчанию, чтобы его исправить, не получится.
Этап пятый. Прописываем нужный нам адрес в качестве шлюза.
Этап шестой. Прописываем адреса DNS-серверов, если это требуется.

Вот такой список. Теперь как это выглядит в коде Powershell.



Вот такой код в своем самом базовом и простом сценарии с одним сетевым адаптером. Если их больше, то и работы скрипту добавится. Хотя логика будет та же.
Все же прощелкать окошки, действительно, проще. С другой стороны, на некоторых достаточно древних железках каждая прогрузка каждого окна займет уйму времени, а powershell-консоль запускается ровно один раз и выполняет все разом.

@музыка: Sandra - Heaven can wait (эх, далекое зеленое нубство...)

@темы: PowerShell, Scripting

19:04 

SQL via Powershell

Stance Dance

Делать было решительно нечего, а идея витала в воздухе давно. Небольшой скрипт с шаблонами для работы с SQL сервером (в частности, MS SQL). Возможно, пригодится в самом ближайшем будущем. Ну а если не только мне - буду рад.

@музыка: Bryan El - Solaris

@темы: PowerShell, Scripting

17:46 

DPM 2012 Data Source Migration

Stance Dance

KnV-программирование, говорите? Их есть у нас. Точнее, не у нас, а в Редмонде. А еще точнее - в каком-нибудь из Соединенных Штатов Индии.
Есть два файловика-виртуалки. Есть у них диск D:, где все данные и лежат. Этот диск имеет свойство пухнуть, как и всякая файлопомойка. Размер VHD-файла с этим диском уперся в свой потолок в 2 Тб (старый vhd). А расширять надо. Ну что же, процедура следующая.
Внутри виртуалки-файлопомойки переводим этот диск в состояние Offline.
В консоли Hyper-V выносим нафиг файл vhd и на его месте создаем новый vhdx с требуемым объемом (vhdx поддерживает файлы больше 2 Тб).
Снова переходим в виртуалку. Находим там свежий диск, переводим его в состояние Online, инициализируем, форматируем, даем прежнюю букву, и говорим развернутой на этом сервере DFSR - а теперь, родная, реплицируй все данные с сервера-партнера. DFSR козырнула и пошла жрать файлы.

А тем временем начинает вопить DPM. Суть в следующем. Когда в DPM в группу защиты добавляем сервер и его какой-либо диск, диск этот идентифицируется не по букве, а по своему GUID (да, опять GUID, снова GUID). Когда файлопомойке дали новый диск, естественно сменился GUID этого диска. И теперь встает вопрос - что делать с группой защиты, как в нее добавить новый диск.

Можно вынести оттуда старый и добавить новый. При попытке провернуть такой фокус DPM вопит, что бекапы, связанные со старым диском, станут невалидными (то есть придется снимать заново полный бекап в те 2 терабайта, а это время).
Можно попытаться связать запись в группе защиты об этом диске с новым GUID диска. Вот это нам и нужно.

Для такого переноса существует специальный скрипт, написанный где-то в недрах MS, который называется Migrate-Datasource.ps1. Вот статья, объясняющая, что это и как оно работает.

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

Exception calling "MigrateDataSource" with "2" argument(s): "The remote
procedure call failed. (Exception from HRESULT: 0x800706BE)"

At C:\Program Files\Microsoft System Center 2012
R2\DPM\DPM\bin\Migrate-DataSource.ps1:220 char:10
+ $dpmServer.MigrateDataSource($newDataSourceId, $oldDataSourceId)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException

Error in Migration

Хм, все веселее и веселее. Ладно, а что ты мне покажешь в ручном режиме? А в ручном режиме оно мне предложило выбрать запись о диске, которую надо исправить, вывело список всех дисков (их GUIDов), которые можно к нашей многострадальной записи подцепить. Этих дисков оказалась ровно 1 штука. И я не знаю, что меня дернуло просмотреть, а кому этот GUID принадлежит, но увиденное заставило отменить скрипт от греха подальше. Дело в том, что предложенный GUID принадлежал MSR-разделу файлопомойки.

Даа, делаа... Поскольку дело было уже поздним вечером, решили эту проблему отложить до утра, чтобы окинуть ее потом свежим взглядом. Вернулись к ней только спустя дня эдак 4. И что бы мы ни делали с этим скриптом, результатом всегда было только одно - предложение связать запись в группе защиты с MSR-партицией. Черт с ним, все равно приближается время полного бекапа, так что уже были готовы убить старую запись и добавить новую. Да не тут-то было:
- Народ, а вы гляньте на последнюю точку восстановления!
- Вчера сделалась? Но ведь бекап не работал?
- Андрюха, походу после этого твоего скрипта бекап все же починился.
И действительно, бекап-то шел, как и полагалось, создалась новая точка восстановления. То есть, источник данных все же мигрировал на новый диск. А теперь поднимаем глаза выше, снова читаем надпись Error in Migration.
Становится понятным, почему провалилась попытка ручной миграции. Потому что новый диск уже был связан с записью в группе защиты и не был доступным для этой операции, только и осталось, что бедную мелкую MSR предложить.

Вот такие индийские скрипты пишутся для Data Protection Manager 2012. Хорошо еще, что хотя бы они есть, тут подсказывают, что в предыдущих версиях нужно было непосредственно базу данных DPM препарировать...

В поднятой в целях теста лаборатории этот же скрипт в такой же ситуации отработал на все сто. Далее много-много непечатного, потому печатать не буду.

Симантек, я, помнится, тебя материл безбожно. Как тут не вспомнить старое-доброе: "Вася! Если сможешь - прости!!!"

@музыка: Metal Gear Rising OST - Denver

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

13:02 

Network, profiles, ports...

Stance Dance

Казалось бы, ничто не предвещало. Ну выключили все оборудование на одной из площадок (шли работы с электричеством). Ну включили его назад, проверили, что все работает, оно и работает. А SCOM ни с того, ни с сего начал вопить, что на гипервизорах Win 2012 по какой-то причине закрыты порты для файлового обмена. И это при том, что на шары тех серверов вполне себе заходишь, все, что надо, видишь. Что за напасть?
Коллега подсказал, что такое возникает в случае, если гипервизор был поднят раньше контроллера домена, и сетевой профиль сбросился с доменного на публичный. Ну а исправлять это, соответственно, перезагрузкой гипервизора при уже живом контроллере.
В этот раз по такому проверенному методу и пошли, перезагрузили гипервизоры. Но ведь неправильно это, должен быть метод сброса профиля на правильный.
Начинаем ковырять. Согласно всемирному разуму, за профили сетей у нас отвечает служба Network Location Awareness (NLA). А что, если ее перезапустить при работающем сервере в ситуации, когда контроллер домена уже жив? Настраиваем небольшую лабораторию: один контроллер на 2008 (выше все равно не поставлю ибо x86 only) и одна ВМ под управлением Windows 7 - она исполнит роль того сервера-гипервизора, что нужно вылечить. Лаборатория поднялась, все отлично. Тушим ее и поднимаем только Windows 7. Так и есть, профиль сети, которая ранее была Domain Network - example.com теперь стала неопознанной публичной сетью. Замечательно, даем рестарт службы NLA. И тут нас поджидает фейл, не смогла она остановиться.
Как же так? А вот как. В дочерних службах NLA указана еще одна - Network List Service. Она заведует списками профилей. И ее тоже надо потушить. И как раз на стадии выключения этой дочерней службы получаем ошибку "Can't stop service...". Причем ссылается ОС на внутреннюю ошибку либо в этой службе, либо в самой ОС, и, как всегда, предлагает обратиться к системному администратору (а я кто, по-твоему?!). Как же тебя корректно потушить. А что если воспользоваться старым грязным хаком, который я уже и не вспомню, откуда в моей голове - сменить тип запуска службы? Меняем на Disabled и пробуем остановить - потухла. Замечательно, теперь очередь их поднять. Сначала поднимаем дочернюю, предварительно выставив ей тип запуска Manual (именно в таком режиме она по-умолчанию). Поднялась. Теперь запускаем NLA - взлетела. Смотрим на профиль сети - Domain network - example.com. Что и требовалось.
Проверка номер два - а теряется ли в этот момент сетевое соединение с "гипервизором". По логике вещей не должно теряться, но если возникло сомнение - проверяй. Повторяем эксперимент, добавив в лабу третью ВМ - рабочую станцию администратора. Запускаем на ней пинг к гипервизору и прямо с нее проводим рестарт служб. Все отлично, "ни единого разрыва" (с). Плюс одна монета в копилку знаний.
На будущее оформляем все в виде скрипта:

@музыка: Ryan Farish - Let it rain

@темы: PowerShell, Scripting

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

главная