michi.wtr
Goto Top

Wie kann ich CIM-Class-Methoden aufrufen?

Hi zusammen,

ich schaue mir gerade WMI- und CIM-Klassen an. Dass das arbeiten mit CIM und WMI "pain in the ...." ist habe ich relativ schnell gemerkt face-smile. Um zu lernen möchte ich versuchen, die CIM-Methoden auszuführen, was mir leider nicht gelingt....
Hierfür wollte ich eine harmlose Methode aufrufen:
PS> Get-CimClass CIM_OperatingSystem | select -ExpandProperty cimclassmethods

Name     ReturnType Parameters Qualifiers
----     ---------- ---------- ----------
Reboot       UInt32 {}         {}
Shutdown     UInt32 {}         {}

Was mir als aller erstes auffällt, warum bekomme ich hierfür andere ausgaben?!?!:
PS> $os = Get-CimInstance CIM_OperatingSystem
PS> $os.CimClass


   NameSpace: root/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_OperatingSystem               {Reboot, Shutdown... {Caption, Description, InstallDate, Name...}


PS> $os.CimClass.CimClassMethods

Name                 ReturnType Parameters                            Qualifiers
----                 ---------- ----------                            ----------
Reboot                   UInt32 {}                                    {Implemented, MappingStrings, Override, Privileges...}
Shutdown                 UInt32 {}                                    {Implemented, MappingStrings, Override, Privileges...}
Win32Shutdown            UInt32 {Flags, Reserved}                     {Implemented, MappingStrings, Privileges, ValueMap}
Win32ShutdownTracker     UInt32 {Comment, Flags, ReasonCode, Timeout} {Implemented, MappingStrings, Privileges, ValueMap}
SetDateTime              UInt32 {LocalDateTime}                       {Implemented, Privileges, ValueMap}

So wie ich das sehe rufe ich noch immer dieselben CimClassMethods wie im 1. Codeblock auf, jedoch mit einem völlig anderen Ergebnis....


Wenn ich das ignoriere und versuche, wie auch immer die CIM-Methode auszuführen, scheitert es auf allen Wegen:
PS> $os = Get-CimInstance CIM_OperatingSystem
PS> $os.Reboot
PS> $os.Reboot()
Fehler beim Aufrufen der Methode, da [Microsoft.Management.Infrastructure.CimInstance] keine Methode mit dem Namen "Reboot" enthält.  
In Zeile:1 Zeichen:1
+ $os.Reboot()
+ ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Reboot:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

PS> $os = Get-CimClass CIM_OperatingSystem
PS> $os.reboot()
Fehler beim Aufrufen der Methode, da [Microsoft.Management.Infrastructure.CimClass] keine Methode mit dem Namen "Reboot" enthält.  
In Zeile:1 Zeichen:1
+ $os.reboot()
+ ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

PS> $os.CimClassMethods.Reboot
PS> $os.CimClassMethods.Reboot()
Fehler beim Aufrufen der Methode, da [Microsoft.Management.Infrastructure.Internal.Data.CimMethodDeclarationOfClass] keine Methode mit dem Namen "Reboot" enthält.  
In Zeile:1 Zeichen:1
+ $os.CimClassMethods.Reboot()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

PS> Invoke-CimMethod -ClassName CIM_OperatingSystem -MethodName Reboot
Invoke-CimMethod : Diese Methode ist in keiner Klasse implementiert.
In Zeile:1 Zeichen:1
+ Invoke-CimMethod -ClassName CIM_OperatingSystem -MethodName Reboot
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (root\cimv2:CIM_OperatingSystem:String) [Invoke-CimMethod], CimException
    + FullyQualifiedErrorId : HRESULT 0x80041055,Microsoft.Management.Infrastructure.CimCmdlets.InvokeCimMethodCommand

Was mache ich hier falsch? Mit den CIM Cmdlets scheint die Shell meine Methode Reboot nicht mehr zu kennen.
Mit WMI Cmdlets:
PS> $os = gwmi CIM_OperatingSystem
PS> $os.Reboot()
Ausnahme beim Aufrufen von "Reboot": "Recht wurde aufgehoben. "  
In Zeile:1 Zeichen:1
+ $os.Reboot()
+ ~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WMIMethodException

Vielen Dank schonmal im Voraus,
Micha

Content-Key: 7989715201

Url: https://administrator.de/contentid/7989715201

Printed on: April 27, 2024 at 14:04 o'clock

Mitglied: 7907292512
7907292512 Jul 29, 2023 updated at 10:33:31 (UTC)
Goto Top
Moin.
Wie kann ich CIM-Class-Methoden aufrufen?
Um CIM Methoden aufzurufen musst du das CMDLet Invoke-CIMMethod benutzen, den die Methoden selbst werden den CIM Objects per Default nicht hinzugefügt, unter anderem auch um Ressourcen beim Abruf zu sparen, deswegen sind CIM Abfragen auch meist schneller und den WMI Abfragen zu bevorzugen.
CIM Abfragen per Get-CimInstance kannst du auch per Pipe an Invoke-CimMethod übergeben um deren Methoden aufzurufen.

Zum Thema unterschiedliche Ausgaben:

Du gibst ja einmal die Klasse selbst aus und eine Instanz davon.
Es gibt Klassen und Klasseninstanzen. Klasseninstanzen können auch je nach Instanz zusätzliche Methoden bereitstellen die die Methoden der Klasse selbst ergänzen, und natürlich erben sie die Methoden ihrer Elternklasse.

Gruß siddius
Member: michi.wtr
michi.wtr Jul 29, 2023 at 10:41:34 (UTC)
Goto Top
Warum aber führt Invoke-CimMethod meine Methode weder bei Angabe des Klassennamens noch beim pipen der CIM-Klasse meine Methode aus?

PS> Get-CimClass CIM_OperatingSystem | Invoke-CimMethod -MethodName Reboot
Invoke-CimMethod : Diese Methode ist in keiner Klasse implementiert.
In Zeile:1 Zeichen:36
+ ... et-CimClass CIM_OperatingSystem | Invoke-CimMethod -MethodName Reboot
+                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (ROOT/cimv2:CIM_OperatingSystem:String) [Invoke-CimMethod], CimException
    + FullyQualifiedErrorId : HRESULT 0x80041055,Microsoft.Management.Infrastructure.CimCmdlets.InvokeCimMethodCommand

PS> Get-CimClass CIM_OperatingSystem | select CimClassMethods

CimClassMethods
---------------
{Reboot, Shutdown}

Gruß Micha
Mitglied: 7907292512
Solution 7907292512 Jul 29, 2023 updated at 10:57:17 (UTC)
Goto Top
Weil du keine Instanz der Klasse nimmst sondern die Klasse selbst (mit Get-CimClass statt Get-CimInstance)!
Du musst die Methode auf einer Instanz ausführen, die Klasse selbst ist nur das "Gerüst" für Instanzen. Wenn du mal objektorientierte Programmiersprachen lernst verstehst du das Prinzip besser. Dort kannst du auch nur Methoden einer Klasse aufrufen wenn du eine Instanz davon erzeugst oder die Klasse statische Member besitzt die sich ohne Instanz aufrufen lassen.
Get-CimInstance Win32_OperatingSystem | Invoke-CimMethod -MethodName Reboot
Member: michi.wtr
michi.wtr Jul 29, 2023 at 11:49:17 (UTC)
Goto Top
Super, nun hats endlich auch funktioniert face-smile. Nur noch kurz einige Fragen:

Ich finde das ganze aber sehr verwirrend. Gibt es irgendwo dazu eine gute Dokumentation? Ein Buch, ein Blog oder sonstiges?

Wenn ich dasselbe mit WMI-Objekten machen möchte erhalte ich folgendes Problem:
PS> (gwmi win32_operatingsystem).reboot()
Ausnahme beim Aufrufen von "Reboot": "Recht wurde aufgehoben. "  
In Zeile:1 Zeichen:1
+ (gwmi win32_operatingsystem).reboot()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WMIMethodException

Ich habe bereits im Internet gefunden, ich soll das ganze mit Invoke-WmiMethod aufrufen und den Switch-Parameter -EnableAllPrivileges aktivieren...
PS> gwmi win32_operatingsystem | gm -MemberType Method | ? Name -EQ Reboot


   TypeName: System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem

Name   MemberType Definition
----   ---------- ----------
Reboot Method     System.Management.ManagementBaseObject Reboot()

PS> Invoke-WmiMethod -EnableAllPrivileges -Class win32_operatingsystem -Name reboot
Invoke-WmiMethod : Die Parameter der Methode sind ungültig.
In Zeile:1 Zeichen:1
+ Invoke-WmiMethod -EnableAllPrivileges -Class win32_operatingsystem -N ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-WmiMethod], ManagementException
    + FullyQualifiedErrorId : InvokeWMIManagementException,Microsoft.PowerShell.Commands.InvokeWmiMethod

PS> Invoke-WmiMethod -EnableAllPrivileges -Class win32_operatingsystem -Name reboot -ArgumentList @{}
Invoke-WmiMethod : Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
In Zeile:1 Zeichen:1
+ Invoke-WmiMethod -EnableAllPrivileges -Class win32_operatingsystem -N ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-WmiMethod], NullReferenceException
    + FullyQualifiedErrorId : System.NullReferenceException,Microsoft.PowerShell.Commands.InvokeWmiMethod

Get-Member verrät mir, dass ich für die Methode Reboot keine Parameter benötige....
Invoke-WmiMethod meckert, dass die Parameter (nie welche angegeben) der Methode ungültig wären....
Invoke-WmiMethod -Arguments @{ } gibt mir ein Problem, dass Der Objektverweis nicht auf eine Objektinstanz festgelegt wurde. Ist das dasselbe Problem wie mit Get-CimInstance ?

Sorry für diese ganzen umständlichen Fragen, hoffe ich konnte mich halbwegs verständlich ausdrücken face-smile
Mitglied: 7907292512
7907292512 Jul 29, 2023 updated at 13:32:30 (UTC)
Goto Top
Ausnahme beim Aufrufen von "Reboot": "Recht wurde aufgehoben. "
Guckst du
https://support.microsoft.com/de-de/topic/fehlermeldung-berechtigung-wur ...

(get-wmiobject win32_operatingsystem -EnableAllPrivileges).reboot()

Ich finde das ganze aber sehr verwirrend. Gibt es irgendwo dazu eine gute Dokumentation? Ein Buch, ein Blog oder sonstiges?
https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmi-reference

Eigentlich erklärt sich das von selbst wenn du dir dazu erst mal die Grundlagen für objektorientierte Programmierung aneignest, das sollte eigentlich als erstes deine Priorität sein um das ganze einigermaßen zu verstehen.

WMI besteht primär aus Namespaces, also Namensräumen für bestimmte gruppierte Aufgaben. Die meisten Klassen befinden sich im Namespaces "root\CIMv2", es gibt aber auch andere wie bspw. für Sicherheit ("root\SecurityCenter") usw.
Namespaces sind baumartig aufgebaut und können auch Kind-Namespaces enthalten.
Dann gibt es "Klassen" die die Gerüste sind für spätere Objekte im Namespace. Die Objekte sind dann Instanzen der Klassen. Ein Namespaces kann also auch mehrere Instanzen beinhalten die alle aus einer bestimmten Klasse abstammen. Welche Klassen in welchem Namespaces erlaubt sind, wird ebenso definiert. Man kann also nicht beliebige Klasseninstanzen in jedem Namespace erstellen, das wird von MOF's vorgegeben.MOF's sind quasi Dateien die festlegen wie ein Namespace und deren Objekte auszusehen haben.
https://learn.microsoft.com/de-de/windows/win32/wmisdk/managed-object-fo ...