Windows 11, 10, etc - Вадим Стеркин
14.6K subscribers
281 photos
6 videos
8 files
1.08K links
Авторский канал. Windows, безопасность, мобильный мир:
• тайное знание
• мощный ликбез
• гадание по логам
• срыв покровов
• доставка пруфов

Чат: @winsiders
Блог: outsidethebox.ms
ЛС: @vsterkin
Донаты ₽: boosty.to/sterkin
РКН: https://clck.ru/3LBugC
Download Telegram
🏃‍♂️ Запуск программ от имени администратора из диалога Run (Выполнить)

Вопрос из форума. Срыва покровов тут нет, но всегда найдутся те, кто не в курсе новинок 6- и 15-летней давности :)

👉 Ctrl + Shift + Enter!

Разумеется, запрос UAC появится. Это #классика канала, см. здесь контекст и дополнительное ускорение. Жаль, что в адресную строку проводника это не прикрутили. Ведь там текущий путь передается в консоль.

ТС однако ответ не устроил, ибо не работает в 1607 🤦‍♂️ Что ж, можно и поглубже копнуть. Есть классика времен в Windows 7 - запуск из планировщика, причем без запроса UAC! Поскольку ссылка не у всех откроется где надо, скопирую суть сюда.

🕑 В планировщике создаётся задание:
schtasks /Create /RL Highest /TN Run /SC ONCE /ST 14:00 /TR "cmd.exe /c start %WINDIR%\SysWOW64\rundll32.exe shell32.dll,#61"

И запускается:
schtasks /run /tn Run

Для этой команды можно сделать ярлык, закрепить на панели задач и/или повесить на него сочетание клавиш.

▶️ Вне диалога "Выполнить" для отдельных приложений запуск с полными правами можно форсировать так:

🔹 В свойствах EXE на вкладке "Совместимость" или в свойствах ярлыка - "Дополнительно" поставить флажок "Запускать от имени администратора".

🔹 Задействовать в #PowerShell командлет Start-Process и его глагол RunAs:
powershell -ex bypass -command Start-Process notepad -Verb RunAs

Разумеется, для этой цели есть и другие встроенные способы (да хоть VBS с тем же глаголом), а также куча сторонних утилит.

#Классика блога в тему:
🔸 Как выполнять задачи с полными правами обычным пользователем без ввода пароля администратора
🔸 Как выполнять команды и скрипты от имени системы средствами Windows
🔸 Как выполнять скрипты с правами TrustedInstaller без сторонних утилит
▶️ Модуль PowerShell для winget

Сегодня в рубрике "Возвращаясь к напечатанному" модуль #PowerShell для менеджера пакетов winget. Разбирая нюансы автоматического обновления приложений осенью 2022 года, я сетовал на неудобство командной строки. Потому что парсинг текста заведомо проигрывает управлению объектами в PowerShell.

Полгода спустя вышла альфа-версия официального модуля, и он продолжает развиваться. К сожалению, это не полноценный модуль, а обертка над утилитой winget 🤷‍♂️ Командлетов пока маловато, и до полного набора возможностей еще далеко. Но уж чем богаты...

📄 Основы

Рекомендуется использовать PowerShell Core нежели входящий в ОС PowerShell 5.1.

# установить модуль winget
Install-Module -Name Microsoft.WinGet.Client

# найти пакет в репозиториях по частичному имени
Find-WinGetPackage -Name 'Bitvise SSH'


Заметьте, что вопреки общепринятой практике здесь не требуется указывать подстановочный символ *. Наоборот с ним ничего не найдется. Одинарные кавычки необходимы при наличии пробелов в имени.

# найти пакет только в репо магазина
Find-WinGetPackage -Name treesize -Source msstore

# обновить все пакеты IrfanView (приложения, плагины)
Get-WinGetPackage -Name irfanview | Update-WinGetPackage


☑️ Работа со списком пакетов

# список всех установленных пакетов
$p = Get-WinGetPackage
# список пакетов с доступными обновлениями
$p | where IsUpdateAvailable
# список пакетов с доступными обновлениями из магазина
$p | where IsUpdateAvailable | where Source -eq msstore
# список пакетов в виде интерактивной таблицы
$p | Out-GridView
# список пакетов в CSV
$p | ConvertTo-CSV | Out-File -Path C:\temp\winget.csv


🔁 Выборочное обновление пакетов

# обновить все пакеты при наличии новой версии, кроме указанных
$p | where IsUpdateAvailable | where Name -notmatch 'calibre|zoom'
| Update-WinGetPackage


Это альтернатива команде pin, которую я недавно разбирал в канале.

# Обновить все, кроме терминала, если он запущен
$u = Get-WinGetPackage | where IsUpdateAvailable
if (Get-Process -ProcessName WindowsTerminal) {
$u | where id -notmatch 'WindowsTerminal' |
ForEach-Object {Update-WinGetPackage -id $_.Id}
}
else {
$u | ForEach-Object {Update-WinGetPackage -id $_.Id}
}

Результат этого скрипта на картинке↓ Кстати, начиная с версии 1.20 установленный из магазина Terminal не должен обновляться, если запущен. Было много жалоб - например, убиваются удаленные сессии.

В общем, с этим модулем можно работать в каких-то сценариях. Разумеется, хотелось бы большего охвата нативных функций - например, команды show. Надеюсь, в будущем мы это увидим ✌️
💡 О каких фишках Windows и ПО Microsoft вы жалеете, что не узнали пораньше?

Я достаточно давно ковыряюсь в Windows, слежу за темой, поэтому меня трудно удивить. Бывает, нахожу новые фичи, о которых успел забыть! Иногда даже обнаруживаю их упоминания в своем блоге :)

Поэтому свой топ-3 я составил не без труда.

🥇 В MS Office двойной щелчок по значку "Формат по образцу" позволяет применять его многократно. Да, я достаточно долго тыкал в кнопку каждый раз 🤷‍♂️

🥈 В диалоговом окне "Открыть" в поле "Имя файла" можно вставлять скопированный файл по Ctrl+V, и туда вставится его путь! Зачастую в файловом менеджере папка с файлом уже открыта или до него проще добраться, чем из диалогового окна. Я регулярно заливаю файлы в интернет таким способом, видео ⬇️ С файлами из интернета тоже работает!

🥉 Ctrl+Z может работать даже там, где не указано явно. Например, в проводнике возвращает на место удаленный файл. Надо пробовать!

А это топ-3 реакций коллег по работе на мои советы.

1️⃣ История буфера обмена в Windows - Win+V. Да, он в подметки не годится продвинутыми менеджерам вроде Charu или Ditto. Но даже это в разы лучше чем ничего.

2️⃣ Вертикальные вкладки браузера - например, в Edge. Когда у вас несколько вложенных сессий RDP, их панели вверху экрана либо постоянно перекрывают вкладки браузера, либо выезжают в ненужный момент. Перемещение вкладок вбок отлично решает эту проблему.

3️⃣ Скрипты #PowerShell. Даже простой однострочник может творить чудеса. Дзен наступает, когда скрипт выполняет за 10 секунд работу, на которую раньше уходило полчаса. Иногда достаточно просто показать человеку путь на конкретном примере.

📢 В обсуждении поделитесь топом своих открытий! Не удивлюсь, если о каких-то вы узнали из моих публикаций ;)
⚙️ О подходах к диагностике - простых и сложных

Однажды я обнаружил, что у меня не работает магазин Windows: вместо содержимого - ошибки. Я очень редко открываю его, поэтому не знал, в какой момент возникла проблема. Но я ничего не менял у себя очень давно. Вместо диагностики я просто установил нужное приложение с помощью winget и пошел дальше.

Спустя какое-то время у меня возник ворох проблем, вызванных сбоем файловой системы. Решил их я следуя своему же любимому совету - переустановил систему поверх 🔃 Однако Магазин это не починило, что намекало на несистемную природу неполадок.

🌐 С сетью у меня было все ок. Я подключился к двум разным VPN, но ничего не изменилось. Oткрыл консоль и сделал сброс магазина, а затем полностью переустановил его. Не помогло. Тогда я зашёл в чистый аккаунт, и в нем такой проблемы не было. Значит, что-то с моим профилем 💯

Чтобы исключить влияние внешних факторов, я убрал все из автозагрузки и наконец перезагрузился. Магазин заработал! И только тут я связал сообщение о проблемах с сетью с установленным у меня клиентом прокси-сервера (SOCKS5). Разумеется, он стоял в автозапуске. Действительно, без прокси магазин заработал! 🎉

👉 7 лет назад я опубликовал тут пост "Простой прием диагностики Windows, о котором не надо забывать". Речь шла о загрузке в безопасный режим. Как и в тот раз, об этом приеме я сейчас успешно забыл :) Но в итоге фактически пришел к нему, потому что в безопасном режиме автозагрузка тоже не работает. Также, ее отключение - это часть режима "чистой загрузки" в терминологии Microsoft, см. KB929135.

////

ℹ️ На практике множество проблем в Windows легко решается простой двухходовкой:
1. Безопасный режим.
2. Если в нем воспроизводится - переустановка поверх, иначе - поиск проблемной программы или службы.

Но этому часто мешают разные факторы:
- нежелание перезагружаться
- знание, что "ничего не делал" смещает фокус диагностики - я чинил магазин, хотя проблема решалась в прокси
- переоценка своих навыков - я знаю #PowerShell и еще много страшных слов :)
- или наоборот недооценка знаний, которая сходу ведет в гуглояндекс, где на бестолковых и "сеошных" советах можно потерять кучу времени

В результате вместо простой диагностики получается квест из сложной 🤷‍♂️

В чате Артём Федотов заметил, что переустановка поверх не повышает уровень знаний, потому что остается невыясненной причинa проблемы. Это правда.

Однако не всегда нужно и целесообразно ее выяснять. Да и не факт, что понимание причины как-то повысит уровень знаний. Ок, узнал я, что проблема в прокси-сервере. Так у меня и раньше с ним внезапно отваливались сервисы Microsoft из-за изменений на их серверной стороне - то не работала Кортана, то блокировался русский голосовой ввод. Решение - тема для отдельного разговора.

В общем, я не имею ничего против сложных методов диагностики. Главное - не забывать о простых ✌️
⬇️ winget: быстрая установка своего набора программ на чистой системе

Недавно я рассказывал в блоге, как прицепить установку программ с winget к автоустановке Windows. (А заодно как установить winget в Windows Server и изданиях LTSC :) В статье был скрипт с ручной подборкой приложений для winget. Создание такого набора можно существенно автоматизировать!

👉 У winget есть команды export и import.

В настроенной системе эта команда сохранит json со списком программ в текущую папку:
winget export -o apps.json


В чистой системе эта команда установит приложения из списка:
winget import C:\temp\apps.json --ignore-unavailable --accept-package-agreements --accept-source-agreements


🤺 Теперь нюансы.

🔹 В список попадут только приложения, доступные в подключенных репозиториях. По умолчанию - это winget и msstore (репо магазина Windows).

🔹 Вы можете убрать ненужные приложения, открыв json в текстовом редакторе. По умолчанию winget пытается обновить приложения до новой версии. Если ее нет, он ничего не делает. Поэтому не тратьте время на удаление из списка предустановленных приложений и компонентов вроде "Microsoft.Edge" и "Microsoft.UI.Xaml.2.8".

🔹 Файл структурирован по репозиториям. Для экспорта конкретного репо есть ключ -s: -s msstore. К сожалению, в этом репо по идентификатору вида 9N8G7TSCL18R невозможно определить приложение. Можно подставить ИД в ссылку на веб-версию магазина или пройтись по json скриптом #PowerShell:

$json = Get-Content -Path "apps.json" -Raw | ConvertFrom-Json
$msstore = $json.Sources | Where-Object {$_.SourceDetails.Name -eq "msstore"} |
ForEach-Object {$_.Packages.PackageIdentifier}
$msstore | ForEach-Object {explorer https://apps.microsoft.com/store/detail/$($_); sleep 1}
# $msstore | ForEach-Object {Get-WinGetPackage -Id $_ -MatchOption Equals} | ft ID,Name -Wrap


Вместо открытия веб-версии магазина вы можете вывести названия с помощью модуля PowerShell (последняя строка).

🔹 Вы можете добавить в список прочие приложения, посмотрев их ИД командной search:
winget search nanazip

Разумеется, добавлять ИД нужно в раздел соответствующего репо, иначе при установке программа не найдется.

🔹 В список не попадут приложения, которые были установлены из образа вместе с системой (winget сообщает о каждом в процессе экспорта). Причем даже с помощью winget нельзя просто взять и получить список их магазинных ИД. Да и не все они доступны в репо магазина. Поэтому команда search в помощь.

✔️ Резюме
Команды import и export призваны ускорить создание привычной среды на чистой системе. И они неплохо с этим справляются! Да, не все программы есть в репозиториях, а перенос настроек приложений - отдельная большая тема. Но грех жаловаться на возможность одной командой установить несколько десятков любимых программ ✌️
▶️ Windows Terminal: перемещение курсора мышью и фрагменты кода

Хочу рассказать вам о паре новых возможностей терминала.

🖱 Перемещение курсора мышью

Нередко бывает, что надо изменить длинную команду. И чтобы перейти в нужное место, приходится давить ⬅️ или ➡️ либо нажимать их, удерживая Ctrl, что быстрее.

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

Этой фичей я уже пользуюсь несколько месяцев в превью терминала, а вчера она стала доступна в стабильной версии. Настраивается для профилей в дополнительных параметрах. Можно включить это поведение для отдельных профилей или сразу для всех (Defaults). Разумеется, у ненужных профилей можно отключить.

Но есть нюанс © Функция экспериментальная, и работает она только в оболочках которые её поддерживают. Например, это PowerShell Core, но не Windows #PowerShell, идущий в комплекте с ОС.

#️⃣ Фрагменты кода (code snippets)

Это только что появилось в превью терминала (я попробовал еще в Canary). Можно сохранять команды и даже небольшие скрипты. И быстро запускать их!

🎦 Демо от ПМа терминала.

По сути осуществляется ввод символов, прописанных в настройках (JSON-файл). В раздел actions добавляйте действие Send Input с нужным фрагментом.

{ "command": 
{
"action": "sendInput",
"input": "ping 1.1.1.1\r ping colts.com\r"
},
"name": "Demo ping",
"keys": "ctrl+alt+p"
}


В этом примере последовательно пингуются два ресурса (\r эмулирует нажатие клавиши Enter).

Сейчас для вызова повторных команд в моем арсенале поиск по истории (Ctrl+R) и Predictive IntelliSense (п. 3, фича модуля PSReadLine). Однако оба способа нередко "замусориваются" вариациями одной команды. Плюс можно выполнять фрагмент заданным сочетанием клавиш. Поэтому я уже вижу применение фрагментам кода!

Попробуйте эти фичи и поделитесь впечатлениями в чате! ✌️
⚙️ Как быстро восстановить разрешения на файл или папку

Недавно в чат поддержки пришел человек, который собственноручно сломал разрешения файла hosts. Он творил полную дичь - пытался сделать этот файл только для чтения, чтобы не слетел некий кряк 🤦‍♂️

Зато у меня появился повод показать один из моих любимых примеров мощи конвейеров в #PowerShell. От имени администратора:

cd C:\Windows\System32\drivers\etc
Get-Acl networks | Set-Acl hosts


В оригинале была одна команда, но так нагляднее. Перейдя в папку с файлами, берем список контроля доступа (ACL) у соседнего файла networks и применяем его к поврежденному hosts. Это всё! Восстанавливаются разрешения на объект файловой системы и его владелец.

ℹ️ Параметр -Path для пути к файлу я опустил. У этих командлетов он первый позиционный, т.е. подразумевается, если не указан. Такие вещи описаны в справке.

Проблему автора вопроса это решило, но ничему не научило. Уже через 5 минут он спросил, как изменить владельца родительской папки etc. Потому что не получалось сохранить измененный файл hosts 🤦‍♂️🤦‍♂️ В его инструкциях же не уточнялось, что текстовый редактор надо запускать от админа...

Вообще, правка разрешений нужна крайне редко. А для внесения изменений в файлы или реестр она фактически не требуется. На такой случай у меня есть отличная #классика блога с быстрым и грамотным способом выполнения операций с правами SYSTEM и TrustedInstaller ✌️
🤷‍♂️ Владельцы локализованных Windows должны страдать

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

Этот тезис получил очередное подтверждение на прошлой неделе. Множество пользователей VMWare Workstation из разных стран не смогли установить новую версию. Всех их объединяло наличие локализованной системы.

An error occurred while applying security settings. Authenticated Users is not a valid user or group.

Методом тыка страдальцы выяснили: установка проходит на ура, если создать в системе две группы с латинскими названиями - Authenticated Users и Users. Причем членство в этих группах не требуется.

Видимо, установщик просто проверял наличие этих групп по именам. Но такие имена будут только при установке с английского дистрибутива! А вот дальнейшая установка языкового пакета на имена групп уже не повлияет 👌

///

По совпадению я недавно разбирал похожую ситуацию на работе. Нас мигрируют в огороженную среду с правами обычного пользователя, поэтому повылезало много проблем с установкой бизнес-приложений. Детали опущу, но вкратце - некоторые программы легко ставятся мимо Program Files и нормально работают дальше. Прочие же этому противятся, причем нетрадиционными способами 🌈

Нормальные разработчики уже лет дцать используют манифест установщика. И если там указано requireAdministrator, он будет запускаться только с правами администратора. А тут некое приложение с бородатых времен поставляется в самораспаковывающемся CAB-архиве. Я извлек содержимое командой expand и увидел несколько батников.

Первый батник сходу проверял наличие прав администратора, а при успехе вызывал другие файлы, устанавливающие службу и прочие штуки. Для проверки он искал в выводе команды whoami /groups строку Mandatory Label\High Mandatory Level 🤦‍♂️

Сравните самостоятельно результат выполнения команды в консоли с правами обычного пользователя и администратора. Искомая строка будет только во втором случае, потому что процесс имеет высокий уровень целостности. У классических приложений обычного пользователя он средний (Medium).

🪲 Казалось бы, цель достигнута. Однако вывод команды локализован! Поэтому в русской или итальянской Windows вы с любыми правами такого не увидите. И соответственно вообще не сможете установить приложение этим инсталлятором.

Я предложил инженеру QA занести на это дефект, но он махнул рукой. Видимо, клиентская база использует исключительно английские ОС. Так-то даже на уровне батников можно было решить вне зависимости от языка. Например, такой костыль #PowerShell вызовет из одного батника другой с правами админа.

powershell -command "Start-Process -FilePath '%~dp0batch2.cmd' -Verb RunAs"

Глагол RunAs недавно был в канале. Я также показывал управление локальными пользователями и группами вне зависимости от языка ОС.

////

Я исторически использую Windows на английском языке, поэтому подобные проблемы мне не грозят. Если для вас такое невыносимо, хотя бы ставьте английский дистрибутив и накатывайте родной языковой пакет. Иначе - не забывайте так страдать ✌️
🆕 Что нового в Windows 11 24H2 для ИТ-специалистов и разработчиков

Для начала всем интересующимся Windows рекомендую большие подборки Community (RU) и Winaero (EN).

ℹ️ Для ИТ-специалистов у Microsoft есть статья What's new in Windows 11, version 24H2 с ценным упоминанием о новой иконке диспетчера задач и эффекте Mica в его настройках :) Отмечу многочисленные изменения в SMB и LAPS, а также новинку - Personal Data Encryption (PDE). Это корпоративное шифрование пользовательских папок на уровне файлов под крылом Windows Hello и под управлением Intune.

Для разработчиков я нашел изменения в:
API электропитания в той же статье для IТ Pro
доступе к Wi-Fi и местоположению
разработке драйверов

В остальном Microsoft делает упор на ИИ - NLP, OCR, живые субтитры, Recall.

////

Помимо списка ссылок расскажу про два заинтересовавших меня нововведения в 24H2.

🔁 Чекпойнты накопительных обновлений
Первый выпуск Windows 11 привнес ряд заметных улучшений в накопительные обновления. В 24H2 процесс эволюционировал. До сих пор при доставке обновлений дельта вычислялась относительно состояния компонентов в [условном] RTM.

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

Сокращение размера обновлений будет наиболее заметным в сценарии, когда новая версия ОС доставляется постепенно в рамках накопительных обновлений и включается тумблером. Так было с Windows 11 23H2 и Windows 10 многократно. Теперь #тумблер будут выпускать наряду с чекпойнтом. Он и станет базой для следующих накопительных обновлений, нежели прошлогодний RTM.

Подробнее в блоге IT Pro 📃

▶️ Sudo для Windows
Тут пошли по стопам Linux. Если выполнить с обычными правами, например: fsutil fsinfo ntfsinfo C:, будет ошибка из-за недостатка прав. Придется перезапускать консоль с полными правами.

Включив sudo в настройках разработчика в Параметрах, можно в той же консоли добавить sudo к команде: sudo fsutil fsinfo ntfsinfo C:, одобрить запрос UAC и получить результат!

Подробнее о параметрах sudo для Windows в документации 📃

Запрос UAC придется одобрять каждый раз. В этом заметное отличие UX от Linux, где после ввода пароля его не просят для sudo на протяжении N минут (настраивается) 🐧

Кэш учетных данных есть в gsudo, которая также может повышать команды #PowerShell. Нативная утилита sudo этого не умеет, но у меня есть #классика блога: sudo и resudo в PowerShell ✌️
🔎 Как очистить историю поисковых запросов в меню Пуск

Недавно таким вопросом задался в чате dartraiden, проиллюстрировав ситуацию скриншотом. В течение пары недель этим же интересовались в форуме и снова в чате. Пора писать пост, и я публикую его под одним из девизов канала - срыв покровов!

Казалось бы, простой вопрос, но ответ не лежит на поверхности.

ℹ️ Для начала поиск в Пуске - это фактически отдельное приложение Поиск (Win+S). Именно в него вы переключаетесь, когда в Пуске ищете приложения или настройки либо выполняете поиск в интернете. Все недавние запросы видны сразу при открытии поиска любым способом.

В статье базы знаний KB4553482 есть раздел "Журнал поиска на этом устройстве" с инструкциями по очистке из Параметров. Также в интернетах можно найти совет сбросить приложение Client.CBS (Feature Experience Pack) из #PowerShell:

Get-AppPackage -Name MicrosoftWindows.Client.CBS | Reset-AppxPackage

Якобы все это удаляет историю поисковых запросов в меню Пуск. И это даже правда. Но есть нюанс © Эти действия очищают историю запросов приложения Поиск, хранящуюся локально 💻

Как следствие, это еще не конец нашей истории, а только середина!

☁️ В приложение Поиск возможен вход с учетной записью Microsoft (MSA). Из коробки это происходит автоматически при:
• использовании MSA в Windows вместо локального аккаунта
• первом входе с MSA в любое приложение Microsoft, что влечет за собой вход с этим аккаунтом во все приложения компании

👤 Визуально связь с облачным аккаунтом определяется по аватарке в правом верхнем углу поиска. И в этом случае все поиски в интернете сохраняются в облаке. Более того, там собраны все запросы в Bing, где бы вы их ни делали.

👉 При использовании MSA очистка локальной истории и сброс Client.CBS не помогут убрать из списка поиски в интернете. Потому что вся история Bing заново подтянется в локальное хранилище из облачного аккаунта! Историю поиска в интернете надо удалять в настройках конфиденциальности учетной записи Microsoft, а именно - в истории поиска!

Если внимательно присмотреться к истории запросов dartraiden, там явно не взрослый мужик, а школьники что-то ищут в интернете 😎 Как выяснилось, это "аккаунт, купленный за копейки для доступа к геймпассу". То есть им пользуется множество людей. Поэтому история будет активно пополняться чужими запросами в любом случае!

Кардинальное решение - локально отключить все обращения к Bing политикой или твиком реестра, тут #классика блога в помощь! Это полностью разрывает связь с облаком - поиск перестает подкачивать историю запросов в Bing и веб-содержимое, обретая аскетичный вид. А поиски приложений и настроек можно очистить из Параметров.

The End ✌️
⚙️ Приложения в образе Windows 11 24H2 - состав и удаление

С выходом каждой новой версии Windows я обновляю свой скрипт #PowerShell для удаления ненужных приложений из образа. Он вполне безвредный, поскольку не затрагивает магазин и его служебные приложения, центр безопасности, а также расширения для воспроизведения медиа.

Я смотрю в подключенном автономном образе, но список предустановленных пакетов вы можете увидеть и в работающей системе:

Get-AppxProvisionedPackage -Online | select DisplayName

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

Из служебных пакетов появились три расширения для медиа: AV1, AVCEncoder, MPEG2. А пакет Microsoft.VCLibs.140.00 больше не входит в образ. Дальше - приложения!

Выбыли

🤷‍♂️ 549981C3F5F10 - Cortana, и я затрудняюсь сказать, какую функцию пакет выполнял в последнее время

ℹ️ Getstarted - никому не нужны эти ваши ролики для знакомства с Windows :)

⚰️ People - людей убили достаточно давно, теперь похоронили

📩 windowscommunicationsapps - старые почта и календарь

🗺 WindowsMaps - внезапно, но приложение есть в магазине

🎮 XboxGameOverlay - что-то про GameBar, причем остался XboxGamingOverlay

⏯️ ZuneVideo - Кино и ТВ, и теперь по умолчанию все медиафайлы воспроизводит современный медиаплеер, aka ZuneMusic

Добавились

🔎 BingSearch - затруднюсь объяснить назначение, т.к. поиск в Пуск и панели задач работает и без него

👨‍👩‍👧‍👦 MicrosoftFamily - семейная безопасность (только в Home)

🤞 CrossDevice - это вдобавок к YourPhone, и, возможно, на этот пакет завязаны беспроводное управление файлами телефона и грядущая фича Resume

💬 MSTeams - ранее Teams доставляли после первого входа в систему, и приходилось предотвращать установку

📨 OutlookForWindows - новые почта и календарь, унылые

🧑‍💻 DevHome - в 23H2 прилеталo после первого входа, как и Outlook, причем предотвращать их установку было сложно

////

По традиции я не удаляю выпиленные пакеты из скрипта, а перемещаю их в конец - в качестве неактуальных. Я исследую только последнюю версию Windows 11, а кто-то может готовить образ Windows 10.

На картинке пакеты, которые остаются после работы скрипта. Разумеется, вы можете закомментировать любое приложение и тем самым сохранить его в образе. Равно как всё удаленное можно установить из магазина при необходимости ✌️
⚙️ О зачистке Windows от хвостов приложений

У меня на нескольких системах было установлено приложение VMWare Horizon для удаленного доступа к ВМ заказчика. Тот перешел на Windows 365, поэтому я штатно удалил клиент VMWare из всех ОС и забыл про него.

А спустя несколько месяцев случайно увидел запущенные службы VMWare. На одном компьютере их было три, а на другом аж пять 🤦‍♂️ Что ж, надо зачистить!

Я исторически не доверяю приложениям типа Revo Uninstaller Они в принципе не могут знать о программе больше, чем ее штатный установщик. А выполняя удаление по косвенным признакам, они могут зацепить что-то важное, о чем я знать не буду.

👉 В таких ситуациях я предпочитаю действовать руками. И первой отправной точкой всегда должен быть раздел реестра:

HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall

Я не помню путь наизусть, поэтому всегда гуглю uninstall windows registry и попадаю в KB247501. В этом разделе содержатся сведения обо всех установленных программах. Отсюда подтягивают данные классический апплет appwiz.cpl и раздел Параметров с установленными приложениями.

У большинства подразделов в качестве имени используется GUID, но принадлежность к программе несложно определить визуально. Также можно сделать выборку скриптом #PowerShell за авторством ChatGPT.

Важны эти параметры:
DisplayName - название программы
UninstallString - команда для удаления

У VMWare Horizon в качестве инсталлятора используется Windows Installer. Поэтому для удаления вызывается msiexec с ключом /x, которому передается ИД программы в базе установщика Windows:

MsiExec.exe /X{2B1D0F22-6025-409A-A248-7C10783FD5F2}

После выполнения всех команд из системы удалились службы и оставшиеся папки приложения Horizon✌️
🕒 Как получить сведения о запланированном задании в PowerShell

Смотрел тут свои старые скрипты, решил поделиться. Задача несложная, однако в зависимости от цели может понадобиться три разных запроса.

1️⃣ Состояние задания - Get-ScheduledTask

Годится запрос по имени задания, в том числе неполному. Заодно выведем чуть больше инфо - полное имя, состояние, адрес.

Get-ScheduledTask -TaskName '*sync*lang*' | fl TaskName,State,URI

TaskName : Synchronize Language Settings
State : Ready
URI : \Microsoft\Windows\International\Synchronize Language Settings


Задание синхронизации языковых настроек включено.

2️⃣ Сведения о последним запуске задания - Get-ScheduledTaskInfo

Здесь наряду с именем задания требуется еще и путь в -TaskPath. Либо в качестве имени указывайте URI из запроса выше.

Get-ScheduledTaskInfo -TaskName '\Microsoft\Windows\International\Synchronize Language Settings

LastRunTime : 1/25/2025 10:22:22
LastTaskResult : 0
NextRunTime :
NumberOfMissedRuns : 0
TaskName : \Microsoft\Windows\International\Synchronize Language Settings


LastTaskResult выводит код завершения предыдущего запуска. 0 означает успех, 1 - неудачу, остальное надо смотреть по коду.

На практике задачи 1 и 2 чаще объединяются в конвейер. Причем можно сходу фильтровать по неполным именам нескольких заданий, обходясь без Where-Object.

Get-ScheduledTask -TaskName *backup*,*sync* | Get-ScheduledTaskInfo | fl TaskName,LastRunTime


3️⃣ Параметры задания - Export-ScheduledTask

Export-ScheduledTask -TaskName '\Microsoft\Windows\International\Synchronize Language Settings'


Выводится XML, как в экспорте задания из планировщика. PowerShell легко перемещается по узлам.

[xml]$task = Export-ScheduledTask -TaskName '\Microsoft\Windows\International\Synchronize Language Settings'
$task.Task.Triggers.LogonTrigger.Delay

PT30S


Задание отложено на 30 секунд после входа в систему.

////

Создание запланированного задания в #PowerShell будет посложнее. Я показывал это в блоге, в том числе в сравнении с утилитой schtasks. Бывает проще импортировать подготовленный XML. Пример уже был на канале ✌️
🧹 Удаление временных файлов из служебных профилей

Недавно я анализировал недостаток дискового пространства на одной системе. Помимо прочего утилита dfp выдала такое:

1.6G      527      191 C:\Windows\ServiceProfiles
1.6G 287 81 C:\Windows\ServiceProfiles\NetworkService
1.6G 281 71 C:\Windows\ServiceProfiles\NetworkService\AppData
1.6G 244 39 C:\Windows\ServiceProfiles\NetworkService\AppData\Local
1.6G 243 34 C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp


Я натравил её на папку Temp и выяснил, что 1.6 GB занято древней папкой с именем типа E58DAD6F-63DE-461C-AB9F-7F58DDC916D9

ℹ️ NetworkService и LocalService - служебные аккаунты, чьи профили хранятся в папке Windows. Их содержимое аналогично профилям интерактивных пользователей из папки C:\Users.

Удаление временных файлов безвредно, причем ухищрений не требуется. В смысле не надо ломиться в системные папки как лось, меняя на ходу разрешения NTFS. Просто в #PowerShell от имени администратора:

Remove-Item -Force -Recurse -Path 'C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp\E58D*'


Total Commander или FАR от админа тоже годятся ✌️
⚙️ Нюансы префетчинга приложений в Windows

Сегодня в рубрике "Возвращаясь к напечатанному" префетчинг приложений и количество записей, которые он хранит и обрабатывает.

• В 2013 году я разбирал префетчинг в рамках мифов оптимизации SSD
• В 2019 году он снова попал в фокус в статье Нюансы отключения службы SysMain в Windows

Niks спросил, работает ли префетчинг по умолчанию, когда система установлена на SSD. Да, работает, и это легко проверить по мотивам статьи про SysMain:

Get-MMagent

ApplicationLaunchPrefetching : True
ApplicationPreLaunch : True
MaxOperationAPIFiles : 512
MemoryCompression : True
OperationAPI : True
PageCombining : True


Параметр ApplicationLaunchPrefetching - это он. Вообще, этот префетчинг еще времён XP, и по большому счету с тех пор ничего не изменилось. Однако сравнивая вывод наших команд, я заметил, что отличается значение MaxOperationAPIFiles. Это предельное количество файлов в сфере префетчинга.

🔢 В Windows 10 и ранее оно по умолчанию 256, а в Windows 11 — 512 (так же и в серверных ОС). Думаю изменение связано с тем, что сама ОС разрослась с 2006 года и запускает больше своих исполняемых файлов.

Niks интересовался, стоит ли увеличить значение до 2048. Чтобы ответить на этот вопрос, нужно:

1. Понимать, запускаются ли .EXE с жесткого диска
2. Проанализировать файлы в папке C:\Windows\Prefetch\

Я не думаю, что древний префетчинг способен ускорить запуск программ с твердотельных накопителей. Но запуск исполняемых файлов (например, игр) с жесткого диска еще может быть актуален. Для оценки можно посчитать количество файлов в папке и сопоставить с лимитом. В #PowerShell от имени администратора:

(Get-ChildItem "C:\Windows\Prefetch\*.pf" -File).Count

ℹ️ На количество файлов могут влиять разные факторы. Например, едва установив систему, вы начинаете ставить и запускать любимые приложения. Каждый установщик - это как минимум один исполняемый файл. С другой стороны, после чистой установки система сама оптимизирует себя, что может быть сопряжено с запуском различных .EXE.

Все это оседает в папке Prefetch. По достижении предела старые записи будут вытеснены автоматически, но "одноразовые" установщики и не нужны.

Если в обжитой системе вы запускаете .EXE с HDD, а количество PF-файлов близко к лимиту, может иметь смысл увеличить предельное значение.

Set-MMAgent -MaxOperationAPIFiles 1024

Так, у Niks спустя две недели после очистки и увеличения лимита в папке стало 354 PF-файла. Что превышает стандартный предел в его Windows 10, но далеко от 512 в Windows 11.

Измерить же реальный прирост скорости запуска исполняемых файлов затруднительно. Зато душу будет греть тот факт, что вы оптимизировали свою ОС не случайно найденной в интернетах подборкой твиков, а на основе грамотного анализа ✌️
🚀 Ускорение загрузки файлов в PowerShell

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

1️⃣ Отключение прогресса
$ProgressPreference = 'SilentlyContinue'

В принципе, эта переменная может слегка ускорить процесс и снизить нагрузку на ЦП не только при скачивании файлов. Но конкретно для командлета Invoke-WebRequest (псевдоним iwr) разница значительная! Один и тот же файл размером 175 мегабайт без прогресса у меня на разных системах скачивался от 16 до 42 секунд, а с прогрессом - от 3 до 13 минут! 🤔

У этого командлета проблема наблюдается только в Windows PowerShell 5.1, но не в PowerShell Core. Я писал об этом в канале 7 лет назад :) И недавно краем глаза где-то видел, что якобы в 5.1 уже починили. Мои тесты это не подтверждают.

2️⃣ Подстановка юзер-агента
На самом деле даже без прогресса у меня Invoke-WebRequest качал слишком долго. Я предположил, что сайт специально притормаживает отдачу, и решил прикинуться браузером.

-UserAgent "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"

После этого скорость окончательно наладилась!

3️⃣ Загрузка с помощью BITS
В Windows помимо командлетов Invoke-WebRequest и Invoke-RestMethod также можно скачивать файлы с помощью Start-BitsTransfer. Этот командлет запускает джоб с помощью службы BITS (фоновая интеллектуальная служба передачи данных). Именно ее использует центр обновления Windows.

Это не совсем про ускорение, а про альтернативы. Но в моем случае был сайт Microsoft, и родную BITS он не тормозил в отличие от iwr без юзер-агента.

////

▶️ Скрипт для экспериментов:

$file = "$env:temp\mpam-fe.exe"
$uri = 'https://go.microsoft.com/fwlink/?LinkID=121721&arch=x64'
$u = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
$ProgressPreference = 'SilentlyContinue'

Measure-Command {
Invoke-WebRequest -Uri $uri -OutFile $file -UserAgent $u
}
Measure-Command {
Start-BitsTransfer -Source $uri -Destination $file
}


Скрипт скачивает актуальный файл сигнатур защитника Windows с этой страницы. Но учтите, что для обновления сигнатур из консоли есть методы получше ✌️
🔍 Расследование: кто перезагрузил Windows

В чате участник A S. сообщил, что в Windows 11 политика NoAutoRebootWithLoggedOnUsers не предотвращает перезагрузку после установки обновлений. Статью про это я написал в 2018 году и с тех пор не перепроверял. Причем 4 года спустя эту политику наряду с другими объявили устаревшей и не поддерживаемой в Windows 11. И пообещали в будущем выпилить.

У ТС все подробности свелись к "отхожу на несколько часов". Обычно, так быстро сразу после установки обновлений перезагрузка не происходит. Стандартно - в 3 часа ночи, но дальше может в любой момент вне активных часов 🕒

Проще проверить всё самому, и я зарядил виртуалку. За несколько часов ничего не произошло, как и с утра. Однако ночью я сплю, и моя основная ОС тоже, т.е. ВМ в ней неактивны. Поэтому наутро я изменил часовой пояс ВМ и продолжил тест.

👉 Перезагрузка произошла! Но чтобы обвинить в ней обновление Windows, надо ответить на второй по важности вопрос всех времен и народов: какие ваши доказательства?

Они собраны в журнале событий, поэтому пост публикуется в рубрике "Гадание по логам" с помощью #PowerShell.

1️⃣ Смотрим время загрузки ОС - сразу после 3 часов ночи. Уже горячо!

(Get-CimInstance Win32_OperatingSystem).LastBootUpTime

Sunday, February 2, 2025 3:01:46 AM


2️⃣ Выясняем, какие процессы это вызвали - событие 1074 в журнале Система:

Get-WinEvent -FilterHashtable @{LogName='System'; Id=1074} | 
Select-Object TimeCreated, Message | Format-List

TimeCreated : 2/2/2025 3:00:03 AM
Message :
The process C:\WINDOWS\uus\AMD64\MoUsoCoreWorker.exe (DESKTOP-GQKOJ6B)
has initiated the restart of computer DESKTOP-GQKOJ6B on behalf of
user NT AUTHORITY\SYSTEM for the following reason:
Operating System: Service pack (Planned)
Reason Code: 0x80020010
Shutdown Type: restart.


3️⃣ Проверяем связь с планировщиком - поиском по части имени файла MoUsoCoreWorker. Время совпадает!

Get-ScheduledTask | where TaskName -match 'Uso' | Get-ScheduledTaskInfo

LastRunTime : 2/2/2025 3:00:05 AM
LastTaskResult : 2147942402
NextRunTime : 2/3/2025 10:48:35 PM
NumberOfMissedRuns : 0
TaskName : USO_UxBroker
TaskPath : \Microsoft\Windows\UpdateOrchestrator\


4️⃣ Но это еще не всё! Надо определить, был ли в это время выполнен вход пользователя в систему. Ведь политика должна предотвращать перезагрузку только в этом случае.

Здесь фильтруем события входа и выхода, затем ищем нужные по части SID - 1001 в конце у администраторов.

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624,4634,4647} | 
where message -match '1001' | Select-Object Id, TimeCreated, Message -First 15 |
ft -AutoSize

Id TimeCreated Message
-- ----------- -------
4634 2/2/2025 3:20:10 AM An account was logged off....
4624 2/2/2025 3:03:05 AM An account was successfully logged on....
4647 2/2/2025 3:00:05 AM User initiated logoff:...
4624 2/1/2025 11:33:32 PM An account was successfully logged on....

Событие 4647! Выход четко совпадает по времени с выполнением запланированного задания оркестратора. Указано, что пользователь инициировал выход, но это издержки регистрации в журналах. По факту он стал неактивен, не отреагировал вовремя на уведомление о перезагрузке, и его выход форсировали.

////

☑️ Итак, мы однозначно определили, что перезагрузку выполнил оркестратор обновлений, проигнорировав групповую политику и завершив пользовательский сеанс.

В Windows 10 политика NoAutoRebootWithLoggedOnUsers продолжает выполнять свою функцию. А в Windows 11 уже нет поддерживаемого способа предотвратить форсированный перезапуск после установки обновлений. Единственный обходной путь - ручное планирование перезагрузки, что позволяет отложить ее максимум на неделю ✌️
▶️ Простой и эффективный поиск текста в PowerShell - Select-String

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

Как правило, люди открывают Notepad++, загружают туда пачку логов и выполняют поиск во всех открытых файлах. На предложение использовать скрипт пожимают плечами - мол, это же разовая задача. И так сойдет 👌

У этого подхода много проблем:
1. Медленно.
2. Не выгружается сводка и найденные данные.
3. При большом количестве / размере файлов это работает плохо или вообще никак.

Да и не разовая это у них задача, поэтому скрипт подходит отлично.

👉 В #PowerShell для этой цели есть командлет Select-String. Он умеет искать простое совпадение или регулярное выражение.
Select-String -Path 'C:\logs\*.log*' -Pattern '0x800f0805' -SimpleMatch
Select-String -Path 'C:\logs\*.log*' -Pattern '0x800f0805|0x80070490'

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

🤖 Чат-боту задача по поиску текста ставится общими словами. Например, найди все строки с 'exception ' в этих файлах, посчитай количество на каждый файл, запиши в файл эту строку и 20 следующих, выведи на экран сводку и т.д.

И бот быстро пишет рабочий скрипт. Только он зачастую использует другой командлет - Get-Content и передает весь массив на поиск командлету Where-Object. А для такой задачи это неэффективно - слишком медленно!

Простое сравнение. Ищем ошибку '0x800f0805' десяти файлах cbs.log общим объемом около 1.2GB.

$logpath = "C:\temp\logs\*cbs*.log"
Measure-Command {
$a = Select-String -Path $logpath -Pattern '0x800f0805' -SimpleMatch
}
$a.count
Measure-Command {
$b = Get-Content -Path $logpath | where $_ -match '0x800f0805'
}
$b.count

У меня Select-String справился за 7.5 секунд, а Get-Content | where понадобилось 4 мин и 40 секунд.

💡 И кстати по поводу контекста, у Select-String есть очень полезный параметр -Context, который выводит строки до и после найденного совпадения.

Select-String -Path $logpath -Pattern 'exception ' -SimpleMatch -Context 2,20


////

В общем, если вам нужно дальше работать с чистыми найденными строками в качестве объектов, Get-Content имеет смысл. Но просто для поиска текста Select-String вполне достаточно. И да, можно сказать чат-боту, чтобы применял конкретный командлет!

🍪 Бонус - #классика канала про мониторинг логов в реальном времени при помощи:
• командлета PowerShell
• утилиты CMTrace
▶️ Как быстро искать по различным параметрам служб Windows
И не только служб. И не только в Windows!

В чате Николай посетовал :

Когда они сделают сквозной поиск по службам Windows. Ну то есть по всем атрибутам служб. Я вот не могу запомнить как какая служба называется в русскоязычном интерфейсе. Вывели хотя бы в оснастке столбец "Отображаемое имя", но нет.

В диспетчере задач Windows 11 есть приличный сквозной поиск по службам. Но отображаемого имени там нет. И многих прочих параметров тоже.

👉 Николаю сразу посоветовали #PowerShell - командлет Get-Service для получения сведений о службах. Однако ТС хотел графический интерфейс и отрицал этот способ. Тогда я добавил еще один командлет - Out-GridView:

Get-Service | Out-GridView


Это самый настоящий графический интерфейс! Здесь есть:
🔹 сквозной фильтр по всем параметрам
🔹 тонкие критерии фильтров
🔹 сортировка по столбцам

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

Get-Service | Select-Object * | Out-GridView


Дальше вы можете управлять набором столбцов в графическом интерфейсе. И да, их можно сразу перечислить в select.

🏷 Наконец, можно сделать ярлык на такую "оснастку".

////

Этот прием можно применять и к другим оснасткам. Именно так я ковыряюсь в дебрях планировщика Windows. Потому что динамическая фильтрация рулит!

Get-ScheduledTask | Select-Object * | Out-GridView


Продолжая пост про задания планировщика, вот список всех заданий с командами:
$tasklist = @()
Get-ScheduledTask | ForEach-Object {
$task = [xml](Export-ScheduledTask -TaskName $_.URI)
$taskdetails = New-Object -Type Psobject -Property @{
"Name" = $_.URI
"Action" = $task.Task.Actions.Exec.Command
}
$tasklist += $taskdetails
}
$tasklist | Select-Object Name,Action | Out-GridView


Разумеется, этот способ не ограничивается оснастками MMC и вообще ОС Windows. Применяйте командлет Out-GridView для анализа любых табличных наборов данных! ✌️
🛍 Как открыть магазинное приложение, если у него нет ярлыка

И в Пуске оно тоже не находится. Этот вопрос задал мне подписчик Андрей К в контексте приложения Сообщения оператора (Operator Messages). Оно показывает служебные SMS мобильного оператора на устройствах с поддержкой 4G/5G.

Как я понял, приложение само открывается для отображения входящих SMS. Но если его закрыть, то потом уже не открыть. Андрей упомянул, что приложение можно закрепить на панели задач. И для меня это уже выглядит решением ✔️

Возможно, он не хотел занимать место на панели задач, предпочитая отдельный ярлык на рабочем столе. В этом случае следует закрыть закрепленное приложение - щелкнуть значок правой кнопкой мыши, удерживая Shift и выбрать пункт "Создать ярлык" или "Отправить -> Рабочий стол" ✔️

Но допустим, что таких пунктов в меню не оказалось. Либо автор вопроса хочет запускать приложение из командной строки. Короче, этюдная задача с элементами матчасти :)

🤔 Рассуждая логически, раз приложение открывается на входящие сообщения, оно должно быть зарегистрировано для какого-то протокола. Найдем протокол - решим задачу.

1. Поищите protocol в Параметрах и откройте страницу с приложениями по умолчанию.
2. В самом низу откройте раздел для сопоставления приложений типам ссылок.
3. Найдите приложение глазами, ориентируясь на значок. (На странице есть фильтр, но только по протоколам, а его-то мы и не знаем :)

В данном случае находится URL:ms-chat. И этого достаточно для решения задачи! У вас это приложение вряд ли установлено, поэтому для наглядности я заменил протокол ms-chat: на ms-calculator:. Вот разные способы открытия:

• окно Win+R: ms-calculator:
• произвольный ярлык: explorer ms-calculator:
• командная строка: start calculator:

Да, протокол calculator: там тоже есть :)

////

ℹ️ Протоколы регистрируются в реестре. Полный список протоколов Microsoft легко отобразить с помощью #PowerShell

New-PSDrive -Name "HKCR" -PSProvider Registry -Root "HKEY_CLASSES_ROOT"
Get-Item HKCR:\ms-* | select name

Не все они будут открывать какое-то приложение. Но в большинстве случаев это сработает.

Читателям со стажем эта тема покажется знакомой. Я как-то рассказывал в канале про быстрый доступ к страницам Параметров. И там всё строится именно на протоколе ms-settings! ✌️