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-Member
tem 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.