Seite 1 von 1

Name des angemeldeten Benutzers ueber WMI ermitteln

Verfasst: Montag 8. Juni 2009, 11:35
von dahaze
Hallo zusammen!

Bei meinem Python Projekt soll in der GUI der volle Name des aktuell am System angemeldeten Beutzers angezeigt werden. Wird das Programm nicht unter Windows ausgeführt, soll der Benutzernamen angezeigt werden.

Die Ermittlung des Names funktioniert momentan mit folgendem Code:

Code: Alles auswählen

import win32com.client
import getpass

self.__Benutzername = getpass.getuser()

if sys.platform == 'win32':
  objWMIService = win32com.client.Dispatch('WbemScripting.SWbemLocator')
  objSWbemServices = objWMIService.ConnectServer('.','root\cimv2')
  colItems = objSWbemServices.ExecQuery('Select * from Win32_UserAccount')

  for objItem in colItems:
    if objItem.Name == self.__Benutzername:
      self.__Name = objItem.FullName

else:
  self.__Name = self.__Benutzername
Da sich das der Rechner jedoch in einem sehr großen Firmennetzwerk befindet, benötigt die Iteration über die Elemente von "colItems" sehr lange aber auf Grund mangelnder Erfahrung mit WMI komme ich leider auf keine andere Möglichkeit!

Um die Iteration zu umgehen, habe ich anstatt

Code: Alles auswählen

colItems = objSWbemServices.ExecQuery('Select * from Win32_UserAccount')
auch schon

Code: Alles auswählen

colItems = objSWbemServicess.Get('Win32_UserAccount.Name='Benutzername'')
versucht, aber leider ohne Erfolg.

Kann mir vielleicht einer von euch weiterhelfen?

Gruß,
Simon[/code]

Verfasst: Montag 8. Juni 2009, 12:20
von HWK

Code: Alles auswählen

import win32com.client
print win32com.client.Dispatch('WScript.Network').UserName
MfG
HWK

Verfasst: Montag 8. Juni 2009, 12:39
von dahaze
Hallo HWK!

Danke für die schnelle Antwort!
Leider will ich nicht den Benutzernamen haben, mit dem der Benutzer am System angemeldet ist, sondern den "vollen Namen" des Benutzers.
So alla "Max Mustermann".

Den Benutzernamen bekomm ich schon plattformunabhängig mit

Code: Alles auswählen

import getpass

getpass.getuser()
Gruß...

Verfasst: Montag 8. Juni 2009, 12:55
von Dill
steht __benutzername nicht auch in der tabelle?
dann könntest du einfach die abfrage mit einem where einschränken.

Verfasst: Montag 8. Juni 2009, 13:07
von HWK
Sorry, das habe ich leider zu spät gesehen. Ich habe zwischenzeitlich aber die beiden Seiten gefunden:
1. Seite Ob das schneller ist, müsstest Du mal ausprobieren.
2. Seite Hier weiß ich noch nicht, wie man das in Python umsetzen kann.

Code: Alles auswählen

win32com.client.Dispatch('WinNT://%s/%s' % (domain, user))
klappt jedenfalls nicht. Auch bei der ähnlichen Lösung

Code: Alles auswählen

win32com.client.Dispatch('WinNT://./dummy').FullName
ergibt sich dasselbe Problem.
MfG
HWK

Verfasst: Montag 8. Juni 2009, 13:24
von HWK
@Dill: Ja, der Name steht in der Tabelle, er enthält aber einen Backslash und der wird in der Abfrage nicht akzeptiert.

Code: Alles auswählen

colItems = objSWbemServices.ExecQuery('Select Fullname from Win32_NetworkLoginProfile where Fullname is not NULL and Name="%s\\%s"' % (domain, user))
funktioniert also nicht.
MfG
HWK

Verfasst: Montag 8. Juni 2009, 13:38
von dahaze
eine Abfrage mit "Where" ist auch möglich, man muss nur auf die Anführungszeichen aufpassen:

Code: Alles auswählen

colItems = objSWbemServices.ExecQuery("Select * from Win32_UserAccount WHERE Name='Benutzername'")

for item in colItems:
  print item.FullName
Dies ergibt nun auch die gewünschte Ausgabe.
Jedoch obwohl, so wie ich das versteh, "colItems" in diesem Fall nur 1 Element hat, dauert die Iteration ewig.
Warum auch immer...?

Verfasst: Montag 8. Juni 2009, 13:46
von HWK
Bei mir lags nicht an den Anführungszeichen, sondern an den Backslashs: Es müssen nämlich 4 sein. Das

Code: Alles auswählen

import win32com.client

network = win32com.client.Dispatch('WScript.Network')
user = network.UserName
domain = network.UserDomain
objWMIService = win32com.client.Dispatch('WbemScripting.SWbemLocator')
objSWbemServices = objWMIService.ConnectServer('.','root\\cimv2')
colItems = objSWbemServices.ExecQuery('Select Fullname, Name from Win32_NetworkLoginProfile where Fullname is not NULL and Name="%s\\\\%s"' % (domain, user))
for objItem in colItems:
    print objItem.Name, objItem.FullName
läuft zumindest bei mir jetzt. Keine Ahnung, wie schnell das in einem großen Netzwerk ist. Kannst es ja mal ausprobieren.
MfG
HWK

Verfasst: Montag 8. Juni 2009, 14:05
von dahaze
:D

Super, das ist es!
Läuft auch hier flott durch!
Vielen Dank an alle!

mfg,
Simon

Verfasst: Dienstag 9. Juni 2009, 13:00
von HWK
Ich habe doch noch eine Lösung mit ADSI hinbekommen:

Code: Alles auswählen

import win32com.client
network = win32com.client.Dispatch('WScript.Network')
user = network.UserName
domain = network.UserDomain
adsi_namespaces = win32com.client.Dispatch('ADsNameSpaces')
user_obj = adsi_namespaces.getobject('', 'WinNT://%s/%s,user' % (domain, user))
print user_obj.Name, user_obj.FullName
Sie sieht auf den ersten Blick einfacher aus. Wie schnell sie ist, kannst Du ja einmal ausprobieren.
MfG
HWK

Verfasst: Mittwoch 10. Juni 2009, 09:15
von mkesper
Für Abfragen des ADS verwende ich ganz gern Tim Goldens Active-Directoy-Modul.