Hay componentes de software con interfaces de .NET Framework y COM que permiten realizar muchas tareas de administración de sistemas. Windows PowerShell permite usar estos componentes, así que no está limitado a las tareas que se pueden realizar con cmdlets. Muchos de los cmdlets de la primera versión de Windows PowerShell no se pueden utilizar con equipos remotos. Vamos a mostrar cómo se puede superar esta limitación al administrar registros de eventos utilizando la clase System.Diagnostics.EventLog de .NET Framework directamente en Windows PowerShell.

Utilizar New-Object para el acceso a registros de eventos

La biblioteca de clases de .NET Framework contiene una clase denominada System.Diagnostics.EventLog que permite administrar registros de eventos. Puede crear una nueva instancia de una clase de .NET Framework usando el cmdlet New-Object con el parámetro TypeName. Por ejemplo, el siguiente comando crea una referencia de registro de eventos:

PS> New-Object -TypeName System.Diagnostics.EventLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

Aunque el comando ha creado una instancia de la clase EventLog, la instancia no contiene datos. Esto es debido a que no hemos especificado un registro de eventos concreto. ¿Cómo podemos obtener un registro de eventos real?

Utilizar constructores con New-Object

Para hacer referencia a un registro de eventos determinado, es necesario especificar el nombre del registro. New-Object tiene un parámetro ArgumentList. los argumentos que se pasan como valores a este parámetro se usan en un método especial de inicio del objeto. Este método recibe el nombre de constructor porque se usa para construir el objeto. Por ejemplo, para obtener una referencia al registro de aplicación, debe especificar la cadena 'Application' como argumento:

PS> New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

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

Puesto que la mayoría de las clases principales de .NET Framework están incluidas en el espacio de nombres System, Windows PowerShell intentará buscar automáticamente en este espacio de nombres las clases especificadas si no encuentra el nombre de tipo especificado. Esto significa que puede especificar Diagnostics.EventLog en lugar de System.Diagnostics.EventLog.

Almacenar objetos en variables

Quizá desee almacenar una referencia a un objeto para poder utilizarlo en el shell actual. Aunque Windows PowerShell permite realizar muchas tareas con canalizaciones, lo que reduce la necesidad de usar variables, a veces almacenar las referencias a objetos en variables permite manipular más fácilmente dichos objetos.

Windows PowerShell permite crear variables que son básicamente objetos con nombre. El resultado de cualquier comando válido de Windows PowerShell se puede almacenar en una variable. Los nombres de variables siempre comienzan por $. Si desea almacenar la referencia al registro de aplicación en una variable llamada $AppLog, escriba el nombre de la variable seguida de un signo de igual y, a continuación, escriba el comando que se utiliza para crear el objeto del registro de aplicación:

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

Si escribe a continuación $AppLog, podrá ver que contiene el registro de aplicación:

PS> $AppLog

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

Acceso a un registro de eventos remoto con New-Object

Los comandos utilizados en la sección anterior van dirigidos al equipo local; el cmdlet Get-EventLog sirve para esta tarea. Para tener acceso al registro de aplicación de un equipo remoto, debe proporcionar el nombre del registro y el nombre del equipo (o dirección IP) como argumentos:

PS> $RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application,192.168.1.81
PS> $RemoteAppLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder            262 Application

Ahora que tenemos una referencia a un registro de eventos almacenado en la variable $RemoteAppLog, ¿qué tareas podemos realizar con él?

Borrar un registro de eventos con métodos de objetos

Los objetos suelen tener métodos que se pueden llamar para realizar tareas. Puede utilizar Get-Member para mostrar los métodos asociados a un objeto. El siguiente comando y el resultado seleccionado muestran algunos de los métodos de la clase EventLog:

PS> $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...

El método Clear() permite borrar el contenido del registro de eventos. Al llamar a un método, debe especificar siempre el nombre del método entre paréntesis, aunque el método no requiera argumentos. Esto permite a Windows PowerShell distinguir entre el método y una posible propiedad con el mismo nombre. Para llamar al método Clear, escriba lo siguiente:

PS> $RemoteAppLog.Clear()

Escriba lo siguiente para mostrar el registro. Observe que se ha borrado el contenido del registro de eventos y ahora contiene 0 entradas en lugar de 262:

PS> $RemoteAppLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder              0 Application

Crear objetos COM con New-Object

Puede utilizar New-Object para trabajar con componentes del Modelo de objetos componentes (COM). Estos componentes abarcan desde las diversas bibliotecas que se incluyen con Windows Script Host (WSH) hasta aplicaciones ActiveX, como Internet Explorer, instaladas en la mayoría de los sistemas.

New-Object usa contenedores RCW (Runtime Callable Wrapper) de .NET Framework para crear objetos COM, por lo que tiene las mismas limitaciones que .NET Framework cuando se llama a objetos COM. Para crear un objeto COM, debe especificar el parámetro ComObject con el identificador de programación o ProgID de la clase COM que desee utilizar. Una descripción completa de las limitaciones de uso de COM y de cómo determinar los ProgID que están disponibles en un sistema se sale del ámbito de este manual del usuario; no obstante, se puede decir que la mayoría de los objetos conocidos de entornos como WSH pueden usarse en Windows PowerShell.

Puede crear los objetos de WSH especificando estos ProgID: WScript.Shell, WScript.Network, Scripting.Dictionary y Scripting.FileSystemObject. Los siguientes comandos crean estos objetos:

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

Aunque la mayoría de las funciones de estas clases están disponibles de otras maneras en Windows PowerShell, algunas tareas, como la creación de accesos directos, son más fáciles con clases de WSH.

Crear accesos directos de escritorio con WScript.Shell

Una tarea que se puede realizar fácilmente con un objeto COM es crear un acceso directo. Supongamos que desea crear un acceso directo en el escritorio que vincule a la carpeta principal de Windows PowerShell. Primero debe crear una referencia a WScript.Shell y almacenarla en una variable denominada $WshShell:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member se puede usar con objetos COM, por lo que se pueden explorar los miembros del objeto escribiendo lo siguiente:

PS> $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 tiene un parámetro InputObject opcional que se puede utilizar en lugar de la canalización para proporcionar la entrada a Get-Member. Puede obtener el mismo resultado utilizando en su lugar el comando Get-Member -InputObject $WshShell. Si usa InputObject, tratará su argumento como un único elemento. Por tanto, si una variable contiene varios objetos, Get-Member los tratará como una matriz de objetos. Por ejemplo:

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

El método WScript.Shell CreateShortcut acepta un único argumento, la ruta de acceso al archivo de acceso directo que se va a crear. Podríamos escribir la ruta completa al escritorio, pero hay una manera más fácil de hacerlo. El escritorio se suele representar mediante una carpeta llamada Escritorio, incluida en la carpeta principal del usuario actual. Windows PowerShell tiene una variable $Home que contiene la ruta de acceso a esta carpeta. Podemos especificar la ruta de acceso a la carpeta principal mediante esta variable y, a continuación, agregar el nombre de la carpeta Escritorio y el nombre del acceso directo que se va crear de la siguiente manera:

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

Si especifica algo parecido al nombre de una variable entre comillas dobles, Windows PowerShell intentará reemplazar un valor que coincida. Si lo especifica entre comillas simples, Windows PowerShell no intentará reemplazar el valor de la variable. Por ejemplo, pruebe a escribir los siguientes comandos:

PS> "$Home\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
PS> '$Home\Desktop\PSHome.lnk'
$Home\Desktop\PSHome.lnk

Ahora tenemos una variable denominada $lnk que contiene una nueva referencia de acceso directo. Para ver sus miembros, puede canalizarla a Get-Member. El resultado siguiente muestra los miembros que debemos utilizar para terminar de crear el acceso directo:

PS> $lnk | Get-Member

TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}

Name MemberType Definition

---- ---------- ----------

...

Save Method void Save ()

...

TargetPath Property string TargetPath () {get} {set}

...

Es necesario especificar TargetPath, que es la carpeta de aplicación de Windows PowerShell y, a continuación, guardar el acceso directo $lnk llamando al método Save. La ruta de acceso a la carpeta de aplicación de Windows PowerShell se almacena en la variable $PSHome, por lo que para hacerlo podemos escribir:

$lnk.TargetPath = $PSHome

$lnk.Save()

Usar Internet Explorer desde Windows PowerShell

Muchas aplicaciones (incluida la familia de aplicaciones Microsoft Office e Internet Explorer) se pueden automatizar mediante COM. Internet Explorer ilustra algunas de las técnicas para trabajar con aplicaciones basadas en COM y los problemas que suelen surgir.

Para crear una instancia de Internet Explorer, debe especificar su ProgID, InternetExplorer.Application:

$ie = New-Object -ComObject InternetExplorer.Application

Este comando inicia Internet Explorer, pero no lo muestra. Si escribe Get-Process, podrá observar que se está ejecutando un proceso denominado iexplore. De hecho, si cierra Windows PowerShell, el proceso seguirá ejecutándose. Deberá reiniciar el equipo o utilizar una herramienta como el Administrador de tareas para finalizar el proceso iexplore.

Nota:

Los objetos COM que se inician como procesos independientes, denominados habitualmente ejecutables ActiveX, pueden mostrar o no una ventana de interfaz de usuario cuando se inician. Si crean una ventana pero no la muestran, como Internet Explorer, el foco se desplaza generalmente al escritorio de Windows y será necesario que haga visible la ventana para poder interactuar con ella.

Si escribe $ie | Get-Member, puede ver las propiedades y los métodos para Internet Explorer. Para que se muestre la ventana de Internet Explorer, establezca la propiedad Visible en $true; para ello, escriba:

$ie.Visible = $true

Después puede navegar a una dirección web específica usando el método Navigate:

$ie.Navigate("http://www.microsoft.com/technet/scriptcenter/default.mspx")

Otros miembros del modelo de objetos de Internet Explorer permiten recuperar contenido de texto de la página web. El comando siguiente muestra el texto HTML de la página web actual:

$ie.Document.Body.InnerText

Para cerrar Internet Explorer desde PowerShell, llame al método Quit() correspondiente:

$ie.Quit()

Esto hará que se cierre. La variable $ie ya no contiene una referencia válida, aunque sigue pareciendo un objeto COM. Si intenta utilizarla, aparecerá un error de automatización:

PS> $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 <<<<

Puede quitar la referencia que queda con un comando como $ie = $null, o quitar totalmente la variable mediante el comando:

Remove-Variable ie
Nota:

No hay un estándar común en lo que respecta a que los ejecutables ActiveX se cierren o sigan ejecutándose cuando se quita una referencia a uno de ellos. Según sean las circunstancias (por ejemplo, si la aplicación está visible, si hay abierto un documento modificado en la aplicación e incluso si se está ejecutando Windows PowerShell), la aplicación puede cerrarse o no. Por este motivo, debe comprobar el comportamiento de finalización de cada ejecutable ActiveX que desee utilizar en Windows PowerShell.

Obtener advertencias acerca de objetos COM encapsulados en .NET Framework

En algunos casos, un objeto COM puede tener asociado un contenedor RCW (Runtime Callable Wrapper) de .NET Framework. Este contenedor se puede utilizar en New-Object. Dado que el contenedor RCW y el objeto COM normal pueden tener comportamientos diferentes, New-Object tiene un parámetro Strict que avisa del acceso al contenedor. Si especifica el parámetro Strict y, a continuación, crea un objeto COM que usa un contenedor RCW, aparecerá un mensaje de advertencia:

PS> $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 inte
rop assembly. If this type exposes different members than the IDispatch members
, scripts written to work with this object might not work if the primary intero
p assembly is not installed.
At line:1 char:17
+ $xl = New-Object  <<<< -ComObject Excel.Application -Strict

Aunque se crea el objeto, se le avisará de que no es un objeto COM estándar.




Tabla de contenido