Сегодня в рубрике «Возвращаясь к напечатанному» приложения, которые прилетают в систему после установки Windows в отличие от применяемых из образа. Строго говоря, я покажу не предотвращение установки, а автоматическое удаление сразу после нее. Зато этот способ подходит для любых приложений и даже поддерживается ;)
⬇️ Скачать архив с файлами из этого руководства.
[+] Сегодня в программе
- Краткая история вопроса
- Суть способа
- Шаг 1 — Выясните журнал и ИД события
- Шаг 2 — Определитесь со стратегией удаления
- Шаг 3 — Сформируйте запрос XPath для поиска события
- Шаг 4 – Подготовьте команды для удаления
- Шаг 5 — Подготовьте запланированное задание
- Шаг 6 – Импортируйте задания в планировщик во время установки
- Результат
- Заключение
Краткая история вопроса
В 2018 году я показывал предотвращение установки с помощью политики Turn off all Windows spotlight features. Однако с тех пор ее действие ограничили изданиями Enterprise и Education в соответствии с документацией. Люди боролись с Яндекс Музыкой и Ко недокументированными твиками, отключая диспетчер доставки содержимого (Content Delivery Manger, CDM). Помимо неясного списка побочных эффектов это не универсальное решение.
Когда в Windows 11 23H2 всем пропихнули приложения Dev Home и новый Outlook for Windows, отключение CDM уже не решало вопрос. Новые твики в итоге обнаружили. Но это же надо ждать, искать их…
Я хочу предложить свой подход к решению задачи в соответствии с девизом блога на примере удаления трех приложений:
- Dev Home
- Outlook for Windows
- Яндекс Музыка
Начиная с Windows 11 24H2 приложения Dev Home и Outlook for Windows входят в состав образа. Поэтому их можно просто удалить из образа моим скриптом.
Суть способа
Мой метод относительно универсальный и не зависящий от того, опубликуют ли в интернетах секретный твик. Однако он не идеальный и под капотом посложнее твика реестра, хотя внедряется легко. Для меня это что-то вроде этюдной задачи с практическим применением.
При установке магазинных приложений вносятся различные записи в журналы событий. Можно определить конкретный журнал и ИД события, по которому будет запускаться запланированное задание, удаляющее приложение сразу после его установки.
Полный алгоритм такой:
- Выясните журнал и ИД события.
- Определитесь со стратегией удаления.
- Сформируйте запрос XPath для поиска события, связанного с конкретным приложением.
- Подготовьте команды для удаления приложения.
- Создайте запланированное задание в формате XML для удаления по событию.
- Импортируйте это задание во время установки, например, из файла ответов.
В принципе, можно обойтись без первых трех пунктов, запуская запланированное задание спустя какое-то время после установки ОС. Но это не так гибко, поскольку приложения из магазина прилетают в разное время.
Разумеется, я подготовил для вас все необходимые файлы. Однако вам придется разобраться в деталях, чтобы воспользоваться ими.
Шаг 1 — Выясните журнал и ИД события
В канале Telegram я публиковал простые скрипты PowerShell для поиска событий по всем журналам в Windows 11 и Windows 10. При установке магазинных приложений создается множество событий от разных источников, но не все они полезны. В одних неудобное или кривое форматирование данных, в других конкретная версия пакета, которая меняется со временем.
Кроме того, журналы варьируются в зависимости от [типа доставки] приложения. И я не смог подобрать журнал, где отметились бы все три тестовых приложения в удобном для синтаксиса XPath формате.
Так, в журнале Microsoft-Windows-Shell-Core/Operational событие 62144 регистрирует автоматическую установку всех приложений из образа, а также прилетающий впоследствии Outlook (только в 23H2, далее входит в образ). Однако в этом журнале нет записей об установке Dev Home и Яндекс Музыки. Зато они засветились в событии 116 журнала Microsoft-Client-Licensing-Platform/Admin, где нет Outlook.
Выбранные события могут регистрироваться чуть раньше, чем завершается установка приложения, но это не критично. На данном этапе главное, что в эти события вносится полное имя пакета, посмотреть которое вы можете командой:
Get-AppxPackage | select PackageFamilyName
Шаг 2 — Определитесь со стратегией удаления
У вас два пути – отдельное задние для каждого приложения или единое задание для всех приложений. От этого зависят запросы XPath и команды на удаление.
Отдельное задание для каждого приложения
Запланированное задание будет реагировать на событие установки конкретного приложения и удалять только его. Я рекомендую этот вариант, поскольку он более гибкий и менее подверженный случайностям.
Если предполагается наличие только одного пользователя в системе, можно автоматически удалить задание после первого же запуска. Так ничто не помешает установить приложение вручную, если возникнет такое желание.
Единое задание для всех приложений
После установки каждого приложения будет выполняться попытка удаления всех приложений. Если каких-то еще или уже нет, с ними ничего и не произойдет.
Общее задание кажется удобнее. Однако могут возникнуть накладки, когда несколько приложений устанавливаются параллельно, а попытка удаления вмешивается в процесс установки. Кроме того, автоматическое удаление задания становится сложнее.
Шаг 3 — Сформируйте запрос XPath для поиска события
Сведения о конкретном приложении находятся в текстовой части события.
Точне, в формате XML они записаны в узле EventData
.
<EventData> <Data Name="PackageName">microsoft.windows.devhome_8wekyb3d8bbwe</Data> <Data Name="UserId">NULL</Data> <Data Name="LicenseId">b79ee5a5-24f8-bd24-cb7c-4000d52b54d3</Data> <Data Name="AssociateId">b79ee5a5-24f8-bd24-cb7c-4000d52b54d3</Data> </EventData> </Event>
Заметьте, что в имени пакета нет версии и прочего шума. Это критично для синтаксиса XPath, который в журналах событий имеет множество ограничений, затрудняющих выборку. Это можно обойти, реализовав мониторинг событий с помощью фонового задания PowerShell, что я покажу в будущей статье на другом примере.
В данном случае мне нравится встроенная возможность планировщика запускать задачи от имени системы. И про XPath я еще не писал в блоге. Упражнения с его вырвиглазным синтаксисом я оставляю вам в качестве домашнего задания. А здесь просто приведу готовые примеры запросов.
⚠️ Не вставляйте такой код в файл XML запланированного задания — там требуется другой вид специальных символов.
Поиск одного приложения
Это для удаления каждого приложения отдельным заданием.
Dev Home (только в 23H2, далее входит в образ)
<QueryList> <Query Id="0" Path="Microsoft-Client-Licensing-Platform/Admin"> <Select Path="Microsoft-Client-Licensing-Platform/Admin">*[System[Provider[@Name='Microsoft-Client-Licensing-Platform'] and (EventID=116)] and EventData[Data[@Name='PackageName']='Microsoft.Windows.DevHome_8wekyb3d8bbwe']]</Select> </Query> </QueryList>
Outlook for Windows (только в 23H2, далее входит в образ)
<QueryList> <Query Id="2" Path="Microsoft-Windows-Shell-Core/Operational"> <Select Path="Microsoft-Windows-Shell-Core/Operational">*[System[Provider[@Name='Microsoft-Windows-Shell-Core'] and (EventID=62144)] and EventData[Data[@Name='PackageFamilyName']='Microsoft.OutlookForWindows_8wekyb3d8bbwe' and Data[@Name='ErrorCode']='0']]</Select> </Query> </QueryList>
Чтобы убедиться в правильной работе запроса, откройте журнал, в правой панели нажмите Фильтр текущего журнала и на вкладке XML вставьте код запроса. Разумеется, искомое событие должно быть зарегистрировано в этом журнале.
Поиск нескольких приложений
Это для удаления всех приложений одним заданием.
<QueryList> <Query Id="0" Path="Microsoft-Client-Licensing-Platform/Admin"> <Select Path="Microsoft-Client-Licensing-Platform/Admin">*[System[Provider[@Name='Microsoft-Client-Licensing-Platform'] and (EventID=116)] and EventData[Data[@Name='PackageName']='Microsoft.Windows.DevHome_8wekyb3d8bbwe']]</Select> </Query> <Query Id="1" Path="Microsoft-Client-Licensing-Platform/Admin"> <Select Path="Microsoft-Client-Licensing-Platform/Admin">*[System[Provider[@Name='Microsoft-Client-Licensing-Platform'] and (EventID=116)] and EventData[Data[@Name='PackageName']='A025C540.Yandex.Music_vfvw9svesycw6']]</Select> </Query> <Query Id="2" Path="Microsoft-Windows-Shell-Core/Operational"> <Select Path="Microsoft-Windows-Shell-Core/Operational">*[System[Provider[@Name='Microsoft-Windows-Shell-Core'] and (EventID=62144)] and EventData[Data[@Name='PackageFamilyName']='Microsoft.OutlookForWindows_8wekyb3d8bbwe' and Data[@Name='ErrorCode']='0']]</Select> </Query> </QueryList>
Шаг 4 – Подготовьте команды для удаления
Команда зависит от того, будете вы удалять ненужные приложения отдельными заданиями или все сразу в рамках одного задания. Также учтите, что приложение может устанавливаться не только у одного пользователя, но еще и подготавливаться для всех пользователей (Dev Home, Outlook). Во втором случае понадобится на одну команду больше.
Я сразу приведу команды формате XML для запланированного задания.
Удаление приложений по одиночке
Яндекс Музыка – только установленные у пользователей пакеты.
<Exec> <Command>powershell</Command> <Arguments>-noprofile -command "sleep 120; Get-AppxPackage -AllUsers | where Name -match 'Yandex.Music' | Remove-AppxPackage -AllUsers"</Arguments> </Exec>
Двухминутной паузы перед удалением должно хватить на период между регистрацией в журнале и завершением установки.
Dev Home — пакеты установленные у текущих пользователей и подготовленные для новых пользователей
<Exec> <Command>powershell</Command> <Arguments>-noprofile -command "sleep 120; Get-AppxPackage -AllUsers | where Name -match 'DevHome' | Remove-AppxPackage -AllUsers; Get-AppxProvisionedPackage -Online | where PackageName -match 'DevHome' | Remove-AppxProvisionedPackage -Online"</Arguments> </Exec>
Для однопользовательской системы вы можете добавить в конце удаление задания после выполнения:
; Unregister-ScheduledTask -TaskName DeleteDevHome -Confirm:$false
Удаление всех приложений сразу
<Exec> <Command>powershell</Command> <Arguments>-noprofile -command "sleep 300; Get-AppxPackage -AllUsers | where Name -match 'DevHome|Outlook|Yandex.Music' | Remove-AppxPackage -AllUsers; Get-AppxProvisionedPackage -Online | where PackageName -match 'DevHome|Outlook' | Remove-AppxProvisionedPackage -Online"</Arguments> </Exec>
Здесь задержка выполнения в 5 минут на случай параллельной установки приложений. Второе отличие от предыдущей команды — выборка всех искомых пакетов оператором -match
. Все найденные приложения будут удалены.
Шаг 5 — Подготовьте запланированное задание
Вы можете создать каждое задание вручную с триггером на событие по фильтру XPath и командой на удаление. А потом экспортировать его.
Но проще импортировать готовое задание, конечно. Ссылка на архив в начале статьи. Обязательно проверьте импорт и корректность отображения фильтра XPath до включения заданий в дистрибутив.
В экспортированном задании символы < и > заменяются на эквивалентные сущности. При ручной правке задания легко запутаться. Надежнее настроить запрос в графическом интерфейсе планировщика и экспортировать задание.
Шаг 6 – Импортируйте задания в планировщик во время установки
Для этого вполне подойдет файл ответов. Он же послужит маркерным файлом для синхронной команды PowerShell. Вы уже видели этот прием в статье про настройку профиля Default.
Скопируйте файлы заданий в корень установочной флешки, и команда импортирует их все в планировщик. Обратите внимание, что она ищет XML-файлы, у которых имя начинается с Del
.
<RunSynchronousCommand wcm:action="add"> <!-- The Path string must be less than 260 symbols --> <Path>powershell -command "(Get-Volume).DriveLetter | Foreach-Object {if (Test-Path "${PSItem}:\AutoUnattend.xml") {Get-ChildItem "${PSItem}:\Del*.xml" | %{schtasks /create /xml $($_.FullName) /tn $($_.BaseName)}}}"</Path> <Order>25</Order> <Description>Import scheduled tasks</Description> </RunSynchronousCommand>
Если вы предпочитаете setupcomplete.cmd, он тоже сгодится. При необходимости поправьте путь к маркеру.
Результат
На картинке успешно отработали задания по удалению Dev Home и Outlook, а Яндекс Музыка пока не прилетала.
Однако успех в планировщике лишь означает, что само задание отработало без ошибок. Проверку наличия пакетов выполняйте так:
Get-AppxPackage | where name -match 'DevHome|Outlook|Yandex.Music' Get-AppxProvisionedPackage -Online | where packagename -match 'DevHome|Outlook'
Заключение
Планировщик рулит, но костыль суровый получился, конечно :) Зато когда Microsoft решит пропихнуть следующее приложение, достаточно будет проверить наличие события в журнале и добавить XML задания в образ.
К сожалению, в последнее время компания регулярно проталкивает приложения и фичи, игнорируя здравый смысл.
Установку Dev Home в домашних изданиях я еще могу понять, но зачем же запрещать его удаление в GUI? Особенно если вы планируете напихать туда еще несколько утилит PowerToys. А почему в корпоративных изданиях устанавливали Teams и закрепляли чат на панели задач, они и сами не знают. Потому что в 23H2 его уже передумали закреплять.
Я уже озвучивал в блоге мысль, что противостояние этим действиям все больше напоминает борьбу с ветряными мельницами. Однако по ходу дела появляется возможность разобраться с некоторыми аспектами работы системы и узнать что-то новое. Поэтому я и публикую такие статьи.
Я благодарю читателя Андрея Шубина за помощь в подготовке статьи.
Dhowti
Автоматизация и встроенные средства это здорово и полезно для развития, но лично я поудалял через Soft Organizer :) В нём всё видно и удаляется. И бесплатно, если не нужны расширенные опции. Правда, долго искал Dev Home, не знал, как по-русски назвали. А там что-то про разработчика. Поставить можно через Winget.
Vadim Sterkin
Для удаления обсуждаемых приложений не нужны сторонние программы
Andrej A.
Автору респект за решение, без вопросов. Но глядя на эти пляски с бубном 80-го уровня всего лишь(!) по удалению пары приложений возникает мысль, что МС свернула не туда. Такой ОС просто нельзя доверять — что завтра она притащит на твой комп? Не проще ли поставить LTSC, где нет этого магазина, и соответственно нет этой проблемы? Еще несколько лет назад Линукс упрекали в сложности — да ладно, там такое колдунство и не снилось! А если и есть какие-то сложные кейсы, так они хотя бы оправданы
Vadim Sterkin
Для начала в Windows 11 нет издания LTSC
Блажен кто верует ©
Andrej A.
Значит все еще хуже чем можно было представить. Остается вариант использования WSUS (реального или несуществующего, чтобы избежать таких сюрпризов) или опять будут в моде отключенные обновы + апдейт-паки как в свое время было для предыдущих версий ОС.
Vadim Sterkin
Я не знаю, что вы себе представляли, но принудительное проталкивание приложений существует как минимум с 2016 года. Тогда появилась политика Turn off all Windows spotlight features. И с самого начала она официально поддерживалась только в корпоративных изданиях.
У организаций, конечно, могут быть вопросы, как централизованно предотвратить появление Dev Home. Но для домашних пользователей по большому счету ничего не поменялось кроме набора приложений.