VBS. Инвентаризация железа.
24.12.2019В сети довольно много примеров использования VBS для проведения инвентаризации компьютеров, но ни один из них не подошел мне в качестве готового варианта для использования.
По этой причине, изучив как они работают, мне пришлось на базе доступных в сети примеров, создать свой, удовлетворяющий на все 100% моё видение процесса инвентаризации.
Рассмотрев известный скрипт Павла Железнова и несколько других, мне удалось собрать код, который инвентаризирует не только начинку системного блока, но и мониторы, и принтеры.
Конечно получить серийный номер принтера не удалось, отличии от всего остального, поэтому исключил вывод серийных номеров везде.
Ниже приведен полностью рабочий код VBS.
[code]
'режим работы
Const SILENT = True 'режим отчета о локальном компьютере без вывода диалогов
'где сохранять отчет по принтерам
'Const DATA_DIR = ""
Const DATA_DIRPRN = "\\сервер\Invent$\printers\" 'сетевой ресурс + "\" в конце
Const DATA_DIRPC = "\\сервер\Invent$\computers\"
'прочее
Const TITLE = "Инвентаризация компьютеров и принтеров" 'заголовок диалоговых окон
Const DATA_EXT = ".csv" 'расширение файла отчета
Const HEAD_LINE = True 'выводить заголовки в первой строке CSV-файла
'не завершать скрипт аварийно
On Error Resume Next
'== ВЫПОЛНЕНИЕ
'объект для доступа к файловой системе
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
'объект WMI
Dim wmio
Dim tfPRN 'файл отчета по принтерам
Dim tf 'файл отчета по компам
'узнать имя локального компьютера
Dim nwo, comp
Set nwo = CreateObject("WScript.Network")
comp = LCase(nwo.ComputerName)
function ipLocal()
xz=""
dim strComputer,objWMIService,IPConfigSet,IPConfig,i,ip
Set WSHNetwork = CreateObject("WScript.Network")
ComputerName=WSHNetwork.ComputerName
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set IPConfigSet = objWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
'определение своего ip
For Each IPConfig in IPConfigSet
If Not IsNull(IPConfig.IPAddress) Then
For i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
if len(IPConfig.IPAddress(i))<16 then
if IPConfig.IPAddress(i)<>xz then
xz=IPConfig.IPAddress(i)
If (inStr(xz, "192.168.")=0) then
'эта проверка стоит для получения IP машины, т.к. мы не используем этот диапазон
ip = IPConfig.IPAddress(i)
end If
end If
end if
Next
End If
Next
ipLocal = ip
End function
'провести инвентаризацию
'============раздел инвентаризация принтеров================
If Len(comp) > 0 Then InventPRN(comp)
'если ошибка
If Len(Err.Description) > 0 Then _
If Not SILENT Then MsgBox comp & vbCrLf & "Ошибка:" & vbCrLf & Err.Description, vbExclamation, TITLE
'сохранение отчета с указанным именем
Sub InventPRN(compname)
Set wmio = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & compname & "\Root\CIMV2")
'некоторые WMI-классы поддерживаются не во всех версиях Windows
Dim build
build = BuildVersion()
'файл отчета по принтерам
Set tfPRN = fso.CreateTextFile(DATA_DIRPRN & compname & "_prn" & DATA_EXT, True)
'первая строка - заголовки
If HEAD_LINE Then tfPRN.WriteLine "Дата проверки;Тип принтера;Номер
экземпляра;ПривязкаПК;Модель;Порт;ShareName;Location;Direct;Shared;WorkOffline"
If build >= 2600 Then
LogPRN "Win32_Printer", _
"SystemName,Name,PortName,ShareName,Location,Direct,Shared,WorkOffline", "(Local = True OR Network = False) AND (PortName LIKE '%USB%' OR
PortName LIKE '%LPT%')", _
"Локальный принтер", _
"SystemName,Наименование,Порт,Сетевое имя,Location,Direct,Shared,WorkOffline"
End If
If build >= 2600 Then
LogPRN "Win32_Printer", _
"SystemName,Name,PortName,ShareName,Location,Direct,Shared,WorkOffline", "(PortName LIKE '%10.%' OR PortName LIKE '%192.%' OR PortName
LIKE '%\\%')", _
"Сетевой принтер", _
"SystemName,Наименование,Порт,Сетевое имя,Location,Direct,Shared,WorkOffline"
End If
'закрыть файл
tfPRN.Close
End Sub
'Наполнение файла отчета данными по принтерам
Sub LogPRN(from, sel, where, sect, param)
Const RETURN_IMMEDIATELY = 16
Const FORWARD_ONLY = 32
Dim query, cls, item, prop
query = "Select " & sel & " From " & from
If Len(where) > 0 Then query = query & " Where " & where
Set cls = wmio.ExecQuery(query,, RETURN_IMMEDIATELY + FORWARD_ONLY)
Dim props, names, num, value
props = Split(sel, ",")
names = Split(param, ",")
num = 1 'номер экземпляра
For Each item In cls
tfPRN.Write Date & ";"
tfPRN.Write sect & ";"
tfPRN.Write num & ";"
For i = 0 To UBound(props)
'взять значение
Set prop = item.Properties_(props(i))
value = prop.Value
'без проверки на Null возможнен вылет с ошибкой
If IsNull(value) Then value = "-" End If
'вывести в файл непустое значение, заменить спецсимвол ";"
value = Trim(Replace(value, ";", "_"))
If Len(value) > 0 Then tfPRN.Write value & ";"
Next 'i
'перейти к следующему экземпляру
num = num + 1
tfPRN.WriteLine
Next 'item
End Sub
'============= конец раздела инвентаризация принтеров===============
'
'============== раздел инвентаризация компов ======================
If Len(comp) > 0 Then InventPC(comp)
'если ошибка
If Len(Err.Description) > 0 Then _
If Not SILENT Then MsgBox comp & vbCrLf & "Ошибка:" & vbCrLf & Err.Description, vbExclamation, TITLE
Sub InventPC(compname)
Set wmio = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\" & compname & "\Root\CIMV2")
'некоторые WMI-классы поддерживаются не во всех версиях Windows
Dim build
build = BuildVersion()
'файл отчета по компьютерам
Set tf = fso.CreateTextFile(DATA_DIRPC & compname & "_pc" & DATA_EXT, True)
'первая строка - заголовки
If HEAD_LINE Then tf.WriteLine "Дата проверки;IP-адрес;Сетевое имя;Домен;Текущий пользователь;Наименование ОС;Дата установки
ОС;Производитель МП;Наименование МП;Модель CPU;CPU (МГц);Сокет CPU;ОЗУ(Гб);HDD модель;HDD Размер(Гб);CD-
привод;Видеоконтроллер;Сетевой адаптер;Звуковое устройство;Монитор №1;Монитор №2;Монитор №3;Монитор №4"
'дата проверки
tf.Write Date & ";"
'IP
tf.Write ipLocal & ";"
On error resume next
set oshell=createobject("WScript.shell")
LogPC "Win32_ComputerSystem", _
"Name,Domain,UserName", "", _
"Компьютер", _
"Сетевое имя,Домен,Текущий пользователь"
LogPC "Win32_OperatingSystem", _
"Caption,InstallDate", "", _
"Операционная система", _
"Наименование,Дата установки"
LogPC "Win32_BaseBoard", _
"Manufacturer,Product", "", _
"Материнская плата", _
"Производитель,Наименование"
'не определяется Core 2 в XP SP2, см. http://support.microsoft.com/kb/953955
LogPC "Win32_Processor", _
"Name,CurrentClockSpeed,SocketDesignation", "", _
"Процессор", _
"Наименование,Частота (МГц),Сокет"
LogPC "Win32_ComputerSystem", _
"TotalPhysicalMemory", "", _
"Модули памяти", _
"Общий объем (Гб)"
'пропускаются USB-диски
LogPC "Win32_DiskDrive", _
"Model,Size", "InterfaceType <> 'USB'", _
"Диск", _
"Наименование,Размер (Гб)"
LogPC "Win32_CDROMDrive", _
"Name", "", _
"CD-привод", _
"Наименование"
'только для XP/2003 и выше
'пропускаются лишние видео-драйверы, собираем реальные видеоадаптеры
If build >= 2600 Then
LogPC "Win32_VideoController", _
"Name", "NOT (Name LIKE '%Secondary' OR Name LIKE '%radmin%' OR Name LIKE '%hook%')", _
"Видеоконтроллер", _
"Наименование"
Else 'для Windows 2000
LogPC "Win32_VideoController", _
"Name,AdapterRAM,VideoProcessor,VideoModeDescription,DriverDate,DriverVersion", "", _
"Видеоконтроллер", _
"Наименование,Объем памяти (Мб),Видеопроцессор,Режим работы,Дата драйвера,Версия драйвера"
End If
'пропускаются отключенные сетевые адаптеры, в том числе минипорты
'пропускаются виртуальные адаптеры VMware
If build >= 2600 Then
LogPC "Win32_NetworkAdapter", _
"Name", "NetConnectionStatus > 0 AND NOT (Name LIKE 'VMware%')", _
"Сетевой адаптер", _
"Наименование"
End If
LogPC "Win32_SoundDevice", _
"Name", "NOT (Name LIKE '%micropho%' OR Name LIKE '%для дисплеев%' OR Name LIKE '%Virtual%')", _
"Звуковое устройство", _
"Наименование"
' собираем мониторы
Set objWMIService = GetObject("winmgmts:\\.\root\WMI")
Set colItems = objWMIService.ExecQuery("Select * From WmiMonitorID")
n=0
For Each objItem in colItems
n=n+1
tf.Write objItem.InstanceName &";"
Next
'закрыть файл
tf.WriteLine
tf.Close
End Sub
Sub LogPC(from, sel, where, sect, param)
Const RETURN_IMMEDIATELY = 16
Const FORWARD_ONLY = 32
Dim query, cls, item, prop
query = "Select " & sel & " From " & from
If Len(where) > 0 Then query = query & " Where " & where
Set cls = wmio.ExecQuery(query,, RETURN_IMMEDIATELY + FORWARD_ONLY)
Dim props, names, num, value
props = Split(sel, ",")
names = Split(param, ",")
num = 1 'номер экземпляра
For Each item In cls
For i = 0 To UBound(props)
'взять значение
Set prop = item.Properties_(props(i))
value = prop.Value
'без проверки на Null возможнен вылет с ошибкой
If IsNull(value) Then
value = "-"
'если тип данных - массив, собрать в строку
ElseIf IsArray(value) Then
value = Join(value,",")
'если указана кратная единица измерения, перевести значение
ElseIf Right(names(i), 4) = "(Мб)" Then
value = CStr(Round(value / 1024 ^ 2))
ElseIf Right(names(i), 4) = "(Гб)" Then
value = CStr(Round(value / 1024 ^ 3))
'если тип данных - дата, преобразовать в читаемый вид
ElseIf prop.CIMType = 101 Then
value = ReadableDate(value)
End If
'вывести в файл непустое значение, заменить спецсимвол ";"
value = Trim(Replace(value, ";", "_"))
If Len(value) > 0 Then tf.Write value & ";"
Next 'i
'перейти к следующему экземпляру
num = num + 1
Next 'item
End Sub
'========= конец раздела инвентаризация компов =================
' ФУНКЦИИ ОБРАБОТКИ ДАННЫХ
'преобразование даты формата DMTF в читаемый вид (ДД.ММ.ГГГГ)
Function ReadableDate(str)
ReadableDate = Mid(str, 7, 2) & "." & Mid(str, 5, 2) & "." & Left(str, 4)
End Function
'ПРОВЕРИТЬ версию (билд) WMI-сервера
'не все версии совместимы, поэтому скрипт должен знать выполняться или нет
Function BuildVersion()
Dim cls, item
Set cls = wmio.ExecQuery("Select BuildVersion From Win32_WMISetting")
For Each item In cls
BuildVersion = CInt(Left(item.BuildVersion, 4))
Next
End Function
то что нужно