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

Чат: @winsiders
Блог: outsidethebox.ms
Oбратная связь: @vsterkin
Поддержать ₽: boosty.to/sterkin
Download Telegram
⚙️ Почему точки восстановления создаются сериями

Готовя предыдущий пост о пользе точек восстановления, я заглянул в список своих точек и увидел странную картину↓ Налицо две серии точек, созданных Windows Update в течение минуты: две точки подряд 23 августа и три подряд 19 августа. Я не раз видел такое и раньше, но на сей раз решил покопаться в причинах.

▶️ В истории центра обновлений Windows в эти дни нет ничего кроме сигнатур защитника. Придётся срывать покровы с журналов событий с помощью #PowerShell. Я показывал в канале работу с датами с Get-Date и быстрый опрос всех журналов сразувозвращался к теме в контексте Windows 10). Сводим все вместе, выбрав четырехминутный диапазон вокруг даты создания точки.

$s = Get-Date -Year 2023 -Month 08 -Day 23 -Hour 00 -Minute 04
$e = Get-Date -Year 2023 -Month 08 -Day 23 -Hour 00 -Minute 08
Get-WinEvent -ErrorAction 0 -FilterHashTable @{
LogName='*'
StartTime=$s
EndTime=$e
} | sort ProviderName | Out-File -FilePath "$ENV:TEMP\sr.txt"


🛍 Сходу выяснилось, что 23 августа основной активностью было обновление магазинных приложений. Связанных с этим событий было множество, но в итоге все свелось к обновлению двух приложений - непосредственно магазина и StorePurchaseApp, компонента для покупок. Поставщик Microsoft-Windows-Install-Agent тщательно протоколирует загрузку, а приложение легко определить по ИД вроде 9WZDNCRFJBMP.

8/23/2023 12:06:39 AM 2006 Information
Progress Update: Item = 9WZDNCRFJBMP  
Progress Stage = DownloadingProduct, Completed = 332800,
Total = 19636239, Total = 3


Аналогично 19 августа обновились три приложения - WhatsApp, DesktopAppInstaller и почта/календарь.

👉 Количество обновленных приложений совпало с числом созданных точек восстановления!

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

Однако смысл всего мероприятия от меня ускользает. По умолчанию Windows не создаёт точки чаще 24 часов. Это обходится твиком реестра и, как мы видим, программным способом. Но зачем? 🤷‍♂️

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

Возможно, это неэффективный код или баг. А не исправляют, потому что нет реальных проблем. Но эту теорию мы сможем подтвердить, только если поведение изменится ✌️
🔐 О состоянии шифрования BitLocker по умолчанию в Windows

Второй день из каждого утюга вещают, что в Windows 11 Pro по умолчанию включено шифрование BitLocker, что влечет снижение производительности SSD до 45%. Первоисточник - Tom's Hardware, а дальше уже может зависеть от фантазии переводчика.

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

Эти утверждения в совокупности вводят в заблуждение:

• Windows 11 Pro форсирует включение шифрования, а на Windows 10 Pro шифрование скорее всего не включено.

• Если у вас [в Windows 11] локальный аккаунт нежели учетная запись Microsoft (MSA), шифрование не включается.

• Windows 11 Home не поддерживает BitLocker, поэтому там шифрование не включается. (Однако автор тут же оговаривается: кажется, на некоторых ноутбуках включено :)

👉 У меня есть подробная #классика блога на эту тему: Автоматическое шифрование BitLocker в Windows. И подзаголовок там в самый раз :) Рекомендую вам прочесть рассказ целиком, а здесь задействую некоторые моменты.

ℹ️ На самом деле шифрование устройств с помощью BitLocker автоматически включается начиная с Windows 8.1 во всех изданиях. Но происходит это только на устройствах, соответствующих определенным требованиям, которые со временем слегка ослабили. Поддержка автоматического шифрования проверяется элементарно.

🔓 Если устройство подходит, BitLocker включается во время установки с незащищенным ключом и приостанавливается. В английской терминологии это состояние называется Suspended, и задать его можно командлетом #PowerShell Suspend-Bitlocker. На картинке↓ шифрование включено, но приостановлено - диск зашифрован, но не защищен. Поэтому неверно заявление автора тестов, что с локальным аккаунтом диск не шифруется.

🔑 Когда первый вход выполняет администратор с MSA или компьютер вводится в домен, шифрование активируется и защищается TPM. Одновременно 48-значный пароль восстановления сохраняется в облачных настройках MSA, а в домене – в Entra ID или AD DS при включенной политике.

Проверка заявлений, касающихся производительности, тоже не помешала бы. Но я оставляю ее вам. С помощью CrystalDiskMark можно относительно быстро прикинуть влияние любого программного шифрования на свою систему. Только, пожалуйста, тестируйте производительность диска, а не его кэша ✌️
⚙️ Как получить доступ к служебному разделу, не изменяя его свойства

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

А тут я изучал содержимое раздела Windows RE на разных системах. Менять свойства туда-сюда утомило с третьего раза, и я посмотрел в сторону #PowerShell. С целью прямого доступа нежели изменения свойств, потому что у Set-Partition не реализовано свойство Required.

ℹ️ В блоге я приводил GUID - идентификатор раздела восстановления, поэтому легко сделать выборку из списка разделов. Нас интересует свойство AccessPaths, т.е. путь доступа. (Его также можно посмотреть нативной командой mountvol, но в списке может оказаться без буквы также раздел MSR - на глаз не отличить.)

$id = "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
Get-Partition | where GptType -eq $id | select Type,AccessPaths

Type AccessPaths
---- -----------
Recovery {\\?\Volume{9896bfe9-69de-4db1-a6f4-ba4630addab3}\}


Теперь легко вывести содержимое раздела - рекурсивно, включая скрытые папки и файлы. Можно даже ванлайнером, но так нагляднее:

$id = "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
$lpath = (Get-Partition | where GptType -eq $id).AccessPaths[0]
Get-ChildItem -Force -Recurse -LiteralPath $lpath


Меня интересовало содержимое winre.wim, и скопировать его не составило труда:

Copy-Item -LiteralPath "\\?\Volume{9896bfe9-69de-4db1-a6f4-ba4630addab3}\Recovery\WindowsRE\Winre.wim" -Destination C:\temp\

В данном случае файл скрытый и системный, но про управление атрибутами файлов в PowerShell я уже рассказывал ✌️
▶️ Как массово удалить папки, распакованные из архивов

В чате участник Павел задал такой вопрос:
В папке ~450 разных файлов, папок и архивов *.rar. Периодически рары разархивируются, и получается папка с тем же именем, что и rar. Стоит задача удалить эти папки, оставив при этом архивы. Как отсортировать, чтобы снизу папки сразу был её родительский архив?

Очевидно, он рассматривал вариант сортировки в файловом менеджере. Хотя надо сразу смотреть в сторону #PowerShell. Для начинающих это отличное практическое упражнение! Впрочем, этому унылому занятию Павел предпочел ожидание поста в канале 😎

Я бы решал задачу в лоб:
1. Отбираем только папки.
2. Для каждой проверяем наличие архива с таким же именем, "приклеивая" к имени папки расширение.
3. При совпадении удаляем.

$folders = Get-ChildItem -Path "C:\test" -Directory
foreach ($folder in $folders) {
if (Test-Path "$($folder.FullName).rar")
{Remove-Item $folder -Recurse -WhatIf}
}


Василий Гусев предложил нестандартное решение - группировка! 🤔 Мне оно в голову не пришло, хотя я трижды показывал Group-Object в блоге:
поиск дубликатов драйверов
выборка уникальных ссылок с веб-страниц
замена дубликатов файлов на жесткие ссылки

Доработав идею, я получил такой конвейер:
1. Группируем по имени папки и файлы без расширения с помощью свойства BaseName.
2. Отбираем группы, где с одинаковыми именами ровно два объекта - файл и папка!
3. Из каждой группы выбираем папки и удаляем их.

Get-ChildItem -Path "C:\test" | Group-Object -Property BaseName |
Where-Object {$_.Count -eq '2'} | ForEach-Object {$_.group} |
Where-Object {$_.Attributes -eq 'Directory'} | Remove-Item -Recurse -WhatIf


⌛️ Примечательно, что с обоими способами перекликается #классика блога Как массово переименовать файлы по маске в PowerShell. Там я склеивал имя файла из фрагментов, одним из которых было свойство BaseName.

🤖 И неудивительно, что ChatGPT тоже задействовал это свойство, когда я поставил задачу перед ним. Он пошел тем же путем что и я, но выбрал перебор архивов нежели папок и создал побольше переменных. В свою очередь чат-бот Bing практически повторил мой способ. Но для определения папки он использовал старое свойство объекта PSIsContainer (параметр -Directory у dir доступен более 10 лет, с версии 3.0).

Короче, получив направление в PowerShell, Павел мог сразу спросить чат-бота. И не дожидаться, пока кожаный мешок опубликует решение его простенькой задачи в канале ✌️
🛍 Как удалить новые приложения Dev Home и Outlook в Windows 11

Вчера был второй вторник, а следовательно в Windows 11 22H2 всем пришло накопительное обновление с функциями Момент 4 - KB5032190. Оно или его превью необходимы для обновления до версии 23H2 - KB5027397. Это опять #тумблер - номер версии меняется переключателем, потому что у них одинаковая кодовая база. Если вам не предлагают 23H2 в центре обновления, проверьте эти причины. 👈

Обновление до 23H2 отчасти формальное, потому что большинство новинок доставляет Момент 4. Именно после его установки через диспетчер доставки содержимого принудительно прилетают два магазинных приложения - превью Dev Home и Outlook for Windows (замена магазинной Почте). У некоторых от этого подгорит. А уж когда они обнаружат, что не могут удалить Dev Home в графическом интерфейсе... 🍑🔥

Эти две команды в #PowerShell от имени администратора решают вопрос:

Get-AppxPackage -AllUsers | where Name -match 'DevHome|OutlookForWindows' | Remove-AppxPackage -AllUsers
Get-AppxProvisionedPackage -Online | where PackageName -match 'DevHome' | Remove-AppxProvisionedPackage -Online


ℹ️ Первая команда удаляет пакеты из всех учетных записей, вторая - из локального хранилища (туда внедряется только Dev Home). Оно служит источником установки при первом входе в систему. Подробнее об этих командах читайте в блоге. И не поленитесь поискать названия командлетов в канале - там много любопытного.

Однако удаление не блокирует доставку этих приложений в новые учетные записи. Если вы знаете поддерживаемый способ предотвратить установку, сообщите мне. О кривых обходных путях я, возможно, напишу отдельно ✌️
▶️ Новое в блоге: Нюансы полной локализации Windows с помощью PowerShell

Сегодняшний рассказ продолжает серию публикаций о языковых настройках. Для управления ими в Windows 11 появились новые командлеты: Install-Language и Copy-UserInternationalSettingsToSystem. С ними стала возможна полная локализации системы командлетами #PowerShell. Но понадобятся еще пять других :)

👉 Цель упражнения — полностью локализовать установленную Windows на русский язык для текущего пользователя и всех созданных впоследствии аккаунтов.

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

➡️ Читайте в блоге: https://www.outsidethebox.ms/22149/
⚙️ Про установку Windows 11 с локальной учетной записью при помощи файла ответов

Я давно опубликовал в блоге простой файл ответов (ФО) для быстрой автоустановки Windows. Прописав в нём локальный аккаунт, вы автоматически обходите требование использовать учетную запись Microsoft (MSA). Но есть нюанс ©

При наличии интернета всё идёт по плану. А когда его нет, программа установки Windows 11 упирается в такое окно↓ Да, это можно обойти способом BypassNRO. Но ФО предназначен для автоматизации установки без таких плясок с бубном. То есть без интернета он уже не работает как положено 🤔

По сути интернет им нужен только для форсирования учетной записи Microsoft (MSA), которая прописана в системных требованиях изданий Home и Pro. И можно предположить, что в них по логике Microsoft нечего файлом ответов баловаться и интернеты отключать

Но в корпоративных изданиях точно такая же ситуация! И параметр ФО для пропуска этого окна как минимум не задокументирован.

⚠️Upd. На самом деле параметр задокументирован, читайте продолжение истории и решение.

▶️ Бонус: в процессе установки вы можете управлять подключением к интернету с помощью синхронных команд и #PowerShell:
Get-NetAdapter -Name * | Disable-NetAdapter -Confirm:$False -WhatIf
Get-NetAdapter -Name * | Enable-NetAdapter
⚙️ Как получить доступ к служебному разделу, не изменяя его свойства - дубль 2

Сегодня в рубрике "Возвращаясь к напечатанному" альтернатива способу, который я показывал пару месяцев назад. Там для выборки в #PowerShell я взял атрибут служебного раздела (GUID). Сегодня я покажу, как обойтись без него.

Неудачная попытка Microsoft обновить среду восстановления вынесла на берег множество безумных конфигураций. Именно такую принёс мне в блог читатель Александр, см. картинку↓ 👀 Здесь на дисках 3 и 4 установлены Windows 10 и 11 соответственно.

Первичным анализом я установил, что в обеих ОС на диске 4 зарегистрирована среда восстановления от Windows 11, а шифрование BitLocker не используется. Поэтому мой совет был не морочить себе и другим голову и скрыть обновление Windows 10. Но читатель оказался перфекционистом 🦩 Он заявил, что отключал все диски кроме 3 (с Windows 10), увеличивал раздел со средой, но так и не смог установить обновление.

Действительно, в конце обоих дисков есть какие-то разделы без букв. При этом на диске 4 нет пометки "Раздел восстановления". Значит, ему не присвоены правильные атрибуты, что ставит под сомнение грамотность действий читателя 🤔 Я хочу проверить, есть ли на диске 3 файл winre.wim, раз он там якобы включал среду.

Get-ChildItem -Force -Recurse -LiteralPath \\?\GLOBALROOT\device\harddisk3\partition4\Recovery
Get-ChildItem -Force -Recurse -LiteralPath \\?\GLOBALROOT\device\harddisk3\partition3\Windows\System32\Recovery
Get-ChildItem -Force -Recurse -LiteralPath \\?\GLOBALROOT\device\harddisk3\partition3\Recovery


Вы могли видеть такие пути в выводе команд reagentc /info и vssadmin. Они глубоко уходят корнями в пространства имён NT и хорошо просматриваются в утилите WinObj от Sysinternals.

Первая команда показывает содержимое раздела восстановления (номер 4), обходя отсутствие назначенной ему буквы. Вот мы и получили доступ к служебному разделу, не изменяя его атрибуты! 🎉

Раздел с RE - просто пример. Вот конфигурация загрузки на разделе EFI - в разметке GPT он первый:
Get-ChildItem -Force -LiteralPath \\?\GLOBALROOT\device\harddisk0\partition1\EFI\Microsoft\Boot

ℹ️ Вторая и третья команды исследуют раздел 3 (ОС) на диске с Windows 10. Причем даже в том случае, если человек будет выполнять их из Windows 11! В этом отличие от пути с буквой диска или переменной среды. Здесь параметр -LiteralPath обрабатывает путь "как есть", передавая его в API напрямую. Заметьте, что с тем же путем параметр -Path ничего не выдаст.

В итоге на диске с Windows 10 файла winre.wim не нашлось . Поэтому мой совет перфекционисту был извлечь образ из дистрибутива и зарегистрировать на выделенном разделе. Так, пройдя пять стадий принятия неизбежного, читатель последовал моему совету и... у него все получилось ✌️
▶️ PowerShell: выборка в Get-ChildItem
-LiteralPath vs. -Path vs. -Filter

На прошлой неделе я показывал исследование путей вида \\?\GLOBALROOT\device в #PowerShell с помощью командлета Get-ChildItem (он же gci, dir, ls). Параметр -LiteralPath передает пути в API "как есть", и для такого странного пути это вполне понятно.

Но есть менее очевидный и, наверное, более распространенный случай - квадратные скобки в именах файлов и папок.

dir -Path C:\[ab]folder

Такая команда не найдет папку с именем [ab]folder, нужен -LiteralPath.

Параметр -Path обрабатывает [ ] как часть регулярного выражения, пытаясь найти afolder и bfolder. Можно избегать этого бэктиками, но там свои подводные камни. Когда имя папки точно известно, проще использовать -LiteralPath.

👉 Также -Path поддерживает подстановочные символы * и ?, что очень удобно для быстрой выборки по имени и/или расширению:

dir -Path *.txt

По странному совпадению на днях я столкнулся одновременно с * и [ ] . Искал мои рецензии на статьи, где я добавлял в начало имени файла свои инициалы: [VS] blah-blah.docx. Без задней мысли я ввел в консоль:

dir '[VS*' -Recurse

И получил ошибку синтаксиса Параметр -Path тут не указан, но подразумевается, поскольку это первый позиционный параметр командлета. И по умолчанию он обрабатывает текущую папку. Параметр -LiteralPath тоже не подходит. Он не работает с подстановочными символами, а для выборки мне нужен *.

ℹ️ На помощь пришел параметр -Filter. Он есть у 20+ командлетов, которые взаимодействуют с поставщиком FileSystem. Строка с путём фильтруется на уровне файловой системы нежели обрабатывается в PowerShell, поэтому такой запрос считается наиболее эффективным. Однако в данном случае важнее поддержка подстановочных символов * и ?.

Такая выборка отлично сработала:

dir -Filter '[VS*' -Recurse

Покопавшись в канале, я нашел упоминание этого параметра в загадке PowerShell четырехлетней давности. Желаю удачи в поисках разгадки! 😎
🕑 Как определить, является ли происходящее следствием запущенного из планировщика задания

Или наоборот - как исключить задание из списка подозреваемых в каком-то поведении системы.

Серебряной пули не существует, но есть подходы.

1️⃣ Запись активности процессов

Если процесс запущен из планировщика, его родительским процессом будет taskeng.exe. Однако он завершается после отработки задания, поэтому отследить его можно только записью. Например, с помощью WPR или Process Monitor, как в деле об автозагрузке Windows. Там из планировщика запускался промежуточный процесс, кстати.

2️⃣ Журнал событий планировщика и аудит процессов

Иногда можно косвенно определить связь по времени, когда поведение наблюдается сразу после выполнения запланированного задания. Аудит процессов помогает сопоставить время выполнения задания и запуск процесса. Однако надо держать в уме, что после — не значит вследствие.

По умолчанию история планировщика отключена, но ее можно активировать в правой панели оснастки. Это действие эквивалентно включению журнала событий Microsoft-Windows-TaskScheduler/Operational. Именно в него пишется история планировщика.

Дальше можно смотреть в журнале событий или #PowerShell. Ниже пример отбора заданий, запущенных за последний час. Я уже разбирал в канале такую выборку с хэш-таблицей.

Get-WinEvent -ErrorAction 0 -FilterHashTable @{
LogName='Microsoft-Windows-TaskScheduler/Operational'
ID='100'
StartTime=(Get-Date).AddMinutes(-60)
#TaskName='\CreateExplorerShellUnelevatedTask'
} | ft -wrap


Здесь закомментировано имя конкретного задания. Выборка по нему сработает только в PowerShell Core. Там можно фильтровать по именованным полям событий, тем самым обходясь без передачи по конвейеру в Where-Object и ускоряя процесс.

Эти поля отображаются в XML-представлении задания↓ Помимо документации см. также мои скрипты для поиска событий аудита реестра и процессов.

Через пару дней в блоге вышла статья, для которой я сопоставлял историю заданий планировщика и запуска процессов ✌️