Checar se um Hotfix está instalado nas máquinas de um domínio

Por Daniel Aguiar/ Reviewer: Diana Hernandez

Recentemente muitos clientes têm ligado no Suporte Microsoft para saber se existe uma maneira de consultar se um hotfix está instalado nas máquinas de um domínio.

Essa demanda tem crescido devido ao boletim critico MS08-067, o qual vem sido explorado por alguns Malwares.

Em vista disso, nós do time Microsoft Latam, desenvolvemos um Script modelo, o qual lhe dará uma boa idéia de como criar um Script usando LDAP e WMI para consultar se suas máquinas de domínio têm um Hotfix especifico instalado ou não.

Lembrando que este Script é um modelo, não sendo suportado pelo Suporte Microsoft.
Mas com certeza ele lhe dará base para construir o um Script.

 ' -----------------------------------------------------------------------------------------
'CONTRATO DE USO (DISCLAIMER)
'
'Esse Script é um Modelo de uso do código
'
'Scripts modelo não são suportados por nenhum Serviço de Suporte ao Produto Microsoft ou 
'qualquer outro Programa de Suporte Microsoft.
'O scripts modelo são fornecidos como “exemplo para uso do código”, sem nenhuma garantia 
'de qualquer espécie
'
'A Microsoft não garante o uso desse script para qualquer fim que seja aplicado. 
'Por conseguinte, não garante o uso do mesmo se implementado de maneira comercial ou se 
'adequado para qualquer outra finalidade.
'
'Todo e qualquer risco decorrente do uso ou desempenho de scripts modelo em qualquer ambiente
'são de responsabilidade do usuário do script modelo.
'Em nenhum caso a Microsoft, seus autores, ou qualquer pessoa outra coisa envolvida na
'criação, produção ou publicação do script será responsabilizada por quaisquer danos 
'(incluindo, sem limitação, danos por perda de negócio, lucros, interrupção comercial, 
'perda de informações comerciais, ou outro título oneroso a perda) decorrentes do uso 
'ou da incapacidade de utilizar os scripts modelo ou documentação, mesmo que a Microsoft
'tenha sido avisada da possibilidade de tais danos.
'
' Este Script foi criado apenas para demonstração do uso de Query LDAP e WMI 
' para obter as máquinas de um dóminio e checar se possuem ou não um determinado Hotfix
' -----------------------------------------------------------------------------------------
' Nós recomendamos fortemente que você utilize o modelo desse Script 
' apenas em ambiente de laboratório, e que se faça as alterações necessárias
' -----------------------------------------------------------------------------------------
' Esse Script deve ser executado sob privilégios administrativos de dominio
' -----------------------------------------------------------------------------------------
' O uso desse Script não faz parte do Suporte Microsoft. Para detalhes veja o link abaixo
' https://blogs.technet.com/latam/about.aspx
' -----------------------------------------------------------------------------------------
' Author - Daniel Aguiar
' -----------------------------------------------------------------------------------------

'A linha abaixo serve suprimir mensagens de erros já controlados no Script 

On Error Resume Next

'Está mensagem alerta o inicio do Script

msgbox "The Script was started. The Script will show a message box 'Script Finished' when it ends",vbYes,"Script Started"

'Constantes definidas para pesquisar todas sub-arvores do Active Directory e para CSV Logging

Const ADS_SCOPE_SUBTREE = 2
Const ForWriting = 2

'A variável strDomain, deve possuir a string do domínio a ser pesquisado
'Exemplo: strDomain = "microsoft.com"

strDomain = InputBox("Enter your Domain name. (Example: microsoft.com)","Information Required")

'A variável strHotfix, deve possuir a string do Hotfix ID a ser procurado em cada máquina
'Exemplo: strHotfix = "KB958644"

strHotfix = InputBox("Enter the Hotfix ID you want to search for. (Example: KB958644)","Information Required")

'A seguir são preparados os objetos para se iniciar uma conexão LDAP

Set objLdapConnection = Createobject("ADODB.Connection")
Set objLdapCommand =   Createobject("ADODB.Command")
objLdapConnection.Provider = "ADsDSOobject"
objLdapConnection.Open "Active Directory Provider"
Set objLdapCommand.ActiveConnection = objLdapConnection

'É feita uma consulta no banco de dados do Active Directory procurando por objetos do tipo Computer, a partir da raiz

objLdapCommand.CommandText = "Select Name from 'LDAP://" & strDomain & "' Where objectCategory='computer'"
'objLdapCommand.Properties("Page Size") = 5000
objLdapCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
Set objLdapRecordSet = objLdapCommand.Execute

'Verifica se a query LDAP retornou algum valor, se não retornou nenhum valor mostra message box e finaliza o Script

If objLdapRecordSet.RecordCount = 0 Then
 msgbox "Ldap query for domain '" & strDomain & "' returned 0 objects. Script will be finished.",vbYes,"Script Failed"
 Wscript.Quit
End if

'Com a lista de objetos do tipo Computer montada no objeto objLdapRecordSet, passamos para o primeiro computador da lista

objLdapRecordSet.MoveFirst

'Agora que temos a lista de computadores pronta, iniciamos um arquivo de Log, do tipo CSV

Set objCSVFileFSO = Createobject("Scripting.FileSystemobject")
Set objCSVLogFile = objCSVFileFSO.CreateTextFile("Status_for_" & strHotfix & "_on_Domain_" & strDomain & ".txt", ForWriting, True)

'Este será o cabeçalho do arquivo CSV

objCSVLogFile.Write "Script using LDAP and WMI"
objCSVLogFile.Writeline
objCSVLogFile.Write "Query against: " & strDomain 
objCSVLogFile.Writeline
objCSVLogFile.Write "Looking for the status of " & strHotfix & " on all computer objects"
objCSVLogFile.Writeline
objCSVLogFile.Writeline
objCSVLogFile.Write "COMPUTER NAME,"
objCSVLogFile.Write "STATUS WHILE QUERYING Hotfix " & strHotfix & ","
objCSVLogFile.Writeline

'Limpamos as variáveis para contagem de computadores com Hotfix encontrado, não encontrado e que deram erro

NumCountError = 0
NumCountHotfixFound = 0
NumCountHotfixNotFound = 0

'Com o arquivo de Log e cabeçalho montados, entramos no looping pesquisando, via WMI, máquina por máquina, se o Hotfix está presente

Do Until objLdapRecordSet.EOF

 'Le o nome do objeto computer que está sendo apontado na query LDAP e faz um Store na variável strComputer

 strComputer = objLdapRecordSet.Fields("Name")

 'Grava nome do objeto Computer no arquivo de Log

 objCSVLogFile.Write strComputer & ","

 'Inicia a query WMI no computador

 Set WMIHotfixQuery = Getobject("winmgmts:\\" & strComputer)
 Set WMIHotfixResult = WMIHotfixQuery.ExecQuery("SELECT * FROM Win32_QuickFixEngineering where HotfixID = '" & strHotfix & "'")

 'Se o acesso for negado ou o computador não responder ou qualquer erro for encontrado na conexão acima, grava o erro no Log

 If Err <> 0 Then

  objCSVLogFile.Write "Error: " & Err.Number & " - " & Err.Description & ","
  NumCountError = NumCountError + 1

 Else
 
  'Se não deu erro, verifica se a busca pelo Hotfix na máquina especifica, retornou pelo menos 1 resultado e então grava como Hotfix encontrado

  If (WMIHotfixResult.Count > 0) Then

   objCSVLogFile.Write "Hotfix Found,"
   NumCountHotfixFound = NumCountHotfixFound + 1

  'Se nenhum resultado foi retornado na query WMI, grava como Hotfix não encontrado nos logs

  Else

   objCSVLogFile.Write "Hotfix Not Found;"
   NumCountHotfixNotFound= NumCountHotfixNotFound+ 1

  End if

 End if

 'Inicia uma nova linha no Log e passa para a próxima objeto Computer da consulta LDAP

 objCSVLogFile.Writeline
 objLdapRecordSet.MoveNext

Loop

'Com todas as consultas finalizadas escreve um sumário do Script

objCSVLogFile.Writeline
objCSVLogFile.Write "Summary of Computers Queries" 
objCSVLogFile.Writeline
objCSVLogFile.Write "Total Queries: " & objLdapRecordSet.RecordCount
objCSVLogFile.Writeline
objCSVLogFile.Write "Hotfix Founds: " & NumCountHotfixFound
objCSVLogFile.Writeline
objCSVLogFile.Write "Hotfix Not Found: " & NumCountHotfixNotFound
objCSVLogFile.Writeline
objCSVLogFile.Write "Query Errors: " & NumCountError
objCSVLogFile.Writeline

'Mensagem alertando o final do Script

msgbox "The Script was finished. Look for the csv log file on the script folder for details.",vbYes,"Script Finished"

 

Esperamos ter ajudado, e bons updates!