Find the login time of the current Windows user
|
|
Thread rating:  |
Ivyleaf - 02 Apr 2008 03:15 GMT Hi,
I have posted this question previously in the microsoft.public.excel.programming group, but unfortunately with no solution.
My goal is to be able to insert the login time of the current Windows user into a cell in Excel. I have searched the net extensively, but although there are plenty of ways to find the user NAME, i can't find any way to find the time that they logged in. Windows obviously records this info (it is displayed in the Windows Security box if you hit Ctrl+Alt+Del, as well as in event log etc etc).
I can handle all the excel side of stuff, but have no idea which API I should be looking for / how to call it.
Any help appreciated, Ivan.
Scott Seligman - 02 Apr 2008 05:15 GMT >I have posted this question previously in the >microsoft.public.excel.programming group, but unfortunately with no [quoted text clipped - 9 lines] >I can handle all the excel side of stuff, but have no idea which API I >should be looking for / how to call it. I don't have VB code handy, but you'll need to call GetUserName() to get the current user, then call NetUserGetInfo() with the USER_INFO_2 structure, and look at the usri2_last_logon value.
 Signature --------- Scott Seligman <scott at <firstname> and michelle dot net> --------- Whenever you find yourself on the side of the majority, it is time to pause and reflect. -- Mark Twain
Karl E. Peterson - 02 Apr 2008 18:35 GMT > My goal is to be able to insert the login time of the current Windows > user into a cell in Excel. I have searched the net extensively, but > although there are plenty of ways to find the user NAME, i can't find > any way to find the time that they logged in. Call NetUserGetInfo, asking for USER_INFO_2 or USER_INFO_3.
Very old (VB4 vintage) example: http://vb.mvps.org/samples/NetUser
 Signature .NET: It's About Trust! http://vfred.mvps.org
Ivyleaf - 03 Apr 2008 11:27 GMT > > My goal is to be able to insert the login time of the current Windows > > user into a cell in Excel. I have searched the net extensively, but [quoted text clipped - 7 lines] > .NET: It's About Trust! > http://vfred.mvps.org Hi Scott / Karl,
I think I am making some headway... thanks for the tips. I have some working code now (kind of). I just need to dissect it to try and simplify for just the bits that I need. Also need to work out how to return the time for just the logged on user (at the moment I am using an IF username = "Joe Bloggs" THEN... in the loop, where I would rather just ask specifically for the user). Also would be nice to work out how to adjust for the user's timezone offset & daylight savings. At the moment I am manually adding 11 hours which is the sort of dodgyness that I loathe. When I trim the code down a bit I might re-post to see if anyone can offer some final tips.
Cheers, Ivan.
Karl E. Peterson - 03 Apr 2008 17:54 GMT >> > My goal is to be able to insert the login time of the current Windows >> > user into a cell in Excel. I have searched the net extensively, but [quoted text clipped - 11 lines] > an IF username = "Joe Bloggs" THEN... in the loop, where I would > rather just ask specifically for the user). What's the issue here? Just call GetUserName, as my sample shows, and you have what (I believe?) you want. Right?
> Also would be nice to work > out how to adjust for the user's timezone offset & daylight savings. See http://vb.mvps.org/samples/TimeZone
 Signature .NET: It's About Trust! http://vfred.mvps.org
Karl E. Peterson - 03 Apr 2008 18:59 GMT >> > My goal is to be able to insert the login time of the current Windows >> > user into a cell in Excel. I have searched the net extensively, but [quoted text clipped - 11 lines] > an IF username = "Joe Bloggs" THEN... in the loop, where I would > rather just ask specifically for the user). Here's a streamlined version, indented to highlight wordwrap...
Option Explicit
Private Declare Function NetUserGetInfo Lib "netapi32" (lpServer As Any, lpUserName As Any, ByVal Level As Long, lpBuffer As Any) As Long Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Const UNLEN As Long = 256 ' Maximum username length Private Const CNLEN As Long = 31 ' Maximum computer name length Private Const NERR_Success As Long = 0&
Private Type USER_INFO_3 ' Level 0 starts here Name As Long ' Level 1 starts here Password As Long PasswordAge As Long Privilege As Long HomeDir As Long Comment As Long Flags As Long ScriptPath As Long ' Level 2 starts here AuthFlags As Long FullName As Long UserComment As Long Parms As Long Workstations As Long LastLogon As Long LastLogoff As Long AcctExpires As Long MaxStorage As Long UnitsPerWeek As Long LogonHours As Long BadPwCount As Long NumLogons As Long LogonServer As Long CountryCode As Long CodePage As Long ' Level 3 starts here UserID As Long PrimaryGroupID As Long Profile As Long HomeDirDrive As Long PasswordExpired As Long End Type
Public Function LastLogon() As Date Dim nRet As Long Dim Server As String Dim User As String Dim ui3 As USER_INFO_3 Dim lpBuffer As Long Const evServer = "LOGONSERVER" ' Retrieve current user and logon server names. User = CurrentUserName() Server = Environ$(evServer) If Len(Server) = 0 Then Server = CurrentMachineName() If InStr(Server, "\\") <> 1 Then Server = "\\" & Server ' Retrieve Level3 information on current user. nRet = NetUserGetInfo(ByVal StrPtr(Server), ByVal StrPtr(User), 3, lpBuffer) If nRet = NERR_Success Then ' Results are returned as a pointer to buffer. CopyMemory ui3, ByVal lpBuffer, Len(ui3) ' Return last logon date/time. LastLogon = NetTimeToVbTime(ui3.LastLogon) End If End Function
Private Function CurrentMachineName() As String Dim Buffer As String Dim nLen As Long Const NameLength = CNLEN + 1 ' Fall back to the ANSI method. nLen = NameLength Buffer = Space$(nLen) Call GetComputerName(Buffer, nLen) ' Trim results and return. If nLen > 0 Then CurrentMachineName = Left$(Buffer, nLen) End Function
Private Function CurrentUserName() As String Dim Buffer As String Dim nLen As Long Const NameLength = UNLEN + 1 ' ANSI method. nLen = NameLength Buffer = Space$(nLen) Call GetUserName(Buffer, nLen) ' Trim results and return. If nLen > 1 Then CurrentUserName = Left$(Buffer, nLen - 1) End Function
Private Function NetTimeToVbTime(NetDate As Long) As Double Const BaseDate# = 25569 'DateSerial(1970, 1, 1) Const SecsPerDay# = 86400 NetTimeToVbTime = BaseDate + (CDbl(NetDate) / SecsPerDay) End Function
Actually, since you're only after one value from the UserInfo3 structure, there's a slightly easier way to get at that. You can skip the structure definition entirely, and just retrieve the results into an array of Longs:
Public Function LastLogon2() As Date Dim nRet As Long Dim Server As String Dim User As String Dim ui3(1 To 29) As Long Dim lpBuffer As Long Const evServer = "LOGONSERVER" ' Retrieve current user and logon server names. User = CurrentUserName() Server = Environ$(evServer) If Len(Server) = 0 Then Server = CurrentMachineName() If InStr(Server, "\\") <> 1 Then Server = "\\" & Server ' Retrieve Level3 information on current user. nRet = NetUserGetInfo(ByVal StrPtr(Server), ByVal StrPtr(User), 3, lpBuffer) If nRet = NERR_Success Then ' Results are returned as a pointer to buffer. ' Copy 29 dwords/pointers into array of Longs. CopyMemory ui3(1), ByVal lpBuffer, UBound(ui3) * 4& ' Return last logon date/time, which is 14th element. LastLogon2 = NetTimeToVbTime(ui3(14)) End If End Function
> Also would be nice to work > out how to adjust for the user's timezone offset & daylight savings. > At the moment I am manually adding 11 hours which is the sort of > dodgyness that I loathe. Not sure I see where timezones are coming into play here? DST may be a factor, though. Not sure.
 Signature .NET: It's About Trust! http://vfred.mvps.org
Ed - 04 Apr 2008 02:48 GMT >Here's a streamlined version, indented to highlight wordwrap... <snip>
>> Also would be nice to work >> out how to adjust for the user's timezone offset & daylight savings. [quoted text clipped - 3 lines] >Not sure I see where timezones are coming into play here? DST may be a factor, >though. Not sure. I was trying to do this yesterday without any luck, so I just tried your code and it seems to be adding 5 hours on to it.
Logon time: April 3 08:39 PM. Code returns: April 4 01:39 AM.
Ed (GMT -6:00)
Larry Serflaten - 04 Apr 2008 12:52 GMT > >Here's a streamlined version, indented to highlight wordwrap... Here's a condensed WMI version....
LFS
Private Sub Form_Load() Dim usr Const qry = "SELECT * FROM Win32_NetworkLoginProfile"
For Each usr In GetObject("winmgmts:").ExecQuery(qry) Debug.Print usr.Caption Debug.Print WMIDateStringToDate(usr.LastLogOn) Next
End Sub
Function WMIDateStringToDate(dtmDate) 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
Ed - 04 Apr 2008 15:24 GMT >> >Here's a streamlined version, indented to highlight wordwrap... > >Here's a condensed WMI version.... > >LFS Was getting errors in WMIDateStringToDate so doing it this way and seems to be working OK, thanks! Ed
'--- Option Explicit
Private Function GetUserName() As String Dim EnvString As String, UserName As String Dim Indx As Integer Indx = 1 Do EnvString = Environ(Indx) If Mid$(EnvString, 1, 9) = "USERNAME=" Then GetUserName = Trim$(Mid$(EnvString, 10)) Exit Do End If Indx = Indx + 1 Loop Until EnvString = "" End Function
Private Sub Command1_Click() Dim usr Dim c As Integer Const qry = "SELECT * FROM Win32_NetworkLoginProfile"
If GetUserName <> "" Then For Each usr In GetObject("winmgmts:").ExecQuery(qry) If usr.Caption = GetUserName Then _ Debug.Print CDate(WMIDateStringToDate(usr.LastLogOn)) Next End If End Sub
Function WMIDateStringToDate(dtmDate) WMIDateStringToDate = 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
Larry Serflaten - 04 Apr 2008 22:30 GMT > Was getting errors in WMIDateStringToDate so doing it this way and seems > to be working OK, thanks! I don't see where you would have encountered errors, perhaps that should be addressed, rather than circumvented. One thing I did notice is that you use enumeration loops to pick out specific items, rather than request the desired item in the first place.
For example, GetUserName loops through the environment variables to find one labled USERNAME. If no such lable exists, it returns an empty string, otherwise it returns the current user name.
To that end, the entire routine could be rewritten to specifically request the desired data:
Private Function GetUserName() As String GetUserName = Environ$("USERNAME") End Function
Similarly, with the WMI method, you loop through the list of logged on users, looking for a specific user. If that is what you want to do, then you might as well pull out just the instance you want using the Get function:
Private Sub Form_Load() Dim usr, wmi, data
usr = "'" & Environ$("USERDOMAIN") & "\" & Environ$("USERNAME") & "'" Set wmi = GetObject("winmgmts:") Set data = wmi.Get("Win32_NetworkLoginProfile.Name=" & usr) Debug.Print data.LastLogOn
End Sub
Of course there's that issue with the time format, but I'm sure you can work that one out from the previous post....
Good luck! LFS
Karl E. Peterson - 04 Apr 2008 23:03 GMT >> Was getting errors in WMIDateStringToDate so doing it this way and seems >> to be working OK, thanks! > > I don't see where you would have encountered errors, I got a Type Mismatch, too, when I tried running it. Wasn't worth figuring out where at the time.
 Signature .NET: It's About Trust! http://vfred.mvps.org
Ed - 04 Apr 2008 23:03 GMT >> Was getting errors in WMIDateStringToDate so doing it this way and seems >> to be working OK, thanks! [quoted text clipped - 3 lines] >use enumeration loops to pick out specific items, rather than request the >desired item in the first place. <snip>
I can only assume the function erorrs because there are Nulls being returned?
For example, using this code,
For Each usr In GetObject("winmgmts:").ExecQuery(qry) Debug.Print usr.Caption Debug.Print usr.LastLogOn Next
I get this,
NT AUTHORITY\SYSTEM Null NT AUTHORITY\LOCAL SERVICE Null NT AUTHORITY\NETWORK SERVICE Null Ed 20080404142632.000000-300
Larry Serflaten - 05 Apr 2008 01:39 GMT > I can only assume the function erorrs because there are Nulls being > returned? That'd do it....
> I get this, > [quoted text clipped - 6 lines] > Ed > 20080404142632.000000-300 Can I ask what OS you use?
LFS
Ed - 05 Apr 2008 04:10 GMT >> I can only assume the function erorrs because there are Nulls being >> returned? [quoted text clipped - 15 lines] > >LFS Win XP Pro (with SP2) Upgrade version, though not sure if that matters?
Ed
Karl E. Peterson - 04 Apr 2008 19:40 GMT >>> Also would be nice to work >>> out how to adjust for the user's timezone offset & daylight savings. [quoted text clipped - 9 lines] > Logon time: April 3 08:39 PM. > Code returns: April 4 01:39 AM. Ah, yeah, I just rebooted myself, so I see now that it is returning UTC logon times. If you grab that TimeZone sample I referred you to earlier (http://vb.mvps.org/samples/TimeZone), you can drop the CTimeZone class into your project and do this:
Dim tz As New CTimeZone Dim logon As Date logon = LastLogon2() Debug.Print tz.Bias, tz.BiasDaylight, tz.BiasStandard, tz.BiasUtc Debug.Print DateAdd("n", -tz.Bias, logon)
I'm hesitant to endorse Larry's suggestion with WMI, as there just seems to be some unpredictable level of "horsiness" with it. That and, to the best of my understanding, it's not anywhere near as universal as what I'm suggesting. That said, even the Net* APIs only run on NT-class systems, so maybe that last bit of hesitation is unwarranted?
> Ed (GMT -6:00) At least part of the year, huh? <g>
 Signature .NET: It's About Trust! http://vfred.mvps.org
Larry Serflaten - 04 Apr 2008 20:48 GMT > I'm hesitant to endorse Larry's suggestion with WMI, as there just seems to be some > unpredictable level of "horsiness" with it. That and, to the best of my > understanding, it's not anywhere near as universal as what I'm suggesting. That > said, even the Net* APIs only run on NT-class systems, so maybe that last bit of > hesitation is unwarranted? Thats a bit cryptic to me, I am not sure what you meant by 'horsiness', nor universal, in that the way I see it, both WMI and the API have to be accessing the same underlying data....
None the less, I did say it was a condensed version; more of a proof of concept than a real solution. It does show another avenue of investigation for achieving the desired goal....
LFS
Karl E. Peterson - 04 Apr 2008 23:05 GMT >> I'm hesitant to endorse Larry's suggestion with WMI, as there just seems to be >> some unpredictable level of "horsiness" with it. That and, to the best of my [quoted text clipped - 3 lines] > > Thats a bit cryptic to me, I am not sure what you meant by 'horsiness', Yeah, I knew I'd owe you a better explantion. Sure wish I had one! <g> WMI has always been mysterious to me. I didn't like the blackbox nature of it, and never gained enough familiarity to trust it. Not to mention the near-total lack of fathomable documentation.
> nor universal, in that the way I see it, both WMI and the API have to be accessing > the same underlying data.... That makes sense. Which is probably the reason I backed off on that point. But in general, this particular usage aside, is WMI as widespread (OS-wise) as your basic Win32 API?
> None the less, I did say it was a condensed version; more of a proof of concept > than a real solution. It does show another avenue of investigation for achieving > the desired goal.... Yep! Sure worth looking at. The API is very straight forward, though, and thoroughly documented.
 Signature .NET: It's About Trust! http://vfred.mvps.org
Larry Serflaten - 05 Apr 2008 01:48 GMT > Yeah, I knew I'd owe you a better explantion. Sure wish I had one! <g> WMI has > always been mysterious to me. I didn't like the blackbox nature of it, and never > gained enough familiarity to trust it. Not to mention the near-total lack of > fathomable documentation. Although I bought the book and have a local .chm file for help, most of the copy is online:
http://www.microsoft.com/technet/scriptcenter/guide/default.mspx?mfr=true
HTH LFS
Ivyleaf - 05 Apr 2008 15:35 GMT On Apr 5, 11:48 am, "Larry Serflaten" <serfla...@usinternet.com> wrote:
> > Yeah, I knew I'd owe you a better explantion. Sure wish I had one! <g> WMI has > > always been mysterious to me. I didn't like the blackbox nature of it, and never [quoted text clipped - 8 lines] > HTH > LFS Hi all,
Thank you so much for your help in this! I'm sorry I hadn't returned to the thread earlier, but for some reason I hadn't been notified of the new activity. Although it was the API code that I got working first (thanks Karl!), I then also had a shot at WMI before it got mentioned here. I got fed up with that though, since the sample I found was the method where you pass a query and loop through the users which for some reason caused a pause of about 5 seconds or so (I know that doesn't sound much, but felt like ages) when you passed the query. However, after playing around again tonight with the new suggestions here, I have ended up with a WMI solution that does exactly what I want, and even corrects for timezone & daylight savings. My final code looks like this:
Function LastLogin() As Date Dim Usr, WMI, Data
Usr = "'" & Environ$("USERDOMAIN") _ & "\" & Environ$("USERNAME") & "'" Set WMI = GetObject("winmgmts:") Set Data = WMI.Get("Win32_NetworkLoginProfile.Name=" & Usr)
LastLogin = CDate(Format(Left(Data.LastLogon, 8), "####-##-##") _ & " " & Format(Mid(Data.LastLogon, 9, 6), "##:##:##"))
End Function
Thanks so much to all who contributed, and I better mention that my final solution is basically a very minor modification of Larry's code.
PS. Karl, I agree that I would actually feel more comfortable with API, but in this case the WMI code is very neat and does exactly what I need without half a page of declarations that to be honest I don't understand :). I am running this on Vista Business SP1, and will try it out on XP Pro when I'm back at work Mon.
Thanks again to all!
Cheers, Ivan.
Ed - 05 Apr 2008 17:28 GMT <snip>
>for timezone & daylight savings. My final code looks like this: > [quoted text clipped - 10 lines] > >End Function Nice, works for me on XP Pro(SP2), but still no where near as fast as API.
Cheers, Ed
Ivyleaf - 06 Apr 2008 01:43 GMT > <snip> > [quoted text clipped - 18 lines] > Cheers, > Ed Hi Ed,
API is still quicker? With the following code, I get 0.012 seconds. I don't think I could tell if something was going any quicker than that!
Option Explicit Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Sub LastLog() Dim Usr, WMI, Data Dim StartTime As Long, elTime As Double Dim LastLogin As Date, msg As String
StartTime = timeGetTime()
Usr = "'" & Environ$("USERDOMAIN") _ & "\" & Environ$("USERNAME") & "'" Set WMI = GetObject("winmgmts:") Set Data = WMI.Get("Win32_NetworkLoginProfile.Name=" & Usr)
LastLogin = CDate(Format(Left(Data.LastLogon, 8), "####-##-##") _ & " " & Format(Mid(Data.LastLogon, 9, 6), "##:##:##"))
elTime = Format((timeGetTime() - StartTime) / 1000, "0.000")
msg = "Last Login: " & LastLogin & " seconds" msg = msg & vbCr & vbCr & "Time elapsed: " & elTime & " seconds" MsgBox msg
End Sub
Cheers, Ivan.
Ivyleaf - 07 Apr 2008 06:19 GMT > > <snip> > [quoted text clipped - 54 lines] > > - Show quoted text - Doh!
Tried the function at work and it is looking at the domain login time, not the local workstation. As a result, I am getting a completely incorrect value (not sure why though). The domain seems to think that I logged in back on the 7th of February for some reason. As I don't know much about WMI, does anyone know how to specify it to look at the local machine rather than the domain? I tried replacing:
Usr = "'" & Environ$("USERDOMAIN") _ & "\" & Environ$("USERNAME") & "'"
with:
Usr = "'.\" & Environ$("USERNAME") & "'"
and a couple of other variations, but I just get errors.
Any further assistance appreciated.
Cheers, Ivan.
Larry Serflaten - 08 Apr 2008 02:13 GMT Tried the function at work and it is looking at the domain login time, not the local workstation. As a result, I am getting a completely incorrect value (not sure why though). The domain seems to think that I logged in back on the 7th of February for some reason. As I don't know much about WMI, does anyone know how to specify it to look at the local machine rather than the domain? I tried replacing:
Usr = "'" & Environ$("USERDOMAIN") _ & "\" & Environ$("USERNAME") & "'"
with:
Usr = "'.\" & Environ$("USERNAME") & "'"
and a couple of other variations, but I just get errors.
Any further assistance appreciated.
I don't get involved with networks too often, but when you log in to Windows, don't you have to provide the domain right there?
I am pressed for time right now, I'll take another look at the info in the morning, check back tomorrow for another reply....
LFS
Larry Serflaten - 08 Apr 2008 13:48 GMT Doh!
Tried the function at work and it is looking at the domain login time, not the local workstation. As a result, I am getting a completely incorrect value (not sure why though). The domain seems to think that I logged in back on the 7th of February for some reason. As I don't know much about WMI, does anyone know how to specify it to look at the local machine rather than the domain?
You may be in for a bit of experimentation. I looked through what docs I could find, and found they recommend a different method to find the logged-in user, but that method does not reveal the log in time: http://msdn2.microsoft.com/en-us/library/aa394586(VS.85).aspx
This is the tool I use for discovery of the various WMI classes: http://www.microsoft.com/downloads/details.aspx?familyid=09dfc342-648b-4119-b7eb -783b0f7d1178&displaylang=en
Which is how I found the Win32_NetworkLoginProfile class that does have a LastLogon property.
About the only thing I can think of to suggest is to loop through all those instances and check for the most recent LastLogon date to see if that will give you a clue as to what (user) account might be needed. As you supposed, the domain may need to be the local computer name rather than the network domain. But again, not being connected to a network, I can't test any of that, you'll have to experiment a little to find your way....
The code below is a VB adaptation from the Scriptomatic tool (linked above) that loops all instances of the Win32_NetworkLogonProfile classes and outputs all of the properties. For my system, I just get one instance, the machine I am currently using. Your milage may vary, see what you get. Post back here if you have questions....
LFS
' BEGIN CODE
Private Sub Form_Load()
On Error Resume Next
Const wbemFlagReturnImmediately = &H10 Const wbemFlagForwardOnly = &H20
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkLoginProfile", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly) For Each objItem In colItems Debug.Print " - = - = - = - = - = - = - = - = -" Debug.Print "Instance ObjectPath (ID): " & objItem.Path_.Path Debug.Print " - = - = - = - = - = - = - = - = -" Debug.Print "AccountExpires: " & WMIDateStringToDate(objItem.AccountExpires) Debug.Print "AuthorizationFlags: " & objItem.AuthorizationFlags Debug.Print "BadPasswordCount: " & objItem.BadPasswordCount Debug.Print "Caption: " & objItem.Caption Debug.Print "CodePage: " & objItem.CodePage Debug.Print "Comment: " & objItem.Comment Debug.Print "CountryCode: " & objItem.CountryCode Debug.Print "Description: " & objItem.Description Debug.Print "Flags: " & objItem.Flags Debug.Print "FullName: " & objItem.FullName Debug.Print "HomeDirectory: " & objItem.HomeDirectory Debug.Print "HomeDirectoryDrive: " & objItem.HomeDirectoryDrive Debug.Print "LastLogoff: " & WMIDateStringToDate(objItem.LastLogoff) Debug.Print "LastLogon: " & WMIDateStringToDate(objItem.LastLogon) Debug.Print "LogonHours: " & objItem.LogonHours Debug.Print "LogonServer: " & objItem.LogonServer Debug.Print "MaximumStorage: " & objItem.MaximumStorage Debug.Print "Name: " & objItem.Name Debug.Print "NumberOfLogons: " & objItem.NumberOfLogons Debug.Print "Parameters: " & objItem.Parameters Debug.Print "PasswordAge: " & WMIDateStringToDate(objItem.PasswordAge) Debug.Print "PasswordExpires: " & WMIDateStringToDate(objItem.PasswordExpires) Debug.Print "PrimaryGroupId: " & objItem.PrimaryGroupId Debug.Print "Privileges: " & objItem.Privileges Debug.Print "Profile: " & objItem.Profile Debug.Print "ScriptPath: " & objItem.ScriptPath Debug.Print "SettingID: " & objItem.SettingID Debug.Print "UnitsPerWeek: " & objItem.UnitsPerWeek Debug.Print "UserComment: " & objItem.UserComment Debug.Print "UserId: " & objItem.UserId Debug.Print "UserType: " & objItem.UserType Debug.Print "Workstations: " & objItem.Workstations Next
End Sub
Function WMIDateStringToDate(dtmDate) If IsNull(dtmDate) Then WMIDateStringToDate = "[NULL]" Else 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 If End Function
' END OF CODE
Ed - 07 Apr 2008 20:17 GMT >API is still quicker? With the following code, I get 0.012 seconds. I >don't think I could tell if something was going any quicker than that! > >Cheers, >Ivan. Seems the first time I call WMI based code there is a slight delay, like in the code you posted it can take as long as 0.150 to 0.250 the very first time I run it, after that I get about the same results as you did.
The API code doesn't have any delay on the very first run and worse time I got was 0.015.
Cheers, Ed
Karl E. Peterson - 07 Apr 2008 23:34 GMT > LastLogin = CDate(Format(Left(Data.LastLogon, 8), "####-##-##") _ > & " " & Format(Mid(Data.LastLogon, 9, 6), "##:##:##")) That's gonna be an issue for half the year, or should your app ever find itself in a different timezone. ;-)
 Signature .NET: It's About Trust! http://vfred.mvps.org
Karl E. Peterson - 07 Apr 2008 23:35 GMT >> Yeah, I knew I'd owe you a better explantion. Sure wish I had one! <g> WMI has >> always been mysterious to me. I didn't like the blackbox nature of it, and never [quoted text clipped - 5 lines] > > http://www.microsoft.com/technet/scriptcenter/guide/default.mspx?mfr=true Bookmarked! Thanks...
Which book was it, btw?
 Signature .NET: It's About Trust! http://vfred.mvps.org
Larry Serflaten - 08 Apr 2008 02:08 GMT > > Although I bought the book and have a local .chm file for help, most of the > > copy is online: [quoted text clipped - 4 lines] > > Which book was it, btw? Microsoft Windows 2000 Scripting Guide:
http://www.amazon.com/Microsoft-Windows-2000-Scripting-Guide/dp/0735618674/ref=p d_bbs_sr_3?ie=UTF8&s=books&qid=1207616507&sr=1-3
LFS
Karl E. Peterson - 08 Apr 2008 18:42 GMT >> > Although I bought the book and have a local .chm file for help, most of the >> > copy is online: [quoted text clipped - 8 lines] > > http://www.amazon.com/Microsoft-Windows-2000-Scripting-Guide/dp/0735618674/ref=p d_bbs_sr_3?ie=UTF8&s=books&qid=1207616507&sr=1-3 Ah, thanks.
 Signature .NET: It's About Trust! http://vfred.mvps.org
Ivyleaf - 09 Apr 2008 14:32 GMT > >> > Although I bought the book and have a local .chm file for help, most of the > >> > copy is online: [quoted text clipped - 15 lines] > > - Show quoted text - Hi All,
Thanks for the follow up. I haven't had a chance to test anything out yet, but when I get a chance, I'll give your suggestions a try and see how I go.
Thanks for your help!
Ivan.
Ed - 04 Apr 2008 23:12 GMT >Ah, yeah, I just rebooted myself, so I see now that it is returning UTC logon times. >If you grab that TimeZone sample I referred you to earlier >(http://vb.mvps.org/samples/TimeZone), you can drop the CTimeZone class into your >project and do this: <snip>
Tada! :)
Thanks Karl! Ed
|
|
|