Windows PowershellA conexão com o WMI

Don Jones

Uma das tecnologias nas quais eu mais confiei no mundo do VBScript foi o WMI (Instrumentação de Gerenciamento do Windows). Curiosamente, o Windows PowerShell tem uma forte conexão com o WMI – e não apenas no sentido técnico. Jeffrey Snover, o arquiteto que projetou o Windows PowerShell, também desempenhou um papel fundamental na criação do

Wmic.exe, uma ferramenta de linha de comando da época do Windows Server® 2003 usada para trabalhar com o WMI. De várias maneiras, o Wmic.exe foi o precursor do Windows PowerShell™ porque funcionava de modo semelhante. (Para obter mais informações sobre o WMIC, consulte o artigo de John Kelbley na edição de setembro de 2006 da TechNet Magazine, disponível online em microsoft.com/technet/technetmag/issues/2006/09/WMIData.)

O Windows PowerShell oferece suporte ao WMI que é fornecido da mesma maneira consistente e baseada em objeto que o restante dos recursos do shell. Isso torna o WMI infinitamente mais fácil de aprender e usar – principalmente em situações ad hoc – do que tecnologias mais recentes, como o VBScript.

Uma prévia do WMI

Se você leu artigos e livros sobre a criação de scripts, é praticamente impossível não ter visto nenhuma menção ao WMI. No entanto, é fácil ficar envolvido com o uso do WMI a ponto de esquecer o modo como ele é criado no escopo, que é uma informação importante para entender como ele funciona no Windows PowerShell.

O WMI é principalmente um sistema de classes organizadas que representam informações de gerenciamento do sistema operacional Windows® e de outros produtos de software e hardware baseados no Windows. Uma classe não é nada mais do que uma descrição abstrata das propriedades e dos recursos que algum componente de software e hardware possui. Por exemplo, uma classe de discos lógicos pode descrever um dispositivo que tem um número de série, uma capacidade de armazenamento fixa, uma quantidade de capacidade disponível, etc. Enquanto isso, uma classe que descreve um serviço do Windows poderia especificar que o serviço tem um nome, pode ser iniciado e interrompido, seu status atual, e assim por diante.

No WMI, as classes representam tudo o que ele pode gerenciar. Se o WMI não tiver uma classe para algum componente, não poderá gerenciá-lo. A Microsoft documenta as classes WMI do Windows principais em msdn2.microsoft.com/aa394554.aspx. Outros produtos, como os Serviços de Informações da Internet e o SQL Server™, documentam suas classes WMI separadamente.

Como existem muitas classes, o WMI as organiza em uma hierarquia de namespaces. Por exemplo, o namespace contendo as classes de sistema operacional do Windows principais chama-se root\cimv2, enquanto o Microsoft IIS 6.0 armazena suas classes em root\MicrosoftIISv2. Convenientemente, o namespace root\cimv2 é o namespace WMI padrão, uma configuração compartilhada pelo Windows PowerShell, o que facilita o trabalho com essas classes principais.

Uma "instância" é uma ocorrência real de uma classe. Se, por exemplo, seu computador tiver dois discos lógicos, você terá duas instâncias da classe Win32_LogicalDisk. Se você tiver 50 serviços sendo executados em seu computador, o WMI verá 50 instâncias da classe Win32_Service. Trabalhar com o WMI é basicamente uma questão de pedir que ele forneça uma ou mais instâncias, examinando depois as propriedades delas para encontrar as informações de gerenciamento de que precisa ou executando os métodos delas para fazer alterações de gerenciamento, como iniciar ou interromper um serviço.

O WMI usa uma arquitetura cliente/servidor. Desde o Windows 2000, todas as versões do Windows vêm com o WMI integrado (as versões posteriores expandiram o número de classes disponíveis), o que significa que você tem o software tanto do cliente WMI como do servidor WMI prontamente disponível. Ao usar o WMI, você está enviando, na verdade, uma solicitação ao Serviço WMI que está sendo executado no computador que lhe interessa. Esse serviço recupera as instâncias do WMI especificadas e as retorna para que você possa trabalhar com elas. É aqui que entra o Windows PowerShell – ele simplifica o processo de pedir instâncias, recebê-las de volta e trabalhar com elas.

Obtendo um objeto WMI

As instâncias de classes WMI são livremente conhecidas como objetos, por isso faz sentido que a forma de recuperá-las no Windows PowerShell seja o cmdlet Get-WMIObject. Esse cmdlet tem um alias conveniente, o gwmi, que usarei para a maioria dos meus exemplos. Em sua forma mais simples, basta especificar o nome da classe WMI que deseja recuperar e depois sentar e examinar os resultados (consulte a Figura 1). Quando executei o gwmi win32_service, o Windows PowerShell se conectou ao serviço WMI no meu computador local (já que eu não tinha especificado outro computador) e ao namespace root\cimv2 (já que eu não tinha especificado outro namespace). O Windows PowerShell recuperou todas as instâncias da classe especificada e, como eu não o mandei fazer nada mais com elas, converteu-as em representação textual. Em outras palavras, o Windows PowerShell pegou esses objetos e produziu um texto que eu, como humano, pudesse ler.

Figura 1 Durante a execução do gwmi win32_service, o Windows PowerShell retorna todas as instâncias da classe especificada em um formato de texto legível

Figura 1** Durante a execução do gwmi win32_service, o Windows PowerShell retorna todas as instâncias da classe especificada em um formato de texto legível **

Especificamente, o Windows PowerShell converte objetos WMI em texto lendo e exibindo os nomes e os valores de propriedades de classes selecionadas. Para a classe Win32_Service, ele seleciona um conjunto de seis propriedades.

Na verdade, o Windows PowerShell converte qualquer objeto em texto dessa forma. As propriedades que ele escolhe para exibir são, em sua maior parte, definidas em um conjunto de arquivos .format.ps1xml localizados na pasta de instalação do Windows PowerShell. Esses arquivos de definição de formato são assinados digitalmente pela Microsoft. Convém não alterá-los, embora você possa fornecer seus próprios arquivos de formatação. (Abordarei esse tópico mais detalhadamente em uma futura coluna.)

O cmdlet gwmi pode ajudá-lo a explorar seu computador para descobrir quais classes estão disponíveis. A execução do gwmi –namespace "root\cimv2" –list, por exemplo, fornece uma lista completa de classes nesse namespace. Lembre-se, porém, que as classes em seu computador só são relevantes se você o estiver gerenciando. Caso você esteja gerenciando um computador remoto, convém descobrir quais classes estão disponíveis nesse sistema. Para isso, é recomendável usar o parâmetro –computer do gwmi para se conectar a um computador remoto. Por exemplo, gwmi –namespace "root\cimv2" –list –computer ServerA listará todas as classes no namespace root\cimv2 no computador remoto chamado ServerA.

WMI remoto

Na versão 1.0 do Windows PowerShell, o gwmi é o único cmdlet que dá suporte diretamente ao gerenciamento remoto. Isso se deve principalmente ao fato de o controle remoto ser incorporado à arquitetura WMI subjacente. Além disso, como o Windows PowerShell está simplesmente utilizando essa arquitetura existente, está sujeito aos recursos de segurança dela. Por exemplo:

C:\> gwmi -namespace “root\cimv2” -computer
mediaserver -list
Get-WmiObject : Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:5
+ gwmi <<<< -namespace “root\cimv2” -computer
mediaserver -list
PS C:\>

Nessa instância, tentei me conectar a um computador remoto, chamado MediaServer, para o qual não possuo permissão de acesso. Como administrador, eu devo ter permissão para trabalhar com o serviço WMI desse computador, mas é provável que as credenciais da minha estação de trabalho local não sejam suficientes. Eu poderia, por exemplo, estar conectado em um domínio diferente e não confiável ou com uma conta com menos privilégios. Felizmente, o gwmi dá suporte a um parâmetro –credential que me permite especificar um conjunto alternativo de credenciais de usuário para minha conexão com o WMI. Veja a seguir um exemplo muito simples:

gwmi win32_service –credential mydomain\administrator –computer mediaserver

Minha credencial – mais especificamente, meu nome de usuário – é fornecida no formato DOMÍNIO\Nome de usuário.

Observe que não há nenhum lugar para digitar senha. Você será solicitado a fazê-lo pelo Windows PowerShell. A ausência de um campo para inserir senha na linha de comando é intencional, pois isso permitiria que você codificasse senhas em arquivos de script, o que é um risco de segurança enorme. Entretanto, existe outra maneira de trabalhar com esse parâmetro –credential, que é criar antecipadamente um tipo de objeto de credencial, chamado PSCredential. A chave é o cmdlet Get-Credential:

$cred = get-credential mydomain\administrator

Preciso fornecer a senha correspondente mesmo quando executo o cmdlet. Dessa vez, porém, o objeto de credencial criado é armazenado na variável $cred. Se eu examinar o conteúdo de $cred, verei o nome, mas não a senha.

PS C:\> $cred

UserName
--------
mydomain\adminstrator

Posso então reutilizar esse objeto de credencial quantas vezes quiser:

gwmi win32_service –credential $cred –computer mediaserver

A definição prévia de um objeto de credencial reutilizável simplifica conexões com o WMI repetidas para um computador remoto. Vale a pena observar, porém, que o cmdlet Get-WMIObject não oferece suporte no momento à especificação de níveis de autenticação (também conhecida como representação) como faz o VBScript. Consulte msdn2.microsoft.com/aa389290.aspx para obter mais informações.

Autodetecção

Um dos pontos que eu mais aprecio no Windows PowerShell é que ele não facilita as coisas. Eu mostrei como o Windows PowerShell selecionou somente um conjunto de propriedades para a classe Win32_Service que eu consultei. O shell ainda tem acesso a todas as propriedades, porém, e pode até lhe dizer quais são. Para fazer isso, basta canalizar o(s) objeto(s) para o cmdlet Get-Member (ou seu alias, gm), como mostra a Figura 2.

Figura 2 A canalização de um objeto para o cmdlet Get-Member lhe diz quais métodos e propriedades você pode acessar

Figura 2**  A canalização de um objeto para o cmdlet Get-Member lhe diz quais métodos e propriedades você pode acessar **(Clique na imagem para aumentar a exibição)

Além de propriedades, o shell também lista métodos disponíveis, o que significa que eu não preciso necessariamente da documentação para descobrir o que uma classe pode fazer. Posso ver que a própria classe fornece os meios para alterar a configuração de uma instância, pausar um serviço, interromper um serviço, etc.

Para utilizar esses métodos ou exibir outras propriedades, geralmente é mais fácil colocar as instâncias em uma variável.

$server = gwmi win32_operatingsystem
$server.reboot()

Esse exemplo irá recuperar a única instância disponível da classe Win32_OperatingSystem (que tem apenas uma instância por computador) e salvá-la na variável $server. Em seguida, usarei a variável $server para acessar o método Reboot da instância, reiniciando o computador. Cuidado com esse aí!

Linguagem de consulta rica

Se você tiver usado o WMI em VBScript ou outra tecnologia, provavelmente já está acostumado a recuperar instâncias de classes WMI usando uma consulta escrita em linguagem WQL. Sua sintaxe semelhante à do SQL facilita a recuperação de instâncias específicas – como um serviço específico – em vez de todas as instâncias de uma determinada classe. Felizmente, o gwmi também permite especificar uma consulta, deste modo:

gwmi –query “select * from win32_service where name=’alerter’”

Essa sintaxe do gwmi (que foi acrescentada um pouco antes do lançamento oficial do Windows PowerShell) é incrivelmente útil e facilita demais a migração de consultas WMI complexas que você tenha desenvolvido para outras finalidades. E, como sempre, o Windows PowerShell retornará rich objects com seus próprios métodos e propriedades, oferecendo acesso completo ao poder do gerenciamento do WMI.

Avançando com o WMI

O WMI continua sendo desenvolvido para futuras versões do Windows, com o acréscimo de novas classes e recursos. E continua sendo adicionado a novos produtos Microsoft. Embora a maioria dos produtos Microsoft não tenha ainda lançado versões criadas especificamente no Windows PowerShell, sua capacidade de se conectar ao WMI é um dos grandes benefícios que tornam o Windows PowerShell útil hoje em dia.

Minha abordagem foi apenas superficial em comparação com o que o WMI pode fazer. Ainda assim, espero ter lhe inspirado a explorar o Windows PowerShell e a descobrir sozinho os recursos que estão disponíveis.

Don Jones é diretor de projetos e serviços da SAPIEN Technologies e co-autor do Windows PowerShell: TFM (SAPIEN Press). Entre em contato com Don pelo seu site em www.ScriptingAnswers.com.

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