1

I was trying to get the reboot historical from a Windows 10 computer with python but I'm affraid I can't read event-viewer.

Is there any option to get something similar to this powershell line?

get-eventlog system | where-object {$_.eventid -eq 1074} | select Timegenerated, EntryType, Message

the main idea is to do this "query" to a computer's list in local network.

  • You can call PowerShell's CLI from Python: Windows PowerShell: [`powershell.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1); PowerShell [Core] v6+: [`pwsh.exe`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pwsh). – mklement0 Jul 16 '20 at 15:43
  • you may want to look at this >>> python - Read Specific Windows Event Log Event - Stack Overflow — https://stackoverflow.com/questions/11219213/read-specific-windows-event-log-event – Lee_Dailey Jul 16 '20 at 15:51
  • @mklement0 You would have to use pythons [subprocess](https://docs.python.org/3/library/subprocess.html#module-subprocess) module to run powershell in python. Its probably just safer to use a python library like `pywin32` that interacts with COM objects natively. – RoadRunner Jul 16 '20 at 16:12
  • 1
    @RoadRunner: Yes, but this is as safe or unsafe as the PowerShell command itself that you invoke. The advantage of this approach is that you can reuse the existing PowerShell command as-is. The disadvantages are performance (though in the case of a long-running process such as this one that probably won't matter) and the need to parse the _text_ output from the PowerShell command (though, conceivably, you can pass `-of XML` to output CLIXML and parse the XML in Python). – mklement0 Jul 16 '20 at 16:17

1 Answers1

4

The simplest approach is to call PowerShell's CLI from Python: Windows PowerShell: powershell.exe; PowerShell [Core] v6+: pwsh.exe.

The following Python 3.6+ solution uses powershell.exe

# Python 3.6+ 
# (Solutions for earlier versions are possible.)

import subprocess

output = subprocess.run([
    'powershell.exe', 
    '-noprofile', 
    '-executionpolicy',
    '-bypass',
    '-c', 
    'get-eventlog system | where-object {$_.eventid -eq 1074} | select Timegenerated, EntryType, Message'
  ], 
  capture_output=True)

# CAVEAT: The *system*'s OEM code page is assumed for decoding the 
#         raw captured stdout output to text.
#         Any in-session changes to the active OEM code page via `chcp`
#         are NOT recognized; e.g., if you've changed to page 65001 (UTF-8)
#         you must use 'utf-8' explicitly.
print(output.stdout.decode('oem'))

Pros and cons:

  • The advantage of this approach is that you can reuse the existing PowerShell command as-is, which gives all the high-level functionality that PowerShell has to offer.

  • The disadvantages are:

    • Slow performance, due to the overhead of launching a PowerShell process (though in the case of a long-running process such as this one that probably won't matter)

    • The need to parse the for-display command output returned from the PowerShell command. Conceivably, you can pass -of XML in order to make PowerShell output CLIXML and parse the XML in Python); a simpler option is to modify the Powershell command to return more structured output, such as appending | ConvertTo-Csv or
      | ConvertTo-Json to the command.

mklement0
  • 382,024
  • 64
  • 607
  • 775