We rise up for the things we believe in over and over again

Даже не знаю, с чего начать. Наверное, с начала.
По роду своей деятельности возникает нужда массовой замены паролей от интерфейсов управления серверного хозяйства. Политики безопасности, все дела, никуда от этого не денешься. И чем дальше, тем более это хозяйство обширное. Но не только по числу севреров, но и по количеству вендоров. Когда серверов штук пять-десять - зайти на каждый из них да поменять пароль от учетки не шибко сложно. Когда их пара-тройка десятков, уже напряжно, но тоже терпимо (сквозь сжатые зубы). Когда число переваливает за сотню - это уже ни в какие ворота. И ладно, если еще ты знаешь, когда очередной дедлайн, можно распланировать. А если задачу спускают внезапно со вполне себе официальным "это должно быть сделано вчера" - волей неволей задумаешься хоть о какой-нибудь, но автоматизации. Вот и в этот раз.
Я уже не помню, чем меня взбесил стандартный инструмент под названием ipmitool, но тогда я пришел к выводу, что это совершенно неюзабельная шляпа. И пришлось колхозить связку Powershell + Rest API. Этот подход работал, пока вендор был один. Когда их число начало увеличиваться, начало увеличиваться и количество скриптов, потому что каждый вендор ваяет свою версию OpenBMC, перекраивая форматы запросов и ответов под себя. В итоге текущий подход меня перестал удовлетворять от слова совсем, и я снова пришел к изначальному вопросу - как это автоматизировать. И снова таки вернулся к ipmitool.
В этой итерации в общем и целом все получилось. Алгоритм набросал, осталось только выбрать, на чем его реализовывать. И вариантов, как ни странно, аж целых несколько, и продиктовано их наличие некоторыми вводными.
1. Можем взять... bash. Внезапно, да. В целом это даже полезно, но загвоздка в том, что не всюду есть возможность дотянуться со своей станции управления под никсами. А туда, куда можно дотянуться, сделать это можно только из под виндов. Да, постепенно отмирает и винда, но пока еще живет. И ускорить этот процесс не в моих силах.
2. Можем взять... cmd. Тоже внезапно. Этот курилка есть гарантировано везде, где мне приходится работать.
3. Можем взять... да-да, название записи говорит обо всем - старую добрую "мощную ракушку".
И на этот раз я решил пойти немного более заковыристым путем - реализовать алгоритм смены пароля через ipmitool во всех перечисленных оболочках. Что тут сказать, результаты меня удивили. ОЧЕНЬ удивили.
Начнем с того, что нужный скрипт на баше, который я не перевариваю, был написан где-то минут за 20. Повторю - я ненавижу баш. Ну да ладно, написал, и написал, нужно идти дальше. Берем в руки cmd и блонот, и... мама мия. Я баш не любил, да? Как вам такое, Илоны вы наши Маски:
- блджад. В зависимости от того, где была объявлена переменная, вызывается в скрипте она ТРЕМЯ разными способами... Это ж просто азаза...
- ?
если объявлена просто в плоском скрипте:
set var=byaka
echo %var%
byaka
- Угу.
- если объявлена в FOR как переменная цикла:
FOR /F "tokens=1" %%I... (
echo I
)
- echo %%I ?
- да, забыл проценты набрать. Если же переменная объявлена внутри FOR:
set c=ipmitool -H %%I...
echo !c!
И да, в этом случае еще и специальную инструкцию не забудь про SETLOCAL EnableDelayedExpansion, про который я, к своему стыду, вообще только сегодня узнал. Твою ж налево, а... Но ладно, с грехом пополам, незнамо сколько кружками зеленого чая (кофемашина сломалась, живо напомнив мне 4-ю книгу цикла Экспансия, кто знает, тот знает) и огромного количества матов в голове и эту реализацию удалось допилить до логического конца.
Осталась ракушка. И черт побери, тут я могу лишь вспомнить слова, подсмотренные в сети, используемые в достаточно пикантной ситуации: Light has failed me. В том плане, что чертова ракушка, служившая мне верой и правдой, столько лет, и дававшая приют и защиту от всякого скриптописательного, разлетелась вдребезги.
Итак, в прошлом уже доводилось нарываться: раз и два. В той истории из двух актов Powershell не фигурировал, зато сама история накрепко вбила в голову истину, что передавать пароли через переменную нужно используя одинарные кавычки, и ни в коем случае не двойные. Почему - там было расписано. Пишем:
Иии... это не работает. Переменная с паролем все равно раскрывается черт знает во что. Несмотря на использовании нужных кавычек во время ее определения. Но где тогда идет раскрытие? Да, как оказалось, прямо в строке Invoke-expression и идет, там ведь как раз стоят двойные, и без них никуда.
Окей, и что делать? Как выяснилось, вариантов обхода целых две штуки. Первый - это использовать экранирование каждого спец.символа в пароле:
Такой вариант вполне себе прокатывает, но поскольку скриптом буду пользоваться не я один, кто-нибудь определенно забудет про эти экраны. Будет плохо.
Второй вариант - вывести все переменные, которые касаются паролей (а их будет две - старый и новый пароли) из кавычек вообще. Пришлось нагородить примерно такое:
И вот этот вариант уже не требует никакой доработки напильником.
Что ж, в итоге все равно остановился на Powershell-варианте, но реализации на cmd и баше лежат под рукой. На всякий случай.
Проблема в том, что их изначально не было, поэтому они прикурчены как нафига козе баян. Синтаксис фор-а заставляет меня плакать и каждый раз читать ман. Самое паршивое, что при отладке в цмд.ехе фор надо писать с переменными через процент. А в цмд-файле через два процента. Почемууу! Почем унельзя было сделать одинаково? Может взять было какой-нибудь другой символ, например решётку, который воспринимается везде одинаково?..