xaero1982
Goto Top

Eingeloggten User ermitteln

Hallo, ich bin dabei ein Netzwerktool zu schreiben mit WMI und VBScript

Folgendes Problem:

Ich sitz in einer Domäne und kann von keinem einzigen Windows 2000 PC den aktuell eingeloggten User ermitteln.
Bei Windows XP Maschinen und auf meiner lokalen geht es einwandfrei.

Alle PC's sind in der Domäne.

Nehme ich einen PC, der nicht in der Domäne ist mit W2000 geht es ebenfalls mit dem Auslesen.

Der Code dazu ist der folgende: Achtung Auszug:

'=======================================================  
Const WbemAuthenticationLevelPktPrivacy = 6
strNamespace = "root\cimv2"  
'=======================================================  

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

	Set colSettings = objWMIService.ExecQuery("Select * from Win32_ComputerSystem", ,wbemFlagReturnImmediately + wbemFlagForwardOnly)  
	str = str & "<H2>Computer systems - Win32_ComputerSystem</H2>" & vbCRLF  
	For Each objComputer in colSettings
	    str = str & GetTableHeader()
	    str = str & GetRow("System Name", objComputer.Name)  
	    str = str & GetRow("Benutzername", objComputer.UserName)  
	    str = str & GetRow("System Manufacturer", objComputer.Manufacturer)  
	    str = str & GetRow("System Model", objComputer.Model)  
	    str = str & GetRow("Total Physical Memory", objComputer.TotalPhysicalMemory)  
	    str = str & GetTableFooter()
	Next

Also der Code geht problemlos mit Ausnahme des nicht-auslesens des Usernamens.

Gibt es alternativen zum auslesen?
Kein Tool!!!
Ich brauch das sozusagen manuell!

edit1:

Ok, ich habe rausgefunden woran es liegt: MICROSOFT
Ich habe einen Rechner genommen und dort einen Gastaccount bzw Benutzeraccount eingerichtet. Angemeldet und dann von meinem PC aus die Daten auslesen wollen und siehe da? Ich kann den Benutzer nicht auslesen. Ich melde mich wieder als Administrator an und siehe da? Es geht.
Desweiteren habe ich festgestellt, dass die Variable UserName nicht leer ist, aber ausgegeben wird dennoch nichts.

Ich würde sagen Danke Microsoft!
Im moment blieb mir nichts übrig als PSloggedon.exe von den sysinternals zu nutzen:

            Set objShell = CreateObject("WScript.Shell")  
                strCommand = "c:\script\iframe\psloggedon.exe \\" & strComputer & " -l"  
            Set objExecObject = objShell.Exec(strCommand)
            Do While Not objExecObject.StdOut.AtEndOfStream
                strText = objExecObject.StdOut.ReadAll()
            loop
        strText = split(strText,":")  
        msgbox  strText(1)
Hier splittet er dann die "Werbung" von sysinternals ab und das Ergebnis sieht so aus: Domäne\Username

Das mit dem Namen auslesen geht noch nicht face-sad nur über die alternative via pstools

Edit2: Habe mich mit MS in Verbindung gesetzt und ein Hotfix erhalten -> Keine Änderung ...

Nun habe ich es in diversen anderen Foren gepostet und einen weiteren Programmierer von WMI angeschrieben. Mal sehen ...

Hier noch mal ein "funktionsfähiger" Code zum selber probieren:

Const WbemAuthenticationLevelPktPrivacy = 6

strComputer = "PCX"   
strNamespace = "root\cimv2"  
strUser = "ADMINISTRATOR"  
strPassword = "ADMINPW"  

Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")  
Set objWMIService = objwbemLocator.ConnectServer _
    (strComputer, strNamespace, strUser, strPassword)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_ComputerSystem")  
For Each objItem in ColItems
    Wscript.Echo strComputer & ": " & objItem.UserName  

Edit3: Und weiter gehts: Neuer Tag neues Glück:

Heute dacht ich mir halt: Hey, warum nicht direkt aus der Registry auslesen? Gesagt getan:

set wshshell = createobject("Wscript.shell")  
Const strBaseKey = "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Logon User Name"  

msgbox (wshshell.regread(strbasekey))

Und siehe da? Es geht sogar auf XP PC's und auf 2000 und das nur mit Benutzerrechten.

Haken? Ja klar: Ich kann das nicht über remote abrufen face-sad
Also ?
Klar eine MOF erstellen und ins WMI Repository aufnehmen. Gesagt getan:
 [dynamic, provider("RegProv"),  
ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),  
ClassContext
("local|HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer")  
] 
class logonuser {
   [key] string KeyName;
   [read, propertycontext("Logon User Name")] string LogonUserName;  
};
Für "Mitmacher" Kopieren und unter *.mof speichern
Cmd öffnen und "mofcomp *.mof" eingeben

Kurz noch nen Abfragescript geschrieben:
Const WbemAuthenticationLevelPktPrivacy = 6

strComputer = "."  
strNamespace = "root\DEFAULT"  
strUser = ""  
strPassword = ""  

Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")  
Set objWMIService = objwbemLocator.ConnectServer (strComputer, strNamespace, strUser, strPassword)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

Set colItems = objWMIService.ExecQuery("Select logonusername From logonuser")  

For Each objItem in colItems
    Wscript.Echo strComputer & ": " & LogonUserName  
Next
Was passiert? NIX! Er geht nicht in die For Each -Anweisung habe ich festgestellt. Sprich irgendwas mit dem Set colItems stimmt nicht!

So also hänge ich mal wieder fest und es kann kein Mensch helfen face-sad

Links zum Thema mof:
http://www.microsoft.com/germany/msdn/library/windows/api/WMIAlsHilfeZu ...
http://www.netscum.dk/germany/technet/datenbank/articles/600682.mspx

Vielleicht jemand nen Plan ? (was ich langsam nicht mehr glaube .. ca. 100 Aufrufe und keine Antwort face-sad(( )

Nu hab ich was tolles gefunden:

http://dieseyer.de/scr-html/alle.html
>>> lastlogon.vbs <<< /<- das ist der Name
darf wohl nicht geposted werden ...
Das geht wieder nur, wenn man Adminrechte hat .... sprich wenn ich Adminrechte auf dem Client habe. Dazu muss ich immer als Domänenadmin angemeldet sein. Ich möchte wenn aber die Daten beim Starten des Scripts mitgeben.

Content-ID: 29737

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

Ausgedruckt am: 23.11.2024 um 05:11 Uhr

Biber
Biber 14.04.2006 um 20:07:49 Uhr
Goto Top
Moin Xaero1982,
erstmal vielen Dank für Deine Super-Recherchen - ich stufe diesen Beitrag mal zu, Tutorial hoch .
Und will auch der erste sein, der dafür ein paar Sternchen verteilt.

Zu Deiner Frage nach der Dieseyer-Variante (lastlogon.vbs):
Aus meiner Sicht kann dieser Schnipsel ruhig zitiert werden, aber ich frag mal den Kollegen Dieseyer direkt.

Dennoch - die lastlogon.vbs hat aus meiner Sicht natürlich zwei Nachteile:
- erstens würde sie die RegObj.Dll registrieren ..okay.. aber hinterher auch jedem Fall de-registrieren.
Ohne Rücksicht darauf zu nehmen, wie der Zustand vorher war. *tztz ...sowas kann der Dieseyer auf seinem PC so machen.. auf meinem wäre mir das unlieb.
- zweitens braucht der Schnipsel Administratorrechte...
... da finde ich Deine Variante über Bande mit PsLoggedOn.exe viel schöner.
(Und habe ehrlich gesagt auch noch nie einen anderen Weg benutzt als über die PsLoggedOn)

Wenn Du bei Gelegenheit noch ein Tutorial zum Thema MOF und MOFComp hier schreiben möchtest:
Der Bereich "Entwicklung" steht Dir Tag und Nacht offen.

Grüße
Biber
Xaero1982
Xaero1982 15.04.2006 um 21:39:31 Uhr
Goto Top
Lieben Dank Biber,

aber das war doch hier mehr ein Hilferuf als ein Tutorial.

Ich kann gerne noch mal eine Zusammenfassung unterm Strich schreiben.

Aber das Problem muss wohl Seitens MS behoben werden, aber 200 ? für einen Supportauftrag sind mir dann doch ein wenig happig.

Wie ich geschrieben habe, hatte ich einen WMI Experten angeschrieben im Firmennamen:
Antwort war:
Sorry, ich kann keinen privaten Support leisten

Ich weiß ja nicht, aber ich finde es verdammt traurig, dass in der Community so eine schlechte Hilfsbereitschaft herrscht.

In den anderen Foren -> Nirgendwo eine Antwort!


So weit so gut.

Zum Thema MOF: Wenn ich mal Zeit finde mich damit noch mal intensiver zu befassen, gerne. Derzeit bin ich aber dabei ein ziemlich großes und umfangreiches Tool für die Hard- und Softwarearchivierung zu schreiben.

Dies auf Basis von WMI, VBScript, WSH, MySQL und anderen Tools.

Tja, nur leider hat MS bei der Vergabe der Benutzerrechte einiges verhunzt face-sad und dieses sehr gigantische Tool WMI kann man nicht im eigentlichen Umfang nutzen. Erst wenn der Clientnutzer Administrative Rechte hat!

Ob ich das Tool allerdings je öffentlich machen werde glaube ich nicht, da für mich da sehr viel Arbeit, Mühe und Nerven drin stecken.

Ich kann bei Vollendigung gerne mal ein paar snipplets posten und mal den Umfang und die Möglichkeiten präsentieren. face-smile

Halt mich mal auf dem Laufenden was die Logon.vbs betrifft, dann kann ich das noch mal hier posten.

Zum Thema psloggedon.exe:

Ich kann diese nicht benutzen, da die Ausgaben ziemlich schlecht zu handlen sind.
Vor dem Splitten:

PsLoggedOn v1.31 - Logon Session Displayer
Copyright (C) 1999-2003 Mark Russinovich
Sysinternals - www.sysinternals.com

Users logged on locally:
     <Unknown> NT-AUTORITÄT\LOKALER DIENST
     <Unknown> NT-AUTORITÄT\NETZWERKDIENST
     15.04.2006 15:06:02    XXX\XXX
     <Unknown> NT-AUTORITÄT\SYSTEM

No one is logged on via resource shares.
Das ist die Ausgabe bei einer XP Maschine.

Und diese bei 2000:

PsLoggedOn v1.31 - Logon Session Displayer
Copyright (C) 1999-2003 Mark Russinovich
Sysinternals - www.sysinternals.com

Users logged on locally:
    15.04.2006 15:06:02    XXX\XXX
No one is logged on via resource shares.

Nach dem Zerlegen:

LOKALER DIENST

Das ist die Ausgabe bei einer XP Maschine.

Und diese bei 2000:

    XXX
Das lässt sich leichter handlen, da ich den ganzen String einlesen kann und dann auseinandernehmen, so das nur XXX übrig bleibt.
Nach gleichem System würde bei XP "Lokaler Dienst" übrig bleiben und damit kann ich nichts anfangen!
dieseyer
dieseyer 16.04.2006 um 08:02:09 Uhr
Goto Top
Hallo!

die RegObj.Dll registrieren ..okay.. aber hinterher auch jedem Fall de-registrieren.
Ohne Rücksicht darauf zu nehmen, wie der Zustand vorher war. *tztz ...sowas kann
der Dieseyer auf seinem PC so machen.. auf meinem wäre mir das unlieb.
Da kann / sollte man drüber diskutieren. Wenn du nur Skripte verwendest, die dies so (wie meine) machen, hast du immer einen definierten (Ausgangs-) Zustand. Ansonsten sammeln sich immer mehr registrierte 'sonstwas' an . . . (was schlecht zu warten ist).

nur mit Administratorrechte auslesen
Aus Datenschutzsicht ist es sinnvoll, dass nur 'priveligierte' User Daten von remote PCs auslesen können. Was du möchtest, ermöglicht es jedem User über jeden User Statistiken über z.B. Arbeitszeiten (auch über dich und seinen bzw. deinen Chef - oder dein Chef über dich?) aufzubauen.

psloggedon.exe - Ausgaben zerlegen
Ich würde die Zeile mit ".200" ermitteln ( If InStr( Zeile, ".200" ) > 0 Then)
und dann 'von hinten' das Zeichen links von "XXX\XXX" als Kreterium verwenden:
LastLogonUser = Mid( Zeile, InStrRev( ZeichenLinks ) +1 )

Skripte von dieseyer.de posten
Natürlich dürfen die gepostet (und kritisiert) werden . . . aber bitte mit Quellenangabe - Quellenangabe kann bei berechtigter Kritik entfallen.
Bitte nicht hier diskutieren: Nicht alles was kostenlos ist, hat nichts gekostet - zumindest Zeit hats 'gekostet'. Und wer ohne Quellenangabe in seiner Ausbildung arbeitet, hat Pech, wenn jemand das Glück hat, das zu bemerken.
Xaero1982
Xaero1982 16.04.2006 um 10:45:42 Uhr
Goto Top
Hallo,

danke für die prompte Antwort.

Das mit .200 sagt mir überhaupt nichts face-smile

Nein, ich will damit keine Statistik aufbauen o.ä.

Wie gesagt programmiere ich ein Tool zum Auslesen der Hard-und Software Informationen.

Wir haben aber leider allerlei DAU's in der Firma, die es teilweise nicht schaffen einen Kleber mit PC Namen abzulesen. Deshalb soll der jenige einfach seinen Namen sagen und mit gut Glück sitzt er auch an diesem PC, an dem er während des Auslesens und Einschreibens in die DB gesessen hat und ich eben nur nach diesem Namen suchen muss.

Für mehr ist das nicht gedacht und auch nicht erdacht geschweige denn von meiner Seite aus zu unterstützen.
Biber
Biber 16.04.2006 um 14:09:31 Uhr
Goto Top
Moin,

@dieseyer
erstmal herzlich willkommen im Forum, dieseyer und vielen Dank für Deine prompte Reaktion.
Freut mich sehr.

@Xaero1982
Die Mimik mit dem Suchen des Strings ".200" , der ja in der Datumsangabe "15.04.2006" o.ä. enthalten ist, kannst Du nicht nur in VBS verwenden, sondern auch im Batch.
Also den Output von "PsloggedOn" so reduzieren:

PsLoggedon ...(params) ..|find ".200"

Dann bleibt nur eine Zeile über, die sich wiederum mit FOR /F in Tokens zerlegen lässt.
> 15.04.2006 15:06:02 XXX\XXX <---------die Zeile
FOR /f "tokens=3" %%i in ('PsLoggedon ...(params) ..^|find ".200" ') do echo %%i  
...im Batch würde nur Domain/User XXX\XXX bringen.
Gruß
Biber
Xaero1982
Xaero1982 19.04.2006, aktualisiert am 18.10.2012 um 17:56:49 Uhr
Goto Top
Edit: Woanders gehts weiter!
PSLoggedon String zerlegen
Raphael
Raphael 01.05.2006 um 21:55:33 Uhr
Goto Top
im dritten Code-Abshcnitt müsste man ein ' durch ein " ersetzen .. oder?
strUser = "ADMINISTRATOR'  

Gruss Raphael
Xaero1982
Xaero1982 03.05.2006 um 07:55:02 Uhr
Goto Top
Jo, ist nur, weil ich es hier editiert habe face-smile

Ansonsten natürlich 2 "

editiert...
Tundra
Tundra 03.05.2006 um 09:25:50 Uhr
Goto Top
Hi,

wer w2k hat, der muss sich die reg.exe ins Systemverzeichnis kopieren.

'Angemeldeten User ermitteln'  
'03.05.06/ge'  

const C_Rechner = "forstvpc-3"  
const C_Log = "c:\Log\Reg-User.txt"  

DIM O_FSO
DIM O_Shell

Set O_FSO = CreateObject("Scripting.FileSystemObject")  
Set O_Shell = CreateObject("Wscript.Shell")  

call S_ReadReg
call S_ReadFile
'####################'  
sub S_ReadReg
    DIM L_Wert
    DIM L_Return
    L_Return = O_Shell.run ("cmd /c reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer /v " & chr(34) & "Logon User Name" & chr(34) & " > " & C_Log,0,true)  
    if err.number <> 0 then
        wscript.echo "Fehler beim Auslesen"  
        wscript.quit
    end if
end sub

sub S_ReadFile
    DIM O_Input
    DIM L_Zeile
    DIM L_Split
    set O_Input = O_FSO.OpenTextFile(C_Log,1,false)
    do until O_Input.AtEndOfStream
        L_Zeile = O_Input.Readline
        if instr(L_Zeile,"REG_SZ") > 0 then  
            L_Split = Split(L_Zeile,"REG_SZ")  
            wscript.echo (L_Split(1))
        end if
    loop
end sub

Grüße
Guido
www.code-master.de
Xaero1982
Xaero1982 03.05.2006 um 10:00:17 Uhr
Goto Top
Danke für den Beitrag Guido,

aber wenn Du diesen Thread mal vollständig gelesen hättest, hättest du festgestellt, dass wir die von dir vorgeschlagene Lösung bereits besprochen haben.

Das war in Bezug auf diseyer.de
Tundra
Tundra 03.05.2006 um 13:54:05 Uhr
Goto Top
Komisch, ich kann da keine Überschneidungen feststellen, da bei mir nichts registriert werden muss und es funktioniert remote mit w2k.
Du rufst ein Proggi auf, dass bei XP dabei ist und auch unter w2k funktioniert.

Wo ist da das Problem?

Dann mache Dir das Leben doch einfacher, lese den Rechner-Namen bei der Anmeldung aus und schreibe ihn z. B. in das Arbeitsplatz-Symbol.
Ermittel den angemeldeten User aus dem Active-Directory und schreibe dazu ein Logfile.

Grüße
Guido
Xaero1982
Xaero1982 03.05.2006 um 14:28:06 Uhr
Goto Top
Stimmt, aber man muss die reg.exe (vermutlich nur auf dem PC, von dem das Skript ausgeführt wird) ins Systemverzeichnis kopieren....naja gut, das sollte nicht das Problem sein face-smile


So weit so gut, aber deine Variable C_Rechner ist unbenutzt und somit nichts mit Remote ...
Oder hast du was vergessen?

Würde mich über eine Ergänzung freuen.

Bei den anderen beiden Punkten weiß ich ehrlich gesagt nicht was du meinst.
Tundra
Tundra 03.05.2006 um 14:52:42 Uhr
Goto Top
Hi,

Du schreibst, ich hätte den Thread nicht richtig gelesen, darauf bezogen sich meine Äußerungen.
Zum Anderen kannst Du Rechnernamen über Network oder den Usernamen über AD bei der Anmeldung ermitteln und beides schreibst Du in ein Logfile, dass z. B. auf einer Freigabe auf dem Server liegt.

Du musst die Reg nicht in ein Systemverzeichnis lokal kopieren, man spart sich dann nur das setzen des Pfades beim Aufrufen.

So funktioniert es auch remote.
    L_Return = O_Shell.run ("cmd /c reg query " & "\\" & C_Rechner & chr(34) & "\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" & chr(34) & " /v " & chr(34) & "DefaultUserName" & chr(34) & " > " & C_Log,0,true)   
Es läuft somit alles lokal auf Deinem Rechner ab.
Selbst die reg kannst Du in das gleiche Verzeichnis packen, in dem auch das Script liegt.

Grüße
Guido
Xaero1982
Xaero1982 03.05.2006 um 15:00:08 Uhr
Goto Top
Ok das mit dem Auslesen über AD etc. bekomm ich im Moment nicht in die Birne face-smile

Aber das andere geht.

Supi face-smile

Vielen Dank für die Ergänzung -> Hat sich nur inzwischen herausgestellt, dass das für mein Vorhaben nicht weiter relevant ist. So ist das ....