Création d’objets .NET et COM

Cet exemple s’exécute uniquement sur les plateformes Windows.

Il existe des composants logiciels avec des interfaces COM et .NET Framework, qui vous permettent d’effectuer de nombreuses tâches d’administration système. PowerShell permet d’utiliser ces composants. Vous n’êtes donc pas limité aux tâches exécutables à l’aide d’applets de commande. La plupart des applets de commande dans la version initiale de PowerShell ne fonctionnent pas sur des ordinateurs distants. Nous allons expliquer comment contourner cette limitation lors de la gestion des journaux des événements à l’aide de la classe .NET Framework System.Diagnostics.EventLog directement à partir de PowerShell.

Utilisation de l’applet de commande New-Object pour l’accès au journal des événements

La bibliothèque de classes .NET Framework inclut une classe nommée System.Diagnostics.EventLog qui permet de gérer les journaux des événements. Vous pouvez créer une nouvelle instance d’une classe .NET Framework en utilisant l’applet de commande New-Object avec le paramètre TypeName. Par exemple, la commande suivante crée une référence de journal des événements :

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

Même si la commande a créé une instance de la classe EventLog, l’instance n’inclut pas de données. Cela est dû au fait que nous n’avons pas spécifié de journal des événements spécifique. Comment obtenir un journal des événements réel ?

Utilisation de constructeurs avec l’applet de commande New-Object

Pour faire référence à un journal des événements spécifique, vous devez spécifier son nom. L’applet de commande New-Object a un paramètre ArgumentList. Les arguments que vous passez en tant que valeurs pour ce paramètre sont utilisés par une méthode spéciale de démarrage de l’objet. La méthode est appelée constructeur, car elle est utilisée pour construire l’objet. Par exemple, pour obtenir une référence au journal des applications, vous spécifiez la chaîne « Application » en tant qu’argument :

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

Notes

Étant donné que la plupart des classes de base de .NET Framework sont contenues dans l’espace de noms système, PowerShell tente automatiquement de trouver les classes que vous spécifiez dans l’espace de noms système s’il ne trouve pas de correspondance pour le nom de type que vous spécifiez. Cela signifie que vous pouvez spécifier Diagnostics.EventLog au lieu de System.Diagnostics.EventLog.

Stockage d’objets dans des variables

Si vous souhaitez stocker une référence à un objet, vous pouvez l’utiliser dans l’interpréteur de commandes en cours. Bien que PowerShell permette d’effectuer de nombreuses tâches avec des pipelines, en réduisant le besoin de variables, parfois, des références de stockage à des objets dans des variables facilite la manipulation de ces objets.

La sortie d’une commande PowerShell valide peut être stockée dans une variable. Les noms de variables commencent toujours par $. Si vous souhaitez stocker la référence de journal des applications dans une variable nommée $AppLog, tapez le nom de la variable, suivi d’un signe égal, puis tapez la commande utilisée pour créer l’objet journal des applications :

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

Si vous tapez $AppLog, vous pouvez voir qu’il contient le journal des applications :

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

Accès à un journal des événements à distance avec New-Object

Les commandes utilisées dans la section précédente ciblent l’ordinateur local. L’applet de commande Get-EventLog peut faire cela. Pour accéder au journal des applications sur un ordinateur distant, vous devez fournir le nom du journal et un nom d’ordinateur (ou une adresse IP) en tant qu’arguments.

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

Maintenant que nous avons une référence à un journal des événements stocké dans la variable $RemoteAppLog, quelles tâches pouvons-nous effectuer sur celui-ci ?

Effacement d’un journal des événements avec des méthodes d’objet

Les objets ont souvent des méthodes associées qui peuvent être appelées pour effectuer des tâches. L’applet de commande Get-Member permet d’afficher les méthodes associées à un objet. La commande suivante et la sortie sélectionnée affichent certaines des méthodes de la 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...

La méthode Clear() permet d’effacer le journal des événements. Lors de l’appel d’une méthode, vous devez toujours faire suivre le nom de la méthode par des parenthèses, même si la méthode ne requiert pas d’argument. Cela permet à PowerShell de faire la distinction entre la méthode et une propriété éventuelle du même nom. Tapez ce qui suit pour appeler la méthode clair :

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

Notez que le journal des événements a été effacé et contient désormais 0 entrée au lieu de 262 :

Création d’objets COM avec New-Object

L’applet de commande New-Object permet d’utiliser des composants COM (Component Object Model). Les composants vont des différentes bibliothèques incluses dans l’environnement d’exécution de scripts WSH (Windows Script Host) aux applications ActiveX telles qu’Internet Explorer qui sont installées sur la plupart des systèmes.

L’applet de commande New-Object utilise des wrappers RCW (Runtime-Callable Wrappers) .NET Framework pour créer des objets COM. Elle est donc sujette aux mêmes limitations que .NET Framework lors de l’appel d’objets COM. Pour créer un objet COM, vous devez spécifier le paramètre ComObject avec l’identificateur programmatique, ou ProgId, de la classe COM que vous souhaitez utiliser. Une description complète des limitations de l’utilisation de COM et de la détermination des ProgID disponibles sur un système dépasserait la portée de ce guide, mais la plupart des objets bien connus d’environnements tels que WSH peuvent être utilisés dans PowerShell.

Vous pouvez créer les objets WSH en spécifiant les ProgID suivants : WScript.Shell, WScript.Network, Scripting.Dictionary, et Scripting.FileSystemObject. Les commandes suivantes créent ces objets :

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

Si l’essentiel de la fonctionnalité de ces classes est rendu disponible par d’autres moyens dans Windows PowerShell, quelques tâches telles que la création de raccourci sont encore plus faciles à effectuer à l’aide des classes WSH.

Création d’un raccourci sur le Bureau avec WScript.Shell

Une tâche exécutable rapidement avec un objet COM est la création d’un raccourci. Supposons que vous souhaitez créer un raccourci sur votre bureau, qui établit un lien vers le dossier de base de PowerShell. Vous devez commencer par créer une référence à WScript.Shell, que nous allons stocker dans une variable nommée $WshShell :

$WshShell = New-Object -ComObject WScript.Shell

L’applet de commande Get-Member fonctionnant avec des objets COM, vous pouvez explorer les membres de l’objet en tapant ce qui suit :

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

L’applet de commande Get-Member dispose d’un paramètre facultatif, InputObject, que vous pouvez utiliser à la place d’un piping pour fournir l’entrée à Get-Member. Vous obtiendriez la même sortie que celle indiquée ci-dessus si vous utilisez à la place la commande Get-Member -InputObject $WshShell. Si vous utilisez InputObject, l’argument est traité comme un seul élément. Cela signifie que, si vous disposez de plusieurs objets dans une variable, l’applet de commande Get-Member les traite comme un tableau d’objets. Par exemple :

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

La méthode WScript.Shell CreateShortcut accepte un seul argument, le chemin d’accès au fichier de raccourci à créer. Nous pourrions taper le chemin d’accès complet au bureau, mais il existe un moyen plus simple. Le bureau est généralement représenté par un dossier nommé Bureau à l’intérieur du dossier de base de l’utilisateur actuel. Windows PowerShell dispose d’une variable $HOME qui contient le chemin d’accès à ce dossier. Nous pouvons spécifier le chemin d’accès au dossier de base à l’aide de cette variable, puis ajouter le nom du dossier Bureau et le nom du raccourci à créer en tapant ce qui suit :

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

Lorsque vous utilisez quelque chose ressemblant à un nom de variable entre guillemets doubles, PowerShell tente de remplacer cet élément par une valeur correspondante. Si vous utilisez des guillemets simples, PowerShell n’essaie pas de remplacer la variable par une valeur. Par exemple, essayez de taper les commandes suivantes :

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

Nous avons désormais une variable nommée $lnk qui contient une nouvelle référence au raccourci. Si vous souhaitez voir ses membres, vous pouvez la canaliser vers l’applet de commande Get-Member. La sortie ci-dessous montre les membres que nous devons utiliser pour achever la création de notre raccourci :

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

Nous devons spécifier TargetPath, qui est le dossier d’application pour PowerShell, puis enregistrer le raccourci en appelant la méthode Save. Le chemin d’accès au dossier d’application de PowerShell étant stocké dans la variable $PSHome, nous pouvons faire cela en tapant ce qui suit :

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

Utilisation d’Internet Explorer à partir de PowerShell

De nombreuses applications, dont la famille d’applications Microsoft Office et Internet Explorer, peuvent être automatisées à l’aide de COM. Les exemples suivants illustrent certains problèmes et techniques classiques impliqués dans l’utilisation d’applications basées sur COM.

Vous créez une instance Internet Explorer en spécifiant le ProgId d’Internet Explorer, InternetExplorer.Application :

$ie = New-Object -ComObject InternetExplorer.Application

Cette commande démarre Internet Explorer, mais ne le rend pas visible. Si vous tapez Get-Process, vous pouvez voir qu’un processus nommé iexplore est en cours d’exécution. En fait, si vous quittez PowerShell, le processus continue à s’exécuter. Pour arrêter le processus iexplore, vous devez redémarrer l’ordinateur ou utiliser un outil tel que le Gestionnaire des tâches.

Notes

Les objets COM qui démarrent en tant que processus séparés, généralement appelés exécutables ActiveX, peuvent ou non afficher une fenêtre d’interface utilisateur au démarrage. S’ils créent une fenêtre mais ne la rendent pas visible, comme Internet Explorer, le focus passe généralement au bureau Windows. Vous devez rendre la fenêtre visible pour interagir avec elle.

Pour afficher les propriétés et méthodes pour Internet Explorer, tapez $ie | Get-Member. Pour afficher la fenêtre Internet Explorer, définissez la propriété Visible sur $true en tapant ce qui suit :

$ie.Visible = $true

Vous pouvez ensuite accéder à une adresse web spécifique à l’aide de la méthode Navigate :

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

En utilisant d’autres membres du modèle d’objet Internet Explorer, vous pouvez récupérer le contenu de texte de la page web. La commande suivante affiche le texte HTML dans le corps de la page web active :

$ie.Document.Body.InnerText

Pour fermer Internet Explorer à partir de PowerShell, appelez sa méthode Quit() :

$ie.Quit()

La variable $ie ne contient plus de référence valide, même si elle apparaît toujours comme un objet COM. Si vous tentez de l’utiliser, vous obtenez une erreur d’automatisation PowerShell :

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

Vous pouvez soit supprimer la référence restante avec une commande telle que $ie = $null, ou supprimer complètement la variable en tapant ce qui suit :

Remove-Variable ie

Notes

Il n’existe aucune norme commune déterminant si les exécutables ActiveX s’arrêtent ou continuent à s’exécuter lorsque vous supprimez une référence à ceux-ci. En fonction des circonstances, selon que l’application est visible, qu’un document modifié est en cours d’exécution dans celle-ci, et même que PowerShell est toujours en cours d’exécution, l’application peut se fermer ou non. C’est pourquoi, vous devez tester le comportement d’arrêt de chaque exécutable ActiveX à utiliser dans PowerShell.

Obtention d’alertes sur les objets COM encapsulés .NET Framework

Dans certains cas, un objet COM peut avoir un wrapper RCW (Runtime-Callable Wrapper) .NET Framework associé, qui sera utilisé par l’applet de commande New-Object. Étant donné que le comportement du wrapper RCW peut différer du comportement de l’objet COM normal, l’applet de commande New-Object dispose d’un paramètre Strict pour vous avertir de l’accès au wrapper RCW. Si vous spécifiez le paramètre Strict, puis créez un objet COM qui utilise un wrapper RCW, vous recevez un message d’avertissement :

$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

Bien que l’objet soit toujours créé, vous êtes averti qu’il ne s’agit pas d’un objet COM standard.