|
|
|
""" SG Backup Doku
|
|
|
|
|
|
|
|
Automagically document the windows backup process
|
|
|
|
"""
|
|
|
|
|
|
|
|
__version__ = "0.0.1"
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
import Evtx.Evtx as evtx
|
|
|
|
import Evtx.Views as e_views
|
|
|
|
|
|
|
|
|
|
|
|
SCHEMA = "{http://schemas.microsoft.com/win/2004/08/events/event}"
|
|
|
|
|
|
|
|
LEFT_TO_RIGHT_MARK = "\u200e"
|
|
|
|
|
|
|
|
LOG_TIME_FORMAT = "%d/%m/%Y %H:%M"
|
|
|
|
DOC_DATE_FORMAT = "%Y-%m-%d"
|
|
|
|
DOC_DATE_TIME_FORMAT = DOC_DATE_FORMAT + " %H:%M"
|
|
|
|
|
|
|
|
|
|
|
|
def _get_backup_time(record):
|
|
|
|
""" extract the raw date from an log entry record """
|
|
|
|
node = record.lxml()
|
|
|
|
for item in node.iter(f"{SCHEMA}Data"):
|
|
|
|
if item.attrib.get("Name") == "ProtectedUpToTime":
|
|
|
|
if item.text in (None, "NULL"):
|
|
|
|
return None
|
|
|
|
raw = item.text.replace(LEFT_TO_RIGHT_MARK, "")
|
|
|
|
return datetime.strptime(raw, LOG_TIME_FORMAT)
|
|
|
|
|
|
|
|
|
|
|
|
def get_last_backup_time(path):
|
|
|
|
with evtx.Evtx(path) as log:
|
|
|
|
time_entries = (_get_backup_time(record) for record in log.records())
|
|
|
|
backup_times = (entry for entry in time_entries if entry)
|
|
|
|
return max(backup_times)
|
|
|
|
|
|
|
|
|
|
|
|
def document_last_backup_time(path, last_backup_time):
|
|
|
|
with open(path, "a") as fh:
|
|
|
|
now = datetime.now()
|
|
|
|
now_text = now.strftime(DOC_DATE_FORMAT)
|
|
|
|
last_backup_text = last_backup_time.strftime(DOC_DATE_TIME_FORMAT)
|
|
|
|
line = f"{now_text}\tLast successful backup on {last_backup_text}"
|
|
|
|
fh.write(f"{line}\n")
|
|
|
|
|
|
|
|
|
|
|
|
def windows():
|
|
|
|
LOG_FILE_PATH = r"C:\Windows\System32\winevt\Logs\Microsoft-Windows-FileHistory-Core%4WHC.evtx"
|
|
|
|
OUT_FILE_PATH = r"C:\Users\Holgi\Documents\safeguard_backup_documentation.txt"
|
|
|
|
|
|
|
|
last_backup = get_last_backup_time(Path(LOG_FILE_PATH))
|
|
|
|
document_last_backup_time(Path(OUT_FILE_PATH), last_backup)
|