Dela via


Skapa .NET- och COM-objekt

Det här exemplet körs bara på Windows-plattformar.

Det finns programvarukomponenter med .NET Framework- och COM-gränssnitt som gör att du kan utföra många systemadministrationsuppgifter. Med PowerShell kan du använda dessa komponenter, så du är inte begränsad till de uppgifter som kan utföras med hjälp av cmdletar. Många av cmdletarna i den första versionen av PowerShell fungerar inte mot fjärrdatorer. Vi visar hur du kommer runt den här begränsningen när du hanterar händelseloggar med hjälp av klassen .NET Framework System.Diagnostics.EventLog direkt från PowerShell.

Använda New-Object för åtkomst till händelselogg

Klassbiblioteket för .NET Framework innehåller en klass med namnet System.Diagnostics.EventLog som kan användas för att hantera händelseloggar. Du kan skapa en ny instans av en .NET Framework-klass med hjälp av cmdleten New-Object med parametern TypeName . Följande kommando skapar till exempel en händelseloggreferens:

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

Även om kommandot har skapat en instans av klassen EventLog innehåller inte instansen några data. det beror på att vi inte angav någon viss händelselogg. Hur får du en riktig händelselogg?

Använda konstruktorer med New-Object

Om du vill referera till en specifik händelselogg måste du ange namnet på loggen. New-Object har en ArgumentList-parameter . Argumenten som du skickar som värden till den här parametern används av en särskild startmetod för objektet. Metoden kallas konstruktor eftersom den används för att konstruera objektet. Om du till exempel vill hämta en referens till programloggen anger du strängen "Application" som ett argument:

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

Kommentar

Eftersom de flesta .NET-klasserna finns i systemnamnområdet försöker PowerShell automatiskt hitta klasser som du anger i systemnamnområdet om det inte går att hitta en matchning för det typnamn som du anger. Det innebär att du kan ange Diagnostics.EventLog i stället för System.Diagnostics.EventLog.

Lagra objekt i variabler

Du kanske vill lagra en referens till ett objekt, så att du kan använda den i det aktuella gränssnittet. Även om PowerShell låter dig utföra mycket arbete med pipelines, vilket minskar behovet av variabler, gör det ibland enklare att lagra referenser till objekt i variabler när du lagrar referenser till objekt i variabler.

Utdata från ett giltigt PowerShell-kommando kan lagras i en variabel. Variabelnamn börjar alltid med $. Om du vill lagra programloggreferensen i en variabel med namnet $AppLogskriver du namnet på variabeln, följt av ett likhetstecken och skriver sedan kommandot som används för att skapa programloggobjektet:

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

Om du sedan skriver $AppLogkan du se att den innehåller programloggen:

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

Komma åt en fjärrhändelselogg med New-Object

Kommandona som används i föregående avsnitt riktar sig till den lokala datorn. cmdleten Get-EventLog kan göra det. För att få åtkomst till programloggen på en fjärrdator måste du ange både loggnamnet och ett datornamn (eller IP-adress) som argument.

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

Nu när vi har en referens till en händelselogg som lagras i variabeln $RemoteAppLog , vilka uppgifter kan vi utföra på den?

Rensa en händelselogg med objektmetoder

Objekt har ofta metoder som kan anropas för att utföra uppgifter. Du kan använda Get-Member för att visa de metoder som är associerade med ett objekt. Följande kommando och valda utdata visar några metoder för klassen 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...

Metoden Clear() kan användas för att rensa händelseloggen. När du anropar en metod måste du alltid följa metodnamnet efter parenteser, även om metoden inte kräver argument. På så sätt kan PowerShell skilja mellan metoden och en potentiell egenskap med samma namn. Ange följande för att anropa metoden Clear :

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

Observera att händelseloggen har rensats och nu har 0 poster i stället för 262.

Skapa COM-objekt med New-Object

Du kan använda New-Object för att arbeta med komponentobjektmodellkomponenter (COM). Komponenterna sträcker sig från de olika bibliotek som ingår i Windows Script Host (WSH) till ActiveX-program, till exempel Internet Explorer som är installerade på de flesta system.

New-Object använder .NET Framework Runtime-Callable Wrappers för att skapa COM-objekt, så det har samma begränsningar som .NET Framework gör när du anropar COM-objekt. Om du vill skapa ett COM-objekt måste du ange comobject-parametern med den programmatiska identifieraren eller ProgId för den COM-klass som du vill använda. En fullständig diskussion om begränsningarna för COM-användning och att avgöra vilka ProgId:er som är tillgängliga i ett system ligger utanför omfånget för den här användarhandboken, men de flesta välkända objekt från miljöer som WSH kan användas i PowerShell.

Du kan skapa WSH-objekten genom att ange dessa progids: WScript.Shell, WScript.Network, Scripting.Dictionary och Scripting.FileSystemObject. Följande kommandon skapar dessa objekt:

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

Även om de flesta av funktionerna i dessa klasser görs tillgängliga på andra sätt i Windows PowerShell, är några uppgifter som att skapa genvägar fortfarande enklare att göra med hjälp av WSH-klasserna.

Skapa en genväg till skrivbordet med WScript.Shell

En uppgift som kan utföras snabbt med ett COM-objekt är att skapa en genväg. Anta att du vill skapa en genväg på skrivbordet som länkar till startmappen för PowerShell. Du måste först skapa en referens till WScript.Shell, som vi lagrar i en variabel med namnet $WshShell:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member fungerar med COM-objekt så att du kan utforska medlemmarna i objektet genom att skriva:

$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 har en valfri InputObject-parameter som du kan använda i stället för att skicka indata till Get-Member. Du skulle få samma utdata som ovan om du i stället använde kommandot Get-Member -InputObject $WshShell. Om du använder InputObject behandlas argumentet som ett enda objekt. Det innebär att om du har flera objekt i en variabel behandlar Get-Member de dem som en matris med objekt. Till exempel:

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

Metoden WScript.Shell CreateShortcut accepterar ett enda argument, sökvägen till genvägsfilen som ska skapas. Vi kan skriva in den fullständiga sökvägen till skrivbordet, men det finns ett enklare sätt. Skrivbordet representeras normalt av en mapp med namnet Desktop i den aktuella användarens hemmapp. Windows PowerShell har en variabel $HOME som innehåller sökvägen till den här mappen. Vi kan ange sökvägen till hemmappen med hjälp av den här variabeln och sedan lägga till namnet på mappen Desktop och namnet på genvägen som ska skapas genom att skriva:

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

När du använder något som ser ut som ett variabelnamn inom dubbla citattecken försöker PowerShell ersätta ett matchande värde. Om du använder enkla citattecken försöker PowerShell inte ersätta variabelvärdet. Prova till exempel att skriva följande kommandon:

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

Nu har vi en variabel med namnet $lnk som innehåller en ny genvägsreferens. Om du vill se dess medlemmar kan du skicka den till Get-Member. Utdata nedan visar de medlemmar som vi behöver använda för att slutföra skapandet av genvägen:

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

Vi måste ange TargetPath, som är programmappen för PowerShell, och sedan spara genvägen genom att anropa Save metoden. Sökvägen till PowerShell-programmappen lagras i variabeln $PSHome, så vi kan göra detta genom att skriva:

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

Använda Internet Explorer från PowerShell

Många program, inklusive Microsoft Office-serien med program och Internet Explorer, kan automatiseras med hjälp av COM. Följande exempel illustrerar några av de typiska tekniker och problem som ingår i arbetet med COM-baserade program.

Du skapar en Internet Explorer-instans genom att ange Internet Explorer ProgId, InternetExplorer.Application:

$ie = New-Object -ComObject InternetExplorer.Application

Det här kommandot startar Internet Explorer, men gör det inte synligt. Om du skriver Get-Processkan du se att en process med namnet iexplore körs. Om du avslutar PowerShell fortsätter processen att köras. Du måste starta om datorn eller använda ett verktyg som Aktivitetshanteraren för att avsluta iexplore processen.

Kommentar

COM-objekt som startas som separata processer, som ofta kallas körbara ActiveX-objekt, kan eller kanske inte visar ett användargränssnittsfönster när de startas. Om de skapar ett fönster men inte gör det synligt, till exempel Internet Explorer, flyttas fokus vanligtvis till Windows-skrivbordet. Du måste göra fönstret synligt för att interagera med det.

Genom att $ie | Get-Memberskriva kan du visa egenskaper och metoder för Internet Explorer. Om du vill se Internet Explorer-fönstret anger du egenskapen Visible till genom att $true skriva:

$ie.Visible = $true

Du kan sedan navigera till en specifik webbadress med hjälp av Navigate metoden:

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

Med hjälp av andra medlemmar i Internet Explorer-objektmodellen går det att hämta textinnehåll från webbsidan. Följande kommando visar HTML-texten i brödtexten på den aktuella webbsidan:

$ie.Document.Body.InnerText

Om du vill stänga Internet Explorer inifrån PowerShell anropar du dess Quit() metod:

$ie.Quit()

Variabeln $ie innehåller inte längre en giltig referens trots att den fortfarande verkar vara ett COM-objekt. Om du försöker använda det returnerar PowerShell ett automatiseringsfel:

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

Du kan antingen ta bort den återstående referensen med ett kommando som $ie = $null, eller helt ta bort variabeln genom att skriva:

Remove-Variable ie

Kommentar

Det finns ingen vanlig standard för om ActiveX-körbara filer ska avslutas eller fortsätta att köras när du tar bort en referens till en. Beroende på omständigheter, till exempel om programmet är synligt, om ett redigerat dokument körs i det och även om PowerShell fortfarande körs, kan programmet avslutas eller inte. Därför bör du testa avslutningsbeteendet för varje Körbar ActiveX-fil som du vill använda i PowerShell.

Få varningar om .NET Framework-omslutna COM-objekt

I vissa fall kan ett COM-objekt ha en associerad .NET Framework Runtime-Callable Wrapper (RCW) som används av New-Object. Eftersom beteendet för RCW kan skilja sig från beteendet för det normala COM-objektet, New-Object har du en strikt parameter som varnar dig om RCW-åtkomst. Om du anger parametern Strict och sedan skapar ett COM-objekt som använder en RCW får du ett varningsmeddelande:

$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

Även om objektet fortfarande har skapats varnas du för att det inte är ett com-standardobjekt.