Share via


Criando objetos .NET e COM

Este exemplo só é executado em plataformas Windows.

Há componentes de software com interfaces .NET Framework e COM que permitem executar muitas tarefas de administração do sistema. O PowerShell permite que você use esses componentes, para que você não esteja limitado às tarefas que podem ser executadas usando cmdlets. Muitos dos cmdlets na versão inicial do PowerShell não funcionam em computadores remotos. Demonstraremos como contornar essa limitação ao gerenciar logs de eventos usando a classe System.Diagnostics.EventLog do .NET Framework diretamente do PowerShell.

Usando New-Object para acesso ao log de eventos

A biblioteca de classes do .NET Framework inclui uma classe chamada System.Diagnostics.EventLog que pode ser usada para gerenciar logs de eventos. Você pode criar uma nova instância de uma classe do .NET Framework usando o New-Object cmdlet com o parâmetro TypeName . Por exemplo, o comando a seguir cria uma referência de log de eventos:

New-Object -TypeName System.Diagnostics.EventLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

Embora o comando tenha criado uma instância da classe EventLog , a instância não inclui nenhum dado. Isso porque não especificamos um log de eventos específico. Como obter um registo de eventos real?

Usando construtores com New-Object

Para fazer referência a um log de eventos específico, você precisa especificar o nome do log. New-Object tem um parâmetro ArgumentList . Os argumentos que você passa como valores para esse parâmetro são usados por um método de inicialização especial do objeto. O método é chamado de construtor porque é usado para construir o objeto. Por exemplo, para obter uma referência ao log do aplicativo, especifique a cadeia de caracteres 'Aplicativo' como um argumento:

New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Max(K) Retain OverflowAction        Entries Name
------ ------ --------------        ------- ----
16,384      7 OverwriteOlder          2,160 Application

Nota

Como a maioria das classes .NET está contida no namespace System, o PowerShell tenta localizar automaticamente as classes especificadas no namespace System se não conseguir encontrar uma correspondência para o typename especificado. Isso significa que você pode especificar Diagnostics.EventLog em vez de System.Diagnostics.EventLog.

Armazenando objetos em variáveis

Talvez você queira armazenar uma referência a um objeto, para que possa usá-lo no shell atual. Embora o PowerShell permita que você trabalhe muito com pipelines, diminuindo a necessidade de variáveis, às vezes armazenar referências a objetos em variáveis torna mais conveniente manipular esses objetos.

A saída de qualquer comando válido do PowerShell pode ser armazenada em uma variável. Os nomes das variáveis sempre começam com $. Se desejar armazenar a referência de log do aplicativo em uma variável chamada $AppLog, digite o nome da variável, seguido de um sinal de igual e, em seguida, digite o comando usado para criar o objeto de log do aplicativo:

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

Se você digitar $AppLog, poderá ver que ele contém o log do aplicativo:

$AppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
  16,384      7 OverwriteOlder          2,160 Application

Acessando um log de eventos remoto com New-Object

Os comandos usados na seção anterior visam o computador local; O Get-EventLog cmdlet pode fazer isso. Para acessar o log do aplicativo em um computador remoto, você deve fornecer o nome do log e um nome do computador (ou endereço IP) como argumentos.

$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application, 192.168.1.81
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder            262 Application

Agora que temos uma referência a um log de eventos armazenado na $RemoteAppLog variável, quais tarefas podemos executar nele?

Limpando um log de eventos com métodos de objeto

Os objetos geralmente têm métodos que podem ser chamados para executar tarefas. Você pode usar Get-Member para exibir os métodos associados a um objeto. O comando a seguir e a saída selecionada mostram alguns dos métodos da classe EventLog :

$RemoteAppLog | Get-Member -MemberType Method
   TypeName: System.Diagnostics.EventLog

Name                      MemberType Definition
----                      ---------- ----------
...
Clear                     Method     System.Void Clear()
Close                     Method     System.Void Close()
...
GetType                   Method     System.Type GetType()
...
ModifyOverflowPolicy      Method     System.Void ModifyOverflowPolicy(Overfl...
RegisterDisplayName       Method     System.Void RegisterDisplayName(String ...
...
ToString                  Method     System.String ToString()
WriteEntry                Method     System.Void WriteEntry(String message),...
WriteEvent                Method     System.Void WriteEvent(EventInstance in...

O Clear() método pode ser usado para limpar o log de eventos. Ao chamar um método, você sempre deve seguir o nome do método entre parênteses, mesmo que o método não exija argumentos. Isso permite que o PowerShell distinga entre o método e uma propriedade potencial com o mesmo nome. Digite o seguinte para chamar o método Clear :

$RemoteAppLog.Clear()
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder              0 Application

Observe que o log de eventos foi limpo e agora tem 0 entradas em vez de 262.

Criando objetos COM com New-Object

Você pode usar New-Object para trabalhar com componentes COM (Component Object Model). Os componentes variam desde as várias bibliotecas incluídas no WSH (Windows Script Host) até aplicativos ActiveX, como o Internet Explorer, instalados na maioria dos sistemas.

New-Object usa o .NET Framework Runtime-Callable Wrappers para criar objetos COM, portanto, ele tem as mesmas limitações que o .NET Framework faz ao chamar objetos COM. Para criar um objeto COM, você precisa especificar o parâmetro ComObject com o identificador programático ou ProgId da classe COM que deseja usar. Uma discussão completa sobre as limitações do uso de COM e determinar quais ProgIds estão disponíveis em um sistema está além do escopo deste guia do usuário, mas os objetos mais conhecidos de ambientes como WSH podem ser usados no PowerShell.

Você pode criar os objetos WSH especificando estes progids: WScript.Shell, WScript.Network, Scripting.Dictionary e Scripting.FileSystemObject. Os comandos a seguir criam esses objetos:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

Embora a maioria da funcionalidade dessas classes seja disponibilizada de outras maneiras no Windows PowerShell, algumas tarefas, como a criação de atalhos, ainda são mais fáceis de fazer usando as classes WSH.

Criando um atalho na área de trabalho com WScript.Shell

Uma tarefa que pode ser executada rapidamente com um objeto COM é criar um atalho. Suponha que você queira criar um atalho na área de trabalho que vincule à pasta base do PowerShell. Primeiro, você precisa criar uma referência ao WScript.Shell, que armazenaremos em uma variável chamada $WshShell:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member funciona com objetos COM, para que você possa explorar os membros do objeto digitando:

$WshShell | Get-Member
   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Va...
CreateShortcut           Method                IDispatch CreateShortcut (str...
...

Get-Membertem um parâmetro InputObject opcional que você pode usar em vez de tubulação para fornecer entrada para Get-Member. Você obteria a mesma saída mostrada acima se, em vez disso, usasse o comando Get-Member -InputObject $WshShell. Se você usar InputObject, ele tratará seu argumento como um único item. Isso significa que, se você tiver vários objetos em uma variável, Get-Member os tratará como uma matriz de objetos. Por exemplo:

$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
...

O método WScript.Shell CreateShortcut aceita um único argumento, o caminho para o arquivo de atalho a ser criado. Poderíamos digitar o caminho completo para a área de trabalho, mas há uma maneira mais fácil. A área de trabalho é normalmente representada por uma pasta chamada Desktop dentro da pasta inicial do usuário atual. O Windows PowerShell tem uma variável $HOME que contém o caminho para essa pasta. Podemos especificar o caminho para a pasta base usando essa variável e, em seguida, adicionar o nome da pasta Desktop e o nome do atalho a ser criado digitando:

$lnk = $WshShell.CreateShortcut("$HOME\Desktop\PSHome.lnk")

Quando você usa algo que se parece com um nome de variável entre aspas duplas, o PowerShell tenta substituir um valor correspondente. Se você usar aspas simples, o PowerShell não tentará substituir o valor da variável. Por exemplo, tente digitar os seguintes comandos:

"$HOME\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
'$HOME\Desktop\PSHome.lnk'
$HOME\Desktop\PSHome.lnk

Agora temos uma variável chamada $lnk que contém uma nova referência de atalho. Se você quiser ver seus membros, você pode canalizá-lo para Get-Member. A saída abaixo mostra os membros que precisamos usar para terminar de criar nosso atalho:

$lnk | Get-Member
TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}
Name             MemberType   Definition
----             ----------   ----------
...
Save             Method       void Save ()
...
TargetPath       Property     string TargetPath () {get} {set}

Precisamos especificar o TargetPath, que é a pasta do aplicativo para o PowerShell, e salvar o atalho chamando o Save método. O caminho da pasta do aplicativo PowerShell é armazenado na variável $PSHome, para que possamos fazer isso digitando:

$lnk.TargetPath = $PSHome
$lnk.Save()

Usando o Internet Explorer do PowerShell

Muitos aplicativos, incluindo a família de aplicativos Microsoft Office e o Internet Explorer, podem ser automatizados usando COM. Os exemplos a seguir ilustram algumas das técnicas típicas e problemas envolvidos no trabalho com aplicativos baseados em COM.

Criar uma instância do Internet Explorer especificando o Internet Explorer ProgId, InternetExplorer.Application:

$ie = New-Object -ComObject InternetExplorer.Application

Este comando inicia o Internet Explorer, mas não o torna visível. Se você digitar Get-Process, poderá ver que um processo chamado iexplore está em execução. Na verdade, se você sair do PowerShell, o processo continuará a ser executado. Você deve reiniciar o computador ou usar uma ferramenta como o Gerenciador de Tarefas para finalizar o iexplore processo.

Nota

Objetos COM que começam como processos separados, comumente chamados de executáveis ActiveX, podem ou não exibir uma janela de interface do usuário quando são iniciados. Se eles criarem uma janela, mas não a tornarem visível, como o Internet Explorer, o foco geralmente se move para a área de trabalho do Windows. Você deve tornar a janela visível para interagir com ela.

Ao digitar $ie | Get-Member, você pode exibir propriedades e métodos para o Internet Explorer. Para ver a janela do Internet Explorer, defina a propriedade Visible como $true digitando:

$ie.Visible = $true

Em seguida, você pode navegar para um endereço da Web específico usando o Navigate método:

$ie.Navigate("https://devblogs.microsoft.com/scripting/")

Usando outros membros do modelo de objeto do Internet Explorer, é possível recuperar conteúdo de texto da página da Web. O comando a seguir exibe o texto HTML no corpo da página da Web atual:

$ie.Document.Body.InnerText

Para fechar o Internet Explorer de dentro do PowerShell, chame seu Quit() método:

$ie.Quit()

A $ie variável não contém mais uma referência válida, embora ainda pareça ser um objeto COM. Se você tentar usá-lo, o PowerShell retornará um erro de automação:

$ie | Get-Member
Get-Member : Exception retrieving the string representation for property "Appli
cation" : "The object invoked has disconnected from its clients. (Exception fro
m HRESULT: 0x80010108 (RPC_E_DISCONNECTED))"
At line:1 char:16
+ $ie | Get-Member <<<<

Você pode remover a referência restante com um comando como $ie = $null, ou remover completamente a variável digitando:

Remove-Variable ie

Nota

Não existe um padrão comum para saber se os executáveis ActiveX saem ou continuam a ser executados quando remove uma referência a um. Dependendo das circunstâncias, como se o aplicativo está visível, se um documento editado está sendo executado nele e até mesmo se o PowerShell ainda está em execução, o aplicativo pode ou não sair. Por esse motivo, você deve testar o comportamento de encerramento para cada executável ActiveX que deseja usar no PowerShell.

Obtendo avisos sobre objetos COM encapsulados pelo .NET Framework

Em alguns casos, um objeto COM pode ter um .NET Framework Runtime-Callable Wrapper (RCW) associado que é usado pelo New-Object. Uma vez que o comportamento do RCW pode ser diferente do comportamento do objeto COM normal, New-Object tem um parâmetro Strict para avisá-lo sobre o acesso RCW. Se você especificar o parâmetro Strict e, em seguida, criar um objeto COM que usa um RCW, você receberá uma mensagem de aviso:

$xl = New-Object -ComObject Excel.Application -Strict
New-Object : The object written to the pipeline is an instance of the type "Mic
rosoft.Office.Interop.Excel.ApplicationClass" from the component's primary interop assembly. If
this type exposes different members than the IDispatch members , scripts written to work with this
object might not work if the primary interop assembly isn't installed. At line:1 char:17 + $xl =
New-Object <<<< -ComObject Excel.Application -Strict

Embora o objeto ainda seja criado, você será avisado de que não é um objeto COM padrão.