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
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:
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:
Und dann wird die Klasse ausgewählt aus der die Informationen gelesen werden sollen:
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:
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.
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:
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:
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
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
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
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;
};
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;
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
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
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 30645
Url: https://administrator.de/contentid/30645
Ausgedruckt am: 05.11.2024 um 23:11 Uhr
7 Kommentare
Neuester Kommentar
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:
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
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