{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Лайвлупинг, медиапродакшн и все эти ваши компьютеры: заметки с тегом PowerShell",
    "_rss_description": "Алексей Батищев. Заметки обо всём, что происходит со мной и окружающим миром",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/batishchev.ru\/blog\/tags\/powershell\/",
    "feed_url": "https:\/\/batishchev.ru\/blog\/tags\/powershell\/json\/",
    "icon": "https:\/\/batishchev.ru\/blog\/pictures\/userpic\/userpic@2x.jpg?1604346823",
    "authors": [
        {
            "name": "Алексей Батищев",
            "url": "https:\/\/batishchev.ru\/blog\/",
            "avatar": "https:\/\/batishchev.ru\/blog\/pictures\/userpic\/userpic@2x.jpg?1604346823"
        }
    ],
    "items": [
        {
            "id": "3843",
            "url": "https:\/\/batishchev.ru\/blog\/all\/zametki-ii-emeli\/",
            "title": "Заметки ИИ-Емели",
            "content_html": "<p>Подумал на днях, что возможности, которые дают нам сейчас нейросети, способны превратить каждого в эдакого современного цифрового Емелю: знай себе придумывай что угодно около-цифровое, и по своему хотенью, да по клодову веленью получай желаемое почти что мгновенно, и почти что бесплатно.<\/p>\n<p>В быту  у меня такие хотелки возникают (или всплывают из памяти) в последнее время всё реже, как будто самое насущное и давно вожделенное переделано. Зато очередные проекты выходят всё продуманней и глубже — приноравливаешься к инструменту, вот и мастерписы получаются всё инкрэдиблней и инкрэдиблней<\/p>\n<p>Про работу же и говорить нечего — там задачи никогда не заканчиваются, но с ассистентами выходит фигачить их быстрее, и лучше, а еще позволяешь себе браться и колоть проблемы, которые силами одного кожаного наверное и не выполнить в реальные сроки совсем.<\/p>\n<p>Расскажу про очередные несколько кейсов, как уже делал тут в блоге не раз<\/p>\n<h2>Реверс-инжиниринг тайного API<\/h2>\n<p>Наверное этот пример будет не очень понятен не-погруженным в разработку и компы читателям, но профильных спецов должно впечатлить. Если 8 месяцев назад я был очарован тем, как агент по спецификации API внешнего сервиса написал мне класс для работы с ним, то на прошлой неделе тут была взята новая вершина. Так вышло, что у очередного сервиса не было документации API. Так вот, все его возможности агент смог отреверсить сам — просто я дал ему креды для входа в веб интерфейс системы, после чего агент увидел в коде страницы javascript который работал с ручками api, и выдернул из его кода всё что мог, а остальное дораскопал, проверяя и пробуя типовые вызовы.<\/p>\n<p>Это сложная работа для фуллстек программиста, за которую в силу объёма и сложности я бы наверное не взялся — а ассистент смог. Просто невероятно<\/p>\n<h2>Безопасность и клон расширения для музыки ВК<\/h2>\n<p><a href=\"https:\/\/batishchev.ru\/blog\/all\/zapozdaly-anons\/\">Две недели назад<\/a> мне понадобилась одна mp3 и ещё пара видео, которые лет 10 назад выложил в ВК мой друг, и которых нигде больше не было. Подручные привычные средства не сработали, я попросил агента достать мне эти записи, и он, пошуршав довольно долго и перепробовав дикое количество гипотез, вытащить их всё-таки смог, попутно разобравшись в алгоритмах стриминга записей соцсетью.<\/p>\n<p>Тогда же я решил, что хочу вытащить весь свой плейлист их вкашечки, так как там оставалось ещё несколько таких артефактов, а что будет дальше с доступами к ним непонятно. Я знал что существуют браузерные расширения для такого вот массового выдёргивания музыки и видео из соцсетей — но так же я всегда испытывал к ним недоверие, потому что сами понимаете, аккаунты-пароли, профеформация безопасника, вот это вот всё.<\/p>\n<p>И я подумал: так пусть мне умный робот всё расскажет. В итоге, спустя 40 минут исследований и моих уточняющих вопросов, у меня появился полный анализ одного из самых популярных таких браузерных расширений, а также возможность полностью его пересоздать-клонировать с нуля если я захочу. Ну и главное, теперь есть точные сведения относительно его безопасности (если кратко — использовать конкретную актуальную версию можно, она ничего не ворует, хотя лишнюю статистику о вас как о пользователе соцсети, хоязевам расширения зачем-то сливает).<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-09-26-ext.png\" width=\"1168.3508102955\" height=\"800\" alt=\"\" \/>\n<\/div>\n<p>То есть, взмахом руки в кафтане (и потратив немножко рублей на токены) я получил себе полуфабрикат клона чужого продукта, всё что нужно для его повторения без авторов, и вдобавок аудит безопасности их решения. Ничо так, без отдела разработки и группы аппсеков в подчинении??<\/p>\n<h2>Кодировщик видосов Видак<\/h2>\n<p>Будучи старым павершелл-рециидивистом, перекодирование видео в целях домашнего архива итп я давно поставил на программную ногу, написав скрипт для запуска кодирования через ffmpeg c выбором нужных именно мне, с учетом потребностей и возможностей железа, параметров. Скрипт строился постепенно, долго, с кропотливым подбором опций и экспериментами, и в результате стал довольно громоздким. Плюс прогресс и кодировщики не стоят на месте, плюс поменялся комп — короче, штука для облегчения жизни стала требовать для своей поддержки слишком много этой самой жизни.<\/p>\n<p>Уточню, что я в курсе про HandBrake, и вообще этих ваших виртуалдабов повидал в жизни немало, но ни один из этих готовых инструментов не даёт мне нужного уровня контроля над качеством и скоростью кодировки.<\/p>\n<p>Ну так вот, однажды вечером я сел и написал (надиктовал) ТЗ на инструмент мечты — чтобы всё было ещё удобней и универсальней, чтобы режимы работали автоматически и умнО, чтобы перламутровые пуговицы и стразы там где надо. Доработал ТЗ в несколько сессий уточнения хотелок, запустил разработку, получил результат и еще пару дней в фоновом режиме его отлаживал-допиливал, находя косяки, придираясь к мелочам и придумывая новые свистелки на ходу.<\/p>\n<p>И теперь у меня есть ультимативный идеально решающий мои задачи комбайн, который я еще и допилить в любую секнуду любой фичей могу. Мог ли я написать такое сам — да. Стал бы делать с учетом трудоёмкости — вряд ли. Кайфую ли я от результата и пользуюсь ли новой автоматизацией в хвост и в гриву — конечно! Чудесный КЭНК будущего, натурально.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-09-25-vidak.png\" width=\"1627.3641851107\" height=\"800\" alt=\"\" \/>\n<\/div>\n<h2>Всякое по мелочи<\/h2>\n<p>Блогер упомянул про информацию, обсуждавшуюся в фрагменте интервью, и дал ссылку на запись эфира в 4 часа длиной, без уточнения таймкода. Фигак — и место обнаружено, и точная цитата у меня есть.<\/p>\n<p>За трендами в ии-разработке и прочим похожим я слежу читая раз в пару недель рекапы нескольких каналов и чатов энтузиастов. Пока ничего важного не пропустил )<\/p>\n<p>Ну и из прикольного на стыке цифры и реальности — на неделе терапевт назначил мне анализы для проверки диагноза и сказал вернуться с ними для расшифровки и уточнения рекомендаций. Я сделал анализы, после чего мой личный доктор Марина Сергеевна изучила выгрузки назначений и результатов, подтвердила мнение терапевта, его диагноз и способ лечения. Необходимость в дополнительном приёме пропала — час времени из жизни можно потратить на что-то другое. Да кстати, Маринсергевна — агент с ролью семейного доктора, который знает все истории болезней (которые я вспомнил или смог найти в цифровом виде), не забывает всякие важные даты и детали, понимает меня как облупленного, короче классный спец и мировая тётка, даром что кремниевая.<\/p>\n<p>Дивные времена, дивные.<\/p>\n<p>Всем сказка, посоны!<\/p>\n",
            "summary": "Подумал на днях, что возможности, которые дают нам сейчас нейросети, способны превратить каждого в эдакого современного цифрового Емелю",
            "date_published": "2026-10-01T17:53:00+03:00",
            "date_modified": "2026-09-26T17:01:09+03:00",
            "tags": [
                "PowerShell",
                "ИИ",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/2026-09-26-ext.png",
            "_date_published_rfc2822": "Thu, 01 Oct 2026 17:53:00 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "3843",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-09-26-ext.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-09-25-vidak.png"
                ]
            }
        },
        {
            "id": "3825",
            "url": "https:\/\/batishchev.ru\/blog\/all\/dyadya-klodya-videomontazher\/",
            "title": "Дядя Клодя — видеомонтажер",
            "content_html": "<p>Продолжим рассказ про нейросети и видеомонтаж. Сегодня расскажу о трех похожих кейсах — как с помощью нейросетей я автоматизировал рутинные действия при обработке видео.<\/p>\n<h2>Авторазмывашка вертикальных видео<\/h2>\n<p>В капкате есть удобная настройка, когда буквально одним кликом ты обеспечиваешь себе, что любое попавшее в монтаж горизонтального ролика вертикальное видео, будет дополнено зазумленной и размытой собственной версией на фоне, таким образом убирая черные полосы сбоку (ну или сверху-снизу, для вертикального таймлайна). Ну, это стандарт де-факто, вы всё это видели мильён раз в соцсетях. Как такое же сделать в давинчи? Довольно просто: всего лишь нужно с каждым таким фрагментом провести стотыщ операций вручную. Это тот самый знаменитый утконос-монтаж от ребят из Австралии, если вы пропустили прошлый пост.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30image-10.png\" width=\"1409.6601073345\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Туториал по созданию Blanking Fill, о лёгком применении которого в 2026 сами авторы давинчи кажется не задумываются.<\/div>\n<\/div>\n<p>Я собирал кино про отпуск, и часть кадров тогда была снята вертикально. Обработав пару таких кейсов на таймлайне в Давинчи, я взвыл и пошел к Клоду. Тот подтвердил, что человеческого способа в Давинчи не существует. И тут я подумал, а нельзя ли эти материалы обработать массово и автоматически? Пара промптов, несколько тестовых итераций — и вот уже у меня есть свежеиспечённый клодом powershell скрипт, который в папке с роликами находит все вертикальные и генерит для них искомую горизонтальную замену с зазумленной размытой копией на фоне, и всё это без моего участия.<\/p>\n<p>Теперь перед сборкой ролика я в один клик заменяю в папке с исходниками вертикалки на готовые горизонтальные сниппеты и фигачу кино из них, не делая ни одного лишнего движения.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30-10.png\" width=\"664.57142857143\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Готовая blanking fill сцена на таймлайне, созданная автоматически из вертикального фрагмента<\/div>\n<\/div>\n<h2>Турбо-слайдшоу<\/h2>\n<p>Ещё один типовой приём, который я часто использую, например для вступительной части кино — нагенерить слайдшоу из самых ярких фоток путешествия. Это классно делает iMovie, но в этот раз мне было лень для этого специально закидывать в галерею телефона старые фотки, да и способности Клода было интересно проверить. Оказалось, что актуальные версии ffmpeg умеют в разнообразные переходы, и с их использованием можно тоже нафигачить абсолютно автоматически слайдшоу с нужными параметрами кадра и длительности, и суперэффектами из влажных мечт любого свадебного видеографа нулевых. Клод написал мне кастомизируемый скрипт, который я просто могу натравить на папку с фотками и получить готовый видеоряд. Пушка, бомба, ультравосторг.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-31-image-11.png\" width=\"1024.7452692868\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Готовое слайдшоу на таймлайне и невероятный эффект перехода в кадре<\/div>\n<\/div>\n<h2>Рилсособиратель<\/h2>\n<p>Кейс от которого меня щас прёт больше всего. В этом году я пропустил абсолютно эпически смытую ливнями до состояния грязеваля Бессонницу, а все кто прошел это событие активно делились впечатлениями в соцсетях. Я решил собрать мини-кино на память, но с минимумом затрат сил. В течение нескольких дней я просто скидывал себе в телегу ссылки на наиболее яркие и эпичные рилсы с кадрами с события, которые попадались в запретограмме. Потом я дал список клоду и попросил его написать скрипт, который будет скачивать рилсы через yt-dlp, по уже отработанному сценарию делать из вертикалок автозаполненные фоном горизонталки, дополнительно добавлять в кадр титр с аккаунтом автора, и склеивать все эти фрагменты в единый ролик. Пара итераций на отладку мелочей типа шрифта — и фигак, у меня есть киношка на 19 минут про фест, а также инструмент чтобы сделать такое же из любого другого набора рилсов.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30-vlcsnap.png\" width=\"1422.2222222222\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Стоп-кадр из готового ролика про Бессонницу<\/div>\n<\/div>\n<p>Теперь, когда роботы захватят власть и уничтожат человечество, мне будет что вспомнить и что посмотреть на садящемся заряде смартфона. Всё не зря.<\/p>\n<p>Выложил скрипты <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-video-tools\">на гитхаб<\/a>, хотя если у вас есть нейросеть, всё это генерится под ваш кастомный запрос сейчас просто и элементарно<\/p>\n<p>Слава роботам!<\/p>\n<p>Всем IEEE1394, посоны!<\/p>\n",
            "summary": "Продолжим рассказ про нейросети и видеомонтаж. Сегодня расскажу о трех похожих кейсах — как с помощью нейросетей я автоматизировал рутинные действия при обработке видео",
            "date_published": "2026-07-31T13:20:59+03:00",
            "date_modified": "2026-07-31T13:22:11+03:00",
            "tags": [
                "PowerShell",
                "ИИ",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30image-10.png",
            "_date_published_rfc2822": "Fri, 31 Jul 2026 13:20:59 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "3825",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30image-10.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30-10.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-31-image-11.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-30-vlcsnap.png"
                ]
            }
        },
        {
            "id": "3821",
            "url": "https:\/\/batishchev.ru\/blog\/all\/kirillicheskiy-rezident-peredayot-iz-klodlyandii\/",
            "title": "Кириллический резидент передаёт из Клодляндии",
            "content_html": "<p>Как уже в курсе любимый читатель, мы живем в эпоху искусственного интеллекта и агентской разработки. ИИшечки пишут код, код работает, все счастливы. Но есть одна проблема — всё около-иишное как правило живёт и мыслится в окружении macOS\/Linux и в контексте в первую очередь питона. А что делать, если ты хочешь использовать иишку для разработки на павершелле и использовать Клода в среде Виндоуз? Ответ по умолчанию — страдать.<\/p>\n<p>Чтобы не было проблем с кириллицей, скрипты нужно хранить в UTF-16 LE с BOM — так их одинаково однозначно опознают что PowerShell 5.1, что pwsh 7+, что тестовые редакторы под Windows, что git\/gitlab, и все живут дружно. А вот Claude Code с его встроенными инструментами `Edit` и `Write` живёт только в своей реальности UTF-8 и плевать хотел, в какой кодировке был файл. А поэтому и читать-редактировать старые наработки по умолчанию не может, и новое пишет сломанное.<\/p>\n<p>Проблема <a href=\"https:\/\/github.com\/anthropics\/claude-code\/issues\/7134\">старая<\/a> и <a href=\"https:\/\/github.com\/anthropics\/claude-code\/issues\/28316\">известная<\/a>, но как ’это часто бывает с корнер кейсами, проблемы индейцев шерифа не волнуют — ни фикса, ни какой-либо настройки для клода не существует и, скорее всего, <a href=\"https:\/\/github.com\/anthropics\/claude-code\/issues\/62862\">не предвидится<\/a>. ИЧСХ, проблема тут не только кириллическая, у японцев например ровно та же беда, только с Shift_JIS вместо UTF-16. Но кому какое дело до этих ваших туземных особенностей?<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11-2.png\" width=\"1342.2818791946\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">карта мира по мнению программистов (гипотеза)<\/div>\n<\/div>\n<p>Сразу как только я наступил на эти грабли, родился обходной маневр: инструкцией в CLAUDE.md агенту было сказано для редактирования PowerShell скриптов делать построчную замену вызовом того же PowerShell. И это в целом работало, но сильно замедляло (и часто ломало) процесс — решение было кустарным, хрупким, и разрешение спрашивалось на каждый чих. Агент регулярно забывал инструкции, а чтобы вспомнить сначала бегло бежал по садовому инвентарю, отнимая моё время, нервные клетки, и тратя драгоценные токены.<\/p>\n<p>Сегодня, устав от очередной порчи скрипта при небольшом изменении, я отправил агента в рисёрч с требованием раз и навсегда решить проблему в корне. Клод обнаружил в интернетах братьев-японцев и других потерпевших, но главное — придумал использовать хуки, которые прозрачно конвертируют файл туда-обратно при редактировании встроенными инструментами. Я затестил и это работает. Щас расскажу.<\/p>\n<h2>Доктор Крюк, или как я перестал страдать и полюбил хуки<\/h2>\n<p>У Claude Code есть `PreToolUse`\/`PostToolUse`\/`Stop` hooks — команды, которые выполняются автоматически вокруг вызовов инструментов. Идея простая: пусть файл на диске «в покое» всегда лежит в UTF-16 LE, а хуки на лету превращают его в UTF-8 непосредственно перед тем, как его коснётся Read\/Edit\/Write, и обратно — сразу после. Модель вообще не должна догадываться, что файл когда-то был не в UTF-8.<\/p>\n<p>Настройки хуков в  ~\/.claude\/settings.json:<\/p>\n<pre class=\"e2-text-code\"><code class=\"json\">&quot;hooks&quot;: {\n  &quot;PreToolUse&quot;: [\n    {\n      &quot;matcher&quot;: &quot;Read|Edit&quot;,\n      &quot;hooks&quot;: [{\n        &quot;type&quot;: &quot;command&quot;,\n        &quot;command&quot;: &quot;C:\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe&quot;,\n        &quot;args&quot;: [&quot;-NoProfile&quot;, &quot;-File&quot;, &quot;C:\\\\Users\\\\[USER]\\\\.claude\\\\hooks\\\\ps1-pre-encoding.ps1&quot;]\n      }]\n    }\n  ],\n  &quot;PostToolUse&quot;: [\n    {\n      &quot;matcher&quot;: &quot;Edit|Write&quot;,\n      &quot;hooks&quot;: [{\n        &quot;type&quot;: &quot;command&quot;,\n        &quot;command&quot;: &quot;C:\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe&quot;,\n        &quot;args&quot;: [&quot;-NoProfile&quot;, &quot;-File&quot;, &quot;C:\\\\Users\\\\[USER]\\\\.claude\\\\hooks\\\\ps1-post-encoding.ps1&quot;]\n      }]\n    }\n  ],\n  &quot;Stop&quot;: [\n    {\n      &quot;hooks&quot;: [{\n        &quot;type&quot;: &quot;command&quot;,\n        &quot;command&quot;: &quot;C:\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe&quot;,\n        &quot;args&quot;: [&quot;-NoProfile&quot;, &quot;-File&quot;, &quot;C:\\\\Users\\\\[USER]\\\\.claude\\\\hooks\\\\ps1-restore-all.ps1&quot;]\n      }]\n    }\n  ]\n}<\/code><\/pre><p>pre-encoding.ps1 (перед Read\/Edit — если увидел BOM UTF-16 LE, конвертирует в UTF-8 и запоминает путь):<\/p>\n<pre class=\"e2-text-code\"><code class=\"powershell\">$ErrorActionPreference = &#039;Stop&#039;\n$stateFile = &quot;C:\\Users\\[USER]\\.claude\\hooks\\ps1-utf16-state.json&quot;\n$scopeRoot = &quot;[ВАШ ПУТЬ]&quot;\n\ntry {\n    $inputJson = [Console]::In.ReadToEnd()\n    $data = $inputJson | ConvertFrom-Json\n    $filePath = $data.tool_input.file_path\n\n    if (-not $filePath) { exit 0 }\n    if ($filePath -notmatch &#039;\\.ps1$&#039;) { exit 0 }\n    if (-not $filePath.StartsWith($scopeRoot, [System.StringComparison]::OrdinalIgnoreCase)) { exit 0 }\n    if (-not (Test-Path -LiteralPath $filePath -PathType Leaf)) { exit 0 }\n\n    $bytes = [System.IO.File]::ReadAllBytes($filePath)\n    if ($bytes.Length -ge 2 -and $bytes[0] -eq 0xFF -and $bytes[1] -eq 0xFE) {\n        $content = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::Unicode)\n        [System.IO.File]::WriteAllText($filePath, $content, (New-Object System.Text.UTF8Encoding($false)))\n\n        $state = @()\n        if (Test-Path -LiteralPath $stateFile) {\n            $raw = Get-Content -LiteralPath $stateFile -Raw -ErrorAction SilentlyContinue\n            if ($raw) { $state = @($raw | ConvertFrom-Json) }\n        }\n        if ($state -notcontains $filePath) { $state += $filePath }\n        ($state | ConvertTo-Json) | Set-Content -LiteralPath $stateFile -Encoding utf8\n    }\n} catch {\n    exit 0\n}\nexit 0<\/code><\/pre><p>post-encoding.ps1 (после Edit\/Write — конвертирует обратно в UTF-16 LE, но только файлы из стейта):<\/p>\n<pre class=\"e2-text-code\"><code class=\"powershell\">$ErrorActionPreference = &#039;Stop&#039;\n$stateFile = &quot;C:\\Users\\[USER]\\.claude\\hooks\\ps1-utf16-state.json&quot;\n\ntry {\n    $inputJson = [Console]::In.ReadToEnd()\n    $data = $inputJson | ConvertFrom-Json\n    $filePath = $data.tool_input.file_path\n\n    if (-not $filePath) { exit 0 }\n    if ($filePath -notmatch &#039;\\.ps1$&#039;) { exit 0 }\n    if (-not (Test-Path -LiteralPath $stateFile)) { exit 0 }\n\n    $raw = Get-Content -LiteralPath $stateFile -Raw -ErrorAction SilentlyContinue\n    if (-not $raw) { exit 0 }\n    $state = @($raw | ConvertFrom-Json)\n    if ($state -notcontains $filePath) { exit 0 }\n    if (-not (Test-Path -LiteralPath $filePath -PathType Leaf)) { exit 0 }\n\n    $content = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8)\n    [System.IO.File]::WriteAllText($filePath, $content, [System.Text.Encoding]::Unicode)\n\n    $state = @($state | Where-Object { $_ -ne $filePath })\n    ($state | ConvertTo-Json) | Set-Content -LiteralPath $stateFile -Encoding utf8\n} catch {\n    exit 0\n}\nexit 0<\/code><\/pre><p>restore-all.ps1 (Stop-хук — подчищает в конце хода всё, что осталось не восстановленным после одиночного Read без последующего Edit):<\/p>\n<pre class=\"e2-text-code\"><code class=\"powershell\">$ErrorActionPreference = &#039;Stop&#039;\n$stateFile = &quot;C:\\Users\\[USER]\\.claude\\hooks\\ps1-utf16-state.json&quot;\n\ntry {\n    [Console]::In.ReadToEnd() | Out-Null\n\n    if (-not (Test-Path -LiteralPath $stateFile)) { exit 0 }\n    $raw = Get-Content -LiteralPath $stateFile -Raw -ErrorAction SilentlyContinue\n    if (-not $raw) { exit 0 }\n    $state = @($raw | ConvertFrom-Json)\n\n    foreach ($filePath in $state) {\n        if (-not (Test-Path -LiteralPath $filePath -PathType Leaf)) { continue }\n        $bytes = [System.IO.File]::ReadAllBytes($filePath)\n        $isUtf16Le = $bytes.Length -ge 2 -and $bytes[0] -eq 0xFF -and $bytes[1] -eq 0xFE\n        if (-not $isUtf16Le) {\n            $content = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8)\n            [System.IO.File]::WriteAllText($filePath, $content, [System.Text.Encoding]::Unicode)\n        }\n    }\n\n    Set-Content -LiteralPath $stateFile -Value &quot;[]&quot; -Encoding utf8\n} catch {\n    exit 0\n}\nexit 0<\/code><\/pre><p>Собственно, делать эти настройки руками не нужно — просто скопипастите текст заметки в чат своему Клоду и попросите настроить так же.<\/p>\n<h2>Доклад окончен<\/h2>\n<p>Скрипты на диске и в git теперь всегда лежат в UTF-16 LE с BOM — ровно так, как его и ждёт PowerShell. Пока файла касается Claude Code — он на долю секунды «мигает» в UTF-8 и обратно, а модель работает через свои обычные беззаботные Edit\/Write. Роботы работают, человек не напрягается.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11-image-9.png\" width=\"1000\" height=\"798\" alt=\"\" \/>\n<\/div>\n<p>Важная тонкость — в скрипты зашита проверка на них самих, чтобы создавая-редактируя их Клод не попадал в бесконечную кодировочную петлю.<\/p>\n<p>Пойду, завайбкожу ещё что-нибудь.<\/p>\n<p>Слава роботам! КЭНК!<\/p>\n",
            "summary": "Как уже в курсе любимый читатель, мы живем в эпоху искусственного интеллекта и агентской разработки. ИИшечки пишут код, код работает, все счастливы",
            "date_published": "2026-07-12T20:42:19+03:00",
            "date_modified": "2026-07-12T20:36:13+03:00",
            "tags": [
                "PowerShell",
                "TG",
                "ИИ",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11.png",
            "_date_published_rfc2822": "Sun, 12 Jul 2026 20:42:19 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "3821",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11-1.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11-2.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-07-11-image-9.png"
                ]
            }
        },
        {
            "id": "3793",
            "url": "https:\/\/batishchev.ru\/blog\/all\/novy-reliz-vkachatora\/",
            "title": "Новый релиз ВКачатора",
            "content_html": "<p>Спустя <a href=\"https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-obnovlenie-vkachatora\/\">три года<\/a> подготовил и выпустил новый релиз ВКачатора — допилил много мелочей, до которых в прошлый раз не доходили руки, благо теперь Клод позволяет реализовывать идеи быстро и технологично. ЧуднО видеть код, на который я в своё время потратил уйму времени, и то как играючи его сейчас колбасит ИИшка<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2026-05-18-image-8.png\" width=\"914.75142624287\" height=\"800\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Приятные мелочи — аватары отправителей и бейджик «processed» на обработанных страницах<\/div>\n<\/div>\n<p>Формат выгрузки за прошедшие годы не поменялся, а вот содержимое профиля заметно поредело: уж не знаю с чем связано, может самизнаетечто повлияло, но много видосов и фоток теперь удалены или скрыты авторами. Ну, такие времена.<\/p>\n<p>При разработке в паре с Клодом пришлось преодолеть новые технологические сложности — оказалось что питоново-юниксовые по происхождению нейросети нативно плохо могут в редактирование powershell-скриптов с кириллицей под виндой. Но в итоге решение придумалось, и работа по впиливанию фич заняла пару вечеров ленивой фоновой постановки задач и контроля результатов. В основном время потратилось на скачивание медиа, ну заодно и свой дамп обновил на актуальный.<\/p>\n<p>Публичную репу решил пересоздать, но адрес оставил прежний: <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher\">https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher<\/a><\/p>\n<p>КЭНК! Слава роботам!<\/p>\n",
            "summary": "Спустя три года подготовил и выпустил новый релиз ВКачатора — допилил много мелочей, до которых в прошлый раз не доходили руки, благо теперь Клод позволяет реализовывать идеи быстро и технологично",
            "date_published": "2026-05-22T20:03:01+03:00",
            "date_modified": "2026-05-22T20:02:55+03:00",
            "tags": [
                "PowerShell",
                "TG",
                "ВКачатор",
                "Забрать своё из облаков",
                "ИИ",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/2026-05-18-image-8.png",
            "_date_published_rfc2822": "Fri, 22 May 2026 20:03:01 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "3793",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/2026-05-18-image-8.png"
                ]
            }
        },
        {
            "id": "1104",
            "url": "https:\/\/batishchev.ru\/blog\/all\/exchangedocsaver-esche-odna-istoriya-pro-lyudey-i-robotov\/",
            "title": "ExchangeDocSaver: еще одна история про людей и роботов",
            "content_html": "<p>Несколько лет назад, за кружкой крепкого чая у мангала, мой старинный друг пожаловался на одну из обязанностей на работе: при общении с контрагентами по электронной почте у них возникают артефакты этого общения — счета и прочие документы — которые нужно из почтовых сообщений сохранять на сетевой диск. Причем в компании исторически сложился процесс документооборота, когда эти файлы должны попасть в свое место в иерархии сетевого диска, где за них уже неистово хватаются другие отделы, а иерархия эта не самая простая (хотя будущее место документа определяется по номеру контракта однозначно, по схеме «ну это все знают»).<\/p>\n<p>В общем, выступает мой друг таким вот высокоинтеллектуальным сортировщиком и раскладывальщиком файликов, в фоне во время других (гораздо более сложных и изящных) задач по заключению договоров, преодолению препонов и прочих зарабатываний мильёнов. Ну натурально вот: придумал как привезти из стран заморских жирафа по частям, и чтобы по документам это была канарейка (задача безусловно творческая), а потом не забывай в течение пары месяцев доки по этому проекту из последующей переписки «правой кнопкой мыши — сохранить как — найти папку — блин где же она — а вот — сохранить»<\/p>\n<p>А что — говорю ему я, потягивая чай у мангала — задачка-то похоже автоматизируется. Можно научить роботов пырить в почтовый ящик по Exchange Web Services (EWS) Managed API, находить непрочитанные письма, понимать какие из них содержат нужные документы (а какие — нет), а также к какому контракту они относятся, ну а по номеру контракта и место на сетевом диске найти можно. Контракт конечно может быть в письме и вложениях непонятно где упомянут, но раз человек справляется с поиском — то и робота настропалить на это дело сможем.<\/p>\n<p>Естественно, согласно всем заветам планирования процессов разработки, реализация алгоритма заняла в три раза больше времени, чем задумывалось. Естественно, так как исходные письма посылают человеки, ошибающиеся и ненадёжные, и не все 100% сообщений оформляются как надо, часть писем (довольно малая) алгоритмом пропускается. Но в целом, за несколько дней рьяного <a href=\"https:\/\/batishchev.ru\/blog\/tags\/kenk\/\">кэнк-программинга<\/a> с использованием наработанных ранее библиотек и с применением худших регулярок ever, был выпущен в прод робот, который начал 24 на 7 делать работу за человека. Робот, который не устаёт, не болеет и не обедает, который днём и ночью мгновенно реагирует на письма от контрагентов изо всех часовых поясов, который всегда кладёт файлы туда, куда надо, и позволяет человеку сфокусироваться на действительно сложных вещах.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/exchangedocsaver-esche-odna-istoriya-pro-lyudey-i-robotov.png\" width=\"526\" height=\"242\" alt=\"\" \/>\n<\/div>\n<p>На днях, после полутора лет успешной эксплуатации, комплекс впервые потребовал доработки из-за смены формата номера контракта на предприятии. Я дополнил алгоритм детектирования ID контракта новым шаблоном, попутно поправил пару замеченных косяков (и чуть выиграл в производительности), выкатил обновление — и клиент снова доволен, надеюсь что на следующие Х лет.<\/p>\n<p>Детали реализации, код, ФИО счастливчика и название компании — под NDA, по очевидным причинам. Могу лишь сказать что при внимании к деталям и некотором опыте автоматизации под винду и Exchange, можно в таком направлении реализовать практически что угодно. Если вы ежедневно тратите время на работу с почтой, не решаемую обычным функционалом правил и другой автоматизации в почтовом клиенте — возможно, пришла пора переложить это на наших электрических братьев. Как-нибудь расскажу потом про конфеденциальную пересылку алертов из почты в телегу, тоже полезная штука.<\/p>\n<p>Кожаные заняты делом, кремнивые — рутиной. Обожаю такое.<\/p>\n<p>КЭНК! Слава роботам!<\/p>\n",
            "summary": "Несколько лет назад, за кружкой крепкого чая у мангала, мой старинный друг пожаловался на одну из обязанностей на работе",
            "date_published": "2024-12-05T12:27:42+03:00",
            "date_modified": "2024-12-09T13:17:05+03:00",
            "tags": [
                "EWS",
                "PowerShell",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/exchangedocsaver-esche-odna-istoriya-pro-lyudey-i-robotov.png",
            "_date_published_rfc2822": "Thu, 05 Dec 2024 12:27:42 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1104",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/exchangedocsaver-esche-odna-istoriya-pro-lyudey-i-robotov.png"
                ]
            }
        },
        {
            "id": "1083",
            "url": "https:\/\/batishchev.ru\/blog\/all\/zapusk-processov-kaspersky-network-agent-v-64-bit-okruzhenii\/",
            "title": "Запуск процессов через Kaspersky Network Agent в 64-bit окружении",
            "content_html": "<p>Через задачу типа «Удалённая установка программы» на windows-клиентах, покрытых Kaspersky Network Agent, удобно запускать инсталляторы или скрипты, выполняющие на хосте необходимые администратору настройки. Тут можно решать множество проблем — от умной деинсталляции или переустановки софта, до настройки параметров ОС и приложений.<\/p>\n<p>Однако, здесь кроется одна засада — агент работает от имени SYSTEM, но запускает нагрузку в 32-битном окружении. В плане powershell из-за этого могут быть недоступны часть ресурсов ОС типа веток реестра и всплывать прочие нюансы.<\/p>\n<p>К счастью, великий стаковерфлоу уже больше 10 лет хранит в себе рецепт на этот случай. Он часто пригождается, поэтому положу его и сюда. Просто добавьте <s>простой советский<\/s> блок кода в начало вашего скрипта, и он будет автоматически перезапущен со всеми параметрами в 64-битном окружении.<\/p>\n<pre class=\"e2-text-code\"><code class=\"powershell\">\n#############################################################################\n#If Powershell is running the 32-bit version on a 64-bit machine, we \n#need to force powershell to run in 64-bit mode .\n#############################################################################\nif ($env:PROCESSOR_ARCHITEW6432 -eq \"AMD64\") {\n    if ($myInvocation.Line) {\n        &\"$env:WINDIR\\sysnative\\windowspowershell\\v1.0\\powershell.exe\" -NonInteractive -NoProfile $myInvocation.Line\n    }else{\n        &\"$env:WINDIR\\sysnative\\windowspowershell\\v1.0\\powershell.exe\" -NonInteractive -NoProfile -file \"$($myInvocation.InvocationName)\" $args\n    }\nexit $lastexitcode\n}\n\nwrite-host \"Main script body\"\n\n#############################################################################\n#End\n#############################################################################\n<\/code>\n<\/pre>\n<h2>Ссылочки на исходники<\/h2>\n<ul>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/19055924\/how-to-launch-64-bit-powershell-from-32-bit-cmd-exe\">https:\/\/stackoverflow.com\/questions\/19055924\/how-to-launch-64-bit-powershell-from-32-bit-cmd-exe<\/a><\/li>\n<li><a href=\"http:\/\/cosmonautdreams.com\/2013\/09\/03\/Getting-Powershell-to-run-in-64-bit.html\">http:\/\/cosmonautdreams.com\/2013\/09\/03\/Getting-Powershell-to-run-in-64-bit.html<\/a><\/li>\n<\/ul>\n",
            "summary": "Через задачу типа «Удалённая установка программы» на windows-клиентах, покрытых Kaspersky Network Agent, удобно запускать инсталляторы или скрипты, выполняющие на хосте необходимые администратору настройки",
            "date_published": "2024-10-02T15:19:08+03:00",
            "date_modified": "2024-11-25T20:13:00+03:00",
            "tags": [
                "PowerShell",
                "безопационная информасность",
                "все эти ваши компьютеры"
            ],
            "_date_published_rfc2822": "Wed, 02 Oct 2024 15:19:08 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1083",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "1049",
            "url": "https:\/\/batishchev.ru\/blog\/all\/otklyuchaem-perezagruzku-windows-pri-obnovleniyah\/",
            "title": "Отключаем перезагрузку Windows при обновлениях",
            "content_html": "<p>В прошлый раз я рассказывал, как <a href=\"https:\/\/batishchev.ru\/blog\/saga-o-perezagruzkah-ili-smekalka-protiv-vlasti-korporaciy\/\">победил самопроизвольную перезагрузку винды<\/a> в производственной среде. Но дома проблема так же актуальна — бесит когда смотришь с утра, что посчиталось в монтажке с новым концертом любимой группы, например, а на тебя в ответ смотрит свежеперезагруженный комп.<\/p>\n<p>Итак, kenk-shift-active-hours или Бесконечный откладыватель авто-перезагрузки Windows при обновлениях<\/p>\n<ul>\n<li>скрипт задаёт в качестве начала активных часов текущий час, а в качестве конца — время на 18 часов позже (это максимальная возможная длительность)<\/li>\n<li>в комплекте идёт инсталлер, который копирует скрипт в профиль пользователя и создает задачу в планировщике, стартующую скрипт автоматически каждые полчаса<\/li>\n<li>в итоге, система корректно сама ходит за апдейтами и устанавливает их, а также сигнализирует о необходимости перезагрузки для завершения обновления, но никогда не перезагружается сама<\/li>\n<\/ul>\n<p>Отмечу отдельно что для домашнего использования такое (потенциально) бесконечное откладывание ребута приемлемо, я достаточно ответственен чтобы в короткий (но удобный мне) срок перезагрузить тачку.<\/p>\n<p>Скрипт на гитхабе: <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-shift-active-hours\">https:\/\/github.com\/alexbatishchev\/kenk-shift-active-hours<\/a><\/p>\n<p>КЭНК!<br \/>\nСлава роботам!<\/p>\n",
            "summary": "В прошлый раз я рассказывал, как победил самопроизвольную перезагрузку винды в производственной среде",
            "date_published": "2024-06-26T16:29:18+03:00",
            "date_modified": "2024-06-26T16:29:16+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "_date_published_rfc2822": "Wed, 26 Jun 2024 16:29:18 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1049",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "1046",
            "url": "https:\/\/batishchev.ru\/blog\/all\/saga-o-perezagruzkah-ili-smekalka-protiv-vlasti-korporaciy\/",
            "title": "Сага о перезагрузках, или смекалка против власти корпораций",
            "content_html": "<p>Сегодняшний рассказ — на мои любимые темы: как заставить роботов работать за людей, и как победить неумолимые корпорации с помощью их же инструментов. А ещё это реальный эксклюзив и ноу-хау, до которого (кажется) ещё никто не задумывался. Устраивайтесь поудобнее.<\/p>\n<p>Предыстория такова: первой большой задачей на нынешнем проекте у меня было внедрить процесс обновления операционок на рабочих местах. Главная проблема тут в <a href=\"https:\/\/bureau.ru\/bb\/soviet\/20150505\/\">бесценности пользовательских данных<\/a> и в том, как в борьбе за безопасность Microsoft перешла грань. Начиная с какого-то момента, штатными средствами и политиками Windows стало невозможно обеспечить обязательную, но бережную установку обновлений системы для клиентских ОС. Да, появились более наглядные нотификации, возможность задавать дедлайны, но в итоге, все варианты сводились к двум сценариям — либо апдейты не будут гарантированно установлены, либо автообновление будет работать, но комп может быть перезагружен в вообще говоря неудобное клиенту время. Самый отстой тут — перезагрузки по ночам или в другие моменты, когда комп что-то делает без активного участия человека — тут администраторы, программисты и прочие рендерщики видео по три часа в фоне начинают беситься, вспоминая потерянное на таких ребутах время и данные.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/wufb-update-deadline-warning.png\" width=\"345\" height=\"144\" alt=\"\" \/>\n<\/div>\n<p>Собственно, рабочую задачу я решил через отключение всех автоматических политик Microsoft и реализации собственного решения — агента, который работает на хостах, по удобному предприятию и сотрудникам расписанию ставит обновления, назначает и следит за сроками установки, адекватно напоминает о необходимости перезагрузки и вообще решает задачу бережно и результативно. Ключевая фишка — умные дедлайны, когда на установку обновлений пользователю отводится некоторое количество рабочих дней, а принудительная перезагрузка (если до неё дойдёт) не происходит пока пользователя нет у компа, и он не может сохранить свои данные. Ну а попутно появился инструмент инвентаризации и управления клиенсткими машинами. Когда-нибудь расскажу об этом отдельно, кодовое имя проекта «Светофор».<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-3.png\" width=\"364\" height=\"599\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Уведомление, которым Светофор достаёт даже самого упорного пользователя<\/div>\n<\/div>\n<p>Однако, с Windows 11 оставалась одна загвоздка — штатными средствами полностью запретить винде перезагружаться по собственному желанию, при включенной авто-установке апдейтов, не получилось. Были найдены и протестированы совсем уж некрасивые варианты типа модификации системных файлов и запрета самой винде их менять на уровне файловых прав, но это было грязно и неудобно для внедрения. До поры таких клиентов было немного, ситуация позволяла терпеть, однако недавно я сам перешёл на Windows 11, миграция в компании тоже стартовала, и проблема начала разрастаться.<\/p>\n<p>Я провёл очередной рисёрч на тему (оказалось что ничего за годы не изменилось), после чего сделал ещё один заход на проблему в КЭНК-парадигме, и тут в ночи перезагрузочного кошмара забрезжил-таки рассвет.<\/p>\n<p>Следим за руками: винда штатно смотрит на заданный в настройках Период Активности (Active Hours), и не ребутает компы во время него. Так отчего бы нам автоматически не сдвигать его постоянно так, чтобы период активности не заканчивался никогда?<\/p>\n<p>Быстрая проверка показала что соответствующие параметры хранятся в реестре и доступны на запись непривилегированным пользователям, и что система реально их регулярно перечитывает. А если параметры сдвигать вперёд постоянно, то неуправляемого саморебута после установки обновлений не случается совсем.<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"1655\" data-ratio=\"2.4701492537313\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-1.png\" width=\"1655\" height=\"670\" alt=\"\" \/>\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-2.png\" width=\"1655\" height=\"670\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-caption\">вот они красавчики в реестре и в гуе<\/div>\n<\/div>\n<p>Дальше — дело техники, добавил в Светофор небольшой модуль, он сдвигает Active Hours на компах пользователей, а перезагрузкой управляет сам.<\/p>\n<p>Компьютеры работают, человек кайфует, корпорации щёлкнуты по носу, ситуация под нашим контролем!<\/p>\n<p>А вот о том, как это может быть полезно простым домашним юзерам — расскажу в следующий раз.<\/p>\n<p>КЭНК!<br \/>\nСлава роботам!<\/p>\n",
            "summary": "Сегодняшний рассказ — на мои любимые темы: как заставить роботов работать за людей, и как победить неумолимые корпорации с помощью их же инструментов",
            "date_published": "2024-06-18T00:21:45+03:00",
            "date_modified": "2025-10-15T00:12:30+03:00",
            "tags": [
                "PowerShell",
                "безопационная информасность",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/wufb-update-deadline-warning.png",
            "_date_published_rfc2822": "Tue, 18 Jun 2024 00:21:45 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1046",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "jquery\/jquery.js",
                    "fotorama\/fotorama.css",
                    "fotorama\/fotorama.js"
                ],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/wufb-update-deadline-warning.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-3.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-1.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2024-06-14-2.png"
                ]
            }
        },
        {
            "id": "1044",
            "url": "https:\/\/batishchev.ru\/blog\/all\/robot-lesnik-i-yolka\/",
            "title": "Робот-лесник и ёлка",
            "content_html": "<p>Сегодня расскажу про суровое, простое и полезное как топор в лесу кэнк-поделие, на разработку и запуск которого в пром ушло меньше часа времени.<\/p>\n<p>Вот ELK-стек, в который собираются некоторые данные. Конечно, мы следим за хостами фермы через мониторинг. Но хотелось бы и смотреть и за состоянием самого сервиса, и — главное — вовремя узнавать если что-то пошло не так.<\/p>\n<p>Выбираем сервак для размещения робота-лесника (в моём случае под виндой ибо фигачим быстро и грязно на павершеле). Пишем скрипт, в котором:<\/p>\n<ul>\n<li>читаем список FQDN нод нашей ёлки из конфига скрипта<\/li>\n<li>проходим по списку, проверяя доступность хостов по сети (через Test-NetConnection -port 9200). Если какая-то нода не пингуется или не отвечает по 9200 — алертим админу<\/li>\n<li>если есть хоть одна живая нода — запрашиваем у неё статус через API «<a href=\"https:\/\/cluster.com\/_cluster\/health?pretty\">https:\/\/cluster.com\/_cluster\/health?pretty<\/a>». В полученном json пырим в «status», если он не «green» — запрашиваем более подробную диагностику через «<a href=\"https:\/\/cluster.com\/_nodes\/process?pretty\">https:\/\/cluster.com\/_nodes\/process?pretty<\/a>» и тоже всё алертим админу.<\/li>\n<\/ul>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/2024-06-10-health.png\" width=\"862\" height=\"301\" alt=\"\" \/>\n<div class=\"e2-text-caption\">типовой результат запроса health<\/div>\n<\/div>\n<ul>\n<li>куда алертим? Ну лично мне удобней получать такое в почту и в специальный аварийный чят в телеге.<\/li>\n<li>повторяем проверку (дёргаем скрипт планировщиком на сервере с нужной периодичностью)<\/li>\n<\/ul>\n<p>Итого, при проблемах с сервисом имеем своевременные оповещения, машины трудятся а человеки отдыхают.<\/p>\n<p>Думал оформить свой скриптец в виде готового продукта, но в целом тула вышла специфичная под мои требования и легко воспроизводимая в нужном виде под требования чужие, так что ограничусь общим алгоритмом и описанием идеи.<\/p>\n<p>КЭНК!<br \/>\nСлава роботам!<\/p>\n",
            "summary": "Сегодня расскажу про суровое, простое и полезное как топор в лесу кэнк-поделие, на разработку и запуск которого в пром ушло меньше часа времени",
            "date_published": "2024-06-11T21:25:10+03:00",
            "date_modified": "2024-10-02T15:27:10+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/image-1.png",
            "_date_published_rfc2822": "Tue, 11 Jun 2024 21:25:10 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1044",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/image-1.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/2024-06-10-health.png"
                ]
            }
        },
        {
            "id": "1008",
            "url": "https:\/\/batishchev.ru\/blog\/all\/kenk-obnovlenie-generatora-fonov-dlya-rabochego-stola\/",
            "title": "КЭНК: обновление генератора фонов для рабочего стола",
            "content_html": "<p>В последнее время всё чаще сталкиваюсь с необходимостью использовать в powershell вызовы системного API для реализации функционала, под который нет готовых командлетов. Разбираясь с решением очередной проблемы этим методом, вспомнил про <a href=\"\/blog\/all\/generator-kartinok-dlya-fona-rabochego-stola-serverov\/\">генератор фонов для RDP<\/a>, который я когда-то пилил, и в котором до идеала не хватало авто-назначения сгенерённого фона, потому что такой функции я тогда не нашел. Ну думаю, через системное API уж точно кто-то сообразил как сделать — напомню, там у меня получилось задать картинку и параметры через реестр, а вот форсировать обновление без перезагрузки я не смог.<\/p>\n<p>Погуглил в эту сторону, нашел пару реализованных вариантов (<a href=\"https:\/\/getps.dev\/blog\/change-desktop-wallpaper-with-powershell\/\">1<\/a> и <a href=\"https:\/\/www.joseespitia.com\/2017\/09\/15\/set-wallpaper-powershell-function\/\">2<\/a>), и скопипиздил в скрипт код, так что теперь генерятор работает без ручного труда совершенно.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/kenk-bgimage-2023-12-31.png\" width=\"969.33638443936\" height=\"800\" alt=\"\" \/>\n<\/div>\n<p><a href=\"https:\/\/github.com\/alexbatishchev\/kenk-bgimage\">Код на гитхабе<\/a>. Слава роботам!<\/p>\n",
            "summary": "В последнее время всё чаще сталкиваюсь с необходимостью использовать в powershell вызовы системного API для реализации функционала, под который нет готовых командлетов",
            "date_published": "2023-12-31T11:15:12+03:00",
            "date_modified": "2024-10-02T15:27:02+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/kenk-bgimage-2023-12-31.png",
            "_date_published_rfc2822": "Sun, 31 Dec 2023 11:15:12 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "1008",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/kenk-bgimage-2023-12-31.png"
                ]
            }
        },
        {
            "id": "988",
            "url": "https:\/\/batishchev.ru\/blog\/all\/servis-isdayoff-dlya-nuzhd-avtomatizacii\/",
            "title": "Сервис isDayOff для нужд автоматизации",
            "content_html": "<p>Несколько лет использую в работе сервис <a href=\"https:\/\/www.isdayoff.ru\/\">isDayOff<\/a>, который позволяет проверить дату на принадлежность к нерабочему дню, согласно официальным указам и распоряжениям.<\/p>\n<p>Я очень люблю автоматизацию, особенно — автоматический контроль за соблюдением правил и договоренностей в системах. Человеческий фактор невозможно полностью исключить, зато можно заставить дотошных и не устающих роботов контролировать, что человек сделал всё правильно. Однако, здесь кроется одна проблема — человеки, в отличие от роботов, уходят на выходные и государственные праздники. Согласно Первому закону робототехники, робот не может причинить вред человеку или своим бездействием допустить, чтобы человеку был причинён вред. А что может быть противней, чем тикет на исправление некритической проблемы, прилетевший в выходные? Да, можно запрограммировать, чтобы тикеты не прилетали в субботы и воскресенья — но что делать с праздниками и переносами выходных?<\/p>\n<p>isDayOff  простой как автомат Калашникова, и легко встраивается в скрипты и пайплайны автоматизации. В простейшем виде через <a href=\"https:\/\/isdayoff.ru\/today\">https:\/\/isdayoff.ru\/today<\/a> можно узнать, является ли текущий день рабочим, ну а дополнительные параметры к запросу могут дать информацию о любой дате в прошлом и будущем (в разумных пределах) и даже о праздниках в соседних странах (поддерживаются Белоруссия, Казахстан и Украина).<\/p>\n<p>База сервиса активно поддерживается и приводится в соответствие законам, когда принимаются решения о переносах праздников и выходных. Чтобы не потерять функционал при возможном отключении сервиса (а в дивные новые времена обо всём начинаешь думать в разрезе «а что если забанят»), я обычно стараюсь в проектах использовать локальную базу на год вперед, сдампленную с сайта, и обновляющуюся ежемесячно — заодно, локальная копия базы снижает нагрузку на сервис, зачем зря напрягать бесплатное отличное решение.<\/p>\n<p>В целом всё просто и понятно. Например, в виде без кеширования запрос обычно посылаю через подготовленную функцию, с логикой обработки ситуации когда сервис недоступен<\/p>\n<script src=\"https:\/\/gist.github.com\/alexbatishchev\/976d9cf2e33759a579086efa6ee999fc.js\"><\/script>\n<p>С учетом простоты решения, его легко встраивать и в других ситуациях, когда требуется контролировать рабочий статус даты — уведомления, расписание резервного копирования, подсчёт количества рабочих дней до наступления дедлайна перезагрузки по обновлениям системы, и так далее.<\/p>\n<p>Слава роботам!<\/p>\n",
            "summary": "Несколько лет использую в работе сервис isDayOff, который позволяет проверить дату на принадлежность к нерабочему дню, согласно официальным указам и распоряжениям",
            "date_published": "2023-06-07T23:37:28+03:00",
            "date_modified": "2024-10-02T15:26:38+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "_date_published_rfc2822": "Wed, 07 Jun 2023 23:37:28 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "988",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "987",
            "url": "https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-obnovlenie-vkachatora\/",
            "title": "Забрать своё из облаков: обновление вКачатора",
            "content_html": "<p>Допилил небольшое, но важное дополнение для <a href=\"https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-kenk-vk-enricher\/\">скрипта обогащения дампов профиля ВКонтакте<\/a>. Эксплуатация предыдущей версии выявила существенный недостаток: видео с YouTube, импортированные в ВК, в разных разделах сайта фигурируют с разными ID (и разными URL). Выходит странненькое — по этим разным ссылкам открывается один и тот же объект (страницца) ВК, с теми же комментариями, лайками, и прочими атрибутами соцсети, и конечно же встроенный в объект ролик YouTube там тоже один и тот же, но ссылки на этот объект разные. И например, добавленное на стену видео, и то же видео, посланное в диалоге, будут иметь разные адреса. Поэтому старая версия скачивала, и складывала в папку видео несколько раз, что расходовало лишнее место (а у меня в избранные как-то попала даже девятичасовая прямая трансляция выхода в открытый космос с МКС).<\/p>\n<p>Идеально было бы научить скрипт сразу узнавать такие дубликаты по адресам, и не скачивать повторы вовсе, но как это сделать я придумать не смог. Зато можно скачать через yt-dlp оригинал с ютуба, и по его метаданным распознать дубль, сравнив с метаданными уже скачанных видео. Так и поступил — теперь скрипт сохраняет в простой json информацию по всем уже скачанным файлам, и при закачке дубля не сохраняет его на диск, заменяя ссылки в дампе на уже скачанный экземпляр. На моем дампе это значительно сократило объём выгрузки.<\/p>\n<p>Обновлённая версия уже на гитхабе: <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher\">https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher<\/a><\/p>\n",
            "summary": "Допилил небольшое, но важное дополнение для скрипта обогащения дампов профиля ВКонтакте. Эксплуатация предыдущей версии выявила существенный недостаток",
            "date_published": "2023-06-01T14:52:34+03:00",
            "date_modified": "2023-06-07T23:38:25+03:00",
            "tags": [
                "PowerShell",
                "ВКачатор",
                "Забрать своё из облаков",
                "КЭНК"
            ],
            "_date_published_rfc2822": "Thu, 01 Jun 2023 14:52:34 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "987",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "985",
            "url": "https:\/\/batishchev.ru\/blog\/all\/powershell-i-strannenkoe-s-timespan\/",
            "title": "Powershell и странненькое с TimeSpan",
            "content_html": "<p>Авторы Powershell, с одной стороны, многое в своём творении придумали системно и логично. С другой стороны, постоянно натыкаешься на странности, объяснения которым в области логики не найти.<\/p>\n<p>Любимый пример — класс TimeSpan, временной промежуток, отрезок времени между двумя датами. У объектов этого класса есть несколько свойств, отражающих заданный объектом промежуток времени в разных единицах измерения. И в перечне этих свойств неочевидная логика авторов языка проявляется в полной красе.<\/p>\n<p>Вот свойства Hours, Minutes, Seconds, Milliseconds. Интуитивно думаешь, что это — значение промежутка времени в часах, минутах, секундах, и миллисекундах. Довольно быстро наступаешь на эти грабли, и узнаёшь, что это кое-что другое, а именно количество часов в рамках дня, минут в рамках часа и тому подобное. То есть, если промежуток времени у вас в 1 день и 1 час, то Hours — не 25, а 1. А если между датами прошло 2 часа и 10 минут, то свойство Minutes будет не 2*60+10, а просто 10. Зачем это надо? Ну, наверное для чего-то может пригодиться, хотя я ни разу за много лет эти свойства не использовал. Зато, сколько ошибок в скриптах из-за неверного их понимания я встречал на стековерфлоу и в прочих местах в интернетах!<\/p>\n<p>Окей, столкнувшись с этим (или прочитав заранее в документации, что вряд ли), ты спустя какое-то время познаешь TotalHours, TotalMinutes, TotalSeconds и TotalMilliseconds, с той самой очевидной логикой «полное количество часов между датами» и так далее. Если между моментами времени прошло два с половиной часа, то это будет 2.5 TotalHours, 150 TotalMinutes и 9000 TotalSeconds. Ура, теперь-то всё понятно, можем смело фигачить!<\/p>\n<p>И вот в этот момент, к полному сил и умиротворённому программисту, из-за угла подходят в кепках и адидасе братюни Days и TotalDays, и объясняют, что понятий он не знает, и вообще зря на раён зашел. Ибо Days — это в в натуре полное количество дней (а не как можно было бы по аналогии предполагать, количество дней в рамках года). А TotalDays — это да, это полное количество дней, дробь (типа, аккуратно посчитанное, вкуриваешь?). А Days — грубо посчитанное. Но полное. Почему? Короч, так надо. Кстати, дай позвонить!<\/p>\n<p>И вот, сидишь, смотришь на это, и думаешь — а оно зачем вообще так?? Потом вздыхаешь, материшься, сверяешься  с документацией ещё раз, пишешь в коде правильное.<\/p>\n<p>Может показаться, что этот пост написан с целью излучить в пространство бессильную злобу — но на деле, это просто справочник. Я буду ходить сюда каждый раз, когда буду юзать TimeSpan, потому что запоминать подобное — просто портить себе мозг.<\/p>\n<blockquote>\n<p>Дорогой Вася! Если тебе надо посчитать промежуток времени, юзай TotalDays, TotalHours, TotalMinutes, TotalSeconds и TotalMilliseconds, помни что они — вещественные, и означают то, что тебе нужно. А про другие свойства TimeSpan забудь!<\/p>\n<\/blockquote>\n<p>А для вас — картинка, иллюстрирующая всю дичь TimeSpan<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/ps-timespan.png\" width=\"652\" height=\"649\" alt=\"\" \/>\n<\/div>\n<p>Слава роботам!<\/p>\n",
            "summary": "Авторы Powershell, с одной стороны, многое в своём творении придумали системно и логично. С другой стороны, постоянно натыкаешься на странности, объяснения которым в области логики не найти...",
            "date_published": "2023-05-17T22:29:53+03:00",
            "date_modified": "2024-10-02T15:26:26+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/ps-timespan.png",
            "_date_published_rfc2822": "Wed, 17 May 2023 22:29:53 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "985",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/ps-timespan.png"
                ]
            }
        },
        {
            "id": "981",
            "url": "https:\/\/batishchev.ru\/blog\/all\/arraylist-i-proizvoditelnost-massivov-v-powershell\/",
            "title": "ArrayList и производительность массивов в Powershell",
            "content_html": "<p>Powershell — язык весьма великодушный к программистам, почти всё в нём делается легко, интуитивно, и не требует особой подготовки и продумывания от автора кода. Однако, при выходе на объемные задачи начинают выстреливать некоторые вещи, которые для удобства изначально выполнены неэффективно.<\/p>\n<p>По одной из задач мне требовалось обрабатывать большие объемы данных (сотни тысяч и миллионы строк таблиц). На тестовых множествах всё работало хорошо, но на прод данных скрипт начинал работать непозволительно долго. Я провел профилирование и выяснил, что с ростом количества данных всё больше времени (с нелинейным ростом) начинает занимать операция добавления элемента в архив.<\/p>\n<p>$array = $array + $newElement — что может быть интуитивней? Оказалось, массивы в Powerhsell это имутабельные объекты, и поэтому предыдущий код фактически создает новый неизменяемый объект из всех элементов предыдущего массива и одного нового. Конечно, на больших объемах массивов такая операция будет занимать всё больше времени, и нелинейный рост вполне объясним. Этой неэффективности лишен специальный тип данных ArrayList — это тот же массив, разве что элементы добавлять самым очевидным способом через «плюс» в него нельзя.<\/p>\n<p>Вот код, на котором я проверил время работы цикла из добавления N случайных строк к массивам в умолчальном варианте и варианте ArrayList<\/p>\n<script src=\"https:\/\/gist.github.com\/alexbatishchev\/a870321637f19fce59879015860bb50e.js\"><\/script>\n<p>На 10 тысячах операций результаты примерно похожи — отличаются в десятки процентов. Но уже на сотне тысяч разница — на порядок. При этом время работы через ArrayList растет линейно вместе с количеством циклов, а у классических массивов — экспоненциально<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/photo_2023-02-07_17-28-08.jpg\" width=\"889\" height=\"446\" alt=\"\" \/>\n<\/div>\n<p>Вот такие тонкости вскрываются спустя годы работы с языком. С другой стороны, это хорошо характеризует его в положительном плане — сколько за это времени гигабайт csvшек и джейсонов было перелопачено без этих ваших ArrayList?!<\/p>\n",
            "summary": "Powershell — язык весьма великодушный к программистам, почти всё в нём делается легко, интуитивно, и не требует особой подготовки и продумывания от автора кода",
            "date_published": "2023-02-07T16:51:56+03:00",
            "date_modified": "2024-10-02T15:26:17+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/photo_2023-02-07_17-28-08.jpg",
            "_date_published_rfc2822": "Tue, 07 Feb 2023 16:51:56 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "981",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/photo_2023-02-07_17-28-08.jpg"
                ]
            }
        },
        {
            "id": "979",
            "url": "https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-kenk-vk-enricher-1-4\/",
            "title": "Забрать своё из облаков: kenk-vk-enricher 1.4",
            "content_html": "<p>Допилил скрипт <a href=\"https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-kenk-vk-enricher\/\">обогащения дампа Вконтакте<\/a>. Теперь скрипт качает видео в разделах Видеозаписи, Стена и Сообщения — закачка идет через  <a href=\"https:\/\/github.com\/yt-dlp\/yt-dlp\">yt-dlp<\/a>, перед использованием желательно обновить его до свежей версии, и залогиниться в ВК в одном из бразуеров на машине, тогда yt-dlp сможет использовать куки и больше видео будет доступно для скачивания. Также скачиваются аттачменты типа «файл» на стене и в сообщениях (те, что доступны по прямым ссылкам).<\/p>\n<p>Сейчас актуальной версией скрипта мой личный профиль выкачивается на почти 200 гб, сказываются видео файлы в переписке и на стене — часто репостились интересные чужие видосы, и всё вместе занимает прилично места. Ну да больше-не меньше.<\/p>\n<p>Скрипт на гитхабе: <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher\"><a href=\"https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher\">https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher<\/a><\/a><\/p>\n<p>Слава роботам!<\/p>\n",
            "summary": "Допилил скрипт обогащения дампа Вконтакте. Теперь скрипт качает видео в разделах Видеозаписи, Стена и Сообщения — закачка идет через yt-dlp, перед использованием желательно обновить его до свежей версии",
            "date_published": "2023-01-11T23:19:20+03:00",
            "date_modified": "2023-05-30T19:05:41+03:00",
            "tags": [
                "PowerShell",
                "ВКачатор",
                "Забрать своё из облаков",
                "КЭНК"
            ],
            "_date_published_rfc2822": "Wed, 11 Jan 2023 23:19:20 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "979",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "975",
            "url": "https:\/\/batishchev.ru\/blog\/all\/zabrat-svoyo-iz-oblakov-kenk-vk-enricher\/",
            "title": "Забрать своё из облаков:  kenk-vk-enricher",
            "content_html": "<p>Причесал и опубликовал <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-vk-enricher\">скрипт<\/a>, докачивающий в дамп официальной выгрузки из ВКонтакте картинки в переписку (сообщения) и фотоальбомы. Фотки выкачиваются и складываются заодно внутрь дампа в папки с именами, соответствующими оригинальным альбомам, а если они были опубликованы с подписью (как например часто было при параллельной публикации в ИГ) — подпись сохраняется в отдельный текстовой файл рядом.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/kenk-vk-enricher.png\" width=\"971\" height=\"631\" alt=\"\" \/>\n<\/div>\n<p>В дампе переписке  все файлы даются прямыми ссылками. А вот в дампе стены картинки прописаны ссылками вида <a href=\"https:\/\/vk.com\/photoXXXXXXXXX_XXXXXXXXX\">https:\/\/vk.com\/photoXXXXXXXXX_XXXXXXXXX<\/a> — но тут был придуман хитрый ход, немного исправляющий ситуацию. Так как среди фотоальбомов есть «Фотографии на моей стене», то если сдампить их и из кода страницы выдернуть и прямые ссылки на файлы, и ссылки photoXXXXXXXXX_XXXXXXXXX (которые там есть), то можно закешировать это соответствие и подставить потом известные картинки в код выгрузки стены. К сожалению, так можно обойти только картинки, и только картинки ваши — репосты от других пользователей или групп так и останутся со ссылками на данные в серверах ВК. Как до них добраться без URL оригинальных файлов непонятно — с парсерами картинок ВК в интернете такая же беда как и с видео. Хотя жаль, стену со своими публикациями хотелось бы содрать в максимально полном виде, включая и репосты.<\/p>\n<p>За недолгое время с прошлой публикации yt-dlp успел разучиться качать видео из вк, и вновь научился этому в свежем апдейте — похоже что война апишников с реверс-инженерами идёт денно и нощно. С учетом этого, выкачку видео пока думаю не реализовывать.<\/p>\n<p>Забавное наблюдение — в дампе стены есть уже удалённые вами сообщения (с пометкой «Запись удалена»). Так приятно что заботливые товарищи всё хранят даже после удаления (евпочя).<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/kenk-vk-enricher2.png\" width=\"645\" height=\"468\" alt=\"\" \/>\n<\/div>\n<p>КЭНК! Слава роботам!<\/p>\n",
            "summary": "Причесал и опубликовал скрипт, докачивающий в дамп официальной выгрузки из ВКонтакте картинки в переписку",
            "date_published": "2023-01-05T22:34:03+03:00",
            "date_modified": "2023-05-30T19:05:28+03:00",
            "tags": [
                "PowerShell",
                "ВКачатор",
                "Забрать своё из облаков",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/kenk-vk-enricher.png",
            "_date_published_rfc2822": "Thu, 05 Jan 2023 22:34:03 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "975",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/kenk-vk-enricher.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/kenk-vk-enricher2.png"
                ]
            }
        },
        {
            "id": "971",
            "url": "https:\/\/batishchev.ru\/blog\/all\/kenk-bezopasno-hranim-sekrety-dlya-skriptov-powershell\/",
            "title": "КЭНК: безопасно храним секреты для скриптов PowerShell",
            "content_html": "<p>Часто из скриптов PowerShell нужно обращаться к системам, требующим аутентификации — например, для парсинга данных о хостах из корпоративной системы мониторинга, или для выгрузки данных об уязвимостях из веб-портала системы обнаружения уязвимостей. Также нередко в этих случаях используются учетные записи с расширенными полномочиями во внешних системах, но в целом это не принципиально — любые секреты хочется хранить так, чтобы до них было невозможно добраться злоумышленнику.<\/p>\n<p>Понятно, что харкодить креды в источниках или держать их в конфигурационных файлах скрипта — дело пропащее. Даже если зарезать на уровне файловой системы доступ только для учетной записи, от которой должен стартовать скрипт, остаётся возможность администратору сервера эти права изменить и данные прочитать. Неаккуратненько  выходит ©.<\/p>\n<p>К счастью, в Windows есть магическая штука на этот случай — Secure Strings — волшебство которых в данном случае заключается в том, что они работают с учетом контекста учетной записи, от которой запущены. Поэтому, если задать пароль ($pw = Read-Host -AsSecureString)  прогнать его через ConvertFrom-SecureString  ($pw | ConvertFrom-SecureString) и результат записать в файл, то на выходе будет чудесная буквенно-цифровая белиберда. А обратно эту белиберду можно превратить в пароль  (Get-Content .\\password.txt | ConvertFrom-SecureString), но только вот пароль правильным получится только если это преобразование работает от той же учетной записи, под которой шло прямое кодирование.<\/p>\n<p>При запуске скрипта на этом компьютере но от другой учетной записи, при запуске скрипта на другой машине, при смене пароля учетной записи — всегда расшифровка будет завершаться с ошибкой. Да, это создаёт неудобства при смене пароля сервисной учетной записи, от которой стартуют скрипты, и ключевую информацию нужно будет перегенерить — но зато спрятанные таким образом секреты точно завязаны на сохранность пароля от учетной записи и не могут быть прочитаны никем кроме неё.<\/p>\n<p>В своих проектах я использую свою маленькую библиотеку, позволяющую запросить и сохранить данные в ключевой файл в формате JSON, и читать данные из него в скриптах. Но в целом подход прозрачен и его можно реализовывать так как удобно<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/IMAGE-2022-11-03-00:14:55.jpg\" width=\"690\" height=\"218\" alt=\"\" \/>\n<\/div>\n<p>В интернетах пишут, что в свежих версиях павершелла появились интеграции с системами хранения паролей, но до этого мои руки пока не дошли — привычное работает, роботы трудятся, люди отдыхают<\/p>\n<p>Пример кода, иллюстрирующий подход:<\/p>\n<script src=\"https:\/\/gist.github.com\/alexbatishchev\/44be2d64097386e190468ec782d60697.js\"><\/script>\n<p>Ссылки по теме:<\/p>\n<p><a href=\"https:\/\/www.techtarget.com\/searchitoperations\/tutorial\/How-to-secure-passwords-with-PowerShell\">https:\/\/www.techtarget.com\/searchitoperations\/tutorial\/How-to-secure-passwords-with-PowerShell<\/a><br \/>\n<a href=\"https:\/\/www.travisgan.com\/2015\/06\/powershell-password-encryption.html\">https:\/\/www.travisgan.com\/2015\/06\/powershell-password-encryption.html<\/a><\/p>\n<p>Слава Роботам! КЭНК!<\/p>\n",
            "summary": "Часто из скриптов PowerShell нужно обращаться к системам, требующим аутентификации — например, для парсинга данных о хостах из корпоративной системы мониторинга",
            "date_published": "2022-11-02T23:19:24+03:00",
            "date_modified": "2024-10-02T15:26:09+03:00",
            "tags": [
                "PowerShell",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "_date_published_rfc2822": "Wed, 02 Nov 2022 23:19:24 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "971",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "955",
            "url": "https:\/\/batishchev.ru\/blog\/all\/tihoe-udalenie-obnovleniya-windows-po-nomeru-kb\/",
            "title": "КЭНК: тихое удаление обновления Windows по номеру KB",
            "content_html": "<p>Задача: тихо удалить с хоста обновление Windows по номеру KB.<\/p>\n<p>Какое-то время проблема легко решалась через wusa.exe \/uninstall \/kb:XXXXXX \/quiet, но теперь в Windows 10 команда с ключом quiet просто игнорируется, а без ключа — задает много вопросов пользователю, что ожидаемо, но не подходит для решения задачи.<\/p>\n<p>В интернетах быстро гуглится <a href=\"https:\/\/social.technet.microsoft.com\/Forums\/windows\/en-US\/f6594e00-2400-4276-85a1-fb06485b53e6\/issues-with-wusaexe-and-windows-10-enterprise?forum=win10itprogeneral\">способ<\/a>, который хорош, но не универсален. Способ рассчитывает на то что KB будет упомянута в имени пакета для DISM, а это бывает не всегда — в примере ниже у двух последних обновлений номера KB в имени пакета нет.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/Screenshot-2021-03-15-110629.png\" width=\"690\" height=\"278\" alt=\"\" \/>\n<\/div>\n<p>Ситуацию усложняет то, что в разных локалях ОС команда dism выдает информацию на разных языках, да к тому же не структурированным объектом — а строкой. К счастью, из строки все же можно выцепить имя пакета, а по нему — запросить подробную информацию (тоже строкой), где номер KB есть (судя по моим тестам) всегда:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/screen20210315116.png\" width=\"930\" height=\"657\" alt=\"\" \/>\n<\/div>\n<p>Итоговое решение задачи такое:<\/p>\n<ul>\n<li>смотрим список всех установленных обновлений и выдергиваем имена пакетов<\/li>\n<li>по каждому пакету смотрим расширенное описание и ищем в нём искомый номер KB<\/li>\n<li>если в описании найден нужный номер KB — пакет по его имени отправляется на деинсталляцию через DISM.exe \/Online \/Remove-Package \/PackageName:$sFoundPackageName \/quiet \/norestart<\/li>\n<\/ul>\n<p>Короткий сниппет, иллюстрирующий подход:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">$sKBNumber = &quot;4578968&quot;\n$aUpdts = dism \/online \/get-packages | ? {$_.Contains(&quot;Package_for&quot;)} | %{($_.Split(&quot;:&quot;))[1].Trim()}\nforeach ($sUpdate in $aUpdts) {\n\t$sInfo = (dism \/online \/get-packageinfo \/packagename:$sUpdate) -join(&quot;, &quot;)\n\tif ($sInfo.Contains($sKBNumber)) {\n\t\twrite-host &quot;Found package $sUpdate for KB number $sKBNumber&quot;\n\t\t# uncomment below to uninstall package\n\t\t# DISM.exe \/Online \/Remove-Package \/PackageName:$sUpdate \/quiet \/norestart\n\t}\n}<\/code><\/pre><p>КЭНК! Слава роботам!<\/p>\n",
            "summary": "Задача: тихо удалить с хоста обновление Windows по номеру KB",
            "date_published": "2021-03-15T13:29:36+03:00",
            "date_modified": "2025-04-14T12:23:44+03:00",
            "tags": [
                "PowerShell",
                "WSUS",
                "безопационная информасность",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/Screenshot-2021-03-15-110629.png",
            "_date_published_rfc2822": "Mon, 15 Mar 2021 13:29:36 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "955",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/Screenshot-2021-03-15-110629.png",
                    "https:\/\/batishchev.ru\/blog\/pictures\/screen20210315116.png"
                ]
            }
        },
        {
            "id": "74",
            "url": "https:\/\/batishchev.ru\/blog\/all\/kenk-sortiruem-i-filtruem-kanaly-iptv\/",
            "title": "КЭНК: сортируем и фильтруем каналы IPTV",
            "content_html": "<p>Решил подарить маме на новый год IPTV от широко известного в узких кругах провайдера. Этот сервис за небольшую плату предоставляет плейлисты с каналами, и главная суть услуги — то что списки каналов обновляются, протухшие источники заменяются новыми, клиент не бегает по интернетам в поисках собранных энтузизястами плейлистов сомнительного качества, и не остаётся вдруг без любимого НТВ под ёлочкой.<\/p>\n<p>Главный недостаток сервиса в том, что встроенная система управления каналами примитивна: можно только включать или исключать каналы целыми категорями, по тематикам или по странам. Нет возможности задания порядка каналов, нет возможности индивидуальной фильтрации. Но так как мама — человек старой закалки, ей во-первых нужно чтобы каналы были По Порядку, усвоенному со времен телевизора Темп, а во-вторых, этого вашего супер-изобилия ей не надо, а моя тайная мечта тут — пересадить её с ток-шоу на видео природы.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/televisortemp.jpg\" width=\"512\" height=\"417\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Телевизор Темп. Ровно такая же модель стала причиной больших перемен в семье моих родителей в начале 1980-х<\/div>\n<\/div>\n<p>При этом вручную колбасить плейлист от провайдера дело муторное, а с учётом протухания ссылок еще и потенциально часто повторяемое: сам провайдер предлагает в плеер забивать ссылку на динамически обновляемый плейлист, и тогда там всё свежо и отлично, а вот если плейлист забить просто в виде текста — тут уже никакой магии волшебства, и со временем окно в дивный мир превратится в тыкву.<\/p>\n<p>По итогу размышлений принимаю решение реализовать компромиссный вариант. По мере протухания каналов и жалоб клиента, буду скачивать и обновлять плейлист, фильровать и обновлять в настройках плеера. Но максимально всё это автоматизирую. На выходе — плейлист с центральными каналами в HD качестве и правильном порядке (Первый, Россия и тому подобное), дополненный избранными каналами про природу, путешествия, и хорошее кино. Под рукой винда — значит фигачим на павершелле.<\/p>\n<p>Первая итерация — скрипт, умеющий взять плейлист, и отфильтровать и отсортировать его по заданному правилу (простой json файл).  В дальнейшем, если потребуется, можно прикрутить в него скачивание провайдерского плейлиста (тривиально) и закачивание в плеер (тут будет непросто разобраться в формате HTTP запроса). Но пока так. Быстро, зло, бесплатно, работает.<\/p>\n<p>Страница на гитхабе <a href=\"https:\/\/github.com\/alexbatishchev\/kenk-iptv-playlister\">https:\/\/github.com\/alexbatishchev\/kenk-iptv-playlister<\/a><\/p>\n<p>КЭНК!<br \/>\nСлава роботам!<\/p>\n",
            "summary": "Решил подарить маме на новый год IPTV от широко известного в узких кругах провайдера. Этот сервис за небольшую плату предоставляет плейлисты с каналами",
            "date_published": "2020-12-24T13:46:13+03:00",
            "date_modified": "2020-12-24T14:49:33+03:00",
            "tags": [
                "PowerShell",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/televisortemp.jpg",
            "_date_published_rfc2822": "Thu, 24 Dec 2020 13:46:13 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "74",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/televisortemp.jpg"
                ]
            }
        },
        {
            "id": "73",
            "url": "https:\/\/batishchev.ru\/blog\/all\/kenk-certutil-check\/",
            "title": "КЭНК: контролируем сроки действия сертификатов",
            "content_html": "<p>Сегодняшняя КЭНК-история короткая и почти без кода, потому что универсальный скрипт предложить сложно, а главную ценность составляет идея.<\/p>\n<p>Итак, проблема: в некоей системе используются сертификаты пользователей. Система (и её клиентская часть) сама по себе никаких средств контроля и мониторинга сертификатов не содержит, и задача контроля срока и необходимости заблаговременного заказа, организации установки сертификатов на устройства полностью лежит на группе поддержки. Необходимо максимально исключить человеческий фактор и заставить трудиться роботов на ниве контроля сроков.<\/p>\n<p>Решение. Выгружать или как-то ещё получать доступ к сертификатам в работе система не даёт, но мы можем договориться с группой поддержки, что они будут хранить сертификаты в отдельной папке с ограниченным доступом, и работать с ней при любом обслуживании клиентов — убирать оттуда ушедшие из работы сертификаты, класть вновь выпущенные и использованные в настройке. После этого остальное дело техники — по расписанию дампим сертификаты, находим в них данные о сроке окончания, начинаем присылать предупредительные письма группе поддержки заранее. Тут кстати родилась универсальная формула, позволяющая не попасть на праздники и прочие выходные  — предупреждения высылаются за 14, 5, и 3 дня до истечения срока действия сертификата.<\/p>\n<p>Главный технический ингредиент — договориться с certutil, которая в разных версиях по разному выдает дампы.<br \/>\nВ моем конкретном случае просто парсится дата окончания через<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">$data = certutil -dump $file | select-string -pattern &quot;NotAfter:&quot;<\/code><\/pre><p>В итоге, письма рассылаются, сроки не продалбываются, клиенты довольны, человеки не держат в голове лишней информации<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/batishchev.ru\/blog\/pictures\/kenk-p7ber2-1.png\" width=\"639\" height=\"400\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Пример уведомления о скором сроке окончания действия сертификата<\/div>\n<\/div>\n<p>КЭНК!<br \/>\nСлава Роботам!<\/p>\n",
            "summary": "Сегодняшняя КЭНК-история короткая и почти без кода, потому что универсальный скрипт предложить сложно, а главную ценность составляет идея",
            "date_published": "2020-12-16T12:47:29+03:00",
            "date_modified": "2024-10-02T15:25:38+03:00",
            "tags": [
                "PowerShell",
                "Windows Server",
                "все эти ваши компьютеры",
                "КЭНК"
            ],
            "image": "https:\/\/batishchev.ru\/blog\/pictures\/kenk-p7ber2-1.png",
            "_date_published_rfc2822": "Wed, 16 Dec 2020 12:47:29 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "73",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/batishchev.ru\/blog\/pictures\/kenk-p7ber2-1.png"
                ]
            }
        }
    ],
    "_e2_version": 4199,
    "_e2_ua_string": "Aegea 11.5 (v4199)"
}