Can I analyze and accumulate work times for my users?

Hi,

Human resources asked us for a way to confirm users are working throughout the day as reported by their key cards. I’m thinking that the best way to accomplish this is to use the checks from the Power Management module. To my understanding, the innate Power Management statistics only give me the duration of a given user’s last idle/busy cycle or generic information about their idle/busy times, whereas I need to provide statistics for the time my users spent at work, not measure the time they took ‘off’ for their bathroom breaks or food or corporate meetings.

Specifically, I intend to run a task on a daily basis in the evening a few hours past the end of the work day that checks for the duration of the idle state. Through simple math I would be able to conclude when the user stopped using his or her computer for the day.

I’m less certain on the starting time for the day. Using the idle checks for that feels unnecessarily cumbersome, so is there an easier method? Perhaps checking in the evening for the first login time that day? At present I’m merely assuming people don’t come in late while I work out the bugs with what I have so far.

Finally, I want to find a way to record this information for at least a month back. That way, when HR want to check a given department I could provide statistics for them. I was thinking of writing the ‘day start’ and ‘day end’ values in a text file located under the BigFix directory on the local disk.

This is what I have so far:

parameter "mainPowerLogFolder" = "{parent folder of client folder of current site}/__Global/UsageData"
parameter "mainPowerLogFile" = "power.csv"

if {not exists file (parameter "mainPowerLogFolder" & "\" & parameter "mainPowerLogFile")}
  createfile until _end_ 
  User,Timestamp,Start of Idle Time,State
  _end_
  move __createfile "{parameter "mainPowerLogFolder"}\{parameter "mainPowerLogFile"}"
endif

if exists {name of current user}
  waithidden cmd.exe /C echo {name of current user},{concatenation "" of substrings separated by "," of (now as string)},{concatenation "" of substrings separated by "," of (start of range of (current system interval of power history) as string)},{state of current system interval of power history} >> "{parameter "mainPowerLogFolder"}\{parameter "mainPowerLogFile"}"
endif

I originally considered using “if (state of current system interval of power history = idle)” as a condition, though since I’m logging the idle state status it felt extraneous.

I have two issues with this task. The first is that for a reason I can’t understand I get a large amount of failures when trying to run it on the company computers, even on computers that previously managed to run it properly. I’m talking about the area of 20-40% of total computers whenever I try to run it.

The second is that I only manage to write the first set of values into the file, rather than append to it properly. I tried running the task as policy, but I ran into issues with that. It seems that I can set it to try again and again (say in case the computer was turned off) until it succeeds, but once it succeeds it stops, whereas I need to try and get data on a daily basis (conditions permitting).

In summary, I’d appreciate a way to fix this or, at least, to understand what I’m doing wrong. Also, is there a more elegant way of doing this?

Sincerely,
Ely

What if an employee has more than one computer?

You should be able to estimate the time spent using the computer by looking at the daily active time for that computer, or like you mentioned, subtract the idle time from 24 hours.

I would not consider this a very reliable way to estimate work time, but it may be a way to look for outliers. It would also not be hard to cheat. I do wonder if you watch an hour long training video without touching the mouse if some of that time would be considered idle time.

In order for this to work, you will need to make sure power history tracking is enabled on all of the systems. You might also want to increase the amount of time that power history is kept to something like 45 days if you really need to be able to create a report for the past month.

The info you are looking for should already be in this file: C:\Program Files (x86)\BigFix Enterprise\BES Client\__BESData\__Global\PowerHistory.db which might be in SQLite format, though I am not certain.


Another issue that I foresee is that it would be easy to double count any active time that spans over midnight. This would be a bigger issue if you try to subtract the daily idle time from 24 hours as then you may be counting the entire range from just after work until the next morning against the current day’s active time.


This is the total active time over the entire power history:

sums of lengths of ranges of system intervals whose("active" = state of it as string) of power history

Q: midnight & local time zone
A: 00:00:00 -0700
T: 0.029 ms

Q: midnight & local time zone & current date
A: Thu, 06 Jul 2017 00:00:00 -0700
T: 0.037 ms

Q: (it & (it - 1*day)) of (midnight & local time zone & current date)
A: Wed, 05 Jul 2017 00:00:00 -0700 to Thu, 06 Jul 2017 00:00:00 -0700
T: 0.080 ms

I have very little confidence in this, but this should be the total active time of the previous day:

sums of lengths of ranges whose( ((it & (it - 1*day)) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history

Hey jgstew,

Thanks for the response! I believe there was a slight misunderstanding of my goals, which I’ll try to correct.

I don’t want to use the innate idle/busy cycles throughout the full day because, as you’ve said, they’re misleading and easy to fool. What I’m interested in is when the user let the computer go idle for the remainder of the day. Assuming a usual work day that ends around 6pm, if I check for idleness around 9pm I should get ~3 hours of idle state for regular users, and say 5 hours of idleness for a user that left around 4pm. Of course if the computer is regularly ‘busy’ and not idle at 9pm while the keycard entries show the user had already clocked out, that would be a good sign of tampering. I don’t really believe this would be an issue, so I’m assuming our users use their computers in good faith.

In the case a user has two or more computers, each computer will collect data for itself. If I need to get their data, I will simply use the one with the latest ‘exit time’, gotten from the math of 9pm - amount of time the computer was idle. I don’t expect this to be an issue, though I could treat such users as miniature ‘departments’ and collate their data that way, same as I intend to do for actual departments for the purpose of statistics.

Going back 45 days or more is a great suggestion, I’ll happily adopt it.

The PowerHistory.db file is indeed in SQLite format, thanks for pointing me in that direction. I’m not exactly sure how far back it goes, however, or how to read the ‘EventTime’ and ‘EventType’ entries. I can guess at the latter, but I’m not sure what format is being used to denote the time. In any case, if BigFix automatically deletes the older entries when it writes in new ones, I don’t think I could use it as my own log so wouldn’t I need to create my own csv/db file after all? Or can I tell Power History to keep all data for 45 days back? If so, where would I do this?

In case I manage to set the Power History to store data as far back as I’m asked, how would you suggest I question it for daily statistics? Let’s say work hours are Sun-Thu, 08:00-18:00, and I want to present my estimated starting times and finish times for the past week, ie, Sun: 08:10-18:15, Mon: 08:00-17:55…

Ely

Okay, so it sounds like you want to get the first active time and last active time of each day of each computer to estimate when a user “clocked in” and “clocked out”?

One problem I can see is that if someone bumps the mouse of a computer after someone left, then it might throw off the numbers.

I’ll have to look into this. I think it is configurable, but I don’t see a setting here: Legacy Communities - IBM TechXchange Community


This could probably be better, but this should be the earliest active time and the latest active time of the previous day:

(minimum of starts of ranges whose( ((it & (it - 1*day)) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) & (maximum of ends of ranges whose( ((it & (it - 1*day)) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history)

This will not be accurate if they worked over midnight. It will also throw an error if there is no active power history on the previous day, which is not ideal.


This should be the length of time between them, plus the range itself:

(length of it, it) of ( (minimum of starts of ranges whose( ((it & (it - 1*day)) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) & (maximum of ends of ranges whose( ((it & (it - 1*day)) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) )

There is probably a better way to optimize doing this for multiple days, but this should be the past 2 days:

(length of it, it) of ( (minimum of starts of ranges whose( (( (it - 0*day) & (it - 1*day) ) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) & (maximum of ends of ranges whose( (( (it - 0*day) & (it - 1*day) ) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) ) ; (length of it, it) of ( (minimum of starts of ranges whose( (( (it - 1*day) & (it - 2*day) ) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) & (maximum of ends of ranges whose( (( (it - 1*day) & (it - 2*day) ) of (midnight & local time zone & current date)) contains it ) of system intervals whose("active" = state of it as string) of power history) )

Doing multiple days in the same statement can cause issues due to either day causing both to throw an error due to there not being an active time in one of the days.

It should be possible to have an action that would store the length of time and the range for the only the past X days that are not already stored. Any day that throws an error would just be a 0.

I also wanted to just say that this is a bit big brother-ish and user trust is definitely important. I’m not a big fan of using BigFix for something like this, even though it is possible.

If all users use Active Directory, then the time they first login each day from a joined computer might be a better start of day metric. It may have a similar big brother effect, but Active Directory is less problematic because it is essential for access and feels better than the idea that the computer itself is spying on you.

1 Like

I’m with JG on this one. It is very big brother. However, I do think that you can do this in a way that won’t be so big brother.

If you are using the ClientUI Dashboard, you could report to them the amount of time their computer was spent off, asleep, idle, or working. This would help them understand their own work and power habits, and let them know that it is being monitored.

2 Likes

I also thought of this use case, though you can have a ClientUI dashboard that gives the user this info but NOT actually monitor it with bigfix centrally… only provide the info to the user using relevance. I was actually thinking this could be useful for my own personal use. I was thinking if I could have the active time by logged on user reported, then know how much time my kids use the computer, but in a way that is transparent to them and me.

there are a ton of factors that could contribute to someones idle time, and a lot of different job roles that probably average various amounts of seat time. what about all of the non idle time that the user is just screwing off? what if they work in a manner that isn’t using their primary workstation at all? I don’t see how that measurement will be very useful, short of maybe identifying outliers that could be further investigated… when HR is asking for this kind of information, I would try to really think it through - the information can be interpreted in a lot of ways and consequences potentially directed poorly. these sort of requests or issues usually speak more to poor management moreso than employees, in my opinion.

1 Like

So you aren’t wrong in general, but it isn’t as bad as you are suggesting. The request is to determine the time between the very first active time of the day and the end of the very last active time of the day. This is more of when the user started their day and ended their day and does not take into account how much idle time they had in between.

This still has some feelings of big brother, but I could see this info being useful for some users in a ClientUI dashboard without any reporting at all. It would give me an idea of the timing of things that I don’t usually remember and also let me know if someone was using my computer before I arrived or after I left if the time range is not what I expected it to be.

Thanks again! On the Big Brother-lite front, I can see where it might make people uneasy, but I believe that wanting to collect information about the first and last time someone touched their work computer during the day (and that’s it) is not that different from collecting information about clocking in and out that day via their employee keycards which is information HR obviously has. And yes, I imagine it would really only be useful to HR to check for outliers. Personally, the possibility interested me since it was an opportunity to customize the power settings better.

jgstew, I made an analysis with your suggestions and they work great! Unfortunately, I still get over 40% of errors from my computers (singular expression refers to nonexistent object). It’s weird, because I reconfirmed that I have power tracking enabled on all computers through the Power Management Health Checks dashboard. I must be missing something, but I can’t figure out what.

Also, from my original question. I like the idea of writing down statistics on the target computers. A good use for it that I can think of is to note when windows updates via BigFix successfully took place, since the Windows Update item under control panel doesn’t list every last update via BigFix unless you go all the way into view update history and then into installed updates. Is there a good way for a policy to do that on a regular basis? Without stopping once there is an error, or upon first success?

Ely

This might be due to how the relevance is written to compute the values. If there are no entries for a particular day, then this error would be expected, which is why it might be needed to handle each previous day separately, which is a bit messy.

if you only want to see when they sign in and when they stop working, why not just analyze local computer events for sign in, sign out, computer lock etc?

I’d add that the computer alone may not be a good judge.

It’s not uncommon for me to spend an hour or two at the beginning or end of the day, sketching designs out on a whiteboard or notebook rather than on my workstation, for example. Or tracking down people and collaborating, sometimes on their workstation rather than one of mine.

Or logged in directly at one server or another rather than my client workstation, when troubleshooting, especially later at night.