Hello there! In this blog post, I am sharing one of the steps from my SOAR project. By completing this guide, you will be able to retrieve Windows logs using Python.
1}Understanding Windows Logs Before retrieving logs using Python, you must understand where Windows stores logs and how they are structured.
Open Event Viewer → expand Windows Logs. You will see: Application Security Setup System Forwarded Events Each category contains events stored in a structured format.
2}Windows Event Structure Windows event has 5 parts. Log Name : Application, Security, System, Setup. Level : The level of security e.g, Info, warning, Critical, Verbose. Data and Time : When event has occurred. Source : The program, service or component that generated the event. Event ID : A unique …
Hello there! In this blog post, I am sharing one of the steps from my SOAR project. By completing this guide, you will be able to retrieve Windows logs using Python.
1}Understanding Windows Logs Before retrieving logs using Python, you must understand where Windows stores logs and how they are structured.
Open Event Viewer → expand Windows Logs. You will see: Application Security Setup System Forwarded Events Each category contains events stored in a structured format.
2}Windows Event Structure Windows event has 5 parts. Log Name : Application, Security, System, Setup. Level : The level of security e.g, Info, warning, Critical, Verbose. Data and Time : When event has occurred. Source : The program, service or component that generated the event. Event ID : A unique Identification of number.
Event Log Structure: Every Windows event has 5 important parts.
- Event ID : You already saw this (e.g., 4624 = logon).
Level : This tells how serious the event is: Information Warning Error Critical Audit Success Audit Failure 4624 = Audit Success 4625 = Audit Failure 1.
Time Created The exact timestamp when the event happened. This tells you when the action occurred. 1.
Provider (Source) This tells you who created the event. Examples: Microsoft-Windows-Security-Auditing Service Control Manager Application Error 1.
Event Details (Description / XML) Scroll down to the bottom and you will see a section called “Details”. Click Details → Select XML view. This XML view is exactly what Python reads using libraries like pywin32 or win32evtlog.
2}Python Libraries for Windows Logs There are three major options –>Option 1: pywin32 Allows Python access to Windows APIs. Offers win32evtlog and win32evtlogutil. Learn: Installing: pip install pywin32 Reading event logs using win32evtlog.OpenEventLog Parsing event records
–>Option 2: win32com / WMI Use WMI to query logs. Learn: Installing: pip install wmi Basic WMI queries (e.g., SELECT * FROM Win32_NTLogEvent)
–>Option 3: subprocess + PowerShell Run PowerShell command Get-WinEvent or Get-EventLog from Python and parse output. Learn: Using subprocess.run Reading command output (stdout)
I choose option 3, here i use python(subprocess) and power shell. Let’s start with power shell basics, Basic level of power shell learning is necessary for this. PowerShell : It is a cross-platform command-line shell and object-oriented scripting language used for system administration.
3} Power Shell Basics –>Core Log Reading Commands 1}Get-WinEvent 2}Get-EventLog 3}wevtutil qe 4}Get-Wmiobject win32_NTLogEvent 5}Get-CimInstance Win32_NTLogEvent
–>Core Log Filtering Commands 1}Where-Object 2}Select-Object 3}Sort-Object 4}Group-Object 5}Measure-Object 6}Select-String
–>Log Exporting Commands 1}Out-File 2}Export-Csv 3}ConvertTo-Json 4}wevtutil epl 5}Out-GridView
–>Log Management Command 1}wevtutil cl 2}wevtutil gl 3}New-EventLog 4}Write-EventLog 5}Remove-EventLog
–>Log File / Folder Commands 1}Get-ChildItem 2}Set-Location 3}New-Item 4}Test-Path 5}Get-Content 6}Get-Content-Wait 7}Get-Content-Tail
–>System/Metadata Commands 1}Get-EventSubscriber 2}Get-Service 3}Get-Process 4}Get-WinEvent -ListLog * 5}Get-WinEvent -ListProvider *
–>PowerShell "Thinking Tools" 1}Get-Help 2}Get-Help -Examples 3}Get-Command 4}Get-Member 5}Get-Alias
Each commands accepts only certain parameter. view them by Get-Help Example :
Get help for Get-EventLog
->Get-Help Get-EventLog
I recommend learn it online and complete some tasks to get familiar with it like ask AI tools to assign some tasks for power shell commands and complete them.
But Not all commands will work for normal user in power shell you need to run it at Administrative level.
4}How Windows Admin Rights Actually Work Windows does not allow any program to just become admin out of no where. Instead : Every program is launched with a security token. That token is either: – A standard User. – Administrator. If your script starts as a normal user, the only way to become Admin is: Show a UAC popup. Or run the script inside a session that is already elevated. Or use a scheduled task that runs elevated.
Understanding the Admin Check Code: ctypes : A python module that lets python call windows system DLLs ctypes.windll.shell32 means: Access the Windows system DLL shell32.dll
Code :
import ctypes import sys def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin()
except: return False if not is_admin(): ctypes.windll.shell32.ShellExecuteW( None, "runas", sys.executable, " ".join(sys.argv),None, 1)
print("Running as admin!")
–>ctypes.windll.shell32.IsUserAnAdmin() This line check whether user or admin
How Python Elevates Itself : If Python is not already admin, if not is_admin(): ctypes.windll.shell32.ShellExecuteW( None, "runas", sys.executable, " ".join(sys.argv),None, 1) sys.exit()
ShellExecuteW : A windows API function that can launch a new program. The above mentioned parameters : None –> No parent Window runas –> Tells windows "Run As Administrator" sys.executable –>Path to python.exe
" ".join(sys.argv) –>Arguments of your script and Because ShellExecuteW CANNOT accept a list.
sys.argv is a list. So you cannot pass it directly. Example: [‘retrivelogs.py’]
ShellExecuteW does not understand lists. It only understands strings like: "retrivelogs.py" So we convert: sys.argv → " ".join(sys.argv)
That is the ONLY reason.
We used " ".join(sys.argv) because Windows API requires ONE STRING not a Python list.
" ".join(sys.argv) = "retrivelogs.py"
None –>Working directory 1 –>Shows the windows
Now you can guess what are we trying to do, We are just executing power shell commands but in python code.
Subprocess module makes our work even easier.
5}Subprocess Module The subprocess module lets you run external commands, spawn new processes, interact with their input/output and retrieve results.
Python offers four main ways to run subprocesses but here we discuss main two: 1}subprocess.run() : Recommended High-Level Function. This is the best way to run a command and collect the result.
Signature : subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, text=False, encoding=None, errors=None)
Example : import subprocess res = subprocess.run(["ls","-l"], capture_output = True, text = True, check =True #raise error if command fails)
2}subprocess.Popen() : This is the advanced, fully configurable way. Signature : subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, text=None,
startupinfo=None, creationflags=0, pipesize=-1)
Example : from subprocess import Popen, PIPE
p = Popen(["grep", "hello"], stdin=PIPE, stdout=PIPE, text=True) out = p.communicate("hello world")[0] print(out)
2}Important Classes Returned by run() Attributes: args returncode stdout stderr
Returned by Popen() Methods: poll() — check if process ended wait() — wait until finished communicate() — send input & read output terminate() — graceful stop (SIGTERM) kill() — force kill (SIGKILL)
NOTE : Popen can stream real time output but run can’t. 1) Stream real-time output from subprocess import Popen, PIPE p = Popen(["ping", "google.com"], stdout=PIPE, text=True) for line in p.stdout: print("LIVE:", line, end="")
run() cannot do this — it waits until the command finishes.
*Python Code *: import subprocess import json import ctypes import sys
def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False
if not is_admin(): ctypes.windll.shell32.ShellExecuteW( None, "runas", sys.executable, " ".join(sys.argv),None, 1) print("Running as admin!")
command = [ "powershell", "-Command",#you can change the commands here "Get-WinEvent -LogName System -MaxEvents 5 | " "Select-Object Id, @{Name=‘TimeCreated’;Expression={$_.TimeCreated.ToString(‘yyyy-MM-dd HH:mm:ss’)}} | " "ConvertTo-Json -Depth 4" ]
result = subprocess.run(command, capture_output=True, text=True)
output = result.stdout
try: events = json.loads(output) except json.JSONDecodeError: print("Error parsing JSON. Raw output:") print(output) exit()
//Ensure output is always a list if isinstance(events, dict): events = [events]
for event in events: print(f"ID: {event[‘Id’]} Time: {event[‘TimeCreated’]}")