using System; using System.Globalization; using System.Management; using System.Reflection; using Microsoft.Win32; using BizTalkSapEnvironmentInventory.Configuration; using BizTalkSapEnvironmentInventory.Models; namespace BizTalkSapEnvironmentInventory.Collectors { /// /// Erfasst lokale Windows-, BizTalk-Installations- und Management-DB-Metadaten. /// internal sealed class SystemCollector { private const string BizTalkKey = @"SOFTWARE\Microsoft\BizTalk Server\3.0"; private const string AdministrationKey = BizTalkKey + @"\Administration"; private readonly CommandLineOptions options; public SystemCollector(CommandLineOptions options) { this.options = options; } /// /// Liest ausschließlich lokale WMI- und Registry-Daten. /// public void Collect(InventoryDocument document) { document.ComputerName = Environment.MachineName; document.ToolVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); document.System.Properties.Add(new NameValueRecord( "Ausführender Benutzer", Environment.UserDomainName + "\\" + Environment.UserName)); document.System.Properties.Add(new NameValueRecord( "64-Bit-Betriebssystem", Environment.Is64BitOperatingSystem ? "Ja" : "Nein")); document.System.Properties.Add(new NameValueRecord( "64-Bit-Prozess", Environment.Is64BitProcess ? "Ja" : "Nein")); document.System.Properties.Add(new NameValueRecord( ".NET Runtime", Environment.Version.ToString())); CollectOperatingSystem(document); CollectBizTalkRegistry(document); CollectBizTalkGroupSetting(document); if (!string.IsNullOrWhiteSpace(options.ManagementServer)) { document.System.ManagementServer = options.ManagementServer; } if (!string.IsNullOrWhiteSpace(options.ManagementDatabase)) { document.System.ManagementDatabase = options.ManagementDatabase; } else if (string.IsNullOrWhiteSpace(document.System.ManagementDatabase)) { document.System.ManagementDatabase = "BizTalkMgmtDb"; } document.System.Properties.Add(new NameValueRecord( "BizTalk Management SQL Server", EmptyAsUnknown(document.System.ManagementServer))); document.System.Properties.Add(new NameValueRecord( "BizTalk Management Database", EmptyAsUnknown(document.System.ManagementDatabase))); if (!string.Equals(document.EnvironmentName, "ACC", StringComparison.OrdinalIgnoreCase) && !string.Equals(document.EnvironmentName, "PROD", StringComparison.OrdinalIgnoreCase)) { document.Findings.Add(new Finding { Severity = "Warnung", Area = "Aufruf", Message = "Die Umgebung ist weder ACC noch PROD: " + document.EnvironmentName, RecommendedAction = "Umgebungsparameter und Zielserver vor der Ablage des Berichts bestätigen.", Owner = "BizTalk-Betrieb" }); } } private static void CollectOperatingSystem(InventoryDocument document) { using (var searcher = new ManagementObjectSearcher( "root\\cimv2", "SELECT Caption,Version,BuildNumber,OSArchitecture,LastBootUpTime FROM Win32_OperatingSystem")) { foreach (ManagementObject item in searcher.Get()) { document.System.Properties.Add(new NameValueRecord("Betriebssystem", Value(item, "Caption"))); document.System.Properties.Add(new NameValueRecord("Windows-Version", Value(item, "Version"))); document.System.Properties.Add(new NameValueRecord("Windows-Build", Value(item, "BuildNumber"))); document.System.Properties.Add(new NameValueRecord("Architektur", Value(item, "OSArchitecture"))); document.System.Properties.Add(new NameValueRecord( "Letzter Systemstart", ConvertWmiDate(Value(item, "LastBootUpTime")))); break; } } } private static void CollectBizTalkRegistry(InventoryDocument document) { foreach (var view in new[] { RegistryView.Registry64, RegistryView.Registry32 }) { using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view)) using (var product = baseKey.OpenSubKey(BizTalkKey, false)) { if (product != null) { AddRegistryValue(document, product, "ProductVersion", "BizTalk Produktversion", view); AddRegistryValue(document, product, "ProductName", "BizTalk Produktname", view); AddRegistryValue(document, product, "Edition", "BizTalk Edition", view); var installPath = FirstRegistryValue( product, "InstallPath", "BizTalkServerInstallPath", "Path"); if (!string.IsNullOrWhiteSpace(installPath) && string.IsNullOrWhiteSpace(document.System.BizTalkInstallPath)) { document.System.BizTalkInstallPath = installPath; document.System.Properties.Add(new NameValueRecord( "BizTalk Installationspfad", installPath, "Registry " + view)); } } } using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view)) using (var administration = baseKey.OpenSubKey(AdministrationKey, false)) { if (administration == null) { continue; } if (string.IsNullOrWhiteSpace(document.System.ManagementServer)) { document.System.ManagementServer = FirstRegistryValue( administration, "MgmtDBServer", "ManagementDBServer"); } if (string.IsNullOrWhiteSpace(document.System.ManagementDatabase)) { document.System.ManagementDatabase = FirstRegistryValue( administration, "MgmtDBName", "ManagementDBName"); } } } if (string.IsNullOrWhiteSpace(document.System.BizTalkInstallPath)) { document.Findings.Add(new Finding { Severity = "Warnung", Area = "BizTalk-Installation", Message = "BizTalk-Installationspfad wurde nicht in der Registry gefunden.", RecommendedAction = "Prüfen, ob das Tool lokal auf einem BizTalk Server 2020 ausgeführt wird.", Owner = "BizTalk-Betrieb" }); } } private static void CollectBizTalkGroupSetting(InventoryDocument document) { try { using (var searcher = new ManagementObjectSearcher( @"root\MicrosoftBizTalkServer", "SELECT Name,MgmtDbServerName,MgmtDbName,BizTalkAdministratorGroup," + "BizTalkOperatorGroup,BizTalkReadOnlyUserGroup,SSOServerName " + "FROM MSBTS_GroupSetting")) { foreach (ManagementObject item in searcher.Get()) { var managementServer = Value(item, "MgmtDbServerName"); var managementDatabase = Value(item, "MgmtDbName"); if (!string.IsNullOrWhiteSpace(managementServer)) { document.System.ManagementServer = managementServer; } if (!string.IsNullOrWhiteSpace(managementDatabase)) { document.System.ManagementDatabase = managementDatabase; } AddWmiValue(document, item, "Name", "BizTalk Gruppenname"); AddWmiValue( document, item, "BizTalkAdministratorGroup", "BizTalk Administratorengruppe"); AddWmiValue( document, item, "BizTalkOperatorGroup", "BizTalk Operatorengruppe"); AddWmiValue( document, item, "BizTalkReadOnlyUserGroup", "BizTalk ReadOnly-Gruppe"); AddWmiValue(document, item, "SSOServerName", "Enterprise SSO Server"); break; } } } catch (ManagementException exception) { document.Findings.Add(new Finding { Severity = "Hinweis", Area = "BizTalk GroupSetting", Message = "MSBTS_GroupSetting konnte für die Management-DB-Erkennung nicht gelesen werden: " + exception.Message, RecommendedAction = "Registry-Ergebnis prüfen oder --management-server explizit angeben.", Owner = "BizTalk-Betrieb" }); } } private static void AddWmiValue( InventoryDocument document, ManagementBaseObject item, string property, string displayName) { var value = Value(item, property); if (!string.IsNullOrWhiteSpace(value)) { document.System.Properties.Add( new NameValueRecord(displayName, value, "MSBTS_GroupSetting")); } } private static void AddRegistryValue( InventoryDocument document, RegistryKey key, string valueName, string displayName, RegistryView view) { var value = Convert.ToString(key.GetValue(valueName), CultureInfo.InvariantCulture); if (!string.IsNullOrWhiteSpace(value) && !document.System.Properties.Exists(item => string.Equals(item.Name, displayName, StringComparison.OrdinalIgnoreCase))) { document.System.Properties.Add(new NameValueRecord( displayName, value, "Registry " + view)); } } private static string FirstRegistryValue(RegistryKey key, params string[] names) { foreach (var name in names) { var value = Convert.ToString(key.GetValue(name), CultureInfo.InvariantCulture); if (!string.IsNullOrWhiteSpace(value)) { return value.Trim(); } } return string.Empty; } private static string Value(ManagementBaseObject item, string property) { try { return Convert.ToString(item[property], CultureInfo.InvariantCulture) ?? string.Empty; } catch (ManagementException) { return string.Empty; } } private static string ConvertWmiDate(string value) { if (string.IsNullOrWhiteSpace(value)) { return "Unbekannt"; } try { return ManagementDateTimeConverter.ToDateTime(value) .ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); } catch (ArgumentOutOfRangeException) { return value; } } private static string EmptyAsUnknown(string value) { return string.IsNullOrWhiteSpace(value) ? "Nicht ermittelt" : value; } } }