Ei, Equipe de Scripts!Os jogos vão começar! Ah, e algum XML também

The Microsoft Scripting Guys

Faça download do código deste artigo: HeyScriptingGuy2008_02.exe (151KB)

Sabe, sempre que as pessoas falam sobre as lendas do mundo esportivo, os mesmos nomes invariavelmente surgem: Babe Ruth. Pelé. Muhammad Ali. Walter Payton. ScooterK e MrRat. Johnny—

Ha, isso foi engraçado, você... ah, você está falando sério? Você realmente não sabe quem são ScooterK e MrRat? Bem, para aqueles que obviamente não acompanham os Jogos de Script de Inverno (de 15 de fevereiro a 3 de março no TechNet Script Center; visite microsoft.com/technet/scriptcenter/funzone/games), ScooterK e MrRat são verdadeiras lendas, competidores que atingiram pontuações perfeitas em ao menos uma divisão dos Jogos de Script de Inverno de 2007.

E aqui está a melhor parte: você realmente tem esperanças realistas de se tornar uma lenda do futebol como o Pelé? Provavelmente não. Você poderia ter esperanças em se tornar o campeão do mundo de boxe peso-pesado? Bem, alguns dos membros da Equipe de Scripts parecem entender da parte peso-pesado, mas ser campeão de boxe é algo muito mais complicado. Mas você—sim, você—pode facilmente se tornar o próximo ScooterK ou o próximo MrRat.

Observação: em teoria, você poderia se tornar o próximo Babe Ruth também. Tudo o que você precisaria fazer seria comer 24 cachorros-quentes entre os jogos de baseball.

Acalme-se; nós diremos como você pode se tornar o próximo ScooterK ou MrRat (e talvez até mesmo o próximo Bizzy ou H2Data). Você só precisa aparecer no Script Center e participar dos Jogos de Script. No dia 15 de fevereiro publicaremos 10 eventos diferentes (10 desafios de script) e desafiá-lo a concluir um ou todos eles. Escreva um script que resolva o problema proposto e envie por email para a Equipe de Script. (Você encontrará as instruções completas na home page dos Jogos de Script). Testaremos o seu script e, se funcionar, computaremos os seus pontos. Conclua com êxito todos os 10 eventos e você também se tornará uma lenda do mundo esportivo. Ou ao menos no mundo esportivo dos scripts, o que é quase a mesma coisa.

Os Jogos de Script (de 15 de fevereiro a 3 de março) são divertidos e desafiadores. O melhor de tudo é que os Jogos de Script são para todos. Você ainda é relativamente novato em scripts de administração do sistema? Então participe da Divisão de Iniciantes; teremos competições separadas para iniciantes em VBScript, Windows PowerShellTM e (novidade este ano) Perl. Você acha que a Divisão de Iniciantes é fácil? Então participe da Divisão de Avançada, que também tem competições em VBScript, Windows PowerShell e Perl.

Os Jogos (já mencionamos que ocorrerão entre o dia 15 de fevereiro e 3 de março?) são simplesmente o evento da temporada de scripts, e você não vai querer perdê-lo. Visite a home page do Script Center agora para obter dicas e truques para treinar para a competição, e volte no dia 15 de fevereiro quando os Jogos começarão oficialmente.

Dia 15 de fevereiro ao dia 3 de março. Caso você não tenha percebido.

O quê? Na verdade, concordamos com você: criar uma nova coluna do Ei, Equipe de Scripts! além do anúncio sobre os Jogos de Script é, provavelmente, muita empolgação para um mês só. No entanto, para manter os caras da TechNet Magazine felizes (nossa meta principal na vida, não é necessário dizer), decidimos arriscar e criar uma nova coluna de qualquer maneira.

Exatamente um ano atrás (uau, já faz assim tanto tempo?), publicamos uma coluna que explicava como usar um script para ler um arquivo XML. O que aquela coluna não dizia era como usar um script para criar, gravar e modificar um arquivo XML. Este mês, estamos corrigindo isso. Você diz que gostaria de saber como escrever um script que possa criar um arquivo XML? Tudo o que você tinha de fazer era perguntar. Bem, perguntar e esperar um ano para que respondêssemos. A Figura 1 mostra o script. Com certeza isso parece complicado, mas explicaremos como tudo isso funciona.

Figure 1 Criando um arquivo XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")  
  
Set objRoot = _
  xmlDoc.createElement("ITChecklist")  
xmlDoc.appendChild objRoot  

Set objRecord = _
  xmlDoc.createElement("ComputerAudit") 
objRoot.appendChild objRecord 
  
Set objName = _
  xmlDoc.createElement("ComputerName")  
objName.Text = "atl-ws-001"
objRecord.appendChild objName  

Set objDate = _
  xmlDoc.createElement("AuditDate")  
objDate.Text = Date  
objRecord.appendChild objDate  

Set objIntro = _
  xmlDoc.createProcessingInstruction _
  ("xml","version='1.0'")  
xmlDoc.insertBefore _
  objIntro,xmlDoc.childNodes(0)  

xmlDoc.Save "C:\Scripts\Audits.xml"  

Para começar, criamos uma instância do objeto Microsoft.XMLDOM. Como você deve ter adivinhado, esse é o objeto que nos permite trabalhar com arquivos XML. Nossa meta é produzir um arquivo XML simples que se pareça com a Figura 2.

Figura 2 Nossa meta: um arquivo XML simples

Figura 2** Nossa meta: um arquivo XML simples **

Para criar esse arquivo XML, a primeira coisa a ser feita é criar o nó raiz (ITChecklist). Como fazemos isso? Assim:

Set objRoot = _
  xmlDoc.createElement("ITChecklist")  
xmlDoc.appendChild objRoot  

Essa foi bem fácil, não foi? Tudo o que precisamos fazer foi chamar o método createElement, passando para createElement o nome que desejamos dar ao nó raiz. Em seguida, simplesmente chamamos o método appendChild, passando a referência de objeto ao nosso novo elemento (objRoot) como o único parâmetro do método. Nesse ponto, temos um nó raiz.

Mas, espere; tem mais. Em seguida, criamos o nó ComputerAudit, filho do nó ITChecklist que representa a informação de um único computador. Como você pode ver, o código para a criação desse nó é semelhante ao código usado para criar o nó raiz:

Set objRecord = _
  xmlDoc.createElement("ComputerAudit") 
objRoot.appendChild objRecord 

A única diferença é essa: ao criar o nó raiz, chamamos appendChild no nosso próprio documento XML. (Observer a referência de objeto xmlDoc). Para adicionar um nó filho à raiz, chamamos appendChild no nó raiz (objRoot) em vez do documento XML. É muito fácil.

É fácil também adicionar os nós ComputerName e AuditDate como nós filho do ComputerAudit. Para fazer isso, vamos passar por um processo semelhante: chamaremos createElement para criar o novo nó e chamaremos appendChild para anexar esse novo nó ao arquivo.

(Pergunta rápida: de onde chamamos appendChild desta vez? Sim, você está certo: de objRecord, o nó pai (ComputerAudit) que acabamos de criar).

Ah, e como os nós ComputerName e AuditDate precisam conter valores, é importante especificar um valor para a propriedade Text de cada nó antes de adicioná-los ao documento.

Tudo deve ficar mais claro depois de examinarmos o código que realmente cria o nó ComputerName:

Set objName = _
  xmlDoc.createElement("ComputerName")  
objName.Text = "atl-ws-001"
objRecord.appendChild objName  

Como esperado, o código para a criação de AuditDate é quase idêntico. Precisamos somente especificar um nome de nó diferente ao chamar createElement e atribuir um valor diferente para a propriedade Text.

Cara, estamos tornando as coisas fáceis demais para todos, não acha?

Depois de concluir a criação dos nós do nosso primeiro (e único, nesse caso) registro, executamos este lindo bloco de código:

Set objIntro = _
 xmlDoc.createProcessingInstruction _
  ("xml","version='1.0'")  
xmlDoc.insertBefore _
  objIntro,xmlDoc.childNodes(0)  

Isso simplesmente insere a marca <?xml version="1.0" ?> ao início do arquivo, assegurando que temos um documento XML bem formado.

Nesse ponto, tudo o que nos resta fazer é chamar o método Save e salvar o nosso novo arquivo como C:\Scripts\Audits.xml:

xmlDoc.Save "C:\Scripts\Audits.xml"  

Assim, de repente, temos um documento XML novo em folha.

Agora, isso é realmente útil: você sabe como criar um arquivo XML novo em folha usando um script. Naturalmente, as chances são grandes de que, na maior parte do tempo, você não precise realmente criar um arquivo XML novo em folha; em vez disso, você simplesmente anexa novos dados a um arquivo existente. Então, será que a Equipe de Scripts mostrará a todos como fazer isso?

Sabe, decidimos originalmente que a resposta a essa pergunta seria não, não mostraremos a todos como anexar dados a um arquivo XML existente. E então, sendo pessoas boas e generosas, decidimos tentar e fazer um acordo com os leitores da TechNet Magazine: se todos que estiverem lendo esta revista concordarem em participar dos Jogos de Script de Inverno de 2008, em troca mostraremos a todos como usar um script para anexar dados a um arquivo XML. Então, todos concordam em participar dos Jogos de Script?

Hum, esperamos por você. Sim, você—o cara em Rochester, MN.

Sim, assim é melhor. E acredite, nos divertimos muito durante os Jogos de Script; todos sempre se divertem. Nós prometemos.

E agora, como um acordo é um acordo, mostraremos um script que anexa dados a um arquivo XML existente. Observe a Figura 3.

Figure 3 Anexando a um arquivo XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set objRoot = xmlDoc.documentElement
  
Set objRecord = _
  xmlDoc.createElement("ComputerAudit")
objRoot.appendChild objRecord

Set objFieldValue = _
  xmlDoc.createElement("ComputerName")
objFieldValue.Text = "atl-ws-100"
objRecord.appendChild objFieldValue

Set objFieldValue = _
  xmlDoc.createElement("AuditDate")
objFieldValue.Text = Date
objRecord.appendChild objFieldValue
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

Como você pode ver, não é extremamente diferente do script que criou o arquivo XML. Começamos criando uma instância do objeto Microsoft.XMLDOM e definindo a propriedade Async como False, o que informa ao script que desejamos carregar o documento de forma síncrona em vez de assíncrona. E daí? Bem, se carregarmos o documento de forma assíncrona, o script ficaria livre para continuar mesmo que o documento não estivesse totalmente carregado. Não é necessário dizer que problemas podem surgir se você tentar realizar uma tarefa em um documento que ainda não existe. Ao certificar-se de que o nosso arquivo XML é carregado de forma síncrona, também nos certificamos de que o arquivo será totalmente carregado antes que o script prossiga.

Por falar em totalmente carregado—bem, deixe pra lá; vamos deixar essa passar. Em vez disso, chamaremos o método Load para abrir o arquivo C:\Scripts\Audits.xml. Assim que o arquivo for aberto, usamos essa linha de código para criar uma instância da classe documentElement, que tem o efeito de ligar-nos à raiz do documento. Nesse caso, é claro, ela é o nó ITChecklist:

Set objRoot = xmlDoc.documentElement

Desse ponto em diante, tudo vai ladeira abaixo. Chamamos uma nova instância do nó ComputerAudit, usando o método appendChild para adicionar o novo nó ao arquivo. Em seguida, criamos novas instâncias dos nós ComputerName e AuditDate, especificando os valores apropriados (atl-ws-100 e a data atual, respectivamente) para cada novo nó. Juntamos esses dois itens dentro do novo nó ComputerAudit que acabamos de criar, chamamos o método Save para salvar o arquivo e voltamos a trabalhar nos nossos scripts para os Jogos de Script.

Jogos que, caso não tenhamos mencionado, estão programados para 15 de fevereiro a 3 de março no TechNet Script Center.

Até aqui tudo bem. Podemos criar um novo arquivo XML e podemos adicionar novos registros ao ele. Isso é muito interessante, mas ainda temos algumas coisas a fazer; por exemplo, como modificar os registros existentes no arquivo? Bem, há ao menos uma forma de fazer isso, como mostrado na Figura 4.

Figure 4 Modificando o XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']/AuditDate")

For Each objNode in colNodes
   objNode.Text = Date
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

A parte importante desse script ocorre ao chamarmos o método selectNodes, um método que determina quais registros a nossa consulta retornará. Como você pode ver, ao chamarmos selectNodes fomos cuidadosos ao especificar dois critérios: desejamos somente registros onde o atributo ComputerName seja igual a atl-ws-100 e desejamos obter somente o atributo AuditDate.

Observação: você diz que não consegue ver como isso funciona? Então observe o nosso primeiro artigo sobre como trabalhar com arquivos XML (technetmagazine.com/issues/2007/02/HeyScriptingGuy); a sintaxe de consulta selectNodes é explicada em maiores detalhes ali.

Como é espero, selectNodes retorna uma coleção de todos os registros XML que atendem aos critérios especificados. Por sua vez, isso significa que podemos atualizar o valor do atributo AuditDate (o único atributo pelo qual pedimos) simplesmente configurando um loop For Each para percorrer todos os itens na coleção e, dentro do loop, atribuir um novo valor a AuditDate:

For Each objNode in colNodes
   objNode.Text = Date
Next

O quê? Você está imaginando se poderíamos modificar mais de um atributo por vez? Sim, poderíamos. Mas infelizmente, não hoje; isso é algo que teremos de tratar em uma coluna no futuro.

Você diz que tem outra pergunta: como atualizar a data de auditoria de todos os computadores em um arquivo? Isso é fácil; você usa o script mostrado na Figura 5.

Figure 5 Alterando a data de auditoria

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit/AuditDate")

For Each objNode in colNodes
   objNode.Text = Date
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"

A única diferença entre esse script e o script de modificação de XML anterior? Com este não especificamos que desejávamos exibir somente os registros onde ComputerName fosse igual a atl-ws-100. Excluindo esse critério, obtivemos todos os registros por padrão.

Vamos dar uma olhada no último script antes de terminar. Vamos supor que nosso antigo colega atl-ws-100 tenha jogado seu último jogo de Paciência e tenha sido embaralhado para o cemitério de computadores no céu.

Nota teológica: para onde vão os computadores quando morrem? Ao que parece, são geralmente dados a um dos caras da Equipe de Script. Por exemplo, o cara da Equipe de Scripts que escreve essa coluna um dia ganhou um laptop porque "você faz muitas coisas boas para a Microsoft e realmente deve ter um laptop". A única desvantagem dessa oferta generosa? O computador estava quebrado e não ligava. O que provavelmente não era um problema. Como aconteceu, ele também não tinha um disco rígido.

Para completar o grande ciclo da vida de silicone, precisamos excluir o atl-ws-100 do nosso arquivo XML. Como faremos isso? Verifique a Figura 6.

Figure 6 Excluindo do arquivo XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']")

For Each objNode in colNodes
  xmlDoc.documentElement.removeChild _
    (objNode)
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

Como você pode ver, esse script é semelhante ao anterior, aquele que modificou a propriedade AuditDate. Há somente duas diferenças. Por um lado, observe que não nos importamos em especificar qualquer valor de propriedade na nossa consulta selectNodes; ao fazermos isso, obteríamos o registro XML inteiro para o atl-ws-100:

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']")

Em seguida, dentro do nosso loop For Each, simplesmente chamamos o método removeChild para excluir todos os registros onde ComputerName seja igual a atl-ws-100:

xmlDoc.documentElement.removeChild _
  (objNode)

E isso é tudo. Adeus, atl-ws-100; nós mal o conhecemos.

Certo, algum editor da TechNet Magazine ainda está lendo a coluna deste mês? Você diz que todos foram tentar o quebra-cabeça de script mensal? Excelente. Agora que não há ninguém lendo sobre nossos ombros, podemos dizer isso: deixe de lado o que você estiver fazendo (como, digamos, ler esta revista), venha para o Script Center e comece a se preparar para os Jogos de Script. Afinal, a TechNet Magazine estará aqui por muito tempo. Mas os Jogos de Script acontecem somente uma vez por ano e por tempo limitado (especificamente, de 15 de fevereiro a 3 de março, pra você ficar sabendo). Não perca!

Observação: sabe, agora que você mencionou, nós esperamos até que você lesse nossa coluna inteira antes de falar para você parar de ler a TechNet Magazine, não foi? Ficamos imaginando como isso foi acontecer...

O desafio de script do Dr. Scripto

O desafio mensal que testa não apenas sua habilidade de resolver quebra-cabeças, mas também de criar scripts.

Fevereiro de 2008: Símbolos misteriosos

O teclado do computador inclui todo tipo de caracter estranho; ainda mais estranho é o fato de que a maior parte desses caracteres têm um uso específico nas linguagens de script VBScript ou Windows PowerShell. Confira se você consegue corresponder cada símbolo ao seu uso em scripts. O primeiro está pronto para você.

ANSWER:

O desafio de script do Dr. Scripto

Resposta: Símbolos misteriosos, fevereiro de 2008

  

The Microsoft Scripting Guys trabalham para a — bem, são empregados da — Microsoft. Quando não estão jogando/treinando/assistindo beisebol (e diversas outras atividades), eles administram o Script Center da TechNet. Confira no site www.scriptingguys.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Todos os direitos reservados. A reprodução parcial ou completa sem autorização é proibida..