Имею серию статей посвящённых теме обслуживания образов Windows командами системы DISM. В моих статьях приводились примеры скриптов на языке интерпретатора командной строки cmd.exe. В результате работы исходный образ Windows (живая система или автономный файл *.wim) изменялся — в него интегрировались обновления, отключались системные компоненты, удалялись универсальные приложения. Но как увидеть внесённые изменения в образ? В данной статье Я представляю скрипт, который используя команды системы DISM извлекает из образа Windows различную информацию и показывает её пользователю на экран, либо экспортирует в файл.
Данный скрипт будет полезен системным администраторам создающим свои «сборки», либо тестирующим чужие. Иногда может возникнуть необходимость посмотреть некоторую информацию об установленной ОС — в этом случае также пригодиться данный скрипт. Все команды DISM для получения информации из образа Windows реализованы в данном скрипте. Информация из образа, которую можно получить, используя данный скрипт:
В скобках указан аспект информации. Если некий тип объектов может быть добавлен или удалён из образа, то информация будет показывать наличие объектов данного типа в образе. Если некоторое свойство операционной системы может быть переключено в образе (например разрешено/запрещено), то информация будет отображать состояние данного свойства. Два последних пункта в списке доступны только на ОС начиная с Windows 8. Я назвал данный скрипт GetWimInfo.cmd, вот он:
Если в папке запуска скрипта присутствует автономный образ операционной системы Windows — файл install.wim, то из него запрашивается информация об имеющихся индексах и пользователю предлагается ввести номер с которым будет вестись работа. В следующем подменю о выбранном индексе отображается расширенная информация и пользователю предлагается смонтировать данный образ для продолжения работы. После монтирования образа на экране отображается основное меню скрипта. Если в папке запуска скрипта отсутствует файл install.wim, то сразу происходит переход в основное меню, а запросы информации будут направлены к текущей ОС. Работать с основным меню очень просто — достаточно нажать соответствующую клавишу для вывода информации на экран. По некоторым пунктам объём данных может быть большим, поэтому добавлены пункты для экспорта информации в создаваемый текстовый файл в папке запуска скрипта. Экспорт в файл — буква в верхнем регистре.
Основное (расширенное) меню скрипта. После нажатия клавиши соответствующей выбранному пункту происходит переход к соответствующей метке в теле скрипта с последующим выполнением требуемых команд и возврат в данное меню. Все пункты вывода информации на экран однотипны и включают некоторую команду DISM. Нет необходимости их разбирать. Чем отображение информации на экране больший интерес представляет экспорт в текстовый файл. Информация записывается в табличной форме, что удобно для восприятия и сравнения. Для каждого типа информации — текстовый файл с определённым именем. Повторный экспорт по некоторому пункту не заменяет файл, а создаёт новый, добавляя числовой индекс к имени. Это удобно когда происходит сбор информации с нескольких разных индексов образа, например.
Размонтирование с ключом /Discard, так как монтирование осуществлялось только для чтения. Отсутствие ключа неприемлемо.
Данный скрипт является логическим дополнением к коллекции скриптов представленных мной в предыдущих статьях. Хотя, по правде, всё это было написано более трёх месяцев назад, а данный скрипт был у меня первый. Просто постепенно раскрываю карты. Конечно, многие системные администраторы давно написали для себя подобные решения и у каждого они свои. Чужие наработки мне показались неудобными, в некоторых случаях громоздкими. Кто то пытался реализовать все возможности системы DISM в одном «мега»-скрипте, Я же решил сделать несколько скриптов, каждый под определённую задачу. Наверно не очень хорошо, что некоторый код повторяется, потому что при реализации некоторых идей и/или исправлении ошибок мне приходилось редактировать все файлы сразу. Рекламисты PowerShell проходят мимо. Я писал этот скрипт для себя и решил поделиться им с вами, таким какой он есть. Надеюсь многим он будет полезен — и для работы и как пример в учёбе.
Данный скрипт будет полезен системным администраторам создающим свои «сборки», либо тестирующим чужие. Иногда может возникнуть необходимость посмотреть некоторую информацию об установленной ОС — в этом случае также пригодиться данный скрипт. Все команды 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 проходят мимо. Я писал этот скрипт для себя и решил поделиться им с вами, таким какой он есть. Надеюсь многим он будет полезен — и для работы и как пример в учёбе.
