Имею серию статей посвящённых теме обслуживания образов Windows командами системы DISM. В моих статьях приводились примеры скриптов на языке интерпретатора командной строки cmd.exe. В результате работы исходный образ Windows (живая система или автономный файл *.wim) изменялся — в него интегрировались обновления, отключались системные компоненты, удалялись универсальные приложения. Но как увидеть внесённые изменения в образ? В данной статье Я представляю скрипт, который используя команды системы DISM извлекает из образа Windows различную информацию и показывает её пользователю на экран, либо экспортирует в файл.

Данный скрипт будет полезен системным администраторам создающим свои «сборки», либо тестирующим чужие. Иногда может возникнуть необходимость посмотреть некоторую информацию об установленной ОС — в этом случае также пригодиться данный скрипт. Все команды DISM для получения информации из образа Windows реализованы в данном скрипте. Информация из образа, которую можно получить, используя данный скрипт:

  • Драйвера устройств (наличие);
  • Пакеты обновлений (наличие);
  • Системные компоненты (состояние);
  • Языковая поддержка (состояние);
  • Редакции Windows (состояние);
  • Классические приложения (наличие);
  • Универсальные приложения (наличие);
  • Ассоциации файлов (состояние).

В скобках указан аспект информации. Если некий тип объектов может быть добавлен или удалён из образа, то информация будет показывать наличие объектов данного типа в образе. Если некоторое свойство операционной системы может быть переключено в образе (например разрешено/запрещено), то информация будет отображать состояние данного свойства. Два последних пункта в списке доступны только на ОС начиная с Windows 8. Я назвал данный скрипт GetWimInfo.cmd, вот он:

Скрипт


@echo off
title Getting information from Windows image

set _file=install.wim
set _img=Online
set _mnt=mount
set _tool=7
set _word=Wim

ver | find "6.1" > nul || set _tool=8
if %_tool% GTR 7 set _word=Image

:pre_menu
cls
if not exist %_file% goto :adv_menu
dism /English /LogLevel:1 /Get-%_word%Info /%_word%File:%_file%
echo -------------------------------------------------------------------------------
if %ERRORLEVEL% NEQ 0 pause & exit
set /p _ind=Input index or press [Enter] for quit: || exit
if %_ind% EQU 0 goto :adv_menu
if %_ind% GTR 0 if %_ind% LEQ 24 goto :ind_menu
goto :pre_menu

:ind_menu
cls
dism /English /LogLevel:1 /Get-%_word%Info /%_word%File:%_file% /Index:%_ind%
echo -------------------------------------------------------------------------------
if %ERRORLEVEL% NEQ 0 pause & goto :pre_menu
choice /c abcdefghijklmnopqrstuvwxyz /n /m "Mount selected image? [m] "
if %ERRORLEVEL% EQU 13 goto :mount
goto :pre_menu

:adv_menu
cls
if %_img%==Online (echo DISM: Online Servicing)^
else (dism /English /LogLevel:1 /Get-Mounted%_word%Info)
echo -------------------------------------------------------------------------------
echo ~~~~Menu~~~~
echo [d] drivers ([D] - export)
echo [p] packages ([P] - export)
echo [f] features ([F] - export)
echo [l] languages
echo [e] editions
echo [a] app
if %_tool% GTR 7 echo [x] appx ([X] - export)
if %_tool% GTR 7 echo [s] assoc ([S] - export)
echo [q] quit (unmount)
echo -------------------------------------------------------------------------------
choice /c dDpPfFleaxXsSq /n /cs /m "Your choice: "
if %ERRORLEVEL% EQU 1 goto :drivers
if %ERRORLEVEL% EQU 2 goto :drivers-export
if %ERRORLEVEL% EQU 3 goto :packages
if %ERRORLEVEL% EQU 4 goto :packages-export
if %ERRORLEVEL% EQU 5 goto :features
if %ERRORLEVEL% EQU 6 goto :features-export
if %ERRORLEVEL% EQU 7 goto :languages
if %ERRORLEVEL% EQU 8 goto :editions
if %ERRORLEVEL% EQU 9 goto :app
if %ERRORLEVEL% EQU 10 if %_tool% GTR 7 (goto :appx) else (goto :adv_menu)
if %ERRORLEVEL% EQU 11 if %_tool% GTR 7 (goto :appx-export) else (goto :adv_menu)
if %ERRORLEVEL% EQU 12 if %_tool% GTR 7 (goto :assoc) else (goto :adv_menu)
if %ERRORLEVEL% EQU 13 if %_tool% GTR 7 (goto :assoc-export) else (goto :adv_menu)
goto :unmount

:drivers
cls
dism /%_img% /English /LogLevel:1 /Get-Drivers /All | more
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:drivers-export
cls
if exist drivers%_numd%.txt set /a _numd+=1 & goto :drivers-export
echo Getting list of drivers. Please wait...
dism /%_img% /English /LogLevel:1 /Get-Drivers /All /Format:Table > drivers%_numd%.txt
goto :adv_menu

:packages
cls
dism /%_img% /English /LogLevel:1 /Get-Packages | more
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:packages-export
cls
if exist packages%_nump%.txt set /a _nump+=1 & goto :packages-export
echo Getting list of packages. Please wait...
dism /%_img% /English /LogLevel:1 /Get-Packages /Format:Table > packages%_nump%.txt
goto :adv_menu

:features
cls
dism /%_img% /English /LogLevel:1 /Get-Features | more
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:features-export
cls
if exist features%_numf%.txt set /a _numf+=1 & goto :features-export
echo Getting list of features. Please wait...
dism /%_img% /English /LogLevel:1 /Get-Features /Format:Table > features%_numf%.txt
goto :adv_menu

:languages
cls
dism /%_img% /English /LogLevel:1 /Get-Intl
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:editions
cls
dism /%_img% /English /LogLevel:1 /Get-CurrentEdition
echo -------------------------------------------------------------------------------
dism /%_img% /English /LogLevel:1 /Get-TargetEditions
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:app
cls
if %_img%==Online goto :adv_menu
dism /%_img% /English /LogLevel:1 /Get-Apps
echo -------------------------------------------------------------------------------
dism /%_img% /English /LogLevel:1 /Get-AppPatches
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:appx
cls
dism /%_img% /English /LogLevel:1 /Get-ProvisionedAppxPackages | more
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:appx-export
cls
if exist appxes%_numx%.txt set /a _numx+=1 & goto :appx-export
echo Getting list of appx. Please wait...
dism /%_img% /English /LogLevel:1 /Get-ProvisionedAppxPackages > appxes%_numx%.txt
goto :adv_menu

:assoc
cls
dism /%_img% /English /LogLevel:1 /Get-DefaultAppAssociations | more
echo -------------------------------------------------------------------------------
choice /c b /n /m "Back [b] "
goto :adv_menu

:assoc-export
cls
if exist associat%_nums%.txt set /a _nums+=1 & goto :assoc-export
echo Getting list of assoc. Please wait...
dism /%_img% /English /LogLevel:1 /Get-DefaultAppAssociations > associat%_nums%.txt
goto :adv_menu

:mount
cls
md %_mnt%
dism /English /LogLevel:1 /Mount-%_word% /%_word%File:%_file% /Index:%_ind% /MountDir:%_mnt% /ReadOnly
if %ERRORLEVEL% NEQ 0 rd %_mnt% & pause & exit
set _img=Image:%_mnt%
goto :adv_menu

:unmount
cls
if not exist %_file% exit
if not %_img%==Online (
dism /English /LogLevel:1 /Unmount-%_word% /MountDir:%_mnt% /Discard
rd %_mnt%
)
set _img=Online
goto :pre_menu

Использование


Если в папке запуска скрипта присутствует автономный образ операционной системы Windows — файл install.wim, то из него запрашивается информация об имеющихся индексах и пользователю предлагается ввести номер с которым будет вестись работа. В следующем подменю о выбранном индексе отображается расширенная информация и пользователю предлагается смонтировать данный образ для продолжения работы. После монтирования образа на экране отображается основное меню скрипта. Если в папке запуска скрипта отсутствует файл install.wim, то сразу происходит переход в основное меню, а запросы информации будут направлены к текущей ОС. Работать с основным меню очень просто — достаточно нажать соответствующую клавишу для вывода информации на экран. По некоторым пунктам объём данных может быть большим, поэтому добавлены пункты для экспорта информации в создаваемый текстовый файл в папке запуска скрипта. Экспорт в файл — буква в верхнем регистре.

Разбор кода


Вначале командой set происходит установка переменных. Можно изменить предполагаемое имя файла образа install.wim (например, на install.esd). Можно изменить имя папки монтирования (по-умолчанию mount) или задать путь, если папка монтирования должна находится за пределами папки запуска.
Также вначале определяется версия ОС, на которой запущен скрипт, по логике — если не Windows 7, то что-то новее. Исходя из этого, делается вывод о том, какая версия системы DISM будет принимать команды скрипта, что влияет на доступность последних двух пунктов меню.

:pre_menu


Предварительное меню. Получение основной информации о wim-файле с контролем ошибок. Если отсутствует файл образа, то запуск в режиме Online.

:ind_menu


Индексное меню. Получение расширенной информации о выбранном «индексе» в wim-файле с контролем ошибок. Предложение смонтировать «индекс».

:adv_menu


Основное (расширенное) меню скрипта. После нажатия клавиши соответствующей выбранному пункту происходит переход к соответствующей метке в теле скрипта с последующим выполнением требуемых команд и возврат в данное меню. Все пункты вывода информации на экран однотипны и включают некоторую команду DISM. Нет необходимости их разбирать. Чем отображение информации на экране больший интерес представляет экспорт в текстовый файл. Информация записывается в табличной форме, что удобно для восприятия и сравнения. Для каждого типа информации — текстовый файл с определённым именем. Повторный экспорт по некоторому пункту не заменяет файл, а создаёт новый, добавляя числовой индекс к имени. Это удобно когда происходит сбор информации с нескольких разных индексов образа, например.

:mount


Монтирование образа. Предварительно создаётся папка монтирования. Контроль ошибок. Изменяется переменная определяющая спецификацию образа, теперь указывает на путь к автономному образу.
Замечу также, что монтирование осуществляется в режиме /ReadOnly, что означает отсутствие возможности внесения каких-либо изменений в образ, включая даты и атрибуты файла образа.

:unmount


Размонтирование образа. Если выполнялось интерактивное обслуживание (/Online), то размонтировать не нужно. Возвращение переменных к исходным значениям.

Размонтирование с ключом /Discard, так как монтирование осуществлялось только для чтения. Отсутствие ключа неприемлемо.

Заключение


Данный скрипт является логическим дополнением к коллекции скриптов представленных мной в предыдущих статьях. Хотя, по правде, всё это было написано более трёх месяцев назад, а данный скрипт был у меня первый. Просто постепенно раскрываю карты. Конечно, многие системные администраторы давно написали для себя подобные решения и у каждого они свои. Чужие наработки мне показались неудобными, в некоторых случаях громоздкими. Кто то пытался реализовать все возможности системы DISM в одном «мега»-скрипте, Я же решил сделать несколько скриптов, каждый под определённую задачу. Наверно не очень хорошо, что некоторый код повторяется, потому что при реализации некоторых идей и/или исправлении ошибок мне приходилось редактировать все файлы сразу. Рекламисты PowerShell проходят мимо. Я писал этот скрипт для себя и решил поделиться им с вами, таким какой он есть. Надеюсь многим он будет полезен — и для работы и как пример в учёбе.

Комментарии (6)


  1. decomeron
    25.02.2018 21:53

    На ХР работает?


    1. alex1t
      25.02.2018 23:25
      +1

      wim файлы появились после неё.


    1. sumanai
      26.02.2018 00:32

      Если вы про применение на дистрибутиве XP, то нет. Хотя некоторые версии XP устанавливаются из WIM, но там свой, особо устаревший формат, и нет поддержки обслуживания через DISM. Кстати, мне формат WIM для Windows Fundamentals For Legacy PC нравится больше, чем новые. Там вместо нескольких полных образов ОС используется один базовый и несколько образов в отдельными компонентами, которые можно выбрать при установке. Даёт намного более широкий выбор, чем несколько редакций в висте и выше.
      А если вы про работу скрипта на XP для изменения образа семёрки, то это теоретически возможно.


      1. decomeron
        26.02.2018 15:35

        Спасибо


  1. Sergey-S-Kovalev
    26.02.2018 16:34
    -1

    /me при виде полотенец для cmd издает шипяще-стонущий крик вампира тающего в лучах солнца.


  1. alexoron
    27.02.2018 17:55

    1. Раздел — «Разбор кода» можно выбросить. И это наблюдается в каждой статье. Комментарии лучше вставить в соответствующие места скрипта. Код должен быть самодокументированным!.
    2. Для работы c WIM существует библиотека wimlib, которую можно установить через менеджер пакетов Chocolatey чтобы установить в систему для запуска с любого места.
    Команда соответствующая названию статьи:

    wiminfo WIMFILE [IMAGE [NEW_NAME [NEW_DESC]]] [OPTION...]