Имею серию статей посвящённых теме обслуживания образов 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 проходят мимо. Я писал этот скрипт для себя и решил поделиться им с вами, таким какой он есть. Надеюсь многим он будет полезен — и для работы и как пример в учёбе.