В работе администратора часто возникает необходимость проверить, установлена ли на некотором компьютере в сети определённая программа и какой версии. Например, можно проверить, установлено ли важное обновление Windows или все ли рабочие станции имеют правильную версию Office.
Как это сделать с помощью командных файлов CMD (BAT) или скриптов (на примере VBScript), рассказывается далее.
Идея основана на том факте, что информация об установленных программах находится в системном реестре по адресу:
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\
Указанная ветвь реестра перечисляет только программы, установленные «для всех пользователей», а программы «для этого пользователя» перечислены в ветви:
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall
В Windows x64 список программ сохраняется также в папке реестра:
HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
Соответственно, для получения полного списка потребуется просканировать информацию из всех трёх ветвей реестра.
Например, на VBScript:
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE strComputer = "computer" strKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" strEntry1a = "DisplayName" strEntry1b = "QuietDisplayName" strEntry2 = "InstallDate" strEntry3 = "VersionMajor" strEntry4 = "VersionMinor" strEntry5 = "EstimatedSize" Set objReg = GetObject("winmgmts://" & strComputer & _ "/root/default:StdRegProv") objReg.EnumKey HKLM, strKey, arrSubkeys WScript.Echo "Installed Applications (" & strComputer & ")" & VbCrLf For Each strSubkey In arrSubkeys intRet1 = objReg.GetStringValue(HKLM, strKey & strSubkey, _ strEntry1a, strValue1) If intRet1 <> 0 Then objReg.GetStringValue HKLM, strKey & strSubkey, _ strEntry1b, strValue1 End If If strValue1 <> "" Then WScript.Echo VbCrLf & "Display Name: " & strValue1 End If objReg.GetStringValue HKLM, strKey & strSubkey, _ strEntry2, strValue2 If strValue2 <> "" Then WScript.Echo "Install Date: " & strValue2 End If objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry3, intValue3 objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry4, intValue4 If intValue3 <> "" Then WScript.Echo "Version: " & intValue3 & "." & intValue4 End If objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry5, intValue5 If intValue5 <> "" Then WScript.Echo "Estimated Size: " & Round(intValue5/1024, 3) & " megabytes" End If Next
Скрипт подключается к компьютеру с сетевым именем strComputer, просматривает раздел реестра SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ и выводит информацию о программах.
Аналогичные действия можно выполнить в командном файле CMD. Этот командный файл выдаёт список программ:
@echo off rem Этот командный файл записывает список программ, установленных на rem удалённом компьютере. rem %1 Сетевое имя компьютера в формате PCNAME (пустое значение означает rem локальный компьютер). rem Определяем путь к папке реестра set reg_key=hklm\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall if not "%1" == "" set reg_key=\\%~1\%reg_key% rem Перебираем установленные программы for /F "tokens=1,2,*" %%a in ('reg query "%reg_key%" /s') do ^ if "%%a" == "DisplayName" echo %%c
Для проверки того, установлена ли конкретная программа (по названию) на каком-то одном компьютере, можно использовать следующий командный файл check-app-pc.cmd
@echo off rem Этот командный файл проверяет, установлена ли заданная программа на rem удалённом компьютере. rem %1 Полное название программы или часть названия, например, KB2570791. rem %2 Сетевое имя компьютера в формате PCNAME (пустое значение означает rem локальный компьютер). rem Возвращаемые коды: rem 0 Программа установлена. rem 2 Программа не найдена. rem 87 Ошибка в параметрах. set app_name=%1 set pc_name=%2 rem Проверяем наличие в списке call apps.cmd %2 | findstr /i "%~1" if errorlevel 1 echo '%~1' program not found && exit /b 2 echo '%~1' program installed. && exit /b 0
Соответственно, команда check-app-pc.cmd KB2570791 ws_alex
проверит, установлено ли обновление KB2570791 на компьютере WS_ALEX.
Теперь можно автоматизировать работу этого командного файла, добавив проверку большего количества компьютеров по списку. Для этого создаём командный файл check-app-pclist.cmd с циклом, перебирающим строчки текстового файла с сетевыми именами компьютеров.
@echo off rem %1 Полное название программы или часть названия программы. rem %2 Имя файла со списком компьютеров. rem Примечание: этот командный файл использует check-app-pclist.cmd if "%~1" == "" exit /b 87 if not exist %2 exit /b 2 for /F %%a in (%2) do ( echo %%a... call check-app-pc.cmd %1 %%a )
Пример списка файлов pc.list
SERVER_DB SERVER_FILES WS_ALEX WS_RECEPTION
Теперь с помощью команды check-app-pclist.cmd KB2570791 pc.list
можно проверить, установлено ли обновление KB2570791 на каждом компьютере, перечисленном в файле pc.list.
Вопрос по скрипту на VBS, в тексте указано что он обходит только одну ветку.
Поэтому если мне необходимо получить полный список, то необходимо обойти еще две оставшиеся.
Вопрос в следующем, как можно отсортировать получаемый список программ и не допустить появление дублей?
а как бы ещё версию добавить или другой параметр ?
GLS
GLS
Командный файл, который перечисляет все программы (компьютера и пользователя, 32/64 бита):
@echo off
echo *** Local Machine x64 Programs
set reg_key=hklm\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
for /F «tokens=1,2,*» %%a in (‘reg query «%reg_key%» /s’) do ^
if «%%a» == «DisplayName» echo %%c
echo *** Local Machine x32 Programs
set reg_key=HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
for /F «tokens=1,2,*» %%a in (‘reg query «%reg_key%» /s’) do ^
if «%%a» == «DisplayName» echo %%c
echo *** Current User programs
set reg_key=hkcu\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
for /F «tokens=1,2,*» %%a in (‘reg query «%reg_key%» /s’) do ^
if «%%a» == «DisplayName» echo %%c