Compartilhar via


Inventariando Hosts Automaticamente com VBScript (pt-BR)

O Vbscript tendenciado a queda com o surgimento do Power Shell, ainda é uma ferramenta bastante útil devido sua simplicidade de execução.

Segue aqui um exemplo de script para fazer inventário de servidores e desktops dentro da rede.

A estrutura funciona assim :

Um arquivo chamado servers.txt será a matriz de dados, neste o nome dos servidores (ou desktops) serão listados (um por linha). Pode ser nome da máquina, FQDN ou IP.

O script fará leitura no arquivo servers.txt e fará a varredura em cada máquina nele contido. Como resultado, irá gerar arquivos [nome da máquina].txt  com o relatório completo de hardware e software. Serão listados CPUs (lógicos e físicos), Ram (em pentes e Mb), tipo de gabinete, SO, Discos e espaço utilizado, softwares instalados, serviços do windows, updates do windows instalados e mais algumas outras informações.  Ai que vem a simplicidade do vbscript, pois em poucos minutos podemos editar seu códico e modificar facilmente a relação de resultados desejados.

Se por algum motivo, uma ou mais máquinas estiverem indisponíveis, estas serão listadas dentro de outro arquivo denominado log_erro.txt

Como fazer:

  1. Crie uma pasta e nesta crie 1 arquivo de nome servers.txt.
  2. Crie um novo arquivo no notepad, copie e cole o script abaixo, e salve este arquivo como inventario.vbs (ou qualquer nome desejado)
  3. Edite o arquivo servers.txt e adicione em lista o nome dos hosts a serem inventáriados. Você pode por exemplo, exportar uma lista de nomes do AD.
  4. Execute o Inventario.vbs e aguarde a mensagem de concluido na tela
  • Segue o Script comentado :

'Script para geração de relatório de inventário de Hardware e Software.
'OBS: Alguns parâmetros são inválidos para Windows 2000/XP e versões mais antigas.
'Para obter núm de CPU´s (core) e HT, necessário fix: http://support.microsoft.com/kb/932370

on error resume Next

Dim objFSO, objFSO1, objFSO2, outFile, outFile2, strTextFile, strData, arrLines, host, host1

CONST ForReading = 1
'Abrir arquivo servers.txt e efetuar leitura dos nomes dos servidores
strTextFile = "servers.txt"
Set objFSO1 = CreateObject("Scripting.FileSystemObject")
strData = objFSO1.OpenTextFile(strTextFile,ForReading).ReadAll
arrLines = Split(strData,vbCrLf)

'Geração de um arquivo de log de erros, onde os hostnames que não pingam serão inclusos.
strFileName2 = "log_erro.txt"
Set objFSO2 = CreateObject("Scripting.FileSystemObject")
Set outFile2 = objFSO2.OpenTextFile(strFileName2, 2, True)
outfile2.writeline "Hosts não encontrados"

'Para efetuar pesquisa onde se digita o servername em vez de buscar em um TXT,
'deve-se comentar a Linha FOR abaixo e a linha host = cstr, e descomentar host =inputbox
'tambem comentar o next no final do script

For Each host1 in arrLines
host = cstr(host1)
'host= InputBox("Digite o nome do host ou IP: ", "Inventário de Hardware", "127.0.0.1")

'Criação do txt com nome do host para relatório.
strFileName = host & ".txt"

'Verificação da existência do host (se o mesmo pinga) - e report no arquivo de log em caso de falha.
Set WshShell = WScript.CreateObject("WScript.Shell")
theCmd = "ping " & host & " -n 1 -w 9999"
Return = WshShell.Run(theCmd, 0, true)
If Return <> 0 Then
outfile2.writeline "" & host
hostcount = 1
End If

'A verificação do hostcount serve para não gerar hostname.txt de hosts que não estão pingando, naturalmente com resultado em branco.
if hostcount <> 1 then

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set outFile = objFSO.OpenTextFile(strFileName, 2, True)

strComputer = host

Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystem",,48)

'Início da geração do relatório em TXT
For Each objItem in colItems

outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "### INVENTÁRIO COMPLETO DO HOST " & objItem.Name & " ###"
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

'HOST
outFile.WriteLine "# INFORMAÇÕES DO HOST: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set WshShell = WScript.CreateObject("WScript.Shell")
theCmd = "ping " & host & " -n 1 -w 9999"
Return = WshShell.Run(theCmd, 0, true)
if Return = 0 Then
outFile.WriteLine "Status: ONLINE"
outFile.WriteLine "HostName: " & objItem.Name
outFile.WriteLine "DNSName: " & objItem.DNSHostName '- não funciona no Windows XP
outFile.WriteLine "Domain: " & objItem.Domain
outFile.WriteLine "Workgroup: " & objItem.Workgroup '- não funciona no Windows 2000 Server
outFile.WriteLine "" & vbCrLf
End If
Next

'SISTEMA OPERACIONAL
outFile.WriteLine "# SISTEMA OPERACIONAL: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_OperatingSystem",,48)
For Each objItem in colItems
outFile.WriteLine "Sistema Operacional: " & objItem.Caption
outFile.WriteLine "Service Pack: " & objItem.ServicePackMajorVersion
outFile.WriteLine "Dir. Sistema: " & objItem.SystemDirectory
outFile.WriteLine "Data da Instalacao: " & objItem.InstallDate
outFile.WriteLine "Organizacao: " & objItem.Organization
outFile.WriteLine "Registro: " & objItem.RegisteredUser & VbCrLf
Next
outFile.WriteLine "" & vbCrLf

'FABRICANTE, MODELO E SERIAL NUMBER
outFile.WriteLine "# FABRICANTE: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystemProduct",,48)
For Each objItem in colItems
outFile.WriteLine "Fabricante: " & objItem.Vendor
outFile.WriteLine "Modelo: " & objItem.Name
outFile.WriteLine "Serial Number: " & objItem.IdentifyingNumber
Next

'TIPO DE GABINETE
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
Set colChassis = objWMIService.ExecQuery _
("Select * from Win32_SystemEnclosure")
For Each objChassis in colChassis
For Each strChassisType in objChassis.ChassisTypes
Select Case strChassisType
Case 1
outFile.WriteLine "Tipo de Gabinete: Outro (ex. VM)"
Case 2
outFile.WriteLine "Tipo de Gabinete: Desconhecido"
Case 3
outFile.WriteLine "Tipo de Gabinete: Desktop"
Case 4
outFile.WriteLine "Tipo de Gabinete: Low Profile Desktop"
Case 5
outFile.WriteLine "Tipo de Gabinete: Pizza Box"
Case 6
outFile.WriteLine "Tipo de Gabinete: Mini Tower"
Case 7
outFile.WriteLine "Tipo de Gabinete: Tower"
Case 8
outFile.WriteLine "Tipo de Gabinete: Portable"
Case 9
outFile.WriteLine "Tipo de Gabinete: Laptop"
Case 10
outFile.WriteLine "Tipo de Gabinete: Notebook"
Case 11
outFile.WriteLine "Tipo de Gabinete: Handheld"
Case 12
outFile.WriteLine "Tipo de Gabinete: Docking Station"
Case 13
outFile.WriteLine "Tipo de Gabinete: All-in-One"
Case 14
outFile.WriteLine "Tipo de Gabinete: Sub-Notebook"
Case 15
outFile.WriteLine "Tipo de Gabinete: Space Saving"
Case 16
outFile.WriteLine "Tipo de Gabinete: Lunch Box"
Case 17
outFile.WriteLine "Tipo de Gabinete: Main System Chassis"
Case 18
outFile.WriteLine "Tipo de Gabinete: Expansion Chassis"
Case 19
outFile.WriteLine "Tipo de Gabinete: Sub-Chassis"
Case 20
outFile.WriteLine "Tipo de Gabinete: Bus Expansion Chassis"
Case 21
outFile.WriteLine "Tipo de Gabinete: Peripheral Chassis"
Case 22
outFile.WriteLine "Tipo de Gabinete: Storage Chassis"
Case 23
outFile.WriteLine "Tipo de Gabinete: Serv. Rack"
Case 24
outFile.WriteLine "Tipo de Gabinete: Sealed-Case PC"
Case Else
outFile.WriteLine "Tipo de Gabinete: Desconhecido"
End Select
Next
Next
outFile.WriteLine "" & vbCrLf

'PROCESSADOR
outFile.WriteLine "# PROCESSADOR: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

'Número de Processador(es)
Set colSettings = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colSettings
outFile.WriteLine "Processadores Físico(s): " & objComputer.NumberOfProcessors
Next

'Numero de Server Core´s
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem",,48)
For Each objItem in colItems
outFile.WriteLine "Processadores Lógicos (core): " & objItem.NumberOfCores
Next

'Numero de Processadores Logicos
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Processor",,48)
For Each objItem in colItems
outFile.WriteLine "Simuladores Lógicos (HT): " & objItem.NumberOfLogicalProcessors
Next

'Detalhes dos processadores
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Processor",,48)
For Each objItem in colItems
outFile.WriteLine "DeviceID: " & objItem.DeviceID
outFile.WriteLine "Fabricante: " & objItem.Manufacturer
outFile.WriteLine "Modelo: " & objItem.Name & VbCrLf
'outFile.WriteLine "Status: " & objItem.Status & VbCrLf
Next

'MEMÓRIA
outFile.WriteLine "# MEMÓRIA :"
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

'Memória Total
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystem",,48)
For Each objItem in colItems
If objItem.TotalPhysicalMemory > 1073741824 Then
outFile.WriteLine "Memória RAM Total: " & round(objItem.TotalPhysicalMemory / 1073741824,2) & " GB "
Else
outFile.WriteLine "Memória RAM Total: " & round(objItem.TotalPhysicalMemory / 1048576,2) & " MB "
End If
Next

'Slots de memória
outFile.WriteLine "" & vbCrLf
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_PhysicalMemoryArray",,48)
For Each objItem in colItems
outFile.WriteLine "Slots de Memória: " & objItem.MemoryDevices
Next

'Informações dos pentes
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_PhysicalMemory",,48)

For Each objItem in colItems
outFile.WriteLine "Pente de Memoria: " & objItem.DeviceLocator & " " & objItem.Capacity / 1048576 & " MB " & objItem.Manufacturer & " " & objItem.Model
Next

'Pagefile
'strComputer = env.Item("Computername")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")

Set colPageFiles = objWMIService.ExecQuery("Select * from Win32_PageFile")

For Each objPageFile in colPageFiles
outFile.WriteLine "Pagefile Drive: " & objPageFile.Drive
If objPageFile.FileSize > 1073741824 Then
outFile.WriteLine "Pagefile Tamanho: " & round(objPageFile.FileSize/ 1073741824,2) & " GB "
Else
outFile.WriteLine "Pagefile Tamanho: " & round(objPageFile.FileSize / 1048576,2) & " MB "
End If

Next

outFile.WriteLine "" & VbCrLf

'DISCOS
outFile.WriteLine "# DISCOS: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

'Discos Físicos
outFile.WriteLine "# DISCOS FÍSICOS:"
outFile.WriteLine "" & vbCrLf
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_DiskDrive",,48)
For Each objItem in colItems
outFile.WriteLine "Caption: " & objItem.Caption
outFile.WriteLine "Description: " & objItem.Description
outFile.WriteLine "InterfaceType: " & objItem.InterfaceType
outFile.WriteLine "MediaType: " & objItem.MediaType
outFile.WriteLine "Partitions: " & objItem.Partitions & VbCrLf
Next

'Unidades Lógicas
outFile.WriteLine "# UNIDADES LÓGICAS:"
outFile.WriteLine "" & vbCrLf
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_LogicalDisk",,48)
For Each objItem in colItems
outFile.WriteLine "Unidade: " & objItem.Caption
outFile.WriteLine "Descriao: " & objItem.Description
outFile.WriteLine "FileSystem: " & objItem.FileSystem
outFile.WriteLine "Espaco Livre: " & INT(objItem.FreeSpace / 1048576) & " MB "
outFile.WriteLine "Tamanho: " & INT(objItem.Size / 1048576) & " MB "
outFile.WriteLine "Status: " & objItem.Status
outFile.WriteLine "Nome do Volume: " & objItem.VolumeName & VbCrLf
Next
outFile.WriteLine "" & vbCrLf

'REDE
outFile.WriteLine "# REDE: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_NetworkAdapterConfiguration",,48)
For Each objItem in colItems
outFile.WriteLine "Detalhes: " & objItem.Description
outFile.WriteLine "DHCP: " & objItem.DHCPEnabled
If isNull(objItem.IPAddress) Then
outFile.WriteLine "Endereco IP: "
Else
outFile.WriteLine "Endereco IP: " & Join(objItem.IPAddress, ",")
End If
If isNull(objItem.IPSubnet) Then
outFile.WriteLine "Mascara: "
Else
outFile.WriteLine "Mascara: " & Join(objItem.IPSubnet, ",")
End If
outFile.WriteLine "MAC: " & objItem.MACAddress & VbCrLf
Next

'SERVIÇOS DO WINDOWS
outFile.WriteLine "# SERVIÇOS: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")

Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service")

For Each objService in colRunningServices
outFile.WriteLine objService.State & VbTab & VbTab & objService.DisplayName
Next
outFile.WriteLine vbCrLf & vbCrLf
'SOFTWARES
outFile.WriteLine "# SOFTWARES: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

Set oShell = CreateObject("wscript.Shell")
Set env = oShell.environment("Process")
Const HKEY_LOCAL_MACHINE = &H80000002
Const UnInstPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\" &_
".\root\default:StdRegProv")
oReg.EnumKey HKEY_LOCAL_MACHINE, UnInstPath, arrSubKeys

For Each subkey In arrSubKeys
If Left (subkey, 1) <> "{" Then 'Para não listar as aplicações com chamadas de chave
If Left (subkey, 2) <> "KB" Then 'Para não listar os KBs da Microsoft
software = software & subkey & vbCrLf
End If
End If
Next

'em separado listando apenas KBs da Microsoft
outFile.WriteLine software

outFile.WriteLine "# UPDATES MICROSOFT: "
outFile.WriteLine "-------------------------------------------------------"
outFile.WriteLine "" & vbCrLf

For Each subkey In arrSubKeys
If Left (subkey, 1) <> "{" Then 'Para não listar as aplicações com chamadas de chave
If Left (subkey, 2) = "KB" Then 'Para listar os KBs da Microsoft
kbs = kbs & subkey & " "
End If
End If
Next

outFile.WriteLine kbs

' Finalizar variáveis
Set objFSO = Nothing
Set objFSO1 = Nothing
Set objFSO2 = Nothing
Set outFile = Nothing

'Descomentar as linhas abaixo para quando a pesquisa for de 1 server sem leitura no servers.txt Isso exibirá o [hostname].txt aberto em tela.

'Set WshShell = WScript.CreateObject("WScript.Shell")
'WshShell.Run("notepad.exe " & host & ".txt")

'O Else abaixo zera o hostcount, pois caso uma máq não pingue, o hostcount será 1, e aqui zera o processo para o novo host.
else
hostcount = 0
end if

next
WScript.Echo "Concluído!"

João Ricardo Wilde Neto
MCTS, MCITP, MCDST, MCT