0

I need to calculate the amount of time a computer was up for per month.

There seem to be various messages to check for different events which shutdown a PC:

Shutdown

  • Event ID 41 The system has rebooted without cleanly shutting down first. This error could be caused if the system stopped responding, crashed, or lost power unexpectedly.
  • Event ID 1074 Logged when an app (ex: Windows Update) causes the system to restart, or when a user initiates a restart or shutdown.
  • Event ID 6006 Logged as a clean shutdown. It gives the message "The Event log service was stopped". 6008 Logged as a dirty shutdown. It gives the message "The previous system shutdown at time on date was unexpected".
  • Event ID 1074 (alternate): "The process X has initiated the restart / shutdown of computer on behalf of user Y for the following reason: Z." Indicates that an application or a user initiated a restart or shutdown.
  • Event ID 1076 (alternate): "The reason supplied by user X for the last unexpected shutdown of this computer is: Y." Records when the first user with shutdown privileges logs on to the computer after an unexpected restart or shutdown and supplies a reason for the occurrence.

Startup

  • Event ID 12: The operating system started at system time
  • Event ID 6005 (alternate): “The event log service was started.” This is synonymous to system startup.
  • Event ID 6009 (alternate): Indicates the Windows product name, version, build number, service pack number, and operating system type detected at boot time.
  • Event ID 6013: Displays the uptime of the computer after last reboot

Is there a single log message I can examine the Windows event log for to catch all of the times a PC has shutdown/restarted?

Does Event ID 12 always get sent regardless of the reason why the shutdown occured?

Stefan
  • 3,669
  • 2
  • 32
  • 43
  • `6005, 6006` seems to be commonly used as explained [here](https://stackoverflow.com/a/11606865/1911064) and [here](https://www.howtogeek.com/277688/how-do-you-find-out-if-windows-was-running-at-a-given-time/). I've been using it for years to track my working hours. Now and then, I encounter days without properly closed interval. – Axel Kemper Jun 18 '20 at 16:24
  • @AxelKemper, if Windows shuts down due to, say, Event 1074 will it still restart with Event 6005 or does it only do that if it shuts down with Event 6006? – Stefan Jun 18 '20 at 16:29
  • `6005` does not depend on the shutdown reason, but I have not tried this constellation. – Axel Kemper Jun 18 '20 at 16:34
  • So you get 6005 regardless of why you shut down? – Stefan Jun 18 '20 at 16:35
  • Yes, this is my personal experience from Windows 95 onwards. – Axel Kemper Jun 18 '20 at 16:39
  • 1
    I should add that powersave and hibernation are not detected using events `6005, 6006`. Sending my PC to powersave caused `Kernel-Power`event `42`. Resuming back to normal led to `Power-Troubleshooter` event `1`. – Axel Kemper Jun 18 '20 at 21:30
  • So can I just check for a 6005, note the time and subtract the previous entry's time to find out how long the machine was down for? – Stefan Jun 19 '20 at 13:14

1 Answers1

0

Here is the central part of my C code which has been in use since 2001:

// Open the Systemevent log. 

h = OpenEventLog(name,  // NULL = use local computer 
         "System");     // source name 
if (h == NULL) 
    fatal("Could not open the System event log"); 

pevlr = (EVENTLOGRECORD *) &bBuffer; 

time(&startTime);

startTime   -= 30*24*3600L;         //  30 days (~ 4 weeks) before now
start        = 0;
prevDay      = 0;
earliestTime = 0;
duration     = 0;

// Opening the event log positions the file pointer for this 
// handle at the beginning of the log. Read the records 
// sequentially until there are no more. 

while (ReadEventLog(h,                // event log handle 
            EVENTLOG_FORWARDS_READ |  // reads forward 
            EVENTLOG_SEQUENTIAL_READ, // sequential read 
            0,            // ignored for sequential reads 
            pevlr,        // pointer to buffer 
            BUFFER_SIZE,  // size of buffer 
            &dwRead,      // number of bytes read 
            &dwNeeded))   // bytes in next record 
{
    while (dwRead > 0) 
    { 
        // The source name is just past the end of the 
        // formal structure. 

        sourceName = (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));
        id         = pevlr->EventID & 0x01FFF;
        now        = (time_t)(pevlr->TimeGenerated);


        if (((id == EL_START) || (id == EL_END)) && 
            (now >= startTime) &&
            !strcmp(sourceName, "EventLog"))
          {
            if (!earliestTime)
              earliestTime = now;

            dwThisRecord++;

            tm  = localtime(&now);
            day = tm->tm_mday;

            if (day != prevDay)
              {
                printf("\n%s ", DateStamp(&now));
                if (id == EL_END)
                  printf("      ... ");
              }
            else if (id == EL_START)
              printf("\n            ");

            if (id == EL_START)
              {
                if (start)
                  {
                    printf("%s ...        (no end time!)", TimeStamp(&start));
                    printf("\n       %s", TimeStamp(&now));
                  }
                else
                  {
                    printf("%s ... ", TimeStamp(&now));
                  }
                start = now;
              }
            else
              {
                if (start)
                  {
                    printf("%s  ", TimeStamp(&now));                        
                    printf("%s", Duration(now - start));
                    duration += (now - start);
                  }
                else
                  {
                    printf(" ... %s  (no start time!)", TimeStamp(&now));
                  }
                start = 0;
              }

            prevDay = day;
          }

        dwRead -= pevlr->Length; 
        pevlr   = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length); 
    } 

    pevlr = (EVENTLOGRECORD *) &bBuffer; 
} 

CloseEventLog(h); 
Axel Kemper
  • 10,544
  • 2
  • 31
  • 54