Esempio n. 1
0
    private static void DoWork(string f, string csv, string dt, bool debug, bool trace)
    {
        var levelSwitch = new LoggingLevelSwitch();

        _activeDateTimeFormat = dt;

        var formatter =
            new DateTimeOffsetFormatter(CultureInfo.CurrentCulture);

        var template = "{Message:lj}{NewLine}{Exception}";

        if (debug)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Debug;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        if (trace)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Verbose;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        var conf = new LoggerConfiguration()
                   .WriteTo.Console(outputTemplate: template, formatProvider: formatter)
                   .MinimumLevel.ControlledBy(levelSwitch);

        Log.Logger = conf.CreateLogger();

        if (f.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("-f is required. Exiting");
            Console.WriteLine();
            return;
        }

        if (csv.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("--csv is required. Exiting");
            Console.WriteLine();
            return;
        }

        if (!File.Exists(f))
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("File '{F}' not found. Exiting", f);
            Console.WriteLine();
            return;
        }

        var userProfile = string.Empty;


        try {
            userProfile = Regex.Match(f, @"\\Users\\(.+?)\\", RegexOptions.IgnoreCase).Groups[1].Value;

            if (userProfile.Length > 0)
            {
                userProfile = $"_{userProfile}";
            }
        } catch (ArgumentException) {
            // Syntax error in the regular expression
        }

        Log.Information("{Header}", Header);
        Console.WriteLine();
        Log.Information("Command line: {Args}", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
        Console.WriteLine();

        if (IsAdministrator() == false)
        {
            Log.Warning("Warning: Administrator privileges not found!");
            Console.WriteLine();
        }


        DumpSqliteDll();

        var sw1 = new Stopwatch();

        sw1.Start();

        var apes      = new List <ActivityPackageIdEntry>();
        var activitys = new List <ActivityEntry>();
        var aoes      = new List <ActivityOperationEntry>();

        var dbFactory = new OrmLiteConnectionFactory(f, SqliteDialect.Provider);

        try
        {
            SqliteDialect.Provider.RegisterConverter <DateTimeOffset>(new EpochConverter());
            SqliteDialect.Provider.RegisterConverter <DateTimeOffset?>(new EpochConverter());

            using (var db = dbFactory.OpenDbConnection())
            {
                try
                {
                    var activityOperations = db.Select <ActivityOperation>();

                    Log.Information("{Table} entries found: {Count:N0}", "ActivityOperation", activityOperations.Count);

                    foreach (var op in activityOperations)
                    {
                        string exeName;

                        var appIdInfo = op.AppId.FromJson <List <AppIdInfo> >();

                        var idInfo = appIdInfo.FirstOrDefault(t =>
                                                              t.Platform.EqualsIgnoreCase("windows_win32") ||
                                                              t.Platform.EqualsIgnoreCase("x_exe_path"));

                        if (idInfo == null)
                        {
                            idInfo = appIdInfo.First();
                        }

                        if (idInfo.Application.Contains(".exe"))
                        {
                            var segs = idInfo.Application.Split('\\');

                            if (segs[0].StartsWith("{"))
                            {
                                var newname = GuidMapping.GuidMapping.GetDescriptionFromGuid(segs[0]);

                                segs[0] = newname;

                                exeName = string.Join("\\", segs);
                            }
                            else
                            {
                                exeName = idInfo.Application;
                            }
                        }
                        else
                        {
                            exeName = idInfo.Application;
                        }

                        var displayText    = string.Empty;
                        var contentInfo    = string.Empty;
                        var devicePlatform = string.Empty;
                        var timeZone       = string.Empty;
                        var description    = string.Empty;

                        var payload = Encoding.ASCII.GetString(op.Payload);

                        var clipPay = string.Empty;

                        if (op.ClipboardPayload is { Length: > 0 })
                        {
                            clipPay = Encoding.ASCII.GetString(op.ClipboardPayload);
                        }

                        if (payload.StartsWith("{"))
                        {
                            var dti = payload.FromJson <PayloadData>();

                            timeZone       = dti.UserTimezone;
                            devicePlatform = dti.DevicePlatform;
                            displayText    = dti.DisplayText;

                            if (dti.ContentUri != null || dti.Description != null)
                            {
                                displayText = $"{dti.DisplayText} ({dti.AppDisplayName})";

                                var ci = dti.ContentUri.UrlDecode();

                                contentInfo = $"{dti.Description} ({dti.ContentUri.UrlDecode()})";

                                if (ci != null)
                                {
                                    if (ci.Contains("{") & ci.Contains("}"))
                                    {
                                        var start = ci.Substring(0, 5);
                                        var guid  = ci.Substring(6, 36);
                                        var end   = ci.Substring(43);

                                        var upContent =
                                            $"{start}{GuidMapping.GuidMapping.GetDescriptionFromGuid(guid)}{end}";

                                        contentInfo = $"{dti.Description} ({upContent})";
                                    }
                                }
                            }
                        }
                        else
                        {
                            payload = "(Binary data)";
                        }

                        var aoe = new ActivityOperationEntry(op.Id.ToString(), op.OperationOrder, op.AppId, exeName,
                                                             op.ActivityType, op.LastModifiedTime, op.ExpirationTime, payload, op.CreatedTime,
                                                             op.EndTime, op.LastModifiedOnClient, op.OperationExpirationTime, op.PlatformDeviceId,
                                                             op.OperationType, devicePlatform, timeZone, description, op.StartTime, displayText,
                                                             clipPay, contentInfo);

                        aoes.Add(aoe);
                    }
                }
                catch (Exception e)
                {
                    if (e.Message.Contains("no such table"))
                    {
                        Log.Error("{Table} table does not exist!", "ActivityOperation");
                    }
                    else
                    {
                        Log.Error(e, "Error processing {Table} table: {Message}", "ActivityOperation", e.Message);
                    }
                }

                try
                {
                    var activityPackageIds = db.Select <ActivityPackageId>();

                    Log.Information("{Table} entries found: {Count:N0}", "Activity_PackageId", activityPackageIds.Count);

                    foreach (var packageId in activityPackageIds)
                    {
                        var exeName = string.Empty;

                        if (packageId.PackageName.Contains(".exe"))
                        {
                            var segs = packageId.PackageName.Split('\\');

                            if (segs[0].StartsWith("{"))
                            {
                                var newname = GuidMapping.GuidMapping.GetDescriptionFromGuid(segs[0]);

                                segs[0] = newname;

                                exeName = string.Join("\\", segs);
                            }
                        }

                        var ape = new ActivityPackageIdEntry(packageId.ActivityId.ToString(), packageId.Platform,
                                                             packageId.PackageName, exeName, packageId.ExpirationTime);

                        apes.Add(ape);
                    }
                }
                catch (Exception e)
                {
                    if (e.Message.Contains("no such table"))
                    {
                        Log.Error("{Table} table does not exist!", "ActivityPackageId");
                    }
                    else
                    {
                        Log.Error(e, "Error processing {Table} table: {Message}", "ActivityPackageId", e.Message);
                    }
                }

                try
                {
                    var activities = db.Select <Classes.Activity>();

                    Log.Information("{Table} entries found: {Count:N0}", "Activity", activities.Count);

                    foreach (var act in activities)
                    {
                        var foo = act.AppId.FromJson <List <AppIdInfo> >();

                        var win32 = foo.FirstOrDefault(
                            t => t.Platform == "windows_win32" || t.Platform == "x_exe_path");

                        string exe;

                        if (win32 != null)
                        {
                            exe = win32.Application;
                        }
                        else
                        {
                            var wu = foo.FirstOrDefault(t => t.Platform == "windows_universal");
                            if (wu != null)
                            {
                                exe = wu.Application;
                            }
                            else
                            {
                                exe = foo.First().Application;
                            }
                        }

                        if (exe.StartsWith("{"))
                        {
                            var segs = exe.Split('\\');

                            if (segs[0].StartsWith("{"))
                            {
                                var newname = GuidMapping.GuidMapping.GetDescriptionFromGuid(segs[0]);

                                segs[0] = newname;

                                exe = string.Join("\\", segs);
                            }
                        }

                        var displayText    = string.Empty;
                        var contentInfo    = string.Empty;
                        var devicePlatform = string.Empty;
                        var timeZone       = string.Empty;

                        var clipPay = string.Empty;

                        if (act.ClipboardPayload is { Length: > 0 })
                        {
                            clipPay = Encoding.ASCII.GetString(act.ClipboardPayload);
                        }

                        var payload = Encoding.ASCII.GetString(act.Payload);

                        if (payload.StartsWith("{"))
                        {
                            var dti = payload.FromJson <PayloadData>();

                            timeZone       = dti.UserTimezone;
                            devicePlatform = dti.DevicePlatform;
                            displayText    = dti.DisplayText;

                            if (dti.ContentUri != null || dti.Description != null)
                            {
                                displayText = $"{dti.DisplayText} ({dti.AppDisplayName})";

                                var ci = dti.ContentUri.UrlDecode();

                                contentInfo = $"{dti.Description} ({dti.ContentUri.UrlDecode()})";

                                if (ci != null)
                                {
                                    if (ci.Contains("{") & ci.Contains("}"))
                                    {
                                        var start = ci.Substring(0, 5);
                                        var guid  = ci.Substring(6, 36);
                                        var end   = ci.Substring(43);

                                        var upContent =
                                            $"{start}{GuidMapping.GuidMapping.GetDescriptionFromGuid(guid)}{end}";

                                        contentInfo = $"{dti.Description} ({upContent})";
                                    }
                                }
                            }
                        }
                        else
                        {
                            payload = "(Binary data)";
                        }

                        var a = new ActivityEntry(act.Id.ToString(), exe, displayText, contentInfo,
                                                  act.LastModifiedTime, act.ExpirationTime, act.CreatedInCloud, act.StartTime,
                                                  act.EndTime,
                                                  act.LastModifiedOnClient, act.OriginalLastModifiedOnClient, act.ActivityType,
                                                  act.IsLocalOnly == 1, act.ETag, act.PackageIdHash, act.PlatformDeviceId, devicePlatform,
                                                  timeZone, payload, clipPay);

                        activitys.Add(a);
                    }
Esempio n. 2
0
    private static void DoWork(string d, string f, bool q, string csv, string csvf, string dt, bool debug, bool trace)
    {
        ActiveDateTimeFormat = dt;

        var formatter =
            new DateTimeOffsetFormatter(CultureInfo.CurrentCulture);

        var levelSwitch = new LoggingLevelSwitch();

        var template = "{Message:lj}{NewLine}{Exception}";

        if (debug)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Debug;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        if (trace)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Verbose;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        var conf = new LoggerConfiguration()
                   .WriteTo.Console(outputTemplate: template, formatProvider: formatter)
                   .MinimumLevel.ControlledBy(levelSwitch);

        Log.Logger = conf.CreateLogger();

        if (f.IsNullOrEmpty() &&
            d.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("Either -f or -d is required. Exiting");
            return;
        }

        if (f.IsNullOrEmpty() == false &&
            !File.Exists(f))
        {
            Log.Warning("File {F} not found. Exiting", f);
            return;
        }

        if (d.IsNullOrEmpty() == false &&
            !Directory.Exists(d))
        {
            Log.Warning("Directory {D} not found. Exiting", d);
            return;
        }

        Log.Information("{Header}", Header);
        Console.WriteLine();
        Log.Information("Command line: {Args}", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));

        if (IsAdministrator() == false)
        {
            Log.Warning("Warning: Administrator privileges not found!");
            Console.WriteLine();
        }

        _csvOuts     = new List <CsvOut>();
        _failedFiles = new List <string>();

        var files = new List <string>();

        var sw = new Stopwatch();

        sw.Start();

        if (f?.Length > 0)
        {
            files.Add(f);
        }
        else
        {
            Console.WriteLine();

            Log.Information("Looking for files in {Dir}", d);
            if (!q)
            {
                Console.WriteLine();
            }

            files = GetRecycleBinFiles(d);
        }

        Log.Information("Found {Count:N0} files. Processing...", files.Count);

        if (!q)
        {
            Console.WriteLine();
        }

        foreach (var file in files)
        {
            ProcessFile(file, q, dt);
        }

        sw.Stop();

        Console.WriteLine();
        Log.Information(
            "Processed {FailedFilesCount:N0} out of {Count:N0} files in {TotalSeconds:N4} seconds", files.Count - _failedFiles.Count, files.Count, sw.Elapsed.TotalSeconds);
        Console.WriteLine();

        if (_failedFiles.Count > 0)
        {
            Console.WriteLine();
            Log.Information("Failed files");
            foreach (var failedFile in _failedFiles)
            {
                Log.Information("  {FailedFile}", failedFile);
            }
        }

        if (csv.IsNullOrEmpty() == false && files.Count > 0)
        {
            if (Directory.Exists(csv) == false)
            {
                Log.Information("{Csv} does not exist. Creating...", csv);
                Directory.CreateDirectory(csv);
            }

            var outName = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_RBCmd_Output.csv";

            if (csvf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(csvf);
            }


            var outFile = Path.Combine(csv, outName);

            outFile =
                Path.GetFullPath(outFile);

            Log.Warning("CSV output will be saved to {Path}", Path.GetFullPath(outFile));

            try
            {
                var sw1       = new StreamWriter(outFile);
                var csvWriter = new CsvWriter(sw1, CultureInfo.InvariantCulture);

                csvWriter.WriteHeader(typeof(CsvOut));
                csvWriter.NextRecord();

                foreach (var csvOut in _csvOuts)
                {
                    csvWriter.WriteRecord(csvOut);
                    csvWriter.NextRecord();
                }

                sw1.Flush();
                sw1.Close();
            }
            catch (Exception ex)
            {
                Log.Error(ex,
                          "Unable to open {OutFile} for writing. CSV export canceled. Error: {Message}", outFile, ex.Message);
            }
        }
    }
Esempio n. 3
0
    private static void DoWork(string f, string d, string csv, string csvf, string json, string jsonf, string xml, string xmlf, string dt, string inc, string exc, string sd, string ed, bool fj, int tdt, bool met, string maps, bool vss, bool dedupe, bool sync, bool debug, bool trace)
    {
        var levelSwitch = new LoggingLevelSwitch();

        _activeDateTimeFormat = dt;

        var formatter =
            new DateTimeOffsetFormatter(CultureInfo.CurrentCulture);

        var template = "{Message:lj}{NewLine}{Exception}";

        if (debug)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Debug;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        if (trace)
        {
            levelSwitch.MinimumLevel = LogEventLevel.Verbose;
            template = "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        }

        var conf = new LoggerConfiguration()
                   .WriteTo.Console(outputTemplate: template, formatProvider: formatter)
                   .MinimumLevel.ControlledBy(levelSwitch);

        Log.Logger = conf.CreateLogger();

        if (sync)
        {
            try
            {
                Log.Information("{Header}", Header);
                UpdateFromRepo();
            }
            catch (Exception e)
            {
                Log.Error(e, "There was an error checking for updates: {Message}", e.Message);
            }

            Environment.Exit(0);
        }

        if (f.IsNullOrEmpty() &&
            d.IsNullOrEmpty())
        {
            var helpBld = new HelpBuilder(LocalizationResources.Instance, Console.WindowWidth);
            var hc      = new HelpContext(helpBld, _rootCommand, Console.Out);

            helpBld.Write(hc);

            Log.Warning("-f or -d is required. Exiting");
            Console.WriteLine();
            return;
        }

        Log.Information("{Header}", Header);
        Console.WriteLine();
        Log.Information("Command line: {Args}", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
        Console.WriteLine();

        if (IsAdministrator() == false)
        {
            Log.Warning("Warning: Administrator privileges not found!");
            Console.WriteLine();
        }

        if (vss & !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            vss = false;
            Log.Warning("{Vss} not supported on non-Windows platforms. Disabling...", "--vss");
            Console.WriteLine();
        }

        if (vss & (IsAdministrator() == false))
        {
            Log.Error("{Vss} is present, but administrator rights not found. Exiting", "--vss");
            Console.WriteLine();
            return;
        }

        var sw = new Stopwatch();

        sw.Start();

        var ts = DateTimeOffset.UtcNow;

        _errorFiles = new Dictionary <string, int>();

        if (json.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(json) == false)
            {
                Log.Information("Path to {Json} doesn't exist. Creating...", json);

                try
                {
                    Directory.CreateDirectory(json);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Json}. Does a file with the same name exist? Exiting", json);
                    Console.WriteLine();
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.json";

            if (jsonf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(jsonf);
            }

            var outFile = Path.Combine(json, outName);

            Log.Information("json output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swJson = new StreamWriter(outFile, false, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }

            JsConfig.DateHandler = DateHandler.ISO8601;
        }

        if (xml.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(xml) == false)
            {
                Log.Information("Path to {Xml} doesn't exist. Creating...", xml);

                try
                {
                    Directory.CreateDirectory(xml);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Xml}. Does a file with the same name exist? Exiting", xml);
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.xml";

            if (xmlf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(xmlf);
            }

            var outFile = Path.Combine(xml, outName);

            Log.Information("XML output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swXml = new StreamWriter(outFile, false, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }
        }

        if (sd.IsNullOrEmpty() == false)
        {
            if (DateTimeOffset.TryParse(sd, null, DateTimeStyles.AssumeUniversal, out var dateTimeOffset))
            {
                _startDate = dateTimeOffset;
                Log.Information("Setting Start date to {StartDate}", _startDate.Value);
            }
            else
            {
                Log.Warning("Could not parse {Sd} to a valid datetime! Events will not be filtered by Start date!", sd);
            }
        }

        if (ed.IsNullOrEmpty() == false)
        {
            if (DateTimeOffset.TryParse(ed, null, DateTimeStyles.AssumeUniversal, out var dateTimeOffset))
            {
                _endDate = dateTimeOffset;
                Log.Information("Setting End date to {EndDate}", _endDate.Value);
            }
            else
            {
                Log.Warning("Could not parse {Ed} to a valid datetime! Events will not be filtered by End date!", ed);
            }
        }

        if (_startDate.HasValue || _endDate.HasValue)
        {
            Console.WriteLine();
        }


        if (csv.IsNullOrEmpty() == false)
        {
            if (Directory.Exists(csv) == false)
            {
                Log.Information(
                    "Path to {Csv} doesn't exist. Creating...", csv);

                try
                {
                    Directory.CreateDirectory(csv);
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex,
                              "Unable to create directory {Csv}. Does a file with the same name exist? Exiting", csv);
                    return;
                }
            }

            var outName = $"{ts:yyyyMMddHHmmss}_EvtxECmd_Output.csv";

            if (csvf.IsNullOrEmpty() == false)
            {
                outName = Path.GetFileName(csvf);
            }

            var outFile = Path.Combine(csv, outName);

            Log.Information("CSV output will be saved to {OutFile}", outFile);
            Console.WriteLine();

            try
            {
                _swCsv = new StreamWriter(outFile, false, Encoding.UTF8);

                var opt = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    ShouldUseConstructorParameters = _ => false
                };

                _csvWriter = new CsvWriter(_swCsv, opt);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unable to open {OutFile}! Is it in use? Exiting!", outFile);
                Console.WriteLine();
                Environment.Exit(0);
            }


            var foo = _csvWriter.Context.AutoMap <EventRecord>();

            foo.Map(t => t.RecordPosition).Ignore();
            foo.Map(t => t.Size).Ignore();
            foo.Map(t => t.Timestamp).Ignore();

            foo.Map(t => t.RecordNumber).Index(0);
            foo.Map(t => t.EventRecordId).Index(1);
            foo.Map(t => t.TimeCreated).Index(2);
            foo.Map(t => t.TimeCreated).Convert(t =>
                                                $"{t.Value.TimeCreated.ToString(dt)}");
            foo.Map(t => t.EventId).Index(3);
            foo.Map(t => t.Level).Index(4);
            foo.Map(t => t.Provider).Index(5);
            foo.Map(t => t.Channel).Index(6);
            foo.Map(t => t.ProcessId).Index(7);
            foo.Map(t => t.ThreadId).Index(8);
            foo.Map(t => t.Computer).Index(9);
            foo.Map(t => t.UserId).Index(10);
            foo.Map(t => t.MapDescription).Index(11);
            foo.Map(t => t.UserName).Index(12);
            foo.Map(t => t.RemoteHost).Index(13);
            foo.Map(t => t.PayloadData1).Index(14);
            foo.Map(t => t.PayloadData2).Index(15);
            foo.Map(t => t.PayloadData3).Index(16);
            foo.Map(t => t.PayloadData4).Index(17);
            foo.Map(t => t.PayloadData5).Index(18);
            foo.Map(t => t.PayloadData6).Index(19);
            foo.Map(t => t.ExecutableInfo).Index(20);
            foo.Map(t => t.HiddenRecord).Index(21);
            foo.Map(t => t.SourceFile).Index(22);
            foo.Map(t => t.Keywords).Index(23);
            foo.Map(t => t.Payload).Index(24);

            _csvWriter.Context.RegisterClassMap(foo);
            _csvWriter.WriteHeader <EventRecord>();
            _csvWriter.NextRecord();
        }

        if (Directory.Exists(maps) == false)
        {
            Log.Warning("Maps directory {Maps} does not exist! Event ID maps will not be loaded!!", maps);
        }
        else
        {
            Log.Debug("Loading maps from {Path}", Path.GetFullPath(maps));
            var errors = EventLog.LoadMaps(Path.GetFullPath(maps));

            if (errors)
            {
                return;
            }

            Log.Information("Maps loaded: {Count:N0}", EventLog.EventLogMaps.Count);
        }

        _includeIds = new HashSet <int>();
        _excludeIds = new HashSet <int>();

        if (exc.IsNullOrEmpty() == false)
        {
            var excSegs = exc.Split(',');

            foreach (var incSeg in excSegs)
            {
                if (int.TryParse(incSeg, out var goodId))
                {
                    _excludeIds.Add(goodId);
                }
            }
        }

        if (inc.IsNullOrEmpty() == false)
        {
            _excludeIds.Clear();
            var incSegs = inc.Split(',');

            foreach (var incSeg in incSegs)
            {
                if (int.TryParse(incSeg, out var goodId))
                {
                    _includeIds.Add(goodId);
                }
            }
        }

        if (vss)
        {
            string driveLetter;
            if (f.IsEmpty() == false)
            {
                driveLetter = Path.GetPathRoot(Path.GetFullPath(f))
                              .Substring(0, 1);
            }
            else
            {
                driveLetter = Path.GetPathRoot(Path.GetFullPath(d))
                              .Substring(0, 1);
            }


            Helper.MountVss(driveLetter, VssDir);
            Console.WriteLine();
        }

        EventLog.TimeDiscrepancyThreshold = tdt;

        if (f.IsNullOrEmpty() == false)
        {
            if (File.Exists(f) == false)
            {
                Log.Warning("\t{F} does not exist! Exiting", f);
                Console.WriteLine();
                return;
            }

            if (_swXml == null && _swJson == null && _swCsv == null)
            {
                //no need for maps
                Log.Debug("Clearing map collection since no output specified");
                EventLog.EventLogMaps.Clear();
            }

            dedupe = false;

            ProcessFile(Path.GetFullPath(f), dedupe, fj, met);

            if (vss)
            {
                var vssDirs = Directory.GetDirectories(VssDir);

                var root = Path.GetPathRoot(Path.GetFullPath(f));
                var stem = Path.GetFullPath(f).Replace(root, "");

                foreach (var vssDir in vssDirs)
                {
                    var newPath = Path.Combine(vssDir, stem);
                    if (File.Exists(newPath))
                    {
                        ProcessFile(newPath, dedupe, fj, met);
                    }
                }
            }
        }
        else
        {
            if (Directory.Exists(d) == false)
            {
                Log.Warning("\t{D} does not exist! Exiting", d);
                Console.WriteLine();
                return;
            }

            Log.Information("Looking for event log files in {D}", d);
            Console.WriteLine();

#if !NET6_0
            var directoryEnumerationFilters = new DirectoryEnumerationFilters
            {
                InclusionFilter = fsei => fsei.Extension.ToUpperInvariant() == ".EVTX",
                RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink,
                ErrorFilter     = (errorCode, errorMessage, pathProcessed) => true
            };

            var dirEnumOptions =
                DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive |
                DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException |
                DirectoryEnumerationOptions.BasicSearch;

            var files2 =
                Directory.EnumerateFileSystemEntries(Path.GetFullPath(d), dirEnumOptions, directoryEnumerationFilters);
#else
            var enumerationOptions = new EnumerationOptions
            {
                IgnoreInaccessible    = true,
                MatchCasing           = MatchCasing.CaseInsensitive,
                RecurseSubdirectories = true,
                AttributesToSkip      = 0
            };

            var files2 =
                Directory.EnumerateFileSystemEntries(d, "*.evtx", enumerationOptions);
#endif

            if (_swXml == null && _swJson == null && _swCsv == null)
            {
                //no need for maps
                Log.Debug("Clearing map collection since no output specified");
                EventLog.EventLogMaps.Clear();
            }

            foreach (var file in files2)
            {
                ProcessFile(file, dedupe, fj, met);
            }

            if (vss)
            {
                var vssDirs = Directory.GetDirectories(VssDir);

                Console.WriteLine();

                foreach (var vssDir in vssDirs)
                {
                    var root = Path.GetPathRoot(Path.GetFullPath(d));
                    var stem = Path.GetFullPath(d).Replace(root, "");

                    var target = Path.Combine(vssDir, stem);

                    Console.WriteLine();
                    Log.Information("Searching {Vss} for event logs...", $"VSS{target.Replace($"{VssDir}\\", "")}");

                    var vssFiles = Helper.GetFilesFromPath(target, "*.evtx", true);

                    foreach (var file in vssFiles)
                    {
                        ProcessFile(file, dedupe, fj, met);
                    }
                }
            }
        }

        try
        {
            _swCsv?.Flush();
            _swCsv?.Close();

            _swJson?.Flush();
            _swJson?.Close();

            _swXml?.Flush();
            _swXml?.Close();
        }
        catch (Exception e)
        {
            Log.Error(e, "Error when flushing output files to disk! Error message: {Message}", e.Message);
        }

        sw.Stop();
        Console.WriteLine();

        if (_fileCount == 1)
        {
            Log.Information("Processed {FileCount:N0} file in {TotalSeconds:N4} seconds", _fileCount, sw.Elapsed.TotalSeconds);
        }
        else
        {
            Log.Information("Processed {FileCount:N0} files in {TotalSeconds:N4} seconds", _fileCount, sw.Elapsed.TotalSeconds);
        }

        Console.WriteLine();

        if (_errorFiles.Count > 0)
        {
            Console.WriteLine();
            Log.Information("Files with errors");
            foreach (var errorFile in _errorFiles)
            {
                Log.Information("{Key} error count: {Value:N0}", errorFile.Key, errorFile.Value);
            }

            Console.WriteLine();
        }

        if (vss)
        {
            if (Directory.Exists(VssDir))
            {
                foreach (var directory in Directory.GetDirectories(VssDir))
                {
                    Directory.Delete(directory);
                }

#if !NET6_0
                Directory.Delete(VssDir, true, true);
#else
                Directory.Delete(VssDir, true);
#endif
            }
        }
    }