Creazione di oggetti .NET e COM

Questo esempio viene eseguito solo su piattaforme Windows.

Sono disponibili componenti software con interfacce .NET Framework e COM che consentono di eseguire molte attività di amministrazione di sistema. PowerShell consente di usare questi componenti, pertanto non è possibile limitare le attività che è possibile eseguire usando i cmdlet. Molti dei cmdlet nella versione iniziale di PowerShell non funzionano nei computer remoti. Verrà illustrato come aggirare questa limitazione quando si gestiscono i log eventi usando la classe System.Diagnostics.EventLog di .NET Framework direttamente da PowerShell.

Uso di New-Object per l'accesso al registro eventi

La libreria di classi .NET Framework include una classe denominata System.Diagnostics.EventLog che può essere usata per gestire i registri eventi. È possibile creare una nuova istanza di una classe .NET Framework usando il New-Object cmdlet con il parametro TypeName . Il comando seguente, ad esempio, crea un riferimento a un registro eventi:

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

Anche se il comando ha creato un'istanza della classe EventLog , l'istanza non include dati. questo perché non è stato specificato un registro eventi specifico. Come ottenere un registro eventi reale?

Uso di costruttori con New-Object

Per fare riferimento a un registro eventi particolare, è necessario specificare il nome del registro. New-Object ha un parametro ArgumentList . Gli argomenti passati come valori per questo parametro vengono usati da un metodo di avvio speciale dell'oggetto. Il metodo viene chiamato costruttore perché viene usato per costruire l'oggetto . Ad esempio, per ottenere un riferimento al registro applicazioni, specificare la stringa 'Application' come argomento:

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

Nota

Poiché la maggior parte delle classi .NET è contenuta nello spazio dei nomi System , PowerShell tenta automaticamente di trovare le classi specificate nello spazio dei nomi System se non riesce a trovare una corrispondenza per il nometipo specificato. Ciò significa che è possibile specificare Diagnostics.EventLog anziché System.Diagnostics.EventLog.

Archiviazione di oggetti nelle variabili

Può essere utile archiviare un riferimento a un oggetto, in modo da poterlo usare nella shell corrente. Anche se PowerShell consente di eseguire molte operazioni con le pipeline, riducendo la necessità di variabili, talvolta archiviando riferimenti agli oggetti nelle variabili, è più conveniente modificare tali oggetti.

L'output di qualsiasi comando di PowerShell valido può essere archiviato in una variabile. I nomi delle variabili iniziano sempre con $. Se si vuole archiviare il riferimento al log applicazioni in una variabile denominata $AppLog, digitare il nome della variabile, seguito da un segno di uguale e quindi digitare il comando usato per creare l'oggetto Registro applicazioni:

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

Se si digita $AppLog, si noterà che contiene il registro applicazioni:

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

Accesso a un registro eventi remoto con New-Object

I comandi usati nella sezione precedente sono destinati al computer locale; il Get-EventLog cmdlet può eseguire questa operazione. Per accedere al registro applicazioni in un computer remoto, è necessario specificare sia il nome del registro che il nome (o indirizzo IP) di un computer come argomenti.

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

Ora che è disponibile un riferimento a un registro eventi archiviato nella $RemoteAppLog variabile, quali attività è possibile eseguire su di esso?

Cancellazione di un registro eventi con metodi oggetto

Gli oggetti spesso includono metodi che possono essere chiamati per eseguire attività. È possibile utilizzare Get-Member per visualizzare i metodi associati a un oggetto . Il comando seguente e l'output selezionato mostrano alcuni metodi della 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...

Il Clear() metodo può essere usato per cancellare il registro eventi. Quando si chiama un metodo, è necessario seguire sempre il nome del metodo tra parentesi, anche se il metodo non richiede argomenti. Ciò consente a PowerShell di distinguere tra il metodo e una proprietà potenziale con lo stesso nome. Digitare il comando seguente per chiamare il metodo Clear:

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

Si noti che il registro eventi è stato cancellato e ora contiene 0 voci anziché 262.

Creazione di oggetti COM con New-Object

È possibile usare New-Object per lavorare con i componenti COM (Component Object Model). I componenti includono varie librerie incluse in Windows Script Host (WSH) e applicazioni ActiveX come Internet Explorer installate nella maggior parte dei sistemi.

New-Object usa .NET Framework Runtime-Callable Wrapper per creare oggetti COM, pertanto presenta le stesse limitazioni che .NET Framework esegue quando si chiamano oggetti COM. Per creare un oggetto COM, è necessario specificare il parametro ComObject con l'identificatore programmatico o ProgId della classe COM da usare. Una descrizione completa delle limitazioni dell'uso com e la determinazione dei ProgId disponibili in un sistema esula dall'ambito della guida dell'utente, ma gli oggetti più noti di ambienti come WSH possono essere usati in PowerShell.

È possibile creare gli oggetti WSH specificando questi ProgId: WScript.Shell, WScript.Network, Scripting.Dictionary e Scripting.FileSystemObject. I comandi seguenti creano questi oggetti:

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

Anche se la maggior parte delle funzionalità di queste classi viene resa disponibile in altri modi in Windows PowerShell, alcune attività, come la creazione di collegamenti, sono ancora più semplici da eseguire usando le classi WSH.

Creazione di un collegamento desktop con WScript.Shell

Un'attività che può essere eseguita rapidamente con un oggetto COM è la creazione di un collegamento. Si supponga di voler creare un collegamento sul desktop che si collega alla home cartella per PowerShell. È prima necessario creare un riferimento a WScript.Shell, che verrà archiviato in una variabile denominata $WshShell:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member funziona con gli oggetti COM, in modo da poter esplorare i membri dell'oggetto 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-Memberha un parametro InputObject facoltativo che è possibile usare invece del piping per fornire l'input a Get-Member. Si potrebbe ottenere lo stesso output di cui sopra usando il comando Get-Member -InputObject $WshShell. Se si usa InputObject, il relativo argomento viene gestito come singolo elemento. Ciò significa che se sono presenti diversi oggetti in una variabile, Get-Member li considera come una matrice di oggetti. Ad esempio:

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

Il metodo WScript.Shell CreateShortcut accetta un solo argomento, ovvero il percorso del file di collegamento da creare. È possibile digitare il percorso completo per il desktop, ma esiste un modo più semplice. Il desktop in genere è rappresentato da una cartella denominata Desktop all'interno della home directory dell'utente corrente. Windows PowerShell include una variabile $HOME che contiene il percorso di questa cartella. È possibile specificare il percorso per la home directory usando questa variabile e quindi aggiungere il nome della cartella Desktop e il nome per il collegamento da creare digitando:

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

Quando si usa un elemento simile a un nome di variabile tra virgolette doppie, PowerShell tenta di sostituire un valore corrispondente. Se si usano virgolette singole, PowerShell non tenta di sostituire il valore della variabile. Ad esempio, provare a digitare i comandi seguenti:

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

Ora è disponibile una variabile denominata $lnk che contiene un nuovo riferimento di collegamento. Se si desidera visualizzare i relativi membri, è possibile inviarlo tramite pipe a Get-Member. L'output seguente mostra i membri che è necessario usare per completare la creazione del collegamento:

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

È necessario specificare TargetPath, ovvero la cartella dell'applicazione per PowerShell, quindi salvare il collegamento chiamando il Save metodo . Il percorso della cartella dell'applicazione PowerShell viene archiviato nella variabile $PSHome, quindi è possibile eseguire questa operazione digitando:

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

Uso di Internet Explorer da PowerShell

Molte applicazioni, inclusa la famiglia di applicazioni di Microsoft Office e Internet Explorer, possono essere automatizzate tramite COM. Gli esempi seguenti illustrano alcune delle tecniche e dei problemi tipici relativi all'uso di applicazioni basate su COM.

Per creare un'istanza di Internet Explorer, è necessario specificare il ProgId di Internet Explorer, ovvero InternetExplorer.Application:

$ie = New-Object -ComObject InternetExplorer.Application

Questo comando avvia Internet Explorer, ma non lo rende visibile. Se si digita Get-Process, si noterà che un processo denominato iexplore è in esecuzione. Infatti, se si esce da PowerShell, il processo continuerà a essere eseguito. Per terminare il iexplore processo, è necessario riavviare il computer o usare uno strumento come Gestione attività.

Nota

Gli oggetti COM avviati come processo separato, comunemente noti come eseguibili ActiveX, potrebbero visualizzare o meno una finestra dell'interfaccia utente all'avvio. Se creano una finestra ma non lo rendono visibile, ad esempio Internet Explorer, lo stato attivo si sposta in genere sul desktop di Windows. È necessario rendere visibile la finestra per interagire con essa.

Digitando $ie | Get-Member, è possibile visualizzare proprietà e metodi per Internet Explorer. Per visualizzare la finestra di Internet Explorer, impostare la proprietà Visible su $true digitando:

$ie.Visible = $true

È quindi possibile passare a un indirizzo Web specifico usando il Navigate metodo :

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

Usando altri membri del modello a oggetti di Internet Explorer, è possibile recuperare il contenuto di testo dalla pagina Web. Il comando seguente visualizza il testo HTML nel corpo della pagina Web corrente:

$ie.Document.Body.InnerText

Per chiudere Internet Explorer da PowerShell, chiamare il Quit() relativo metodo:

$ie.Quit()

La $ie variabile non contiene più un riferimento valido anche se sembra ancora essere un oggetto COM. Se si tenta di usarlo, PowerShell restituisce un errore di automazione:

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

È possibile rimuovere il riferimento rimanente con un comando come $ie = $nullo rimuovere completamente la variabile digitando:

Remove-Variable ie

Nota

Non esiste uno standard comune che stabilisce se gli eseguibili ActiveX devono essere interrotti o continuare l'esecuzione quando si rimuove un riferimento a uno di essi. A seconda delle circostanze, ad esempio se l'applicazione è visibile, se un documento modificato è in esecuzione e anche se PowerShell è ancora in esecuzione, l'applicazione potrebbe o meno uscire. Per questo motivo, è consigliabile testare il comportamento di terminazione per ogni eseguibile ActiveX da usare in PowerShell.

Visualizzazione di avvisi sugli oggetti COM con wrapping di .NET Framework

In alcuni casi, un oggetto COM potrebbe avere un wrapper runtime callable (RCW) di .NET Framework associato usato da New-Object. Poiché il comportamento dell'RCW può essere diverso dal comportamento dell'oggetto COM normale, New-Object ha un parametro Strict per avvisare l'utente dell'accesso RCW. Se si specifica il parametro Strict e poi si crea un oggetto COM che usa un RCW, viene visualizzato un messaggio di avviso:

$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

Anche se l'oggetto viene ancora creato, viene visualizzato un avviso che non è un oggetto COM standard.