Ei, rapaz do script!Cadê os suportes para copos?

A equipe de script da Microsoft

Esta coluna é baseada em uma versão de pré-lançamento do Windows PowerShell. Todas as informações deste artigo estão sujeitas a alterações.

Sempre que uma nova tecnologia é introduzida, normalmente, leva algum tempo para que as pessoas consigam diferenciá-la da que havia antes. Pense nos primeiros automóveis, por exemplo. Há um motivo pelo qual aquelas engenhocas eram conhecidas como carruagens sem cavalo: elas realmente eram quase isso. Se formos direto ao ponto, a única diferença entre os primeiros automóveis e as carruagens a tração animal era o fato de que uma usava cavalos e a outra não. Fora isso, era difícil dizer o que era uma e o que era a outra.

Hoje, naturalmente, poucas pessoas confundiriam um automóvel com uma carruagem a tração animal. Isso porque, com o passar do tempo, os fabricantes de automóveis começaram a fazer coisas que separam, claramente, carros de carruagens. Por exemplo, os carros de hoje vêm direto da fábrica com CD players, ar condicionado e sistemas de navegação por satélite; já não podemos dizer o mesmo das carruagens a tração animal. Da mesma forma, suponha que você estivesse conduzindo uma carruagem a tração animal em 1880 e precisasse largar seu Frappuccino por um instante; que pena, você estaria sem sorte. Por outro lado, alguns utilitários esportivos vêm, por padrão, com até 17 suportes para copos, sendo que existe pelo menos um exemplar de automóvel que dispõe de três suportes para copos apenas para o motorista. Alguns dos últimos modelos possuem até mesmo alguns suportes para aquecer ou esfriar a sua bebida, conforme a necessidade.

Observação Sim, é difícil de acreditar que as pessoas conseguiam sobreviver sem poderem tomar três bebidas diferentes enquanto dirigiam. Você consegue imaginar dirigir com apenas uma ou duas bebidas à disposição?

Para que uma nova tecnologia possa realmente ter êxito, as pessoas precisam saber por que devem preferir o novo e desconhecido no lugar do antigo e confiável. Quando os DVDs apareceram pela primeira vez, eles nos permitiam assistir a filmes em casa, exatamente como os videocassetes já faziam. Por outro lado, os DVDs eram bem mais caros do que os videocassetes e não podiam ser usados para gravar nossos programas favoritos. Desnecessário dizer, os DVDs não chegaram ao mundo arrasando. Na verdade, foi só quando os fabricantes de DVD começaram a incluir em seus discos cenas cortadas, comentários de um ator que sequer sabíamos que estava no filme e outras coisas que não podíamos ter com uma fita de videocassete que os DVDs começaram a suplantar seus sósias VHS. Poder assistir a um filme em casa não bastava; os fabricantes de DVD tinham que fornecer recursos acima e além daqueles que as pessoas já tinham.

Observação Se alguém chega, realmente, a assistir algum desses extras ou bônus está fora de questão: a natureza humana sendo o que é, se há alguma coisa diferente disponível, todos simplesmente passam a ter que tê-la. Por coincidência, a equipe de script está pensando em produzir um DVD que consista, principalmente, em textos excluídos das colunas da TechNet Magazine e finais alternativos para scripts de administração de sistemas.

Uso do Windows PowerShell

O Windows PowerShell™, a nova tecnologia de shell de comando/script lançada pela Microsoft, representa um outro exemplo disso. Quando as pessoas ouvem falar no Windows PowerShell pela primeira vez, normalmente, ouvem algo como:

  • "O Windows PowerShell lhe permite gerenciar processos e serviços."
  • "O Windows PowerShell lhe permite recuperar eventos a partir dos logs de eventos."
  • "O Windows PowerShell lhe permite usar WMI para gerenciar computadores."

Bem, não há nada de errado nisso; são todas tarefas úteis e importantes. O único problema, obviamente, é que todas essas tarefas já podem ser feitas pelo VBScript e Windows Script Host. A compatibilidade retroativa é importante e o Windows PowerShell não seria exatamente uma inovação se não pudesse, também, fazer as mesmas coisas que o VBScript. (Imagine um DVD player que não exibisse filmes. Na verdade, você nem precisa imaginar isso: um dos rapazes da equipe de script tem um desses em casa.)

Ao mesmo tempo, contudo, se o Windows PowerShell só fizesse as mesmas coisas que o VBScrip, então por que, em primeiro lugar, deveríamos nos importar com essa nova tecnologia? É verdade, o VBScript não possui nenhum suporte para copos; bom, tudo bem, o Windows PowerShell também não. Então, que diferença faz a tecnologia de script que usamos?

Para ser honesto, pode ser que não faça diferença nenhuma. Entretanto, fora a falta de suportes para copos, o Windows PowerShell tem alguns recursos que o VBScript não tem. Se tudo o que você precisa fazer é gerenciar processos e serviços, então, pode não haver nenhum motivo convincente para que você olhe para o Windows PowerShell; como diz o ditado, não se conserta o que não está quebrado. (Quando usada pela equipe de script, essa máxima tende a ser "Não tentem consertar isso, porque acabarão quebrando"). O Windows PowerShell se torna verdadeiramente atraente quando pode ser usado para fazer algo de que o VBScript não é capaz. Algo como, digamos, alterar a última hora de gravação de um arquivo.

Alteração da última hora de gravação

Você ouviu bem: alteração da última hora de gravação de um arquivo. Por diversos motivos (como uma forma rápida e fácil de controle de versão), os autores de script sempre sonharam com o dia em que eles poderiam alterar a última hora de gravação (ou de criação) de um arquivo ou conjunto de arquivos. É muito triste, contudo, que esse recurso não exista nem no WMI (Instrumentação de gerenciamento do Windows) e nem no FileSystemObject; em ambas as tecnologias, datas e horas de arquivos são para somente-leitura.

Com o Windows PowerShell, no entanto, alterar a última hora de gravação de um arquivo para a data e hora atuais é tão fácil quanto executar este comando:

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

Antes de explicarmos como o comando funciona, vamos responder a uma pergunta que, provavelmente, está na cabeça de todos: como o Windows PowerShell consegue modificar a última hora de gravação de um arquivo, se o WMI não consegue? Nós achávamos que devíamos tratar dessa questão antes de qualquer coisa, simplesmente porque ela representa uma concepção equivocada comum a respeito do Windows PowerShell. As pessoas tendem a pressupor que o Windows PowerShell é apenas uma nova maneira de usar o WMI. Está certo, você pode, definitivamente, usar o Windows PowerShell para acessar dados do WMI; também é verdade que, enquanto esperamos a criação de cmdlets (comandos nativos do Windows PowerShell) adicionais, a maiorias dos scripts de administração de sistemas continuarão a se basear, primordialmente, no WMI. Em seu cerne, todavia, o Windows PowerShell se baseia em .NET Framework, sendo que os cmdlets do Windows PowerShell lidam, normalmente, com objetos .NET em vez de objetos WMI. E isso é importante, porque as propriedades disponíveis pelo .NET Framework não são necessariamente as mesmas disponíveis pelo WMI.

Por exemplo, quando usamos o cmdlet Get-Item para fazer a ligação com um arquivo, não obtemos uma instância da classe WMI CIM_Datafile; em vez disso, obtemos um objeto .NET. Será que isso é mesmo um negócio tão bom assim? Pode apostar que sim. O objeto .NET expõe um conjunto de propriedades e métodos para gerenciamento de arquivos ligeiramente diferente do exposto pelo WMI. Porém, como acabamos de ver, essas ligeiras diferenças podem ser muito importantes, como a diferença entre uma propriedade ser para somente-leitura em vez de leitura/gravação.

Uma pergunta que não quer calar: como sabemos que o cmdlet Get-Item retorna um objeto .NET? Neste caso, e na maioria dos casos, a maneira mais fácil de descobrir com que tipo de objeto estamos lidando (bem como a maneira mais fácil de identificar as propriedades e os métodos disponíveis) é fazer a ligação com o arquivo e transmitir o objeto ao cmdlet Get-Member:

Get-Item c:\scripts\test.txt | Get-Member

Os resultados deste comando são exibidos na Figura 1. Como você pode ver, trata-se, realmente, de um objeto .NET (como se a equipe de script pudesse errar numa coisa dessas!)

Figure 1 Membros do objeto retornado por Get-Item

   
TypeName: System.IO.FileInfo

Name                      MemberType     Definition
----                      ----------     ----------
AppendText                Method         System.IO.StreamWriter AppendText()
CopyTo                    Method         System.IO.FileInfo CopyTo(String destFileName),
                                         System.IO.FileInfo CopyTo(S...
Create                    Method         System.IO.FileStream Create()
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(
                                         Type requestedType)
CreateText                Method         System.IO.StreamWriter CreateText()

Por acaso, esse comando pequenino e simples ilustra dois dos recursos mais interessantes (e úteis) do Windows PowerShell: pipelining e meta-informações. Apesar de não entrarmos em detalhes técnicos agora, a idéia básica por trás da criação de pipelining é que você pode usar um cmdlet para agarrar um objeto e passá-lo a um outro cmdlet. Neste comando, usamos o cmdlet Get-Item para obtermos um objeto representando o arquivo C:\Scripts\Test.txt e o passamos (enquanto objeto) pelo pipeline até o cmdlet Get-Member. (O símbolo | representa o pipeline em um comando do Windows PowerShell.)

O Get-Member, então, faz o que sabe, que é recuperar as propriedades e os métodos do objeto recuperado. Este é outro dos excelentes recursos do Windows PowerShell: é muito fácil acessar meta-informações, informações sobre informações. Usando cmdlets tais como Get-Member e Get-Command, é possível interrogar o Windows PowerShell sobre tudo, praticamente da mesma forma que se pode gravar um script WMI para recuperar informações sobre classes, propriedades e métodos WMI disponíveis.

Observação O Get-Member dá, realmente, um passo além do que é possível com o WMI. Embora você possa usar o WMI para obter informações sobre objetos WMI, não é possível usá-lo para obter informações sobre outros objetos de COM (como, por exemplo, FileSystemObject). Esse não é o caso do Windows PowerShell. O Get-Member funciona com qualquer objeto que se possa ligar ou criar. Não consegue lembrar os métodos disponíveis ao usar o FileSystemObject? Então, execute o seguinte comando:

New-Object -comobject "Scripting.     FileSystemObject" | Get-Member

Este recurso é incrivelmente útil, logo, extremamente subutilizado.

Legal, hein? Se rolarmos a lista de propriedades e métodos disponíveis ao trabalhar com o arquivo C:\Scripts\Test.txt, veremos, eventualmente, esta linha:

LastWriteTime             Property       System.DateTime LastWriteTime {get;set;}

Interessante. Aparentemente, LastWriteTime é uma propriedade com suporte tanto para get (ler), quanto para set (gravar). Será que isso significa que podemos usar o Windows PowerShell para alterar o valor da última hora de gravação do arquivo? Hummm...

Glossário do Windows PowerShell

Alias Um nome personalizável que representa um cmdlet existente. O Windows PowerShell fornece uma variedade de aliases padrão que mapeiam comandos de shell comuns para seus cmdlets equivalentes.

Cmdlet A menor unidade de funcionalidade no Windows PowerShell, análoga aos comandos internos de outros shells.

Comando Uma unidade de execução no Windows PowerShell. Os comandos podem incluir várias operações conectadas em pipe e transpor linhas por meio do caractere ";".

Frappuccino Uma bebida gelada mista, à base de café, vendida pela Starbucks.

Monad/MSH/Microsoft Command Shell Codinomes antigos do Windows PowerShell.

Objeto Dados estruturados recuperados a partir do sistema ou de um comando. O Windows PowerShell manipula dados como objetos .NET, permitindo-lhe manipular as propriedades do objeto por nome, em vez de ter que analisar a saída do comando baseado em texto.

Parâmetro Opções definidas em um cmdlet na linha de comando. O Windows PowerShell usa um caractere hífen (-) inicial para designar um parâmetro.

Pipeline Permite enviar a saída de um comando para a entrada de um outro comando. Também conhecido como pipe; representado em comandos pelo caractere “|”.

Perfil Configurações, carregadas quando o Windows PowerShell é iniciado, que lhe permitem configurar como o shell deve operar.

Script Um ou mais comandos salvos como e executados a partir de um arquivo. O Windows PowerShell usa a extensão .ps1 para arquivos de script.

Shell Um ambiente de linha de comando no qual se pode executar tanto comandos, quanto cmdlets.

Variável Um objeto ou parâmetro cujo valor pode ser definido, alterado ou recuperado durante a execução do comando.

Agora, vamos voltar um pouco e falar sobre o comando que define a última hora de gravação de Test.txt como a data e a hora atuais. É semelhante ao seguinte:

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

Como você pode ver, este comando não tem mesmo nada de mais. Para começar, vamos declarar uma variável denominada $a. Em seguida, vamos usar o cmdlet Get-Item para fazer a conexão com o arquivo C:\Scripts\Test.txt. Agora é a vez de armazenarmos esse objeto na variável $a. Depois de digitar um ponto-e-vírgula (que nos permite ter vários comandos em uma única linha), vamos definir o valor da propriedade LastWriteTime como a data e a hora atuais. Olha só, isso quase compensa a falta de suporte para copos, não é?

Sonhemos um pouco mais

É claro que você tampouco está limitado a definir a última hora de gravação como a data e a hora atuais. Por exemplo, considere este comando:

$b = Get-Date "5/22/2006 8:15 PM";
$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = $b

Desta vez, nós amarramos três comandos juntos. Para começar, usamos o cmdlet Get-Date para criar um objeto de data-hora igual a 5/22/2006, 8:15 PM. Por que não tivemos que usar Get-Date para criar um objeto de data-hora em nosso primeiro script, aquele que define a última hora de gravação como a data e a hora atuais? É fácil: o comando Date retorna automaticamente um objeto de data-hora. (Para verificar isso sozinho, digite o seguinte comando no console do Windows PowerShell: Date | Get-Member.)

Após criar um objeto de data-hora igual à data e hora desejadas, usamos nosso comando Get-Item familiar para obtermos um objeto representando o arquivo Test.txt (que armazenamos na variável $a). Finalmente, definimos a propriedade LastWriteTime com o valor representado pela variável $b:

$a.LastWriteTime = $b

Acredite ou não, você ainda não viu nem metade. Espie só este comando aparentemente inócuo:

$b = Get-Date "5/22/2006 8:15 PM";
Get-ChildItem c:\scripts | ForEach-Object {$_.LastWriteTime = $b}

O que tem de tão interessante neste comando? Bem, vejamos o que ele faz. A primeira parte é fácil: mais uma vez, criamos um objeto de data-hora equivalente a 8:15 PM em 5/22/2006. Contudo, note que, na parte dois, nós não usamos o cmdlet Get-Item; em vez disso, usamos o comando:

Get-ChildItem c:\scripts

O que tem isso? Bem, toda vez que se aplica o cmdlet Get-ChildItem a uma pasta, é retornada uma coleção com todos os arquivos da pasta. Vamos apanhar essa coleção e passar todos os seus itens pelo pipeline (lá está aquele símbolo | de novo) para o cmdlet ForEach-Object.

E o que ForEach-Object tem a ver com todos esses arquivos? Ora, ele é que vai alterar o valor da propriedade LastWriteTime de todos e de cada um deles, é claro:

ForEach-Object {$_.LastWriteTime = $b}

Observação Embora esta coluna mensal não pretenda ser um guia para iniciantes no Windows PowerShell, devemos notar que $_ é uma variável especial que representa o item atual em um loop For Each. Ela equivale a objItem no seguinte loop de VBScript:

For Each objItem in colItems
    Wscript.Echo objItem.Name
Next

Quando nosso comando de Windows PowerShell terminar de executar, todos os arquivos da pasta C:\Scripts terão a mesma última hora de gravação. Nós gostaríamos de ver uma daquelas inovadoras carruagens sem cavalos fazer isso!

Poderíamos executar variações desse comando a noite toda. Por exemplo, talvez você queira alterar a última hora de gravação somente nos arquivos .txt da pasta C:\Scripts. Certo, tudo o que você teria que fazer seria perguntar:

$b = Get-Date "5/22/2006 8:15 PM"; Get-ChildItem c:\scripts\*.txt | ForEach-Object {$_.LastWriteTime = $b}

Desperte o seu apetite

É mesmo muito legal. Entretanto, devemos notar que o objetivo desta coluna não é "vender" o Windows PowerShell e nem encorajá-lo a jogar fora todos os seus scripts de VBScript e convertê-los, todos, em Windows PowerShell. Se esses scripts fazem o que você quer e precisa que eles façam, simplesmente deixe-os em paz; o mesmo vale para arquivos de lote, ferramentas de linha de comando, palavras mágicas e quaisquer outras ferramentas utilizadas para gerenciar seus computadores. Lembre-se, se ele não estiver quebrado...

A questão não é que o Windows PowerShell lhe permite fazer coisas que já é capaz de fazer, mas sim que, em parte porque fornece acesso ao .NET Framework, o Windows PowerShell lhe permite fazer coisas que antes não eram possíveis. Modificar a última hora de acesso de um arquivo (ou grupo de arquivo) é um dos exemplos disso. Se existem ou não outros exemplos, depende do que você precisa fazer. São esses recursos que fazem valer a pena dar uma olhada no Windows PowerShell.

Para muitos, esta talvez tenha sido uma introdução pouco usual ao Windows PowerShell, afinal, em vez de começarmos com um exemplo simples, do tipo "Olá, mundo", partimos direto para um comando multicomponentes do Windows PowerShell, todo o tempo lançando termos como pipeline e cmdlet, muito embora todos soubessem o que queríamos dizer com tudo aquilo. Foi intencional. Afinal, nós sabemos que muitos ainda precisam experimentar o Windows PowerShell e ficamos com medo de que, se mostrássemos como recuperar uma lista de serviços em um computador, você simplesmente daria de ombros e voltaria a fazer o que estava fazendo.

Observação Esperamos que você não esteja dirigindo. Para muitos de nós ainda é muito difícil tomar três bebidas, assistir a um DVD e falar em um telefone celular enquanto dirige, sem falar na quot;leitura da TechNet Magazine" no meio disso tudo.

Ei, qual é! Nós dissemos para muitos de nós, não para todos.

A equipe de script da Microsofttrabalha para — bem, são empregados por ela — a Microsoft. Quando não está jogando/treinando/assistindo beisebol (e diversas outras atividades), ela administra o TechNet Script Center. Verifique em www.scriptingguys.com (em inglês).

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