static void Main(string[] args) { Log.licenseHeader(); if (Array.IndexOf(args, @"/?") >= 0) { Console.WriteLine("See https://github.com/dc-sql/DBAid for more details"); return; } Arguments flag = new Arguments(args); string server = flag.ContainsFlag("-server") ? flag.GetValue("-server") : String.Empty; string database = flag.ContainsFlag("-db") ? flag.GetValue("-db") : "_dbaid"; int errorCount = 0; int warningCount = 0; string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; string logFile = Path.Combine(baseDirectory, logID + DateTime.Now.ToString("yyyyMMdd") + logExt); string workingDirectory = String.Empty; string processDirectory = String.Empty; bool logVerbose = true; byte fileRententionDays = 7; bool emailEnable = true; string emailSmtp = String.Empty; string[] emailTo = { String.Empty }; string emailFrom = String.Empty; string emailSubject = String.Empty; long emailAttachmentByteLimit = 0; int emailAttachmentCountLimit = 0; bool emailEnableSsl = true; bool emailIgnoreSslError = false; bool emailAnonymous = true; int defaultCmdTimout = 0; ConnectionStringSettingsCollection cssc = new ConnectionStringSettingsCollection(); try { if (String.IsNullOrEmpty(server) || String.IsNullOrEmpty(database)) { cssc = ConfigurationManager.ConnectionStrings; } else { string cs = "Server=" + server + ";Database=" + database + ";Trusted_Connection=True;"; cssc.Add(new ConnectionStringSettings(server.Replace("\\", "@"), cs)); } workingDirectory = ConfigurationManager.AppSettings["WorkingDirectory"]; processDirectory = Path.Combine(workingDirectory, processedDir); logVerbose = bool.Parse(ConfigurationManager.AppSettings["logVerbose"]); fileRententionDays = byte.Parse(ConfigurationManager.AppSettings["ProcessedFileRetentionDays"]); emailEnable = bool.Parse(ConfigurationManager.AppSettings["emailEnable"]); emailSmtp = ConfigurationManager.AppSettings["EmailSmtp"]; emailTo = ConfigurationManager.AppSettings["EmailTo"].Split(';'); emailFrom = ConfigurationManager.AppSettings["EmailFrom"]; emailSubject = ConfigurationManager.AppSettings["EmailSubject"]; emailAttachmentByteLimit = long.Parse(ConfigurationManager.AppSettings["EmailAttachmentByteLimit"]); emailAttachmentCountLimit = int.Parse(ConfigurationManager.AppSettings["EmailAttachmentCountLimit"]); emailEnableSsl = bool.Parse(ConfigurationManager.AppSettings["EmailEnableSsl"]); emailIgnoreSslError = bool.Parse(ConfigurationManager.AppSettings["EmailIgnoreSslError"]); emailAnonymous = bool.Parse(ConfigurationManager.AppSettings["EmailAnonymous"]); defaultCmdTimout = int.Parse(ConfigurationManager.AppSettings["default_cmd_timeout_sec"]); if (!Directory.Exists(workingDirectory)) { Directory.CreateDirectory(workingDirectory); } if (!Directory.Exists(processDirectory)) { Directory.CreateDirectory(processDirectory); } Log.message(LogEntryType.INFO, "DBAidCollector", "Starting DBAid Collector", logFile); } catch (Exception ex) { Log.message(LogEntryType.ERROR, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); errorCount++; if (emailEnable) { Smtp.send(emailSmtp, emailFrom, emailTo, Environment.MachineName, "Failed to initialise DBAid collector", null, emailAttachmentByteLimit, emailAttachmentCountLimit, emailEnableSsl, emailIgnoreSslError, emailAnonymous); } Console.Write("Settings in App.Config may be incorrect and/or missing, or permissions to write log file is missing."); return; } try { //Clean up old files FileIo.delete(baseDirectory, "*" + logExt, DateTime.Now.AddDays(-7)); FileIo.delete(processDirectory, "*" + processedExt, DateTime.Now.AddDays(fileRententionDays * -1)); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); warningCount++; } foreach (ConnectionStringSettings css in cssc) { DateTime runtime = DateTime.UtcNow; SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(css.ConnectionString); DataRowCollection procedures; List <string> attachments = new List <string>(); string publicKey = String.Empty; string instanceTag = String.Empty; csb.ApplicationName = logID + Guid.NewGuid().ToString(); Log.message(LogEntryType.INFO, "DBAidCollector", "Starting Collection on [" + csb.DataSource + "]", logFile); try { // query database for assigned application name. csb.ApplicationName = Query.Select(csb.ConnectionString, mssqlAppSelect, defaultCmdTimout).Rows[0][0].ToString(); // query database for instance guid. instanceTag = Query.Execute(csb.ConnectionString, mssqlInstanceTagProc, defaultCmdTimout).Rows[0][0].ToString(); if (String.IsNullOrEmpty(instanceTag)) { instanceTag = css.Name.Replace("\\", "@").Replace("_", "~") + "_" + IPGlobalProperties.GetIPGlobalProperties().DomainName.Replace(".", "_"); } // query database for public key. publicKey = Query.Select(csb.ConnectionString, mssqlKeySelect, defaultCmdTimout).Rows[0][0].ToString(); // get procedure returned from control procedure. procedures = Query.Select(csb.ConnectionString, mssqlControlProc, defaultCmdTimout).Rows; } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); warningCount++; continue; } foreach (DataRow dr in procedures) { string file = instanceTag + "_" + dr[0].ToString().Replace("].[", "_").Replace(".", "_") + "_" + runtime.ToString("yyyyMMddHHmmss") + encryptedExt; string filepath = Path.Combine(workingDirectory, file); // execute procedure, compress, and encrypt stream. Write contents out to file. using (MemoryStream msRaw = new MemoryStream()) using (StreamWriter swRaw = new StreamWriter(msRaw, Encoding.Unicode)) { try { DataTable dt = Query.Execute(csb.ConnectionString, dr[0].ToString(), defaultCmdTimout); StringBuilder sb = new StringBuilder(dt.TableName.Length); foreach (char c in dt.TableName) // remove special characters from table name as this causes issues with SSIS xml source. { if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '_') { sb.Append(c); } } dt.TableName = sb.ToString(); dt.WriteXml(swRaw, XmlWriteMode.WriteSchema); dt.Clear(); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); warningCount++; continue; } try { if (logVerbose) { Log.message(LogEntryType.INFO, "DBAidCollector", "Writing Encrypted File: \"" + filepath + "\"", logFile); } Crypto.encrypt(publicKey, msRaw, filepath); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); warningCount++; continue; } } } Log.message(LogEntryType.INFO, "DBAidCollector", "Completed Collection on [" + csb.DataSource + "]", logFile); try { foreach (string file in Directory.GetFiles(workingDirectory, "*" + encryptedExt)) { attachments.Add(file); } string body = "DBAid collector process logged: \n\t" + errorCount.ToString() + " error(s) \n\t" + warningCount.ToString() + " warning(s) \n"; if (emailEnable) { Smtp.send(emailSmtp, emailFrom, emailTo, emailSubject, body, attachments.ToArray(), emailAttachmentByteLimit, emailAttachmentCountLimit, emailEnableSsl, emailIgnoreSslError, emailAnonymous); foreach (string file in attachments) { FileIo.move(file, Path.Combine(processDirectory, Path.GetFileName(file) + processedExt)); } Log.message(LogEntryType.INFO, "DBAidCollector", "Email Sent to \"" + string.Join("; ", emailTo) + "\"", logFile); } } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidCollector", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); } } Log.message(LogEntryType.INFO, "DBAidCollector", "Completed DBAid Collection", logFile); //System.Threading.Thread.Sleep(10000); }
static void Main(string[] args) { Log.licenseHeader(); if (Array.IndexOf(args, @"/?") >= 0) { Console.WriteLine("See https://github.com/dc-sql/DBAid for more details"); return; } string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; string logFile = Path.Combine(baseDirectory, logID + DateTime.Now.ToString("yyyyMMdd") + ".log"); Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Process Started", logFile); Arguments flag = new Arguments(args); string server = flag.ContainsFlag("-server") ? flag.GetValue("-server") : String.Empty; string database = flag.ContainsFlag("-db") ? flag.GetValue("-db") : "_dbaid"; bool disableWmi = flag.ContainsFlag("-disablewmi") ? bool.Parse(flag.GetValue("-disablewmi")) : false; bool disableMd = flag.ContainsFlag("-disablemd") ? bool.Parse(flag.GetValue("-disablemd")) : false; bool logVerbose = flag.ContainsFlag("-logverbose") ? bool.Parse(flag.GetValue("-logverbose")) : false; string emailSmtp = flag.ContainsFlag("-emailsmtp") ? flag.GetValue("-emailsmtp") : String.Empty; string[] emailTo = flag.ContainsFlag("-emailto") ? flag.GetValue("-emailto").Split(new char[] { ';' }) : new string[0]; string emailFrom = flag.ContainsFlag("-emailfrom") ? flag.GetValue("-emailfrom") : String.Empty; string emailSubject = flag.ContainsFlag("-emailsubject") ? flag.GetValue("-emailsubject") : String.Empty; long emailAttachmentByteLimit = flag.ContainsFlag("-emailbytelimit") ? long.Parse(flag.GetValue("-emailbytelimit")) : 10000000; int emailAttachmentCountLimit = flag.ContainsFlag("-emailattlimit") ? int.Parse(flag.GetValue("-emailattlimit")) : 15; bool emailEnableSsl = flag.ContainsFlag("-emailssl") ? bool.Parse(flag.GetValue("-emailssl")) : false; bool emailIgnoreSslError = flag.ContainsFlag("-emailignoresslerror") ? bool.Parse(flag.GetValue("-emailignoresslerror")) : false; bool emailAnonymous = flag.ContainsFlag("-emailanonymous") ? bool.Parse(flag.GetValue("-emailanonymous")) : true; int connectionTimeout = flag.ContainsFlag("-connectionTimeout") ? int.Parse(flag.GetValue("-connectionTimeout")) : 60; int timeOut = flag.ContainsFlag("-commandTimeout") ? int.Parse(flag.GetValue("-commandTimeout")) : 30; if (String.IsNullOrEmpty(server)) { Log.message(LogEntryType.WARNING, "DBaidAsBuilt", "No -server specified. Exiting program...", logFile); return; } string host = String.Empty; string instance = String.Empty; if (server.Contains("\\")) { host = server.Split(new char[] { '\\' }, 2)[0]; instance = server.Split(new char[] { '\\' }, 2)[1]; } else { host = server; } string file = Path.Combine(baseDirectory, server.Replace(@"\", "@").ToLower() + "_asbuilt.md"); var csb = new SqlConnectionStringBuilder(); csb.ApplicationName = logID + Guid.NewGuid().ToString(); csb.DataSource = server; csb.InitialCatalog = database; csb.IntegratedSecurity = true; csb.ConnectTimeout = connectionTimeout; try { //clean up log files older than 3 days FileIo.delete(Path.GetDirectoryName(logFile), "*.log", DateTime.Now.AddDays(-3)); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBaidAsBuilt", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); } try { csb.ApplicationName = Query.Select(csb.ConnectionString, mssqlAppSelect, timeOut).Rows[0][0].ToString(); } catch (ApplicationException ex) { Log.message(LogEntryType.ERROR, "DBaidAsBuilt", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); Console.Write(ex); return; } if (!disableWmi) { var parameters = new Dictionary <string, object>(); foreach (Wmi.PropertyValue prop in Wmi.getHostInfo(host)) { parameters.Clear(); parameters.Add("hierarchy", prop.Path); parameters.Add("property", prop.Property.Value); parameters.Add("value", prop.Value); Query.Execute(csb.ConnectionString, mssqlInsertService, parameters, timeOut); } Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Loaded WMI HostInfo.", logFile); foreach (Wmi.PropertyValue prop in Wmi.getServiceInfo(host, instance)) { parameters.Clear(); parameters.Add("hierarchy", prop.Path); parameters.Add("property", prop.Property.Value); parameters.Add("value", prop.Value); Query.Execute(csb.ConnectionString, mssqlInsertService, parameters, timeOut); } Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Loaded WMI ServiceInfo.", logFile); foreach (Wmi.PropertyValue prop in Wmi.getDriveInfo(host)) { parameters.Clear(); parameters.Add("hierarchy", prop.Path); parameters.Add("property", prop.Property.Value); parameters.Add("value", prop.Value); Query.Execute(csb.ConnectionString, mssqlInsertService, parameters, timeOut); } Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Loaded WMI DriveInfo.", logFile); } if (!disableMd) { using (StreamWriter outfile = new StreamWriter(file)) { try { outfile.Write("# As-Built Document - " + csb.DataSource + Environment.NewLine + "---" + Environment.NewLine); outfile.Write("## Contents" + Environment.NewLine); outfile.Write(Markdown.getMarkdown(csb.ConnectionString, mssqlControlFact, timeOut)); Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Generated AsBuilt for [" + csb.DataSource + "]", logFile); } catch (Exception ex) { Log.message(LogEntryType.ERROR, "DBaidAsBuilt", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); throw ex; } } if (!String.IsNullOrEmpty(emailSmtp)) { try { Smtp.send(emailSmtp, emailFrom, emailTo, emailSubject, "", new [] { file }, emailAttachmentByteLimit, emailAttachmentCountLimit, emailEnableSsl, emailIgnoreSslError, emailAnonymous); Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Email sent to \"" + String.Join("; ", emailTo) + "\"", logFile); } catch (Exception ex) { Log.message(LogEntryType.ERROR, "DBaidAsBuilt", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); throw ex; } } else { Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Emailing of config not enabled or configured.", logFile); } } Log.message(LogEntryType.INFO, "DBaidAsBuilt", "Process Completed", logFile); //System.Threading.Thread.Sleep(10000); }
static void Main(string[] args) { Log.licenseHeader(); string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; string logFile = Path.Combine(baseDirectory, logID + DateTime.Now.ToString("yyyyMMdd") + logExt); string workingDirectory = String.Empty; string processDirectory = String.Empty; bool logVerbose = true; int fileRententionDays = 31; string inbox = String.Empty; string searchSubject = String.Empty; try { workingDirectory = ConfigurationManager.AppSettings["WorkingDirectory"]; processDirectory = Path.Combine(workingDirectory, processedDir); logVerbose = bool.Parse(ConfigurationManager.AppSettings["LogVerbose"]); fileRententionDays = int.Parse(ConfigurationManager.AppSettings["ProcessedFileRetentionDays"]); inbox = ConfigurationManager.AppSettings["Inbox"]; searchSubject = ConfigurationManager.AppSettings["SearchSubject"]; if (!Directory.Exists(workingDirectory)) { Directory.CreateDirectory(workingDirectory); } if (!Directory.Exists(processDirectory)) { Directory.CreateDirectory(processDirectory); } } catch (Exception ex) { Log.message(LogEntryType.ERROR, "DBAidExtractor", ex.Message + " - " + ex.StackTrace, logFile); Log.message(LogEntryType.ERROR, "DBAidExtractor", "Settings in App.Config may be incorrect and/or missing." + " - " + ex.StackTrace, logFile); Console.Write("Settings in App.Config may be incorrect and/or missing."); return; } try { //Clean up old log files FileIo.delete(baseDirectory, "*" + logExt, DateTime.Now.AddDays(-7)); if (fileRententionDays > 0) { fileRententionDays = fileRententionDays * -1; } //Clean up old processed files FileIo.delete(processDirectory, "*" + processedExt, DateTime.Now.AddDays(fileRententionDays)); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); } Log.message(LogEntryType.INFO, "DBAidExtractor", "Starting DBAid Extractor", logFile); //download emails from exchange try { Exchange.DownloadAttachement(inbox, searchSubject, workingDirectory, logFile, logVerbose); } catch (Exception ex) { Log.message(LogEntryType.ERROR, "DBAidExtractor", ex.Message, logFile); Log.message(LogEntryType.ERROR, "DBAidExtractor", "Error Downloading attachment from exchange", logFile); throw; } ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[0]; SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(css.ConnectionString); csb.ApplicationName = logID + Guid.NewGuid().ToString(); foreach (string fileToProcess in Directory.GetFiles(workingDirectory, "*" + ext)) { Dictionary <string, object> parameters = new Dictionary <string, object>(); string servername = Path.GetFileNameWithoutExtension(fileToProcess); //if the instance name has an underscore, convert back. if (servername.Substring(0, 1) == "[") { servername = servername.Substring(1); servername = servername.Split(']')[0]; parameters.Add("server_name", servername); } else { servername = servername.Split('_')[0]; parameters.Add("server_name", servername); } try /* Read in and decrypt encrypted files */ { string privateKey = Query.Execute(csb.ConnectionString, privateKeyProc, parameters).Rows[0][0].ToString(); try { using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(fileToProcess))) { Crypto.decrypt(privateKey, ms, fileToProcess.Replace(ext, ".decrypted.xml")); } } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); Log.message(LogEntryType.WARNING, "DBAidExtractor", "Failed to decrypted " + fileToProcess, logFile); continue; } try { FileIo.move(fileToProcess, Path.Combine(processDirectory, Path.GetFileName(fileToProcess) + ".processed")); } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); Log.message(LogEntryType.WARNING, "DBAidExtractor", "Failed to decrypted " + fileToProcess, logFile); continue; } if (logVerbose) { Log.message(LogEntryType.INFO, "DBAidExtractor", "Processed file: " + fileToProcess, logFile); } } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); Log.message(LogEntryType.WARNING, "DBAidExtractor", "Could not decrypt file for " + servername + " Check if server exists in DailyCheck db server table and public private key is correct", logFile); continue; } } Log.message(LogEntryType.INFO, "DBAidExtractor", "Finished processing encrypted files.", logFile); // try to move the files using the the setting in FileIo.Config try { string moveConfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "move.config"); XmlDocument doc = new XmlDocument(); string source = String.Empty; string filter = String.Empty; string destination = String.Empty; if (File.Exists(moveConfig)) { doc.Load(moveConfig); foreach (XPathNavigator child in doc.CreateNavigator().Select("move/file")) { source = child.SelectSingleNode("@source").Value; filter = child.SelectSingleNode("@filter").Value; destination = child.SelectSingleNode("@destination").Value; List <MoveList> movedFiles = FileIo.movelist(source, filter, destination); foreach (MoveList i in movedFiles) { try { FileIo.move(i.sourcefile, i.destfile); if (logVerbose) { Log.message(LogEntryType.INFO, "DBAidExtractor", "Moved file: \"" + i.sourcefile + "\" > \"" + i.destfile + "\"", logFile); } } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); Log.message(LogEntryType.WARNING, "DBAidExtractor", "Error occured when moving file: " + i.sourcefile, logFile); } } } } else { Log.message(LogEntryType.INFO, "DBAidExtractor", "No \"move.config\" file found in executable directory, skipping. ", logFile); } } catch (Exception ex) { Log.message(LogEntryType.WARNING, "DBAidExtractor", ex.Message + (logVerbose ? " - " + ex.StackTrace : ""), logFile); } Log.message(LogEntryType.INFO, "DBAidExtractor", "Completed DBAid Extractor", logFile); }