После установки ноябрьского пакета обновлений Windows 11 скрипт, который годами запускался без нареканий, может перестать проходить проверку подписи. Внешне файл не менялся, подпись на месте, но Get-AuthenticodeSignature возвращает статус NotSigned. Причина — в KB5132061: Microsoft ужесточила проверку кодировки текста при подписании и верификации цифровых подписей.
Речь не о новой политике безопасности и не о сбое. Windows и раньше разбирала содержимое скрипта при проверке подписи, но допускала поблажку: недопустимые символы вроде бы заменялись в процессе декодирования, и проверка проходила. Теперь некорректный UTF-8 отклоняется однозначно, а вместе с ним — и подпись файла.
Почему обновление Windows 11 ломает подпись скриптов PowerShell
Подпись Authenticode считается по байтам файла, но перед этим система читает текст, чтобы привести его к каноническому виду. Если в файле лежат битые последовательности UTF-8 — остатки старой кодировки Windows-1251, обрезанные символы, случайный байт после копирования через буфер, — прежняя версия декодера подставляла замену и продолжала работу. Новая версия на таком файле останавливается.
Дальше цепочка короткая. Раз содержимое не удалось прочитать корректно, проверяющий код не может подтвердить, что подпись относится именно к этим данным. Результат — отказ. Тот же отказ получает и попытка подписать файл заново командой Set-AuthenticodeSignature: подпись не ставится на файл, который не декодируется.
Самое неприятное здесь — эффект отложенного действия. Скрипт никто не трогал, он просто лежал на сетевом ресурсе или в папке задач планировщика, и проблема проявляется не в момент обновления, а при первом же запуске — часто ночью или в выходные, когда срабатывает регламентное задание.
Какие файлы попадают в группу риска
Не всякий старый скрипт пострадает. Основной признак — файл сохраняли в кодировке, отличной от UTF-8 с меткой порядка байтов (BOM), либо он прошёл через цепочку редакторов и систем контроля версий, где кодировку могли исказить. Чаще всего это наработки, которые создавались в начале 2010-х и с тех пор кочевали по копиям, архивам и общим дискам.
Второй типичный случай — скрипты с русскими комментариями и сообщениями в выводе. Кириллица в кодировке Windows-1251 при чтении как UTF-8 как раз и даёт недопустимые последовательности. Файл с латинскими командами и без комментариев обычно проходит проверку без изменений.
Что стоит проверить в первую очередь:
- скрипты для задач планировщика, которые запускаются по расписанию и без участия человека;
- файлы, подписанные внутренним сертификатом организации, а не публичным удостоверяющим центром;
- модули и библиотеки, подтягиваемые из общих сетевых папок;
- архивные версии скриптов, которые «на всякий случай» лежат рядом с рабочими.
Отдельно про инфраструктуру: изменения не ограничены Windows 11. Рекомендации Microsoft распространяются на Windows 10 Enterprise LTSC 2021 и отдельные версии Windows Server, включая Windows Server 2025. В смешанном парке обновление может прийти на сервер раньше, чем на рабочую станцию администратора, и тогда проблема всплывёт на стороне, которую никто не проверял.
Чем это отличается от обычной ошибки политики выполнения
Сообщение о неподписанном файле при включённой политике AllSigned выглядит похоже, но причина другая. Там система прямо говорит, что подписи нет. Здесь подпись физически присутствует в файле, а статус NotSigned — следствие того, что проверка не смогла достоверно сопоставить её с содержимым. Лечить такой случай правкой политики выполнения бессмысленно, а иногда и вредно: политику ослабят, а ошибка останется.
Как найти проблемные скрипты до того, как они откажут
Проверка сводится к двум проходам по парку файлов. Первый — технический: получить статус подписи для каждого скрипта в каталоге и отобрать те, что раньше считались подписанными. Второй — содержательный: посмотреть, в какой кодировке файл реально сохранён.
Microsoft выпустила отдельный инструмент для исправления скриптов PowerShell, рассчитанный на массовую обработку. Он сканирует файлы на наличие проблем с кодировкой и пытается их устранить, сохраняя существующие подписи. Оригиналы при этом не перезаписываются — это важно, потому что даёт возможность откатиться. Но автоматика справляется не со всеми случаями, и часть файлов придётся разбирать вручную.
| Симптом | Вероятная причина | Что делать |
|---|---|---|
| Get-AuthenticodeSignature возвращает NotSigned при наличии подписи | Некорректный UTF-8 в исходном файле | Пересохранить в UTF-8 с BOM и подписать заново |
| Set-AuthenticodeSignature завершается ошибкой | Файл не декодируется, подпись не ставится | Сначала устранить проблему кодировки, потом подписывать |
| Скрипт работал до апдейта, отказал после перезагрузки | Проверка подписи при запуске задачи | Прогнать через инструмент Microsoft, проверить результат вручную |
| Ошибка только на сервере, на рабочей станции всё в порядке | Разные сроки установки обновлений | Сверить версии KB на всех узлах, где исполняется скрипт |
Массовая проверка удобна тем, что даёт картину целиком, но опираться только на неё рискованно. Инструмент может поправить кодировку в файле, который в остальном работал иначе, чем ожидает администратор. Поэтому перед прогоном по продуктивному каталогу нужна копия.
Порядок восстановления подписи
Порог входа здесь низкий: нужен текстовый редактор, умеющий сохранять UTF-8 с BOM, и доступ к сертификату, которым скрипт подписывался. Само восстановление занимает минуты на файл, но требует аккуратности в одном месте — при сохранении легко потерять исходные байты безвозвратно.
- Открыть файл в редакторе, который показывает текущую кодировку, и убедиться, что проблема действительно в ней, а не в отсутствии подписи.
- Сохранить файл в UTF-8 с меткой порядка байтов, проверив, что кириллица в комментариях и строках вывода отображается корректно.
- Просмотреть содержимое на предмет символов, попавших случайно: обрезанные слова в комментариях, странные знаки в начале или конце строки, лишние байты после последней команды.
- Подписать файл заново тем же сертификатом и повторно запросить статус подписи.
- Прогнать скрипт в тестовом окружении до того, как возвращать его в регламентное задание.
Шаг с просмотром содержимого часто пропускают, а он важен. Исправление кодировки не убирает символы, которые когда-то попали в файл при копировании, — оно лишь делает их корректно закодированными. Если в теле скрипта остался мусорный фрагмент, после пересохранения он станет валидным UTF-8 и спокойно пройдёт проверку подписи, но при исполнении поведёт себя непредсказуемо.
Что обычно делают неправильно
Первая реакция при отказе подписи — отключить проверку или ослабить политику выполнения на узле. Это снимает симптом на одной машине и создаёт привычку, которая однажды сработает против администратора: скрипт с испорченной кодировкой продолжит выполняться, а вместе с ним и любой подменённый файл.
Вторая ошибка — пересохранить файл в UTF-8 без BOM. Некоторые редакторы предлагают такой вариант по умолчанию, и для PowerShell это не то же самое, что UTF-8 с меткой. Разница проявляется именно на этапе проверки подписи.
Третья — массовая правка без резервной копии. Инструмент Microsoft оригиналы не перезаписывает, но ручная обработка в редакторе такого поведения не гарантирует. Если в каталоге сотня скриптов и часть из них уникальна, откат без копии будет болезненным.
«Изменение затрагивает не только новый код, но и накопленный за годы. Проверять нужно то, что реально исполняется, а не то, что лежит в репозитории для порядка.»
Практика системного администрирования
Есть и четвёртый сценарий, который встречается реже, но обходится дороже: скрипт подписан сертификатом, срок действия которого истёк. Тогда усиление проверки кодировки лишь ускоряет отказ, а настоящая причина — в сертификате. Проверять срок действия стоит сразу, чтобы не тратить время на пересохранение файла, который всё равно не пройдёт проверку.
Ограничения и случаи, когда автоматика не поможет
Скрипты, где кириллица присутствует в виде строковых литералов и участвует в сравнениях или путях, требуют ручной проверки после исправления. Замена байтов могла изменить содержимое строки, и логика ветвления тихо сломается — без ошибки, просто пойдёт по другой ветке.
Файлы, сохранённые в однобайтовой кодировке с частичной потерей символов, автоматически восстановить нельзя: часть данных утрачена ещё при первом сохранении. Такие скрипты придётся переписать или найти исходную версию в резервной копии.
Отдельно — сценарии, где подпись ставилась не организацией, а внешним поставщиком. Переподписать чужой скрипт своим сертификатом технически можно, но это меняет модель доверия: система будет доверять файлу на основании сертификата организации, а не разработчика. Для внутренних задач это допустимо, для стороннего ПО — требует отдельного решения и, возможно, согласования со службой безопасности.
С чего начать проверку на своём парке
Разумный первый шаг — выгрузить список скриптов, которые запускаются по расписанию и участвуют в критичных процессах, и прогнать по ним проверку статуса подписи. Если проблемных файлов единицы, быстрее обработать вручную: сохранить копию, пересохранить в UTF-8 с BOM, переподписать и проверить запуск в тестовом окружении. Если счёт идёт на десятки, стоит сначала опробовать инструмент Microsoft на копии каталога, сверить результат и только потом запускать его по продуктивным путям — с обязательным резервным копированием перед прогоном.
