diff --git a/pyproject.toml b/pyproject.toml index 6d8c4d1..073c451 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,8 @@ classifiers = [ ] requires = [ - + "python-evtx", + "lxml", ] requires-python = ">=3.7" @@ -46,6 +47,10 @@ dev = [ "pre-commit", ] + +[tool.flit.scripts] +sg_document_backup = "sg_backup_doku:windows" + [tool.black] line-length = 79 py37 = true diff --git a/sg_backup_doku/__init__.py b/sg_backup_doku/__init__.py index 0d752a2..e243d2a 100644 --- a/sg_backup_doku/__init__.py +++ b/sg_backup_doku/__init__.py @@ -4,3 +4,54 @@ 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) \ No newline at end of file