You are on page 1of 37

Manual do VBScript

Este artigo é derivado do System Administration Scripting Guide, um novo livro que
será publicado como parte do Windows .NET Server Resource Kit.

Quando combinado a tecnologias como a instrumentação de gerenciamento do


Windows (WMI) e as interfaces de serviço do Active Directory (ADSI), o Microsoft®
Visual Basic® Scripting Edition (VBScript) torna-se uma linguagem de scripts
poderosa. Usando o VBScript juntamente com essas tecnologias, você pode escrever
um script de aproximadamente 10.000 linhas, um script completo com tratamento de
erros, sub-rotinas e outras construções de programação avançadas. Por sua vez, esse
script fornece a você controle completo sobre todos os aspectos do seu ambiente de
computação.

No entanto, o que torna o VBScript uma ferramenta tão útil para administradores de
sistema é o fato de que não é preciso criar soluções tão elaboradas e complicadas.
Reconhecidamente, scripts podem ser usados para criar uma solução de
gerenciamento empresarial abrangente. Porém, talvez o mais importante seja o fato
de que os scripts também podem ser usados do seguinte modo: um administrador do
sistema pode gastar alguns minutos digitando algumas linhas de código no Bloco de
Notas e criar instantaneamente uma solução personalizada para um problema
específico.

Por exemplo, o script de três linhas mostrado na listagem 1 pode ser executado
sempre que você precisar saber a quantidade de espaço livre em disco disponível na
unidade C do seu computador.

Listagem 1 Recuperando espaço livre em disco com o VBScript

1 Set objWmiService = GetObject("winmgmts:")


2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
3 WScript.Echo objLogicalDisk.FreeSpace

Se estiver enfrentado problemas com usuários que utilizam muito espaço na unidade C
de seus computadores, agora você tem uma solução personalizada para identificar os
computadores com pouco espaço livre em disco. Além disso, você pode desenvolver
essa solução personalizada usando somente o Bloco de Notas e só precisará digitar as
três linhas de código já mencionadas.

É claro que talvez esse script não atenda completamente às suas necessidades. Por
exemplo, o script só informa a respeito do espaço livre em disco disponível no seu
computador local; ele não pode informar a quantidade de espaço livre disponível em
um computador remoto. Da mesma forma, o script relata apenas o espaço livre
disponível na unidade C; ele não informa nada a respeito do espaço livre disponível
nas unidades D e E, por exemplo.

Porém, se o script não atender completamente às suas necessidades, ele poderá ser
facilmente modificado, sem que seja preciso iniciar um novo script a partir do zero.
Essa é outra vantagem do VBScript: é possível iniciar com um script muito simples e
adicionar recursos a ele à medida que suas necessidades forem mudando e você for se
tornando mais proficiente com a linguagem.

Conceitos básicos do VBScript

Este artigo foi criado para ilustrar o processo de se começar com um script básico e de
se adicionar, gradualmente, mais recursos sofisticados a ele. O artigo começa com o
script mostrado na listagem 1, um script que relata o espaço livre em disco na unidade
C. Seções subseqüentes usarão esse script simples de três linhas e gradualmente
adicionarão mais recursos para torná-lo mais útil em mais situações. Quando essa
série de aprimoramentos estiver completa, você terá um script que pode:

• Recuperar informações sobre o espaço livre em disco de qualquer computador


de sua empresa, inclusive computadores remotos.
• Recuperar informações sobre o espaço livre em disco de vários computadores.
• Recuperar informações sobre o espaço livre em disco de todas as unidades
instaladas em um computador.
• Emitir uma notificação somente se uma unidade tiver pouco espaço em disco.
• Continuar funcionando caso um usuário digite um nome de computador inválido
ou caso um computador não esteja disponível na rede.

À medida que os novos recursos forem adicionados ao script, as construções do


VBScript necessárias para fornecer esses aprimoramentos também serão brevemente
explicadas. (No capítulo do System Administration Scripting Guide do qual esse
arquivo é derivado, essas construções são explicadas em mais detalhes.)

Trabalhando com objetos

O VBScript permite a administradores do sistema criar scripts complexos usando


recursos de programação avançados, como árvores de decisão, loop, tratamento de
erros e a capacidade de chamar funções e sub-rotinas. Porém, o VBScript não inclui
funções intrínsecas à execução de tarefas de administração de sistemas. O VBScript
possui funções internas para a determinação da raiz quadrada de um número ou do
valor ASCII de um caractere, mas não possui funções internas para a interrupção de
serviços, para a recuperação de eventos em logs de eventos ou para a execução de
outras tarefas do interesse de administradores de sistemas.

Usando objetos COM

Felizmente, há maneiras de se executar essas tarefas por meio de programação. Isso é


feito basicamente através do uso de objetos de automação. Objetos de automação são
um subconjunto de COM (modelo de objeto componente), uma forma padrão de
aplicativos (arquivos .exe) ou bibliotecas de programação (arquivos .dll) apresentarem
seus recursos como uma série de objetos. Por sua vez, os programadores (ou
escritores de script) podem utilizar esses objetos -- e os recursos do aplicativo ou da
biblioteca de programação -- em seus próprios projetos. Por exemplo, um aplicativo de
processamento de texto pode expor o verificador ortográfico como um objeto de
automação, fornecendo aos escritores de script uma maneira de adicionar a verificação
ortográfica a seus projetos.
A capacidade de trabalhar com objetos de automação e utilizar as propriedades e os
métodos desses objetos torna o VBScript uma ferramenta poderosa para administração
de sistemas. O VBScript sozinho não pode ler eventos em um log; no entanto, ele pode
usar os recursos incluídos na WMI para recuperar esses eventos. O VBScript não
possui funções intrínsecas à criação de contas de usuário no Active Directory; porém, a
linguagem pode usar os recursos da ADSI para criar essas contas. Na verdade, o
VBScript é freqüentemente chamado de "linguagem cola", pois uma de suas aplicações
principais é "colar" objetos. Em vez de fornecer um número infinito de funções
intrínsecas dedicadas à administração de sistemas, o VBScript fornece duas funções,
GetObject e CreateObject, e os elementos de linguagem necessários para o uso dos
métodos e das propriedades de objetos de automação.
O script mostrado na listagem 2 ilustra a importância de objetos de automação no
VBScript. Esse script relata a quantidade de espaço livre em disco na unidade C do
computador local. E, ainda, ele faz isso usando pouco código VBScript. Em vez disso, o
script:

1. Usa a função VBScript GetObject para se conectar à WMI através da biblioteca


de scripts WMI (um objeto de automação).
2. Usa o método Get, fornecido pelo objeto de automação WMI, para recuperar as
propriedades da unidade C.
3. Usa o método Echo do Windows Script Host (WSH) para relatar a quantidade de
espaço livre em disco na unidade C. Aliás, WSH é apenas outro objeto de
automação.

Listagem 2 Usando objetos no VBScript


1 Set objWmiService = GetObject("winmgmts:")
2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
3 WScript.Echo objLogicalDisk.FreeSpace
No exemplo anterior, o objetivo principal do VBScript era colar os recursos da WMI e
do WSH. Isso permitiu a você recuperar o espaço livre em disco (algo que o WSH não
pode fazer sozinho) e exibir o valor de volta para a tela (algo que a WMI não pode
fazer sozinha).

Criando objetos

Antes de utilizar os métodos ou as propriedades de um objeto de automação, você


deve obter uma referência ao objeto, um processo conhecido como criar ou determinar
o objeto.
Criar objetos pode parecer confuso à primeira vista, pois o VBScript e o WSH fornecem
os métodos CreateObject e GetObject para acessar objetos. Além disso, embora as
implementações sejam semelhantes, há algumas diferenças sutis que crescem em
importância à medida que você se torna proficiente em scripts. Essas diferenças são
discutidas em mais detalhes no livro. Por enquanto, use as seguintes diretrizes práticas
sem se preocupar com o fato de estar usando as funções do VBScript ou os métodos
do WSH (porém, na maioria dos casos, você usará as funções do VBScript):
• Use GetObject para criar objetos WMI ou ADSI. Quando estiver utilizando
GetObject, use um identificador de origem para identificar o objeto a ser criado.
Um identificador de origem é simplesmente uma seqüência de caracteres, com
um prefixo obrigatório, que facilita a descrição do objeto de destino, da mesma
forma como um nome de arquivo e um caminho completo descrevem um
arquivo específico no sistema de arquivos.
• Use CreateObject para criar objetos que não sejam WMI ou ADSI.
CreateObject usa um identificador por meio de programação, ProgID, para
identificar o objeto a ser criado. Um ProgID é a seqüência de caracteres fixa
que um objeto adiciona ao Registro quando o objeto é instalado e registrado no
computador. Prefixos de identificador de origem também são armazenados no
Registro.

Estas não são regras fixas; algumas vezes você precisará usar CreateObject para criar
objetos WMI que não sejam SWbemServices (por exemplo, SWbemDateTime). Alguns
objetos ADSI exigem, de forma semelhante, o uso de CreateObject. Porém, em geral,
CreateObject será necessário somente durante a criação de novas instâncias de itens
como objetos de shell, de rede e de controlador do WSH, objetos de dicionário,
FileSystemObject e o Internet Explorer, entre vários outros objetos.
Objetos intrínsecos
Alguns objetos são intrínsecos. Objetos intrínsecos são os objetos criados sem nunca
ter sido necessário efetuar uma chamada para GetObject ou CreateObject. No script
mostrado na listagem 2, o script conecta-se à WMI usando este código:
Set objWmiService = GetObject("winmgmts:")
Isso cria uma referência, chamada objWmiService, ao objeto SwbemServices da
biblioteca de scripts WMI.
Observe que nenhuma seqüência de caracteres semelhante é usada para criar uma
referência ao objeto Wscript do WSH na listagem 2. Em vez disso, o método Echo é
chamado sem a criação anterior de qualquer tipo de objeto WSH. Isso ocorre porque
WScript é um objeto intrínseco. Não é necessário criar um objeto Wscript, pois WScript
será criado automaticamente quando você executar um script de VBScript. O objeto de
erro do VBScript, Err, é outro objeto intrínseco. O objeto Err será criado
automaticamente quando ocorrer um erro no script. Examinaremos o objeto Err
posteriormente neste artigo.

Usando uma referência de objeto


Com a automação, você não trabalha diretamente com o próprio objeto. Em vez disso,
você cria uma referência ao objeto usando GetObject ou CreateObject e atribuindo o
objeto a uma variável. Após a criação dessa referência, você poderá acessar os
métodos e as propriedades do objeto usando a variável e não o objeto propriamente
dito. Na listagem 2, GetObject é usado para atribuir o objeto SWbemServices da WMI
à variável objWmiService. Depois que a atribuição for concluída, todos os métodos e as
propriedades do objeto SWbemServices poderão ser acessados através de
objWmiService. Por exemplo, na linha 2 do script, o método Get é usado para
recuperar as propriedades da unidade C.
Sempre que criar uma referência de objeto, você deverá usar a palavra-chave Set
quando atribuir a referência a uma variável. Por exemplo, esta linha de código
resultará em erro em tempo de execução:
objWmiService = GetObject("winmgmts:")
Para criar a referência do objeto, use a palavra-chave Set da seguinte maneira:
Set objWmiService = GetObject("winmgmts:")
Set só é usada durante a criação de uma referência de objeto. Se você usar essa
palavra-chave para outros propósitos, como atribuir um valor a uma variável, ocorrerá
um erro em tempo de execução. Por exemplo, esta linha de código falhará, pois
nenhum objeto chamado y poderá ser encontrado no computador:
Set x = y

Métodos de chamada

Os objetos de automação permitem usar os recursos dos objetos nos scripts. Por sua
vez, isso permite a você criar scripts mais úteis e poderosos do que faria se estivesse
restrito aos recursos da linguagem de scripts. Por exemplo, é impossível desenhar um
gráfico usando somente o VBScript. No entanto, com a automação, você pode utilizar
os recursos do Microsoft Excel e adicionar facilmente um gráfico a, por exemplo, uma
página da Web.
Normalmente, os objetos de automação expõem métodos e propriedades (porém, não
há requisitos para que exponham nenhum dos dois). Os métodos são equivalentes às
ações que os objetos podem executar. Por exemplo, embora o script da listagem 2
tenha somente três linhas, ele usa a automação para acessar os métodos de dois
objetos COM diferentes e, assim, executar duas ações distintas:
• O método Get, disponível através do objeto SWbemServices da WMI. O método
Get recupera informações do recurso gerenciado pela WMI especificado.
• O método Echo, disponível através do objeto WScript. O método Echo exibe
informações na tela. Se um script estiver sendo executado em uma janela de
prompt de comando e, portanto, sob Cscript.exe, essa informação será exibida
dentro dessa janela. Se o script estiver sendo executado sob Wscript.exe, a
informação será exibida em uma caixa de diálogo.

Depois de criar uma referência a um objeto, você poderá chamar os métodos desse
objeto usando a notação de pontos. A notação de pontos tem esse nome, pois você
chama um método digitando o nome da variável que faz referência ao objeto, um
ponto e o nome do método (dependendo do método, você também poderá digitar seus
parâmetros). Geralmente, a notação de pontos tem a seguinte aparência:
Referência_de_Objeto.Nome_do_Método
Na listagem 2, a chamada do método Get de SWbemServices pode ser dividida
conforme mostrado na tabela 1.
Tabela 1
Item Descrição
objWmiService Referência do objeto.
. Ponto (separa a referência do objeto e o nome do
método).
Get Nome do método.
("Win32_LogicalDisk.DeviceID='C:'") Parâmetro do método. Para o método Get, isso
pode ser lido como "Obtenha a instância da classe
Win32_LogicalDisk onde DeviceID é igual a C:".

Uma observação sobre Wscript.Echo

Em vez de usar Wscript.Echo para exibir o espaço livre em disco, você pode usar a
função Msgbox do VBScript:
Msgbox objLogicalDisk.FreeSpace
Porém, neste artigo, usaremos Wscript.Echo e não Msgbox. Isso será feito porque a
função Msgbox sempre exibe as informações em uma caixa de diálogo gráfica. Quando
essa caixa de diálogo for exibida, você deverá clicar no botão OK antes que o script
prossiga.
Recuperando propriedades

Propriedades são atributos associados a um objeto. Elas são especialmente


importantes em scripts de administração de sistemas, pois vários dos objetos que você
usa são representações virtuais de objetos reais de sistema operacional e de
computador. Na listagem 2, a propriedade FreeSpace é recuperada com a mesma
notação de pontos usada para chamar métodos.
Isso pode parecer irrelevante, mas com a WMI, a referência não é algum algoritmo de
programação amorfo, mas sim a um disco rígido real no computador. Portanto, a
propriedade FreeSpace não é somente uma propriedade de um objeto de automação;
ela é uma propriedade da unidade C. De certa maneira, WMI cria um espelho virtual de
um objeto físico real. Quando você recupera as propriedades desse espelho virtual,
também recupera as propriedades do objeto físico.

Variáveis

O script mostrado na listagem 2 funciona exatamente como o esperado; quando


executado, ele relata o espaço livre em disco na unidade C. Porém, isso não significa
que o script não possa ser aprimorado. Por exemplo, a propriedade FreeSpace informa
o número de bytes disponíveis em uma unidade. Como unidades de disco são
normalmente medidas em gigabytes, quase sempre a propriedade FreeSpace retorna
um valor difícil de interpretar. Por exemplo, a figura 1 mostra o valor relatado para
uma unidade com aproximadamente 10 gigabytes de espaço livre em disco.

Figura 1
Embora pareça óbvio que a unidade C possui espaço em disco adequado, é muito
menos óbvio a quantidade de espaço em disco realmente disponível. Administradores
de sistema podem achar fácil interpretar os dados retornados pelo script, caso os
dados sejam relatados como megabytes em vez de bytes.
O VBScript inclui uma grande variedade de funções matemáticas que permitem
executar ações, como a conversão de bytes em megabytes. Além disso, o VBScript
também fornece uma construção -- a variável -- que pode ser usada para armazenar
os resultados dessas equações matemáticas. Variáveis fornecem uma maneira de
armazenar qualquer tipo de dado enquanto o script está sendo executado.
Variáveis representam partes da memória disponíveis ao script durante sua execução.
Com essa finalidade, você pode pensar em memória de computador como sendo uma
série de pequenos compartimentos. Uma variável nada mais é do que um desses
compartimentos com um rótulo identificador anexado. Você pode armazenar qualquer
tipo de dado nesse compartimento e ter certeza de que o VBScript poderá recuperar os
dados se necessário. Quando você desejar fazer referência a esses dados, o VBScript
simplesmente procurará o endereço da memória e relatará as informações lá
armazenadas.

Usando variáveis

Como outras linguagens de script comuns, as variáveis do VBScript podem ser criadas
e usadas imediatamente em qualquer ponto de um script. Você não precisa se
preocupar em declarar ou inicializar uma variável antes de usá-la. (Por outro lado, há
algumas vantagens em declarar e inicializar variáveis antes de usá-las. Para obter
detalhes, consulte o System Administration Scripting Guide.)
Na linha 3 da listagem 3, uma variável chamada FreeMegabytes é usada para
armazenar os resultados da divisão de FreeSpace por 1048576 (o valor necessário
para converter bytes em megabytes). Assim que a linha 3 for executada, a variável
FreeMegabytes assumirá o valor dessa equação. Se for necessário fazer referência ao
número de megabytes de espaço livre em disco em qualquer outro local do script, você
não precisará repetir essa equação. Em vez disso, simplesmente faça referência à
variável FreeMegabytes. Isso é mostrado na linha 4, onde o valor da variável é exibido
para a tela.
Listagem 3 Usando variáveis
1 Set objWmiService = GetObject("winmgmts:")
2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
3 FreeMegaBytes = objLogicalDisk.FreeSpace / 1048576
4 WScript.Echo FreeMegaBytes
A Figura 2 mostra o valor relatado como megabytes.

Figura 2
Observação A equação usou o número 1048576 e não o número 1.048.576 (com
pontos para separar os milhares). Você não pode usar pontos ou qualquer outro
caractere para separar milhares no VBScript. Em vez disso, você deve executar todos
os dígitos juntos. Isso se aplica a números embutidos em código no script, bem como
números inseridos como um argumento de linha de comando ou como resposta a
qualquer tipo de solicitação.

Modificando variáveis

Provavelmente, o valor 10340.4458007813 (significando 10.340 megabytes de espaço


livre) é muito mais significativo para o administrador de sistema típico do que o valor
10842824704. Porém, pode-se argumentar que os números após o ponto decimal não
contêm muitas informações úteis. Felizmente, o VBScript fornece várias maneiras
diferentes para você modificar os dados armazenados em variáveis. Por exemplo, a
função Int retorna a parte inteira de um número, deixando de fora todos os dígitos
após o ponto decimal. Portanto, você pode usar a função Int para modificar o valor
decimal armazenado no compartimento FreeMegaBytes, conforme mostrado na linha 4
da listagem 4.
Listagem 4 Modificando variáveis
1 Set objWmiService = GetObject("winmgmts:")
2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
3 FreeMegaBytes = objLogicalDisk.FreeSpace / 1048576
4 FreeMegaBytes = Int(FreeMegaBytes)
5 WScript.Echo FreeMegaBytes
A função Int recupera o valor decimal original, descarta todos os dígitos após o ponto
decimal e retorna somente a parte inteira arredondada do número, que sobrescreve o
valor original armazenado no compartimento FreeMegaBytes (variável). Quando o
script da listagem 4 for executado, FreeMegaBytes será relatado como um número
inteiro, conforme mostrado na figura 3.

Figura 3

Constantes

No script mostrado na listagem 3, a quantidade de megabytes livres é calculada


através da divisão do valor da propriedade FreeSpace pelo valor embutido em código
1048576 (valores embutidos em código como esse são chamados de literais, pois
representam literalmente o valor e não variáveis).
Em um script pequeno como esse (especialmente, um script pequeno escrito para seu
próprio uso), valores literais embutidos em código não apresentam problemas. Porém,
talvez seja necessário um script maior, especialmente um script usado na configuração
de empresas. Nessas situações, literais podem resultar em, pelo menos, dois
problemas:

• Confusão. Em um script pequeno, pode estar evidente que 1048576 é o valor


necessário para converter bytes (o valor retornado da propriedade FreeSpace)
em megabytes. Em um script maior, que inclua várias equações matemáticas,
isso pode não estar tão evidente. Esse problema ocorre principalmente em
configurações de empresas, onde vários administradores podem usar -- e
modificar -- o mesmo script. Embora seja fácil para você saber o que 1048576
representa, talvez não seja tão evidente para outro administrador encarregado
de modificar o script.
• Mais trabalho e mais risco de erro. Se você tem certeza de que seu script
nunca será alterado, talvez não seja relevante que o uso de literais possa ser
confuso. Porém, se houver possibilidade de alteração no script, os valores
literais não só serão confusos, como também exigirão mais trabalho para a
pessoa que estiver modificando o script. Por exemplo, considere que esse
mesmo procedimento -- converter quilobytes em megabytes -- seja usado 5 ou
6 vezes em um script. Se mais tarde você decidir converter o valor em
gigabytes em vez de megabytes, você terá de modificar corretamente cada
linha de código em que ocorrer a conversão. Se não fizer isso, o script não
fornecerá resultados precisos.

Uma maneira de evitar os problemas que podem surgir devido ao uso de literais é
utilizar constantes. Constantes são similares a variáveis, pois ambas são locais para
armazenar dados. Porém, ao contrário das variáveis, as constantes, depois que são
definidas (isto é, depois que um valor é atribuído a elas), não podem ser modificadas
durante a execução do script. Ao atribuir itens importantes, como o valor necessário
para converter bytes em megabytes, a uma constante, você pode garantir que o valor
permanecerá o mesmo: um valor de constante não pode ser alterado, nem
inadvertidamente nem de qualquer outra forma.
Na listagem 5, uma constante chamada CONVERSION_FACTOR é definida na linha 1 e
o valor 1048576 é atribuído a ela. Posteriormente no script (linha 4), o número de
bytes de espaço livre em disco é convertido no número de megabytes de espaço livre
em disco. Em vez de usar o valor literal 1048576, a constante CONVERSION_FACTOR
é utilizada. Ambas as equações retornam o mesmo resultado; porém, é mais fácil ler e
compreender a equação da listagem 5.
Listagem 5 Usando constantes
1 Const CONVERSION_FACTOR = 1048576
2 Set objWmiService = GetObject("winmgmts:")
3 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
4 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
5 FreeMegaBytes = Int(FreeMegaBytes)
6 WScript.Echo FreeMegaBytes
Outro benefício da utilização de constantes é que elas podem ser definidas uma vez e
usadas várias vezes no mesmo script. Por exemplo, uma versão expandida do script
mostrado na listagem 5 pode exigir que você converta bytes em megabytes várias
vezes durante a execução do script. Em vez de usar o valor literal em cada equação,
use a constante. Se mais tarde você decidir converter bytes em gigabytes, precisará
somente alterar o valor da constante; não será necessário alterar o valor usado em
cada equação.

Seqüências de caracteres

À medida que você escreve scripts cada vez mais sofisticados, começa a encontrar
tipos diferentes de dados (esse tópico é abordado em mais detalhes no livro). Na
listagem 5, por exemplo, você precisou usar dados numéricos para atribuir o valor
literal 1048576 à constante CONVERSION_FACTOR:
Const CONVERSION_FACTOR = 1048576
Essa linha de código será executada corretamente, pois um valor numérico está sendo
atribuído à constante. Sempre que você atribuir um valor numérico a uma variável ou
a uma constante, digite o sinal de igual seguido do valor.
No entanto, resultados inesperados poderão ocorrer se você tentar atribuir um valor
alfanumérico (geralmente chamado de valor de seqüência de caracteres) usando a
mesma abordagem. Por exemplo, o código a seguir tenta atribuir a seqüência de
caracteres atl-dc-01 à variável Computer e, em seguida, exibir o valor da variável:
Computer = atl-dc-01
Wscript.Echo Computer
Quando esse script for executado, o valor mostrado na figura 4 será exibido.

Figura 4
Como o valor -1 foi atribuído à variável Computer? Quando o VBScript encontra um
conjunto de caracteres alfanuméricos que não está entre aspas duplas, ele pressupõe
que os caracteres representam o nome de uma variável. Se ele vir um hífen "perdido",
presumirá que representa um sinal de menos. Como resultado, ele interpretará a linha
Computer = atl-dc-01 como à variável Computer será atribuído:

• O valor da variável atl


• Menos o valor da variável dc
• Menos o valor 01

Como atl e dc são exibidas como novas variáveis que não foram inicializadas, o valor 0
será atribuído a elas. Dessa forma, o VBScript interpretará essa linha de código como
se estivesse escrita assim:
Computer = 0 - 0 - 1
Por isso a atribuição errônea de -1.
Quando você atribui um valor de seqüência de caracteres a uma variável ou a uma
constante, deve colocá-lo entre aspas duplas; essa é a única forma de assegurar que o
VBScript tratará a seqüência de caracteres como um valor alfanumérico e não como
uma variável. Por exemplo, esse código atribui corretamente a seqüência de caracteres
atl-dc-01 à variável Computer e, em seguida, exibe os resultados:
Computer = "atl-dc-01"
Wscript.Echo Computer
Quando esse script for executado, a seqüência de caracteres mostrada na figura 5 será
exibida.

Figura 5

Seqüências de caracteres como variáveis

Freqüentemente, as seqüências de caracteres são usadas para atribuir valores a


variáveis. Por exemplo, os scripts usados até agora neste capítulo empregam o
seguinte código para conectarem-se à WMI:
Set objWmiService = GetObject("winmgmts:")
Sem explicar todos os detalhes da conexão com a WMI (para obter essas informações,
consulte o capítulo sobre a WMI no livro), esse código sempre conecta você ao
computador local. Isso é suficiente, a menos que você seja um administrador de
sistema responsável pelo gerenciamento de alguns computadores remotos. Nesse
caso, é aconselhável usar um script que possa recuperar o espaço livre em disco de
um computador remoto. Isso permitirá a você verificar, a partir da sua estação de
trabalho, o espaço em disco disponível em qualquer computador sob o seu controle.
Com a WMI, é possível conectar-se a um computador remoto simplesmente incluindo o
nome do computador como parte do identificador de origem GetObject. Por exemplo,
esta linha de código conecta você ao serviço WMI no computador remoto atl-dc-01:
Set objWmiService = GetObject("winmgmts://atl-dc-01")
Você pode usar o código precedente para escrever um script que faça a conexão com o
computador remoto. Porém, em uma configuração de empresa, talvez você deseje um
script mais flexível que possa conectar-se a qualquer computador remoto. Para isso,
edite o script sempre que executá-lo, substituindo o nome embutido em código do
computador pelo nome embutido em código do computador de destino. Uma
alternativa ainda melhor é fornecer alguma maneira para o script aceitar entradas
quando estiver sendo executado e assim operar, por exemplo, em um computador
inserido como um argumento de linha de comando.
A entrada do usuário será discutida posteriormente neste artigo. No entanto, antes de
começar essa discussão, é importante compreender como os valores de seqüência de
caracteres (como nomes de computador) podem ser atribuídos a uma variável e, em
seguida, utilizados como parte do código de script.
Por exemplo, na linha 2 da listagem 6, o valor da seqüência de caracteres atl-dc-01 é
atribuído à variável Computer. Na linha 3, essa variável é usada para fazer a conexão
com o serviço WMI no computador atl-dc-01. Porém, isso não é feito embutindo-se em
código o valor atl-dc-01 no identificador de registro, mas sim através do valor da
variável Computer.
Listagem 6 Usando seqüências de caracteres
1 Const CONVERSION_FACTOR = 1048576
2 Computer = "atl-dc-01"
3 Set objWmiService = GetObject("winmgmts://" & Computer)
4 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
5 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
6 FreeMegaBytes = Int(FreeMegaBytes)
7 WScript.Echo FreeMegaBytes
Em um pequeno script de demonstração como esse, usar uma variável para o nome do
computador provavelmente exige mais esforço do que embutir o valor em código.
Porém, esse script ilustra um conceito importante: você pode atribuir um valor a uma
variável e usá-la no lugar de um valor embutido em código. Por que isso é importante?
Imagine que esse script foi criado para recuperar espaço livre em disco de 100
computadores. Em vez de embutir em código seqüências de caracteres separadas do
identificador de registro da WMI em cada computador, é possível criar uma única
seqüência de caracteres com a variável Computer. Em seguida, o script poderá
executar essa única seqüência de caracteres 100 vezes, a cada vez substituindo o
valor de Computer por um nome de computador diferente.
Porém, no momento, você só precisa se concentrar na linha 3:
Set objWmiService = GetObject("winmgmts://" & Computer)
É desta forma que o VBScript interpreta essa linha de código:

1. O VBscript lê tudo até a segunda aspa dupla. Em outras palavras:

Set objWmiService = GetObject("winmgmts://"

2. Ele lê o E comercial, que significa basicamente "acrescentar o próximo item à


seqüência de caracteres precedente". O que vem depois do E comercial é a
variável Computer, à qual foi atribuída o valor atl-dc-01. O VBScript vê a linha
da seguinte forma:

Set objWmiService = GetObject("winmgmts://atl-dc-01"

3. Ele lê o caractere de parêntese de fechamento. O VBScript exige que você


tenha um número igual de parênteses de abertura e de fechamento. Se o
parêntese de fechamento não estiver incluído, você receberá uma mensagem
de erro. Agora, o VBScript lê a linha de código como

Set objWmiService = GetObject("winmgmts://atl-dc-01")

4. Após chegar ao final da linha, o VBScript executa a instrução. Por sua vez, o
script se conecta ao serviço WMI em atl-dc-01. Para conectar-se ao serviço WMI
em um computador diferente, você só precisa alterar o valor da variável
Computer.

Concatenando seqüências de caracteres

Concatenação refere-se ao processo de combinar duas ou mais seqüências de


caracteres em uma única seqüência de caracteres (também é possível combiná-las
com valores numéricos ou de datas). A concatenação é usada com freqüência para
fornecer saída mais significativa e legível. Por exemplo, o script mostrado na listagem
4 retorna um valor como 10340. Essa informação é bastante útil, desde que você
tenha certeza de que o script foi desenvolvido para retornar o número de megabytes
de espaço livre em disco da unidade C. Caso você não conheça a função do script, a
saída será sem sentido.
Entre outras funções, a concatenação ajuda a fornecer contexto para sua saída de
script. Por exemplo, em vez de exibir o valor 10340, é aconselhável exibir uma
mensagem similar a "Há 10340 megabytes de espaço livre em disco". Para fazer isso,
você pode combinar os três itens a seguir:

• "Há ", uma seqüência de caracteres simples representando o início da


mensagem.
• FreeMegaBytes, a variável contendo o número de megabytes livres na unidade.
• " megabytes de espaço livre em disco.", uma segunda seqüência de caracteres
representando o final da mensagem.

Conforme mostrado nas linhas 3, 7 e 8 da listagem 7, você concatena itens no


VBScript usando o E comercial (&).
Listagem 7 Concatenando seqüências de caracteres
1 Const CONVERSION_FACTOR = 1048576
2 Computer = "atl-dc-01"
3 Set objWmiService = GetObject("winmgmts://" & Computer)
4 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'")
5 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
6 FreeMegaBytes = Int(FreeMegaBytes)
7 WScript.Echo "Há " & FreeMegaBytes & _
8 " megabytes de espaço livre em disco."
Observação O sublinhado (_) no final da linha 7 é conhecido como o caractere de
continuação de linha e é usado para indicar uma quebra na instrução. Isso significa
que as linhas 7 e 8 devem ser tratadas como uma única linha. Por ser muito grande
para caber no espaço reservado, a linha foi quebrada. As quebras de instrução são
abordadas em mais detalhes no livro.
Como alternativa, você pode ter atribuído o valor "Há " a uma variável chamada
MessageStart e a seqüência de caracteres " megabytes de espaço livre em disco." a
uma variável chamada MessageEnd. Em seguida, você pode ter concatenado as três
variáveis da seguinte maneira:
Wscript.Echo MessageStart & FreeMegaBytes & MessageEnd
Se você observar as linhas 7 e 8, perceberá que os espaços em branco foram
embutidos em código nos valores da seqüência de caracteres "Há " e " megabytes de
espaço livre em disco.". Isso é necessário, pois o E comercial não insere espaços entre
os itens sendo concatenados. Por exemplo, exclua os espaços em branco, desta forma:
WScript.Echo "Há" & FreeMegaBytes & "megabytes de espaço livre em disco."
Nesse caso, a mensagem resultante executará os três valores juntos, conforme
mostrado na figura 6.

Figura 6
Para formas simples de concatenação, você pode evitar esse problema usando uma
vírgula em vez do E comercial para combinar os valores:
WScript.Echo "Há", FreeMegaBytes, "megabytes de espaço livre em disco."
Quando itens são separados por vírgula, um espaço em branco é inserido
automaticamente entre eles. Como resultado, a mensagem é formatada de maneira
apropriada, conforme mostrado na figura 7.

Figura 7

Coleções

Até este ponto do artigo, os scripts foram criados para recuperar o espaço livre na
unidade C de um computador especificado. Determinar o espaço livre em uma única
unidade é uma tarefa administrativa comum, especialmente quando você está
trabalhando com estações de trabalho de usuários que possuem somente uma
unidade. Como a intenção era recuperar apenas o espaço livre em disco da unidade C,
o DeviceID foi embutido em código no script.
É claro que, provavelmente, outros computadores -- incluindo a maioria dos servidores
-- possuem várias unidades. Para esses computadores, a determinação do espaço livre
na unidade C não é informação suficiente; como administrador do sistema, você
também precisa conhecer o espaço livre da unidade D, da unidade E e das outras
unidades instaladas no computador. (Na verdade, a classe Win32_LogicalDisk pode
identificar e retornar as propriedades de todos os tipos de unidade, incluindo
disquetes, CD-ROMs e unidades de rede mapeadas.)
Porém, isso apresenta um problema imediato: como saber quais unidades estão
instaladas em um determinado computador? Teoricamente, você pode verificar o
espaço livre das unidades C a Z, mas, se um computador não possuir, por exemplo,
uma unidade E, o script falhará. Embora seja possível incluir um código criado para
tratar esses erros e impedir que o script falhe, o script resultante seria muito longo,
dificultando a sua leitura e a sua manutenção. Esse script específico também seria
muito ineficiente; mesmo que um computador tivesse somente uma unidade, o script
tentaria recuperar o espaço livre nas unidades D a Z inexistentes.
Felizmente, objetos de automação quase sempre retornam informações na forma de
coleções. Como coleções de selos ou de moedas, essas coleções de automação são
simples grupos de itens relacionados. Por exemplo, o script da listagem 8 usa o
método InstancesOf da WMI (linha 4) para retornar não apenas uma unidade
específica, mas uma coleção consistindo em todos os discos lógicos instalados no
computador. Se o computador tiver quatro unidades (C, D, E e F), a coleção terá
quatro itens, um para cada unidade.
Listagem 8 Usando coleções
1 Const CONVERSION_FACTOR = 1048576
2 Computer = "atl-dc-01"
3 Set objWmiService = GetObject("winmgmts://" & Computer)
4 Set colLogicalDisks = objWmiService.InstancesOf("Win32_LogicalDisk")
5 For Each objLogicalDisk In colLogicalDisks
6 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
7 FreeMegaBytes = Int(FreeMegaBytes)
8 WScript.Echo objLogicalDisk.DeviceID & " " & FreeMegaBytes
9 Next
Obter informações retornadas como uma coleção significa que você não precisa
antecipar quais unidades estão instaladas ou não em um computador. Em vez disso,
simplesmente pergunte pela coleção (todas as instâncias de unidades de disco
instaladas no computador). Depois que a coleção tiver sido retornada, você poderá
usar um loop For Each (também conhecido como um loop de iteração) para examinar
cada item individual da coleção.

For Each

A instrução For Each fornece uma maneira simples de iterar todos os itens em uma
coleção (ou em uma matriz). Ao contrário da instrução For (que será abordada
posteriormente), For Each não exige que você saiba quantos itens existem na coleção.
Em vez disso, ela inicia com o primeiro item da coleção (ou matriz) e continua até que
tenha efetuado um loop em cada item.
Um loop For Each típico tem a seguinte aparência:
For Each objLogicalDisk In colLogicalDisks
WScript.Echo objLogicalDisk.DeviceID
Next
Os itens individuais que compõem esse loop são descritos na tabela 2.
Tabela 2
Item Descrição
objLogicalDisk Variável que representa as instâncias de unidade de
disco individuais.
colLogicalDisks Nome dado à coleção de unidades de disco recuperada
com a WMI.
For Each objLogicalDisk in Inicia o loop. A sintaxe básica pode ser lida como
colLogicalDisks Instância For Each de um objeto em uma coleção de
objetos executa uma ação. Neste exemplo, isso pode
ser lido como "Para cada unidade de disco individual
na coleção de unidades de disco instalada neste
computador … "
Wscript.Echo Instruções executadas para cada unidade de disco na
objLogicalDisk.DeviceID coleção (neste exemplo, há somente uma instrução,
mas pode haver várias instruções entre as instruções
For Each e Next).
Observe que a referência a unidades de disco
individuais é feita com a variável objLogicalDisk e com
a propriedade adequada (neste caso, DeviceID). O
valor dessa propriedade será alterado todas as vezes
através do loop. Por exemplo, em um computador
com unidades C, D e E, objLogicalDisk.DeviceID será
igual a C na primeira iteração, pois C é o DeviceID da
primeira unidade da coleção. Em passagens
subseqüentes através do loop,
objLogicalDisk.DeviceID será igual a D e, em seguida,
a E.
Next Indica o final do loop. Depois de iterar cada item da
coleção, o script prosseguirá na linha após a instrução
Next. Se não houver linhas após essa instrução, o
script será finalizado.

Coleções sem itens

É possível que uma coleção não contenha itens. Por exemplo, considere este script,
que retorna o conjunto de todas as unidades de fita instaladas em um computador:
Set objWmiService = GetObject("winmgmts:")
Set colTapeDrives = objWmiService.InstancesOf("Win32_TapeDrive")
For Each objTapeDrive In colTapeDrives
WScript.Echo objTapeDrive.Name
Next
Se esse script for executado em um computador sem unidades de fita, parecerá que
nada aconteceu. Na verdade, o script será executado conforme o esperado. Porém,
como o computador não possui uma unidade de fita, a coleção resultante de todas as
unidades de fita instaladas no computador não conterá itens. Quando executado em
um computador sem unidades de fita, o script irá:

1. Conectar-se ao serviço WMI.


2. Recuperar a coleção de unidades de fita instalada no computador.
3. Configurar um loop For Each para percorrer toda a coleção, exibindo o nome de
cada unidade de fita individual da coleção. Porém, como não há itens na
coleção, o loop For Each e as instruções nele incluídas não serão de fato
executados. Em vez disso, o loop For Each será ignorado e o script irá para a
primeira linha após a instrução Next. Nesse script de exemplo, não há linhas de
código após a instrução Next, logo, o script é finalizado.

Infelizmente, isso pode ser confuso: não existe maneira óbvia de saber se o script foi
executado ou não. Uma forma de aprimorar esse script é usar a propriedade Count
para determinar a quantidade de itens na coleção. Por exemplo, esse script usa a
propriedade Count para exibir o número de unidades de fita instaladas em um
computador:
Set objWmiService = GetObject("winmgmts:")
Set colTapeDrives = objWmiService.InstancesOf("Win32_TapeDrive")
Wscript.Echo colTapeDrives.Count
O seu script pode usar a propriedade Count para determinar o número de itens da
coleção e executar uma das seguintes opções:

• Exibir as propriedades do item, caso haja um ou mais itens na coleção.


• Exibir uma mensagem como "Não há unidades de fita instaladas neste
computador.", caso a coleção não contenha itens.

O script poderá ter esta aparência (o uso da instrução If-Then-Else será explicado
posteriormente neste artigo):
Set objWmiService = GetObject("winmgmts:")
Set colTapeDrives = objWmiService.InstancesOf("Win32_TapeDrive")
If colTapeDrives.Count = 0 Then
Wscript.Echo "Não há unidades de fita instaladas neste computador."
Else
For Each objTapeDrive In colTapeDrives
WScript.Echo objTapeDrive.Name
Next
End If

Loop

Você já viu uma forma de loop quando usou a instrução For Each do VBScript. Embora
a instrução For Each seja a forma ideal de iteração através de uma coleção ou de uma
matriz, outros cenários podem garantir uma construção de loop mais flexível. Por
exemplo, scripts que monitoram ou medem recursos de sistema normalmente
precisam coletar dados em intervalos periódicos. É improvável que você verifique o
espaço livre em disco momentos após instalar um novo disco rígido e depois nunca
mais verifique o espaço livre ainda disponível na unidade. Em vez disso, é provável
que você verifique o espaço livre em disco em intervalos regulares, talvez uma vez por
semana, uma vez por dia, ou a de hora em hora, dependendo do computador que está
sendo monitorado (por exemplo, servidores de correio normalmente usam espaço em
disco de maneira mais rápida do que outras estações de trabalho do usuário).
Se houver um período de tempo relativamente longo entre coleções de dados, é
aconselhável executar o script como uma tarefa agendada. Dessa forma, você pode
agendar o script para ser executado todas as manhãs, às 2:00, e nunca mais se
preocupar com o assunto.
Porém, usar tarefas agendadas não é sempre uma opção. Por exemplo, digamos que
você deseje medir o uso do processador em um computador. Além disso, você deseja
medir esse uso a cada 10 segundos até coletar 500 amostras. Embora, teoricamente,
você possa criar 500 tarefas agendadas, uma após a outra, isso resulta em muito mais
trabalho. Uma abordagem mais adequada é executar um único script que colete todas
as 500 amostras.
Uma maneira de fazer com que um único script execute o mesmo conjunto de
comandos várias vezes é incluir esses comandos em um loop For. Com um loop For, é
possível executar um conjunto de comandos um determinado número de vezes.
Por exemplo, o script mostrado na listagem 9 verifica de hora em hora por 12 horas o
espaço livre em disco em um computador. Para isso, uma instrução For é usada na
linha 7 indicando que o loop deve ser executado 12 vezes. As linhas 8-14 representam
o corpo do loop For e determinam o espaço livre em disco de cada unidade de disco do
computador. A linha 14 interrompe o script por uma hora (por meio de uma constante
que interrompe o script por 3.600.000 milissegundos) e a linha 15 é simplesmente a
instrução Next, que marca o final do loop.
Quando o script for executado, uma conexão será estabelecida com o computador
remoto atl-dc-01. O script recuperará e exibirá as informações de espaço livre em
disco e, em seguida, fará uma interrupção de uma hora. Após o término dessa
interrupção, o script executará um loop e recuperará as informações sobre espaço livre
em disco uma segunda vez. Esse processo continuará até que as informações de
espaço em disco tenham sido recuperadas 12 vezes. Em seguida, o script executará a
linha de código após a instrução Next. Como não há linhas de código após essa
instrução, o script será finalizado.
Listagem 9 Executando comandos várias vezes
1 Const CONVERSION_FACTOR = 1048576
2 Const ONE_HOUR = 3600000
3 Computer = "atl-dc-01"
4
5 Set objWmiService = GetObject("winmgmts://" & Computer)
6
7 For i = 1 to 12
8 Set colLogicalDisk = objWmiService.InstancesOf("Win32_LogicalDisk")
9 For Each objLogicalDisk In colLogicalDisk
10 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
11 FreeMegaBytes = Int(FreeMegaBytes)
12 WScript.Echo objLogicalDisk.DeviceID & " " & FreeMegaBytes
13 Next
14 Wscript.Sleep ONE_HOUR
15 Next

For

A instrução For permite executar um bloco de código um determinado número de


vezes. Ela não deve ser confundida com a instrução For Each. A instrução For Each é
usada para iterar os itens individuais em uma coleção (ou em uma matriz). A instrução
For é usada para executar um conjunto específico de instruções um determinado
número de vezes.
Para usar a instrução For, é necessário determinar um ponto inicial e um ponto final.
Como instruções For normalmente são criadas para executar um conjunto de
instruções X vezes, você iniciará com 1 e terminará com X. Portanto, para executar a
mesma ação dez vezes, inicie com 1 e termine com 10.
Observação Você pode escolher um ponto inicial arbitrário (por exemplo, 314 ou
6.912) e concluir com o ponto final apropriado (324 ou 6.922). Porém, será mais fácil
ler e manter seu código se você iniciar com 1 e terminar com 10.
A instrução For exige que você use uma variável de loop (também chamada de
contador) que mantém um cálculo contínuo informando quantas vezes o loop foi
executado. Por exemplo, a variável i é usada como o contador no código a seguir. O
contador iniciará em 1 e executará as linhas de código contidas no corpo da instrução
For. Após as instruções terem sido executadas, o contador aumentará
automaticamente em 1, significando que i é agora igual a 2. O script retornará
automaticamente ao início da instrução For e verificará se o valor 2 ainda está no
intervalo válido. Como ele está, o corpo da instrução For será executado uma segunda
vez.
For i = 1 To 5
Wscript.Echo i
Next
Wscript.Echo "Loop For concluído."
O que acontecerá se i for igual a 6? O script retornará automaticamente ao início do
loop For e verificará se 6 faz parte do intervalo válido. Como não faz, o loop For será
imediatamente finalizado e a execução do script continuará na primeira linha após a
instrução Next.
A saída do script terá a seguinte aparência:
1
2
3
4
5
Loop For concluído.
Observação Haverá vezes em que você desejará executar o mesmo conjunto de
instruções continuamente; porém, não será possível determinar antecipadamente
quantas vezes será necessário executar o código. Por exemplo, digamos que você
deseje verificar o espaço livre em disco uma vez por hora e que deseje continuar
executando essa verificação até que o espaço em disco fique abaixo do espaço
especificado. Nesse caso, você deseja que o script inicie e continue a ser executado até
que o espaço em disco fique abaixo do limite, independentemente da quantidade de
iterações necessária para executar essa ação. Em situações como essa, é aconselhável
usar um loop Do (discutido no livro).

Tomando decisões

Um dos principais motivos para a utilização de scripts como ferramentas de


administração de sistema é o fato de que eles reduzem a necessidade de intervenção
humana. Os scripts introduzidos até o momento neste capítulo tentam atingir esse
objetivo; a versão do script mostrado na listagem 8, por exemplo, pode conectar-se a
qualquer computador (mesmo remoto), conectar-se à WMI e determinar o espaço livre
em disco de cada unidade lógica instalada no computador. Executando esse script
regularmente, os administradores poderão receber uma notificação antecipada caso
alguma unidade esteja com pouco espaço em disco.
Porém, ainda é tarefa do administrador do sistema analisar a saída do script e
determinar se um disco está ou não com pouco espaço. O script pode ser aprimorado
através do exame de espaço e da emissão de uma notificação somente quando o
espaço livre está abaixo do nível especificado. Com essa abordagem, os
administradores só serão notificados se um disco estiver com pouco espaço. Se não
houver notificações, é porque todos os discos estão em conformidade com os padrões
e nenhuma ação será necessária.
O VBScript fornece várias construções de programação que permitem aos scripts
"tomarem decisões". Isso significa que um script pode analisar alguns dados e, em
seguida, executar uma ação especificada com base no valor dos dados.
A forma mais simples do código de tomada de decisão é a instrução If. Com a
instrução If, o script examina o valor de um dado específico, comparando-o a um
limite pré-determinado (por exemplo, se o espaço livre em disco é menor do que 100
megabytes). Se a instrução for verdadeira (que seria o caso se somente 99 megabytes
de espaço em disco estivessem disponíveis), o script executará uma ação. Se a
instrução não for verdadeira, nenhuma ação será executada.
Esse tipo simples de tomada de decisão é mostrado na listagem 10. Na linha 11, o
script verifica se o espaço livre é menor do que 100 megabytes (isso é feito através da
comparação entre o valor e a constante WARNING_THRESHOLD). Se essa instrução
condicional for verdadeira (por exemplo, se uma unidade tiver somente 99 megabytes
de espaço livre), a instrução imediatamente após a construção If será executada.
Neste exemplo, a instrução seguinte é a linha 12, que exibe a mensagem de que a
unidade tem pouco espaço em disco.
Se a instrução condicional for falsa (por exemplo, se a unidade tiver 101 megabytes de
espaço livre em disco), a linha 12 não será executada. Em vez disso, o processamento
será transferido para a linha 13, que marca o final da instrução If, e continuará na
linha 14.
Listagem 10 Tomando decisões
1 Const CONVERSION_FACTOR = 1048576
2 Const WARNING_THRESHOLD = 100
3 Computer = "atl-dc-01"
4
5 Set objWmiService = GetObject("winmgmts://" & Computer)
6 Set colLogicalDisks = objWmiService.InstancesOf("Win32_LogicalDisk")
7
8 For Each objLogicalDisk In colLogicalDisks
9 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
10 FreeMegaBytes = Int(FreeMegaBytes)
11 If FreeMegaBytes < WARNING_THRESHOLD Then
12 WScript.Echo objLogicalDisk.DeviceID & " tem pouco espaço em disco."
13 End If
14 Next

Executando várias ações usando If-Then-Else

O script mostrado na listagem 10 exibirá uma mensagem de aviso se uma unidade


tiver pouco espaço em disco. Porém, se a unidade de disco tiver espaço livre
adequado, nenhuma mensagem será exibida. Para um script simples de monitoração,
isso é aceitável. Por outro lado, o usuário que estivesse executando esse script, não
teria como saber se a falta de saída havia ocorrido porque todas as unidades possuíam
espaço em disco adequado ou porque a execução do script havia falhado por algum
motivo.
Em outras palavras, às vezes é necessário que o script avalie uma condição e, em
seguida, execute uma ação diferente com base nessa avaliação. Por exemplo, talvez
você deseje exibir uma mensagem de aviso quando a unidade tiver pouco espaço em
disco e uma mensagem "Sem problemas" quando a unidade tiver espaço em disco
adequado. Esse tipo de abordagem pode ser implementado com a instrução If-Then-
Else.
A função da instrução If-Then-Else está implícita em seu nome. Se (If) uma condição
for verdadeira (ou falsa), execute esta ação. Caso contrário (Else), execute esta ação.
Se houver pouco espaço em disco, ecoe uma mensagem de aviso. Caso contrário, ecoe
a mensagem "Sem problemas".
Um exemplo disso é mostrado na listagem 11. Na linha 11, o espaço livre em disco de
uma unidade é comparado a um limite de aviso. Se a instrução condicional for
verdadeira (isto é, se o espaço livre em disco for menor do que o limite de aviso), a
linha 12 será executada.
E se a instrução condicional for falsa? Para lidar com essa possibilidade, uma cláusula
Else foi incluída na linha 13. Se a instrução condicional for falsa e a unidade tiver
espaço adequado, a linha 14, linha imediatamente após a cláusula Else, será
executada.
Listagem 11 Usando uma instrução If-Then-Else
1 Const CONVERSION_FACTOR = 1048576
2 Const WARNING_THRESHOLD = 100
3 Computer = "atl-dc-01"
4
5 Set objWmiService = GetObject("winmgmts://" & Computer)
6 Set colLogicalDisks = objWmiService.InstancesOf("Win32_LogicalDisk")
7
8 For Each objLogicalDisk In colLogicalDisks
9 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
10 FreeMegaBytes = Int(FreeMegaBytes)
11 If FreeMegaBytes < WARNING_THRESHOLD Then
12 WScript.Echo objLogicalDisk.DeviceID & " tem pouco espaço em disco."
13 Else
14 WScript.Echo objLogicalDisk.DeviceID & " tem espaço em disco adequado."
15 End If
16 Next
É possível construir cenários mais elaborados, cenários que possam executar mais do
que apenas duas ações possíveis. Formas diferentes de construir esses cenários são
discutidas no System Administration Scripting Guide.

Matrizes

Coleções são uma forma excelente de empacotar informações, pois permitem trabalhar
com vários itens, mesmo que você não conheça os detalhes sobre esses itens. Por
exemplo, o script introduzido na listagem 8 permite recuperar o espaço livre em disco
de todas as unidades instaladas em um computador, mesmo que você não saiba
quantas unidades estão instaladas no computador. Para executar uma ação em cada
item da coleção, simplesmente use um loop For Each para iterar em toda a coleção e
execute a ação em todos os itens, um por um.
Objetos de automação podem criar coleções automaticamente. Porém, pode haver
outras informações, não retornadas por um objeto de automação, que serão mais
fáceis de manipular se você puder iterar no conjunto de itens um por um. Por exemplo,
digamos que você deseje verificar o espaço livre em disco disponível em três
computadores e não apenas em um. Você pode escrever o código para verificar o
primeiro computador, copiar e colar esse código e, em seguida, modificar o código
colado para verificar o espaço livre em disco no segundo computador. É possível
repetir esse processo para verificar o espaço livre em disco no terceiro computador.
Embora essa abordagem funcione, ela logo se tornará tediosa, especialmente se você
precisar verificar, por exemplo, 100 computadores. Além disso, digamos que você
precise alterar o código, talvez retornando não apenas o espaço livre na unidade, mas
também o tamanho total da unidade. Para fazer essa alteração, seria necessário
alterar todas as 100 instâncias, um processo que levaria muito tempo e aumentaria a
possibilidade de erro.
Uma abordagem mais adequada seria usar um loop For Each e percorrer uma lista de
computadores, verificando o espaço livre em disco de cada um. Para fazer isso, deve-
se colocar os nomes dos computadores em uma matriz, uma estrutura de dados que
pode ser usada praticamente da mesma forma que uma coleção.
O script mostrado na listagem 12 coloca os nomes de três computadores (atl-dc-01,
atl-dc-02 e atl-dc-03) em uma matriz e usa um loop For Each para conectar-se a cada
computador e recuperar as informações de espaço livre em disco. Na linha 3, uma
matriz chamada Computers é criada. Isso é feito com a função Array, através da
especificação dos nomes dos três computadores como os parâmetros da função (os
nomes são colocados entre aspas, pois são seqüências de caracteres). Na linha 5, um
loop For Each é usado para percorrer todos os elementos da matriz Computers.
Listagem 12 Usando matrizes
1 Const CONVERSION_FACTOR = 1048576
2 Const WARNING_THRESHOLD = 100
3 Computers = Array("atl-dc-01", "atl-dc-02", "atl-dc-03")
4
5 For Each Computer In Computers
6
7 Set objWmiService = GetObject("winmgmts://" & Computer)
8 Set colLogicalDisks = objWmiService.InstancesOf("Win32_LogicalDisk")
9
10 For Each objLogicalDisk In colLogicalDisks
11 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
12 FreeMegaBytes = Int(FreeMegaBytes)
13 If FreeMegaBytes < WARNING_THRESHOLD Then
14 WScript.Echo Computer & " " & objLogicalDisk.DeviceID & _
15 " tem pouco espaço em disco."
16 End If
17 Next
18
19 Next
Embora matrizes possam parecer similares a coleções, pelo menos no contexto da
instrução For Each, existe uma diferença importante. Uma matriz é uma lista de
valores simples e indexada e uma coleção é um objeto de automação, baseado em
COM e completamente desenvolvido. Isso afeta o modo como os dois tipos de lista são
criados e como itens de lista individuais podem ser acessados. Por exemplo, você deve
usar a palavra-chave Set para criar uma coleção (linha 8) da mesma forma como faria
com qualquer objeto de automação. As matrizes não possuem esses requisitos, pois
não são objetos de automação.
Um número de índice é atribuído a cada elemento de uma matriz. No VBScript, o
número de índice 0 é atribuído ao primeiro elemento de uma matriz e os números 1, 2,
3 etc. são atribuídos aos elementos subseqüentes. Logo, a matriz criada no script
anterior conteria os números de índice e os elementos mostrados na tabela 3. Observe
que o número de índice mais alto será sempre uma unidade menor do que o número
de elementos da matriz.
Tabela 3
Número de índice Elemento
0 atl-dc-01
1 atl-dc-02
2 atl-dc-03
Você pode usar esses números de índice para acessar elementos individuais na matriz.
Por exemplo, essa linha de código exibirá atl-dc-02, o valor do número de índice 1 e o
segundo elemento da matriz:
Wscript.Echo Computers(1)
Para exibir o valor de um item diferente na matriz, substitua o valor 1 pelo número de
índice apropriado.
Métodos adicionais para criar matrizes e acessar os elementos individuais dessas
matrizes são abordados no System Administration Scripting Guide.

Entrada

O script mostrado na listagem 12 foi criado para uma empresa que não espera
alterações na infra-estrutura de computação, já que essa infra-estrutura já está
estabelecida. Uma infra-estrutura estática como essa é a exceção e não a regra. A
maioria das empresas possui um ambiente mais dinâmico; embora somente três
servidores (atl-dc-01, atl-dc-02, atl-dc-03) precisem de monitoração no momento, não
há garantias de que somente esses três servidores precisarão de monitoração
posteriormente.
Itens embutidos em código, como nomes de computador nos scripts, ocasionam dois
problemas relacionados:
• Falta de flexibilidade. O script da listagem 12 recuperará somente
informações sobre o espaço em disco disponível nos computadores atl-dc-01,
atl-dc-02 e atl-dc-03. Se você precisar recuperar espaço livre em disco para o
computador atl-dc-04, será necessário modificar o script.
• Atualizações freqüentes. O script da listagem 12 foi criado para recuperar
informações sobre o espaço livre em disco de um conjunto específico de
computadores (por exemplo, todos os controladores de domínio em uma
localização específica). Sempre que um novo controlador de domínio for
adicionado ou sempre que um controlador de domínio existente for retirado, o
script precisará ser atualizado. Se você usar somente esse script em sua
empresa, isso talvez não cause problemas. Porém, se usar vários scripts, você
provavelmente perderá mais tempo modificando-os do que economizará
usando-os.

Há várias formas de se permitir que os usuários insiram informações, como nomes de


servidor, em um script (para obter mais detalhes sobre vários desses métodos,
consulte o System Administration Scripting Guide). Talvez a maneira mais fácil seja
fazer com que os usuários especifiquem essas informações como argumentos sempre
que o script for executado.
Um argumento (também conhecido como parâmetro) é a informação fornecida junto
com o comando que de fato executa o script. Por exemplo, digamos que você
normalmente inicie um script da seguinte maneira:
cscript DiskSpace.vbs
Um argumento é qualquer informação extra adicionada ao final do comando. Por
exemplo, esse comando possui três argumentos, um para cada nome de computador:
cscript DiskSpace.vbs atl-dc-01 atl-dc-02 atl-dc-03
Além de fornecer argumentos, o script deve incluir o código que usa esses
argumentos. Esse tipo de código é abordado em detalhes no capítulo 3 do System
Administration Scripting Guide. Um exemplo simples também é mostrado na listagem
13. Na linha 9 desse script, um loop For Each é estabelecido para percorrer o conjunto
de argumentos fornecido na inicialização do script. Nesse script, cada argumento é
atribuído sucessivamente à variável Computer e, em seguida, usado para estabelecer
conexão com o serviço WMI no computador (linha 11). Com base na linha de comando
de exemplo acima, na primeira vez que o loop For Each for executado, o valor atl-dc-
01será atribuído a Computer. Em iterações subseqüentes, os valores atl-dc-02 e atl-
dc-03 serão atribuídos a Computer.
Listagem 13 Obtendo entrada de usuário
1 Const CONVERSION_FACTOR = 1048576
2 Const WARNING_THRESHOLD = 100
3
4If WScript.Arguments.Count = 0 Then
5 WScript.Echo "Uso: DiskSpace.vbs servidor1 [servidor2] [servidor3] ..."
6 WScript.Quit
7 End If
8
9 For Each Computer In WScript.Arguments
10
11 Set objWmiService = GetObject("winmgmts://" & Computer)
12 Set colLogicalDisks = objWmiService.InstancesOf("Win32_LogicalDisk")
13
14 For Each objLogicalDisk In colLogicalDisks
15 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
16 FreeMegaBytes = Int(FreeMegaBytes)
17 If FreeMegaBytes < WARNING_THRESHOLD Then
18 WScript.Echo Computer & " " & objLogicalDisk.DeviceID & _
19 " tem pouco espaço em disco."
20 End If
21 Next
22
23Next
Uma vantagem em usar argumentos é o fato de que eles são colocados
automaticamente em uma coleção (Wscript.Arguments). Isso torna mais fácil percorrer
os argumentos fornecidos a um script: você simplesmente configura um loop For Each
e itera cada argumento da coleção, exatamente da mesma forma como itera as
unidades de disco individuais em uma coleção de unidades de disco.
Como argumentos são colocados em uma coleção, também é fácil verificar quantos
argumentos, se houver, foram fornecidos quando o script foi iniciado. Na linha 4 do
script, Wscript.Arguments.Count é usado para determinar a quantidade de argumentos
fornecida (o número de argumentos fornecido será igual ao número de itens da
coleção de argumentos). Se a contagem for igual a 0, significando que nenhum
argumento foi fornecido, um conjunto de instruções de utilização será exibido e o
script será finalizado (com o método Wscript.Quit).
Tratamento de erros

O script mostrado na listagem 13 é bastante arriscado. Digamos que o usuário tenha


inserido um nome de servidor inválido como um argumento. Quando o script tentar se
conectar a esse computador inexistente, falhará e a mensagem de erro "The remote
server machine does not exist or is unavailable" será exibida.
Claro que uma determinada porcentagem de risco é inerente a todos os scripts usados
até o momento neste artigo, incluindo os scripts em que os nomes de computador
foram embutidos em código. Afinal, o script não pode distinguir entre um nome de
computador inválido e um nome de computador válido que, por algum motivo, não
está disponível na rede. Por exemplo, digamos que você execute o script da listagem
12 e que o computador chamado atl-dc-01 esteja off-line no momento. Neste ponto, o
script falhará e não será mais processado. Isso significa que você não só falhará ao
recuperar o espaço livre em disco no computador atl-dc-01, como também falhará ao
recuperar o espaço livre em disco nos computadores atl-dc-02 e atl-dc-03, mesmo que
eles estejam conectados à rede e funcionando corretamente. Isso ocorre pois o script é
finalizado antes de tentar se conectar a atl-dc-02 ou atl-dc-03.
A incapacidade em se conectar ao computador atl-dc-01 é um exemplo de erro em
tempo de execução, que ocorre após o script ter sido iniciado (por comparação, um
erro de sintaxe, como uma palavra-chave incorreta, é gerado e o script é finalizado
antes que as linhas de código sejam de fato executadas). Para obter ajuda na proteção
contra erros em tempo de execução, você pode incluir a instrução de tratamento de
erros do VBScript, On Error Resume Next, em seus scripts.
Sem o tratamento de erros, um script é finalizado imediatamente quando encontra um
erro em tempo de execução. Com o tratamento de erros, o script não é finalizado, em
vez disso, ele tenta executar a linha seguinte do script. O script procede desta
maneira, ignorando as linhas que geram erros e executando as linhas que não geram
erros.

Tratamento de erros com o objeto Err

On Error Resume Next permite que o script continue funcionando caso ocorra um erro
em tempo de execução. Porém, isso pode causar pelo menos dois problemas. Por um
lado, nenhuma mensagem de erro é gerada para informar que ocorreu erro. Se
executar um script e nada ocorrer, você não terá como saber onde houve falha.
Por outro lado, talvez você prefira que um script não tente executar todas as linhas
caso ocorra erro em tempo de execução. Por exemplo, considere um script que siga
este procedimento:

1. Conecta-se a um computador remoto.


2. Copia um conjunto de arquivos do computador local para o computador remoto.
3. Exclui o conjunto de arquivos original do computador local.

Digamos que você tenha executado esse script, mas que o computador remoto não
esteja disponível. Veja a seguir uma seqüência possível de eventos.

1. O script tenta se conectar ao computador remoto e falha. Porém, On Error


Resume Next assegura que o script continue sendo executado.
2. O script tenta copiar arquivos para o computador remoto. A operação falha,
pois o computador remoto não está acessível.
3. O script exclui os arquivos do computador local. Infelizmente, essa ação é bem-
sucedida, pois o computador local está disponível. Como resultado, os arquivos
são excluídos do computador local, mas não são copiados para o computador
remoto.

Felizmente, você pode usar o objeto Err intrínseco do VBScript para determinar se o
erro ocorreu ou não, e caso tenha ocorrido, para executar a ação apropriada.
O objeto Err é criado automaticamente sempre que você executa um script (há
somente um objeto Err por instância de script). Esse objeto contém várias
propriedades, incluindo as três mostradas na tabela 4. Sempre que o script encontra
um erro em tempo de execução, essas propriedades são preenchidas automaticamente
com as informações que identificam o erro.
Tabela 4
Propriedade Descrição
Description Descrição do erro. A descrição pode ser usada para informar ao
usuário que ocorreu erro. Isso pode ser realizado com o eco do
valor:
Wscript.Echo Err.Description

Number Número inteiro que identifica de forma exclusiva o erro ocorrido.


Esse número pode representar um número de erro intrínseco do
VBScript ou um número de erro derivado de um objeto de
automação (números de erro do objeto de automação são
conhecidos como SCODE, abreviatura para código de status).
Para determinar a origem do número de erro, use a propriedade
Source.
Source Nome da classe ou identificador programático (ProgID) do objeto
que causou o erro. Normalmente, quando o VBScript é
responsável pelo erro, a mensagem "Microsoft VBScript runtime
error" é exibida como a origem. Se um objeto de automação for
responsável pelo erro, você verá o ProgID (por exemplo,
"Word.Application").
Quando um script é iniciado, o valor padrão 0 (sem erros) é atribuído à propriedade
Number. Caso um erro seja encontrado, o valor da propriedade Number é alterado.
Isso permite a você verificar periodicamente se o script encontrou erros. Por exemplo,
talvez você deseje verificar o status de erro após tentar se conectar a um computador
remoto. Se Err.Number for igual a 0, nenhum erro terá ocorrido. Se Err.Number não
for igual a zero, terá ocorrido algum tipo de erro e você poderá supor que a tentativa
de conexão com o computador remoto falhou. Como resultado, o script executará uma
ação com base no fato de que o computador remoto não estava disponível.
Esse tipo de tratamento de erro é implementado no script mostrado na listagem 14. Na
linha 1 do script, o tratamento de erros é ativado com a instrução On Error Resume
Next do VBScript. Na linha 11, o script usa um loop For Each para percorrer uma lista
de nomes de servidor. Na linha 12, o script tenta se conectar a cada um desses
servidores.
Mas o que ocorre se um desses servidores não está acessível? Conforme observado, na
linha 12 o script tenta se conectar a um desses servidores remotos. Se a conexão for
bem-sucedida, nenhum erro será gerado, significando que Err.Number permanecerá
igual a 0. Porém, se a conexão falhar, um erro será gerado e Err.Number será alterado
para refletir o número atribuído ao erro.
Se a tentativa de conexão na linha 12 falhar, On Error Resume Next garantirá que o
script tente executar a linha 13. Na linha 13, o script verifica o valor de Err.Number.
Se o valor for diferente de 0 (significando que um erro ocorreu), o script exibirá
Err.Description e, em seguida, reiniciará o loop com o próximo nome de servidor. Se o
valor for 0, isso significa que a conexão foi bem-sucedida. Em seguida, o script
recupera o espaço livre em disco do computador remoto.
Listagem 14 Tratamento de erros
1 On Error Resume Next
2
3 Const CONVERSION_FACTOR = 1048576
4 Const WARNING_THRESHOLD = 100
5
6 If WScript.Arguments.Count = 0 Then
7 WScript.Echo "Uso: DiskSpace.vbs servidor1 [servidor2] [servidor3] ..."
8 WScript.Quit
9 End If
10
11 For Each Computer In WScript.Arguments
12 Set objWmiService = GetObject("winmgmts://" & Computer)
13 If Err.Number <> 0 Then
14 WScript.Echo Computer & " " & Err.Description
15 Err.Clear
16 Else
17 Set colLogicalDisks = _
18 objWmiService.InstancesOf("Win32_LogicalDisk")
19 For Each objLogicalDisk In colLogicalDisks
20 FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
21 FreeMegaBytes = Int(FreeMegaBytes)
22 If FreeMegaBytes < WARNING_THRESHOLD Then
23 WScript.Echo Computer & " " & objLogicalDisk.DeviceID & _
24 " tem pouco espaço em disco."
25 End If
26 Next
27 End If
28 Next
Se você executar o script da listagem 14 e um dos servidores não estiver on-line, o
objeto Err e suas propriedades serão preenchidos como mostrado na tabela 5.
Tabela 5
Propriedade Valor
Err.Description The remote server machine does not exist or is unavailable
Err.Number 462
Err.Source Microsoft VBScript runtime error

Limpando erros

A linha 15 do script usa o método Clear para redefinir explicitamente as propriedades


do objeto Err. Isso é importante, pois caso essa redefinição não ocorra, essas
propriedades só serão alteradas quando outro erro ocorrer. Os valores da propriedade
não são alterados quando não ocorrem erros. Como resultado, o script pode agir de
forma não apropriada com base na noção errônea de que ocorreu erro.
Isso é o que acontecerá se você não redefinir explicitamente as propriedades do objeto
Err. Quando um script é iniciado, o objeto Err apresenta o número padrão 0 e as
propriedades de descrição e de origem vazias. Se o script não puder se conectar ao
computador atl-dc-01, as propriedades do objeto Err serão definidas como mostrado
na tabela 5.
Isso funciona conforme o esperado. Porém, o que acontece quando o computador
efetua um loop e tenta se conectar ao computador atl-dc-02? Nesse caso, a tentativa é
bem-sucedida e nenhum erro é gerado. No entanto, como nenhum erro foi gerado, o
objeto Err ainda contém os valores de propriedade mostrados na tabela 5, pois esse
objeto só é atualizado quando ocorre um erro. Por sua vez, o script verifica que 462 é
o número do erro, o valor restante da tentativa malsucedida de conexão com o
computador atl-dc-01. Como 462 não é igual a 0, o script executa uma ação com base
na decisão incorreta de que um erro ocorreu e, portanto, o computador atl-dc-02 deve
estar inacessível. Esse mesmo problema ocorre quando o script tenta recuperar espaço
livre em disco no computador atl-dc-03.
O método Clear supera esse problema redefinindo o objeto Err para os valores padrão
(number igual a 0, source e description definidas como vazio). Como os valores são
redefinidos, eles refletirão corretamente o fato de que nenhum erro ocorreu quando o
script tentar recuperar espaço livre em disco para o computador atl-dc-02.

Aviso de isenção de responsabilidade da versão Beta

Esta documentação é uma versão antecipada da documentação final e pode ser


alterada substancialmente antes da versão comercial final. Além disso, é informação
confidencial de propriedade da Microsoft Corporation. Ela é divulgada conforme
descrito no acordo de não-divulgação estabelecido entre o adquirente e a Microsoft.
Este documento é fornecido somente para fins informativos e a Microsoft não oferece
quaisquer garantias, explícitas ou implícitas, neste documento. As informações
contidas neste documento, incluindo o URL e outras referências ao site da Internet na
Web, estão sujeitas a alterações sem aviso prévio. O usuário assume inteiro risco
quanto ao uso e aos resultados do uso deste documento. Salvo indicação em contrário,
os exemplos de empresas, organizações, produtos, pessoas e acontecimentos aqui
mencionados são fictícios. Nenhuma associação com qualquer empresa, organização,
produto, pessoa ou acontecimento real é intencional ou deve ser inferida. Obedecer a
todas as leis de direitos autorais aplicáveis é responsabilidade do usuário. Sem limitar
os direitos autorais, nenhuma parte deste documento pode ser reproduzida,
armazenada ou introduzida em um sistema de recuperação, ou transmitida de
qualquer forma por qualquer meio (eletrônico, mecânico, fotocópia, gravação ou
qualquer outro), ou para qualquer propósito, sem a permissão expressa, por escrito,
da Microsoft Corporation.
A Microsoft pode ter patentes ou requisições para obtenção de patente, marcas
comerciais, direitos autorais ou outros direitos de propriedade intelectual que
abrangem o conteúdo deste documento. A posse deste documento não lhe confere
nenhum direito sobre as citadas patentes, marcas comerciais, direitos autorais ou
outros direitos de propriedade intelectual, salvo aqueles expressamente mencionados
em um contrato de licença, por escrito, da Microsoft.
Trabalho não publicado. © 2002 Microsoft Corporation. Todos os direitos reservados.