Archive

Archive for January, 2010

Problemas corriqueiros com o apt-get

January 21, 2010 2 comments

Vou postar uma séries de resoluções de problemas que eu tive com a ferramenta “apt” e “dpkg” umas que descobri outras que li em outros blogs a referência esta no final do post.

Problema 1:
Se estiver tentando instalar um pacote e receber a mensagem

E: The package XXXX needs to be reinstalled, but I can’t find an archive for it.
E: Internal error opening cache (1). Please report.

ou

dpkg – warning, overriding problem because –force enabled:
Package is in a very bad inconsistent state – you should
reinstall it before attempting a removal.

ou

subprocess post-removal script returned error exit status 127
Errors were encountered while processing:

Solução: Utilize o comando “dpkg –remove –force-remove-reinstreq nome_do_pacote”, um exemplo para a remoção do pacote vim.

dpkg –remove –force-remove-reinstreq vim

Força a remoção do pacote inconsistente.

Problema 2

Se receber a seguinte mensagem:

The packages have files that are overwritten. – The packages have dependencies poorly resolved – There are conflicts between packages – a package can not be removed or updated by dpkg

Solução
execute os comandos

#echo “force-all” >/etc/dpkg/dpkg.cfg
#apt-get -f install

Problema 3

Um pacote é instalado e por alguma razão corrompido , você tenta instalar novamente e o apt-get diz que já esta instalado!

Solução:

#apt-get remove seu_pacote_corrompido
#apt-get update
#apt-get clean
#apt-get –reinstall install nome_do_pacote

Problema 4: O apt-get reclama que o repositório não tem a chave GPG(NO_PUBKEY) que serve para verificar a autenticidade dos pacotes

Solução:
Para resolver isso, execute o comando “apt-get update”

Copie o código que aparece no erro em negrito no log abaixo:

W: GPG error: ftp://ftp.debian.org/ testing Release:
The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 010908312D230C5F

W: There is no public key available for the following key IDs:
010908312D230C5F

Então rode os comandos com o key ID encontrado:

#gpg –keyserver pgpkeys.mit.edu –recv-key 010908312D230C5F
#gpg -a –export 010908312D230C5F | sudo apt-key add –

Problema 5: Mensagem de erro como

sub-processo post-installation script retornou estado de saída de erro -1
Erros foram encontrados durante o processamento de:

Solução
Para solucionar determine o nome do pacote que causou o erro, por exemplo no log abaixo, mostro em negrito o nome do pacote que causou o problema no meu caso(em negrito, xosview):

newaliases: warning: valid_hostname: numeric hostname: 69522
newaliases: fatal: bad parameter value: 69522
dpkg: error processing xosview (–configure):
subprocess post-installation script returned error exit status 75 sub-processo post-installation script retornou estado de saída de erro 75
Errors were encountered while processing:
Erros foram encontrados durante o processamento de:
xosview

Tendo determinado o nome do pacote, execute os comandos adaptado para teu pacote

#rm -f /var/lib/dpkg/info/xosview.post*
#rm -f /var/lib/dpkg/info/xosview.pre*
#apt-get -f install

Problema 6: Erro durante a remoção de pacote..

Solução

TROQUE abaixo a palavra pacote_defeituoso pelo nome do pacote que não quer ser removido e então rode estes comandos:

#rm -f /var/lib/dpkg/info/pacote_defeituoso.post*
#rm -f /var/lib/dpkg/info/pacote_defeituoso.pre*
#apt-get remove escreva_aqui_o_nome_do_pacote_defeituoso

Problema 7: Erro no /var/lib/dpkg/status…

Muitas vezes o apt-get da erros de leitura no arquivo /var/lib/dpkg/status

Solução

#cp /var/lib/dpkg/status-old /var/lib/dpkg/status

Problema 8: Se o problema de erro em /var/lib/dpkg/status… persiste ou exibe a mensagem “erro de out of room também” ou a mensagem abaixo

E: Dynamic MMap ran out of room

Solução

Edite o arquivo /etc/apt/apt.conf, aumentando o cache limit.

Apt::Cache-Limit “8388604″;

http://www.ubuntu-ac.org/archives/319
http://linuxhard.org/site/archives/1013

Espero que este post ajude. Afinal o apt tem o poder da vaca 😛

root@Capsula:~# apt-get moo
       (__)
       (oo)
  /——\/
/  |    ||
* /\—/\
  ~~ ~~
….”Have you mooed today?”…
root@Capsula:~#

Att.

Categories: Linux

Script em ruby para monitoramento de serviços – Nagios

January 13, 2010 1 comment

   Estou em um projeto de monitoramento de infra-estrutura de TI onde estou tendo que monitorar roteadores, servidores(tanto linux quando windows). Para o monitoramento dos recursos mais usuais como CPU, memória, trafego, etc, o uso do SNMP e plugins padrões do nagios são bastante eficazes. Entretanto, tive que monitorar processos e daemon destes servidores e pelo menos na busca nos plugins padroes do nagios não encontrei algum que pudesse atender minha demanda. Então parti para o desenvolvimento, teria que criar um script que iria dar um get em MIB de vários servidores buscando determinado processo. Graças aos padrões criados do protocolo SNMP existe na principal “base de dados” de um host uma MIB chamada MIB-2(Padrão na maioria das implementações) que já possue essas informações(como nome de processos, uso de memória por processo, etc). Então vi a chance de aprender uma nova linguagem de programação. Há tempos venho tentando arrumar um tempo para aprender ruby, eis que a chance surgiu. Resolvi desenvolver o script de monitoramento do Nagios em ruby. Fiz um “hello world” em ruby, e logo percebi o poder dessa linguagem. Uma linguagem dinâmicamente tipada, possue um framework criado para desenvolvimento web o Rails, além disso no ruby tudo o que é manipulado é um objeto, não havendo tipos primitivos, ela é altamente produtivo(você escreve pouco e faz muito), e várias outras vantagens :D. O Ruby foi criado por Yukihiro “Matz” Matsumoto, o qual dizia que a linguagem deveria ter o nome de uma pedra preciosa, o qual batizou o nome de ruby.

  Bom para começar a escrever meu plugin do nagios precisaria ver como funciona a parte de sockets no ruby ou usar uma biblioteca pronta. Para minha “sorte” essa bilblioteca existe 😀

http://snmplib.rubyforge.org/

  Utilizei a snmplib, fiz alguns testes com sucesso fiquei impressionado com a rapidez de se “fazer as coisas”. O código que se segue funciona da seguinte forma, ele vai receber via parametros de linha de comando a comunidade SNMP, versão SNMP, nome do processo/aplicativo a verificar, um descritivo além do endereço IP.

#!/usr/bin/env ruby

include SNMP
require ‘optparse’
require ‘pp’
require ‘snmp’

optparse = OptionParser.new do|opts|
 opts.banner = “Usage: check_windows_processes_snmp.rb [options] host”

 options[:opt_comunidade] = nil
  opts.on( ‘-c’, ‘–comunidade NOME’, ‘Nomme da Comunidade SNMP’ ) do|comunidade|
  options[:opt_comunidade] = comunidade
end

 options[:opt_descricao] = nil
  opts.on( ‘-d’, ‘–descricao NOME’, ‘Descricao do processo’ ) do|descricao|
  options[:opt_descricao] = descricao
 end

 options[:opt_versao] = nil
  opts.on( ‘-v’, ‘–versao NOME’, ‘Versao SNMP’ ) d do|versao|
  options[:opt_versao] = versao
 end

 options[:opt_processo] = nil
  opts.on( ‘-p’, ‘–processo NOME’, ‘Nome do Processo’ ) do|processo|
  options[:opt_processo] = processo
 end

 opts.on( ‘-h’, ‘–help’, ‘Display this screen’ ) do
  puts opts
  exit
 end
end

optparse.parse!

if ( (options[:opt_versao] == nil) && (options[:opt_comunidade] == nil) && (options[:opt_processo] == nil) )
  puts “Argumentos inexistente: utilize o parametro -h para obter ajuda”
  exit
end

comunidade = options[:opt_comunidade]
processo = options[:opt_processo]
descricao = options[:opt_descricao]

case options[:opt_versao]
 when “1”
  versao = :SNMPv1
 when “2c”
  versao = :SNMPv2c
 when “3”
  versao = :SNMPv3
end

axou = 0

Manager.open(:Host => ARGV[0],:Version => versao, :Community => comunidade) do |manager|
 ifTable = ObjectId.new(“1.3.6.1.2.1.25.4.2.1.2”)
 next_oid = ifTable
 while next_oid.subtree_of?(ifTable)
  response = manager.get_next(next_oid)
  varbind = response.varbind_list.first
  next_oid = varbind.name
  string = varbind.to_s
  if string.match(processo)
   puts “Processo: #{descricao} STATUS: rodando”
   axou = 1
  end
 end
end

if ( axou != 1 )
 puts “Processo: #{descricao} STATUS: stop”
 exit
end

Encontrei um biblioteca muito interessante chamada optparse (http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html) ela serve para manipular caracteres passados na linha de comando vamos dissecar esse código por partes. Abaixo declaração de bilblioteas como você faz em outras linguagens como C, Perl e python, etc.

include SNMP
require ‘optparse’
require ‘pp’
require ‘snmp’

Aqui declaramos um objeto do tipo “OptionParser” que será o obejto para manipular os parametros repassados pela linha de comandos. Um parametro interessante dessa biblioteca é o “objeto.on”, o qual insere cada parametros da linha de comando no caso criamos a opção de linha de comando “-c”, “-v”, “-p” e “-d” para você especificar a comunidade SNMP, versão do protocolo SNMP usado, nome do processo/aplicativo e descrição respectivamente.

optparse = OptionParser.new do|opts|
 opts.banner = “Usage: check_windows_processes_snmp.rb [options] host”

 options[:opt_comunidade] = nil
  opts.on( ‘-c’, ‘–comunidade NOME’, ‘Nomme da Comunidade SNMP’ ) do|comunidade|
  options[:opt_comunidade] = comunidade
 end

 options[:opt_descricao] = nil
  opts.on( ‘-d’, ‘–descricao NOME’, ‘Descricao do processo’ ) do|descricao|
  options[:opt_descricao] = descricao
 end

 options[:opt_versao] = nil
  opts.on( ‘-v’, ‘–versao NOME’, ‘Versao SNMP’ ) do|versao|
  options[:opt_versao] = versao
 end

 options[:opt_processo] = nil
  opts.on( ‘-p’, ‘–processo NOME’, ‘Nome do Processo’ ) do|processo|
  options[:opt_processo] = processo
 end

 opts.on( ‘-h’, ‘–help’, ‘Display this screen’ ) do
  puts opts
  exit
 end
end

Aqui fazemos uma validação(precaução) caso o usuário digite o script sem parametro algum.

if ( (options[:opt_versao] == nil) && (options[:opt_comunidade] == nil) && (options[:opt_processo] == nil) )
  puts “Argumentos inexistente: utilize o parametro -h para obter ajuda”
  exit
end

Definimos as variaveis comunidade, processo, descricao e versao obtidos atraves da biblioteca “optparse”. Uma pecualiaridade manipulamos a variavel versao para utilizar a MACRO correspondente a versão do protocolo SNMP. Utilizei uma variavel “axou” para manipular quando encontrar o retorno da busca.

comunidade = options[:opt_comunidade]
processo = options[:opt_processo]
descricao = options[:opt_descricao]

case options[:opt_versao]
  when “1”
    versao = :SNMPv1
  when “2c”
    versao = :SNMPv2c
  when “3”
    versao = :SNMPv3
end

axou = 0

Abaixo temos a parte do código que faz o “get” na MIB dos servidores via biblioteca “snmplib”, são passados os parametros host, versão, comunidade, e o retorno e analisado com o nome do processo passado via linha de comando se der “match” ele escreve que o processo esta rodando no servidor em questão, senão(a variavel “axou” esta definida como falso ou seja igual a zero), ele testa a variavel axou e printa que o processo não esta sendo executado.

Manager.open(:Host => ARGV[0],:Version => versao, :Community => comunidade) do |manager|
   ifTable = ObjectId.new(“1.3.6.1.2.1.25.4.2.1.2”)
   next_oid = ifTable
   while next_oid.subtree_of?(ifTable)
     response = manager.get_next(next_oid)
     varbind = response.varbind_list.first
     next_oid = varbind.name
    string = varbind.to_s
    if string.match(processo)
      puts “Processo: #{descricao} STATUS: rodando”
      axou = 1
    end
   end
end

if ( axou != 1 )
  puts “Processo: #{descricao} STATUS: stop”
  exit
end

Abaixo segue a execução do script.

ricardobarbosa@capsula:~$ ./check_snmp.rb
Argumentos inexistente: utilize o parametro -h para obter ajuda
ricardobarbosa@capsula:~$ ./check_snmp.rb -h
Usage: check_windows_processes_snmp.rb [options] host
-c, –comunidade NOME Nomme da Comunidade SNMP
-d, –descricao NOME Descricao do processo
-v, –versao NOME Versao SNMP
-p, –processo NOME Nome do Processo
-h, –help Display this screen
ricardobarbosa@capsula:~$

Testamos o snmp via comando snmpwalk do tools net-snmp(http://www.net-snmp.org/), vamos buscar os nomes de todos os processos.

ricardobarbosa@capsula:~$ snmpwalk -c public -v 2c 192.168.1.3 hrSWRunName
HOST-RESOURCES-MIB::hrSWRunName.1 = STRING: “init”
HOST-RESOURCES-MIB::hrSWRunName.2 = STRING: “kthreadd”
HOST-RESOURCES-MIB::hrSWRunName.3 = STRING: “migration/0”
HOST-RESOURCES-MIB::hrSWRunName.4 = STRING: “ksoftirqd/0”
HOST-RESOURCES-MIB::hrSWRunName.5 = STRING: “watchdog/0”
HOST-RESOURCES-MIB::hrSWRunName.6 = STRING: “events/0”
HOST-RESOURCES-MIB::hrSWRunName.7 = STRING: “khelper”
HOST-RESOURCES-MIB::hrSWRunName.41 = STRING: “kblockd/0”
HOST-RESOURCES-MIB::hrSWRunName.44 = STRING: “kacpid”
HOST-RESOURCES-MIB::hrSWRunName.45 = STRING: “kacpi_notify”
HOST-RESOURCES-MIB::hrSWRunName.88 = STRING: “kseriod”
HOST-RESOURCES-MIB::hrSWRunName.123 = STRING: “pdflush”
HOST-RESOURCES-MIB::hrSWRunName.124 = STRING: “pdflush”
HOST-RESOURCES-MIB::hrSWRunName.125 = STRING: “kswapd0”
HOST-RESOURCES-MIB::hrSWRunName.167 = STRING: “aio/0”
HOST-RESOURCES-MIB::hrSWRunName.1289 = STRING: “ata/0”
HOST-RESOURCES-MIB::hrSWRunName.1294 = STRING: “ata_aux”
HOST-RESOURCES-MIB::hrSWRunName.1308 = STRING: “scsi_eh_0”
HOST-RESOURCES-MIB::hrSWRunName.1312 = STRING: “scsi_eh_1”
HOST-RESOURCES-MIB::hrSWRunName.2317 = STRING: “kjournald”
HOST-RESOURCES-MIB::hrSWRunName.2473 = STRING: “udevd”
HOST-RESOURCES-MIB::hrSWRunName.2667 = STRING: “kpsmoused”
HOST-RESOURCES-MIB::hrSWRunName.3648 = STRING: “dhclient3”
HOST-RESOURCES-MIB::hrSWRunName.4041 = STRING: “getty”
HOST-RESOURCES-MIB::hrSWRunName.4044 = STRING: “getty”
HOST-RESOURCES-MIB::hrSWRunName.4047 = STRING: “getty”
HOST-RESOURCES-MIB::hrSWRunName.4051 = STRING: “getty”
HOST-RESOURCES-MIB::hrSWRunName.4053 = STRING: “getty”
HOST-RESOURCES-MIB::hrSWRunName.4090 = STRING: “syslogd”
HOST-RESOURCES-MIB::hrSWRunName.4109 = STRING: “dd”
HOST-RESOURCES-MIB::hrSWRunName.4111 = STRING: “klogd”
HOST-RESOURCES-MIB::hrSWRunName.4130 = STRING: “sshd”
HOST-RESOURCES-MIB::hrSWRunName.4186 = STRING: “mysqld_safe”
HOST-RESOURCES-MIB::hrSWRunName.4228 = STRING: “mysqld”
HOST-RESOURCES-MIB::hrSWRunName.4229 = STRING: “logger”
HOST-RESOURCES-MIB::hrSWRunName.4313 = STRING: “asterisk”
HOST-RESOURCES-MIB::hrSWRunName.4359 = STRING: “atd”
HOST-RESOURCES-MIB::hrSWRunName.4370 = STRING: “cron”
HOST-RESOURCES-MIB::hrSWRunName.4392 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4408 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4410 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4412 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4413 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4414 = STRING: “apache2”
HOST-RESOURCES-MIB::hrSWRunName.4415 = STRING: “miniserv.pl”
HOST-RESOURCES-MIB::hrSWRunName.4422 = STRING: “login”
HOST-RESOURCES-MIB::hrSWRunName.4423 = STRING: “bash”
HOST-RESOURCES-MIB::hrSWRunName.4439 = STRING: “bash”
HOST-RESOURCES-MIB::hrSWRunName.4855 = STRING: “snmpd”
ricardobarbosa@capsula:~$

Em seguida executamos nosso script em busca do processo apache2 e do postfix para verificar a inexistencia do processo.

ricardobarbosa@capsula:~$ ./check_snmp.rb -c public -v 2c -d “Servidor HTTP APACHE2” -p apache2 192.168.1.3
Processo: Servidor HTTP APACHE2 STATUS: rodando
ricardobarbosa@capsula:~$
ricardobarbosa@capsula:~$ ./check_snmp.rb -c public -v 2c -d “Servidor SMTP POSTFIX” -p master 192.168.1.3
Processo: Servidor SMTP POSTFIX STATUS: stop
ricardobarbosa@capsula:~$

Agora e necessário configurar o arquivo checkcommands.cfg do nagios e inserir o comando com as variaveis.(para o post não ficar muito extenso não vou passar essa configuração num post futuro eu farei isso :D)
Não sou desenvolvedor atualmente mas já trabalhei como desenvolvedor delphi e php. Gosto de criar códigos que me ajudem na infra-estrutura. Espero que o post seja útil até a próxima.

Att. Read more…

Categories: ruby

VBScript – Script de verificação de data de criação de usuários

January 7, 2010 2 comments

Estava trocando idéia com um grande amigo Rodrigo Diniz, ele me dizia que precisava de um script para verificar a datas de criação das contas de usuário do Active Directory. Então achei interessante e aceitei o desafio, resolvi ajuda-lo a encontrar a solução. Fiz algumas pesquisas na internet especificamente no site technet e montei um vbscript baseado no link abaixo.

http://blogs.technet.com/heyscriptingguy/archive/2005/01/06/how-can-i-tell-on-what-date-an-active-directory-user-account-was-created.aspx

O script usa “Active Data Objects” (que dá base para o provedor de serviços de diretorio OLE DB provider chamado ADsDSOObject) para extrair ou buscar informações de objetos a partir do servidor de diretório da Microsoft o Active Directory.

On Error Resume Next

Set objConnection = CreateObject(“ADODB.Connection”)
Set objCommand = CreateObject(“ADODB.Command”)

objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”

Set objCommand.ActiveConnection = objConnection

objCommand.Properties(“Page Size”) = 1000
objCommand.Properties(“Searchscope”) = 2

objCommand.CommandText = “SELECT ADsPath FROM ‘LDAP://dc=yamaha,dc=com,dc=br’ WHERE objectCategory=’user'”

Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
strPath = objRecordSet.Fields(“ADsPath”).Value
Set objUser = GetObject(strPath)
Wscript.Echo “Usuario: ” & objUser.FullName
Wscript.Echo “Data de criacao: ” & objUser.whenCreated & ” GMT”
objRecordSet.MoveNext
Loop

Vou tentar explicar passo a passo os comandos do script.

Set objConnection = CreateObject(“ADODB.Connection”)

Criamos o objeto ADODB.Connection o qual é usado para criar uma conexão para uma fonte de dados ou data source como se fosse um ponteiro, e através deste objeto você pode acessar e manipular o banco de dados, no nosso caso não será um banco de dados com tabelas e sim um serviço de diretório.

Set objCommand = CreateObject(“ADODB.Command”)

Criamos outro objeto “ADODB.Command” o qual é usado para executar uma consulta ou comandos dentro do banco de dados(ou data source), este objeto também serve para você poder deletar, excluir ou atualizar dados.

objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”

Aqui definimos as propriedades da variavel objConnection. A propriedade “Provider” determina qual provedor OLE DB será utilizado no caso do nosso script “ADsDSOObject” o qual é usado para conexão ao Active Directory.

Set objCommand.ActiveConnection = objConnection

Nesta linha ativamos a conexão ao AD utilizado um “ponteiro” para executar comandos dentro do AD(falando resumidamente).

objCommand.Properties(“Page Size”) = 1000
objCommand.Properties(“Searchscope”) = 2

Definimos algumas propriedades.

objCommand.CommandText = “SELECT ADsPath FROM ‘LDAP://dc=yamaha,dc=com,dc=br’ WHERE objectCategory=’user'”

Definimos a string de consulta, o qual iremos buscar todos os objetos do AD com categoria “User”, ou seja, vamos buscar todos os objetos que representam usuários.

Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Executamos a consulta e movemos o ponteiro para o primeiro registro.

Do Until objRecordSet.EOF
strPath = objRecordSet.Fields(“ADsPath”).Value
Set objUser = GetObject(strPath)
Wscript.Echo “Usuario: ” & objUser.FullName
Wscript.Echo “Data de criacao: ” & objUser.whenCreated & ” GMT”
objRecordSet.MoveNext
Loop

Aqui fazemos um loop buscando nos objetos “User”, nome e data de criação da conta e “printando” e no final movendo o “ponteiro” para o próximo registro.

Nomeie o arquivo para user.vbs dé um duplo o qual invocará o
wscript.exe que é o padrão para o WIndows e usa janelas gráficas ou ainda utilizar o cscript.exe para poder escrever arquivos de lote sem recursos gráficos. Abaixo segue a saída do comando via cscript.exe.

C:\Documents and Settings\Administrator\Desktop>cscript user.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Account created: 5/5/2009 8:08:02 PM GMT
Password last changed: 5/5/2009 1:42:23 PM

Account created: 5/5/2009 8:08:02 PM GMT

User: CN=Microsoft Corporation,L=Redmond,S=Washington,C=US
Account created: 5/5/2009 8:08:02 PM GMT
Password last changed: 5/5/2009 4:48:36 PM

Account created: 5/5/2009 7:15:59 PM GMT
Password last changed: 5/5/2009 5:15:59 PM

User: srv-winbind
Account created: 5/26/2009 8:26:54 PM GMT
Password last changed: 5/28/2009 6:31:36 PM

User: kakaroto
Account created: 5/28/2009 8:23:08 PM GMT
Password last changed: 6/25/2009 6:22:54 PM

User: email
Account created: 6/19/2009 9:52:05 PM GMT
Password last changed: 6/25/2009 6:27:04 PM

C:\Documents and Settings\Administrator\Desktop>

Após o script ser testado e funcionando o Dr Diniz veio com mais uma “bucha”, descobrir qual a ultima vez que o usuario fez logon. Aceitei mais uma fez o desafio, em principio e somente dar um “wscript.echo” no lastlogon, porém não é bem assim lendo e relendo nos confins da internet descobri uma coisa interessante conforme link abaixo.

http://www.linhadecodigo.com.br/Artigo.aspx?id=1706

O valor retornado representa número de segundos passados desde as 0:00 de 01/01/1601. assim teremos que fazer um pequeno calculo para converter para o formato de data convencional.

On Error Resume Next

Set objUser = GetObject(“LDAP://cn=kakaroto,cn=users,dc=yamaha,dc=com,dc=br”)
Wscript.Echo objUser.WhenCreated

Set objLastLogon = objUser.Get(“lastLogonTimestamp”)
intLastLogonTime = objLastLogon.HighPart * (2^32) + objLastLogon.LowPart
intLastLogonTime = intLastLogonTime / (60 * 10000000)
intLastLogonTime = intLastLogonTime / 1440
Wscript.Echo “Last logon time: ” & intLastLogonTime + #1/1/1601#

Salve o arquivo com qualquer nome de sua preferencia, porém com extensão vbs e execute(novamente com cscript.exe).

C:\Documents and Settings\Administrator\Desktop>cscript lastlogon.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

5/28/2009 8:23:08 PM
Last logon time: 1/1/1601

C:\Documents and Settings\Administrator\Desktop>

Bom nao é muito de costume programar, mas gosto de utilizar o desenvolvimento para resolver problema de infra-estrutura e este foi mais um exemplo. Como dizia um grande amigo Thiago(vulgo maluco) “O melhor programador é o melhor administrador de rede” e “O melhor administrador de rede é o melhor programador”. 🙂

Até a próxima.

Categories: vbscript, windows