xaero1982
Goto Top

MOF-WMI-Registry

Hallo,

zunächst möchte ich allen Interessenten ein paar Links ans Herz legen:
WMI:
http://www.microsoft.com/germany/msdn/library/windows/api/LeitfadenFuer ...
http://www.microsoft.com/germany/msdn/library/windows/api/LeitfadenFuer ...
http://www.microsoft.com/germany/msdn/library/windows/api/WMIAlsHilfeZu ...
MOF:
http://www.microsoft.com/germany/technet/datenbank/articles/600682.mspx
Tools:
WMI Tools
WMI Scriptomatic 2.0

Wie kann ich Probleme mit den Benutzerrechten von MS umgehen und WMI einsetzen? Hier erfährst du es face-smile

MOF?
WMI?

Nie gehört?

Tja, also um es kurz zu machen:

Die WMI (Windows Management Instrumentation) ist seit Windows ME Standardmäßig bei Windows dabei. Ohne WMI läuft Windows nicht!
Was aber ist WMI?
WMI ist ein "Tool", mit dem man:

1. Inventardaten von Hardware und Software verwalten (WMI Repository)
2. Computer (re)booten
3. Dienste und Warteschlangen abfragen, starten, beenden
4. Ereignisprotokolle und Performance Logs lesen, konfigurieren, löschen
5. Registry bearbeiten
6. Programme starten

kann.

Ich werde in meinem kleinen Tutorial nicht auf WMI an sich eingehen, sondern auf die MOF Dateien.

Eine MOF - Datei dient dazu selbst Abfragen zu erstellen und diese dem WMI Namespace hinzuzufügen.

Ein Beispiel zu WMI:

On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

arrComputers = Array(".")  
For Each strComputer In arrComputers
   WScript.Echo
   WScript.Echo "=========================================="  
   WScript.Echo "Computer: " & strComputer  
   WScript.Echo "=========================================="  

   Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")  
   Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", _  
                                          wbemFlagReturnImmediately + wbemFlagForwardOnly)

   For Each objItem In colItems
      WScript.Echo "AdminPasswordStatus: " & objItem.AdminPasswordStatus  
      WScript.Echo "AutomaticResetBootOption: " & objItem.AutomaticResetBootOption  
      WScript.Echo "AutomaticResetCapability: " & objItem.AutomaticResetCapability  
      WScript.Echo "BootOptionOnLimit: " & objItem.BootOptionOnLimit  
      WScript.Echo "BootOptionOnWatchDog: " & objItem.BootOptionOnWatchDog  
      WScript.Echo "BootROMSupported: " & objItem.BootROMSupported  
      WScript.Echo "BootupState: " & objItem.BootupState  
      WScript.Echo "Caption: " & objItem.Caption  
      WScript.Echo "ChassisBootupState: " & objItem.ChassisBootupState  
      WScript.Echo "CreationClassName: " & objItem.CreationClassName  
      WScript.Echo "CurrentTimeZone: " & objItem.CurrentTimeZone  
      WScript.Echo "DaylightInEffect: " & objItem.DaylightInEffect  
      WScript.Echo "Description: " & objItem.Description  
      WScript.Echo "Domain: " & objItem.Domain  
      WScript.Echo "DomainRole: " & objItem.DomainRole  
      WScript.Echo "FrontPanelResetStatus: " & objItem.FrontPanelResetStatus  
      WScript.Echo "InfraredSupported: " & objItem.InfraredSupported  
      strInitialLoadInfo = Join(objItem.InitialLoadInfo, ",")  
         WScript.Echo "InitialLoadInfo: " & strInitialLoadInfo  
      WScript.Echo "InstallDate: " & WMIDateStringToDate(objItem.InstallDate)  
      WScript.Echo "KeyboardPasswordStatus: " & objItem.KeyboardPasswordStatus  
      WScript.Echo "LastLoadInfo: " & objItem.LastLoadInfo  
      WScript.Echo "Manufacturer: " & objItem.Manufacturer  
      WScript.Echo "Model: " & objItem.Model  
      WScript.Echo "Name: " & objItem.Name  
      WScript.Echo "NameFormat: " & objItem.NameFormat  
      WScript.Echo "NetworkServerModeEnabled: " & objItem.NetworkServerModeEnabled  
      WScript.Echo "NumberOfProcessors: " & objItem.NumberOfProcessors  
      strOEMLogoBitmap = Join(objItem.OEMLogoBitmap, ",")  
         WScript.Echo "OEMLogoBitmap: " & strOEMLogoBitmap  
      strOEMStringArray = Join(objItem.OEMStringArray, ",")  
         WScript.Echo "OEMStringArray: " & strOEMStringArray  
      WScript.Echo "PauseAfterReset: " & objItem.PauseAfterReset  
      strPowerManagementCapabilities = Join(objItem.PowerManagementCapabilities, ",")  
         WScript.Echo "PowerManagementCapabilities: " & strPowerManagementCapabilities  
      WScript.Echo "PowerManagementSupported: " & objItem.PowerManagementSupported  
      WScript.Echo "PowerOnPasswordStatus: " & objItem.PowerOnPasswordStatus  
      WScript.Echo "PowerState: " & objItem.PowerState  
      WScript.Echo "PowerSupplyState: " & objItem.PowerSupplyState  
      WScript.Echo "PrimaryOwnerContact: " & objItem.PrimaryOwnerContact  
      WScript.Echo "PrimaryOwnerName: " & objItem.PrimaryOwnerName  
      WScript.Echo "ResetCapability: " & objItem.ResetCapability  
      WScript.Echo "ResetCount: " & objItem.ResetCount  
      WScript.Echo "ResetLimit: " & objItem.ResetLimit  
      strRoles = Join(objItem.Roles, ",")  
         WScript.Echo "Roles: " & strRoles  
      WScript.Echo "Status: " & objItem.Status  
      strSupportContactDescription = Join(objItem.SupportContactDescription, ",")  
         WScript.Echo "SupportContactDescription: " & strSupportContactDescription  
      WScript.Echo "SystemStartupDelay: " & objItem.SystemStartupDelay  
      strSystemStartupOptions = Join(objItem.SystemStartupOptions, ",")  
         WScript.Echo "SystemStartupOptions: " & strSystemStartupOptions  
      WScript.Echo "SystemStartupSetting: " & objItem.SystemStartupSetting  
      WScript.Echo "SystemType: " & objItem.SystemType  
      WScript.Echo "ThermalState: " & objItem.ThermalState  
      WScript.Echo "TotalPhysicalMemory: " & objItem.TotalPhysicalMemory  
      WScript.Echo "UserName: " & objItem.UserName  
      WScript.Echo "WakeUpType: " & objItem.WakeUpType  
      WScript.Echo
   Next
Next


Function WMIDateStringToDate(dtmDate)
WScript.Echo dtm:
	WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _  
	Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _  
	& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))  
End Function
Speichern als *.vbs

Diese "kleine" Script dient dazu verschiedene Informationen auszulesen.
All diese Informationen werden zum Teil aus der Registrierung oder sonstigen Ressourcen des PC's ausgelesen.

Zunächst wird eine Verbindung zum Namespace hergestellt:
   Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")  

Und dann wird die Klasse ausgewählt aus der die Informationen gelesen werden sollen:
   Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", _  
                                          wbemFlagReturnImmediately + wbemFlagForwardOnly)

Mit dem WMI Scriptomatic 2.0 kann man sich hierzu alle vorhandenen Namespaces auflisten lassen und alle dazugehörigen Klassen.
Der CIMV2 ist der meistbenutzte Namespace in dem auch alle wichtigen Klassen gespeichert sind.

Zum Thema MOF:
Ich bin auf die Idee gekommen eine eigene MOF zu schreiben, da ich (siehe anderes TUT von mir) leider feststellen musste, dass egal wie mächtig WMI auch ist es ein Problem hat.

Wenn der derzeit angemeldete Benutzer von dem Client, von dem man die Informationen auslesen möchte nur Benutzerrechte hat werden diverse Dinge nicht ausgelesen.
Leider ist mir keine Lösung bekannt und anderen ist wohl ebenfalls noch keine Lösung eingefallen!

Also dachte ich mir: Warum les ich nicht den Wert direkt aus der Registrierung?
In meinem speziellen Fall war es der derzeit eingeloggte User.

Vorraussetzung: Der Registrierungsschlüssel muss auf allen PC's die man auslesen möchte gleich sein.
Sprich z.b. Software die auf einem PC vorhanden ist und auf dem anderen nicht wird nicht gehen.

Kommen wir gleich auf den Punkt wie diese MOF auszusehen hat:

qualifier dynamic:ToInstance;
qualifier ProviderClsid:ToInstance;
qualifier ClassContext:ToInstance;
qualifier propertycontext:ToInstance;
 [dynamic, provider("RegProv"),  
ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),  
ClassContext
("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion")  
]
class LoggedUsername {
   [key] string KeyName;
   [read, propertycontext("DefaultUserName")]      string DefaultUserName;  
};
Speichern unter *.mof


Wichtig für eigenständige Änderungen ist nur der Registrierungsschlüssel.
Zu beachten ist, dass IMMER das local vorne stehen bleibt und nicht evtl. PC1.
Dies geht natürlich auch, aber dann kann immer nur der angegebene Schlüssel von PC1 ausgelesen werden.
Desweiteren ist zu beachten, dass es immer "\\" sein müssen.
Nächster Punkt ist der Schlüssel an sich. Dieser Schlüssel darf nicht bis zum letzten Tree kopiert werden sondern den nächsthöheren. Wenn man sich den obigen Schlüssel mal in der Registrierung ansieht wird man festellten, dass dieser keine eigenen Attribute hat. Der "DefaultUserName" steht im Schlüssel WinLogon.
Der Klasse muss natürlich ein anderer Name gegeben werden, damit diese hinzugefügt werden kann ohne die andere, falls vorhandene, Klasse zu überschreiben.

   [read, propertycontext("DefaultUserName")]      string DefaultUserName;  
Hiermit gebt ihr an welchen Wert ihr aus dem genannten Schlüssel auslesen wollt.
In dem Fall ist es DefaultuserName. Das ist der Wert in den Klammern. "string DefaultUserName" ist der Wert, der in den WMI Namespace eingetragen wird.
In diesem Fall wollen wir nur lesen -> read!

Zum mitmachen gehen wir nun in die CMD und wechseln in das Verzeichnis in dem die MOF Datei liegt.

Nun schreiben mir "mofcomp -check DATEINAME.mof"
Hiermit wird der Syntax überprüft (der hier nun korrekt sein sollte).
Anschließend wird nun nur "mofcomp DATEINAME.mof" eingeben und die neue Klasse wird dem DefaultNamespace hinzugefügt.
Sprich die klasse landet nicht in root\CIMV2 sondern in root\DEFAULT!

WICHTIG: Das muss auf allen PC's passieren, auf denen diese Klasse ausgelesen werden soll! Dies lässt sich per Batch oder aber, mit win32_prozess:createprocess realisieren!

Zum Auslesen benutzen wir folgendes Script:
strComputer = "."  
Set WMI = GetObject("winmgmts:\\" & strComputer & _  
    "\root\default")  
Set colItems = WMI.ExecQuery("Select * from LoggedUsername")  
For Each objItem In colItems
    WScript.Echo "DisplayName: "  & objItem.DefaultUserName  
    WScript.Echo "KeyName: " & objItem.KeyName  
Next
Speichern unter *.vbs


Als Ausgabe bekommt ihr nun zum einen den eingeloggten Benutzer und anschließend den Key in dem dieser Wert steht (Winlogon)

Was bringt das alles? Ich weiß doch wer gerade an diesem PC sitzt.
Natürlich kann man das ganze so erweitern, dass man den Benutzer des RemotePC's auslesen kann.

Hier der Code:
Const WbemAuthenticationLevelPktPrivacy = 6
strUser = InputBox("Please enter the user name: ")  
strPassword = InputBox ("Please enter the Password: ")  
strComputer = InputBox ("Please enter the Computername: ")  
strNamespace = "root\default"  

'Verbindung zum WMI Namespace herstellen================  
Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")  
Set objWMIService = objwbemLocator.ConnectServer (strComputer, strNamespace, strUser, strPassword)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy


'Set objWMIService = GetObject("winmgmts:\\{impersonationLevel=impersonate}!\\" & strComputer & "\root\default")  
Set colItems = objWMIService.ExecQuery("Select * from LoggedUsername")  
For Each objItem In colItems
    WScript.Echo "DisplayName: "  & objItem.DefaultUserName  
    WScript.Echo "KeyName: " & objItem.KeyName  
Next
Speichern unter *.vbs.

In dem Fall werden zunächst 3 Abfragen getätigt und anschließend die Verbindung zum RemoteComputerNamespace hergestellt.
Hierzu benötigt ihr natürlich administrative Rechte!
Der User kann (falls nötig) auch als DOMÄNE\ADMIN eingegeben werden bzw. muss wenn sich der RemotePC in einer anderen Domäne befindet als der eigene.

Soooo
Genug davon
Bei Fragen fragen

So far
Xaero

Content-ID: 30645

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

Ausgedruckt am: 05.11.2024 um 23:11 Uhr

acey
acey 18.04.2006 um 21:18:21 Uhr
Goto Top
sowas gehört in ein tutorial

und pcwelt hat da auch fleißig recherchiert

mfg acey007
Xaero1982
Xaero1982 19.04.2006 um 07:08:19 Uhr
Goto Top
sowas gehört in ein tutorial

und pcwelt hat da auch fleißig
recherchiert

mfg acey007
?
Punkt 1: Das ist ein Tutorial: Warum sonst ist es unter der Überschrift Tutorial?
Punkt 2: Die werten Herren der PC Welt haben keine Ahnung
Punkt 3: Ich habe ein WMI Problem in deren Forum gepostet und siehe da -> Keine Lösung!
Punkt 4: Du kannst gerne sinnvolle Kritik üben, aber das war ein sprichwörtlicher Griff ins Klo!
acey
acey 19.04.2006 um 10:17:58 Uhr
Goto Top
hä, sorry da hab ichs irgendwie verpeilt

komisch in der ausgabe 7/05 kommt einem das irgendwie anders vor face-wink
ne mal im ernst, riesen artikel über wmi unter 2000 und wmic unter xp inkl. lösungsvorschläge...

na egal aber ich hab irgendwie tats. geglaub das es n beitrag wär...

mfg. acey
test1linux
test1linux 29.12.2006 um 15:58:42 Uhr
Goto Top
gibt es mittlerweile eine bessere lösung?
Xaero1982
Xaero1982 12.03.2007 um 15:05:49 Uhr
Goto Top
? Eine bessere Lösung?

Ich habe hier gar keine Problemstellung angebracht ...
Bitsqueezer
Bitsqueezer 04.11.2007 um 10:13:57 Uhr
Goto Top
Hallo Xaero,

ich fand Deinen Artikel zur Erweiterungsmöglichkeit von WMI per MOF-Dateien interessant - bin noch am Anfang mit WMI und wußte nicht, daß das überhaupt geht, eröffnet aber wieder neue Möglichkeiten.

Allerdings verstehe ich das Problem nicht:

Wenn der derzeit angemeldete Benutzer von dem Client, von dem man die Informationen auslesen möchte nur Benutzerrechte hat werden diverse Dinge nicht ausgelesen.
Leider ist mir keine Lösung bekannt und anderen ist wohl ebenfalls noch keine Lösung eingefallen!


Denn das beantwortest Du doch selbst unten:

Set objWMIService = objwbemLocator.ConnectServer (strComputer, strNamespace, strUser, strPassword)

Damit verbindest Du Dich zum WMI mit dem eingegebenen Benutzerkontext. Nur so macht es auch Sinn, denn wenn ein als Benutzer eingeloggter User per WMI auf Dinge zugreifen könnte, die nur ein Admin darf, wäre das ganze Sicherheitsmodell über den Haufen geworfen.

Was in dem Zusammenhang Deine MOF-Erweiterung bewirken soll, ist mir nicht klar geworden. Du liest den angemeldeten Benutzer aus - was bringt Dir das?

Gruß

Christian
Xaero1982
Xaero1982 08.02.2008, aktualisiert am 18.10.2012 um 18:35:22 Uhr
Goto Top

Wenn der derzeit angemeldete
Benutzer von dem Client, von dem man die
Informationen auslesen möchte nur
Benutzerrechte hat werden diverse Dinge nicht
ausgelesen.
Leider ist mir keine Lösung bekannt und
anderen ist wohl ebenfalls noch keine
Lösung eingefallen!


Denn das beantwortest Du doch selbst unten:

Set objWMIService =
> objwbemLocator.ConnectServer (strComputer,
> strNamespace, strUser,
> strPassword)

Damit verbindest Du Dich zum WMI mit dem
eingegebenen Benutzerkontext. Nur so macht es
auch Sinn, denn wenn ein als Benutzer
eingeloggter User per WMI auf Dinge zugreifen
könnte, die nur ein Admin darf,
wäre das ganze Sicherheitsmodell
über den Haufen geworfen.

Was in dem Zusammenhang Deine
MOF-Erweiterung bewirken soll, ist mir nicht
klar geworden. Du liest den angemeldeten
Benutzer aus - was bringt Dir das?

Gruß

Christian


Hallo,

das Problem bezog sich auf das standard-wmi, dass ich mit Hilfe einer eigenen MOF umgehen wollte.
Die Problematik des Auslesens ist hier, dass WMI genau das Problem eben hat, dass wenn ein Benutzer nicht mit Administrativen Rechten angemeldet ist, kann man dort nicht alles auslesen. Genau das widerspricht nämlich deiner Theorie und so wie es natürlich eigentlich sein sollte.

Bei mir jedoch lief es nicht, dass ich beispielsweise den Benutzernamen auslesen konnte. Diese Problematik ist in einem anderen Beitrag beschrieben.
Eingeloggten User ermitteln