db/sqlserver_scanner.py (72 lines of code) (raw):

"""Copyright 2021 Google LLC. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. version 1.5.1 """ import logging from db.db_info import Query class SqlServerScanner: """Helper class to scan SQL Server database.""" def __init__(self, region): self.region = region def scan(self, rds_info, output): """Connects to SQL Server database and collects data. Args: rds_info: Dictionary object with database connection information output: Dictionary object to store the collected data Returns: True if collection is successful False otherwise """ queries = self.get_queries() collection = {} try: pyodbc = __import__('pyodbc') conn = pyodbc.connect( 'Driver={SQL Server};' + 'SERVER=' + rds_info.host + ',' + str(rds_info.port) + ';DATABASE=master' + ';UID=' + rds_info.username + ';PWD=' + rds_info.password) for query in queries: try: cur = conn.cursor() cur.execute(query.query) row_headers = [x[0] for x in cur.description] query_results = cur.fetchall() if query.query_type == "SQLServer_Version": version = query_results[0][0] collection["version"] = version output["version"] = version else: result_array = [] for result in query_results: result_array.append(dict(zip(row_headers, result))) collection[query.query_type] = result_array except Exception as ex: # pylint: disable=broad-except if query.query_type == "SQLServer_Version": raise ex logging.error("Failed to run %s", query.query_type) logging.error(ex) output["SQLServer"] = collection return True except Exception as e: # pylint: disable=broad-except logging.error("Received an unexpected error") logging.error(e) return False def get_queries(self): """Gets a list of data collection queries. Returns: List of data collection queries """ version_query = "select @@version as version" return [ Query("SQLServer_Version", version_query), Query("SQLServer_DBs", "select name from sys.databases"), Query("SQLServer_SSISPackage", "select count(*) as ssisPackageCount from msdb.[dbo].[sysssispackages] where ownersid <>0x01"), Query("SQLServer_WindowsSQLLogin", "select count(*) as windowsSQLLoginCount from master..syslogins where isntname = 1 and hasaccess = 1 and loginname not like 'NT %'"), Query("SQLServer_StorageInGB", "select s.[name], sum ((convert(Decimal(18,2),size)*8/1024))/1024 as GB_Storage_Used from sys.master_files m join sys.databases s ON m.database_id = s.database_id group by m.database_id, s.[name]"), Query("SQLServer_AlwaysOn", "select CAST(coalesce(serverproperty('IsHadrEnabled') ,0) AS NVARCHAR(50)) IsHadrEnabled"), Query("SQLServer_FailoverCluster", "select CAST(serverproperty('IsClustered') AS NVARCHAR(50)) [IsClustered]"), Query("SQLServer_LogShipping", "exec master.sys.sp_help_log_shipping_monitor"), Query("SQLServer_MailInUse", "select CAST(value_in_use AS NVARCHAR(50)) DBMailEnabled from sys.configurations where name = 'Database Mail XPs'"), Query("SQLServer_FileTable", "select count(*) FTDBs from sys.database_filestream_options where non_transacted_access_desc <> 'OFF'"), Query("SQLServer_MaintenancePlans", "select count(*) MaintPlans from msdb..sysmaintplan_plans"), Query("SQLServer_PolicyMgmtPolicies", "select count(*) PoliciesEnabled from msdb..syspolicy_policies where is_enabled =1"), Query("SQLServer_ExternalScripts", "select convert(int, value_in_use) as ExtScriptsEnabled from sys.configurations where (name collate Latin1_General_CI_AS) = 'external scripts enabled'"), Query("SQLServer_ComputeNodes", "select count(*) ComputeNodes from sys.dm_exec_compute_nodes"), Query("SQLServer_ResourceGovernorGroups", "select count(*) ResGovGroups from sys.resource_governor_workload_groups"), Query("SQLServer_Audits", "select count(*) ServerAudits from sys.server_audits"), Query("SQLServer_ServerLevelTriggers", "select count(*) ServTriggers from sys.server_triggers"), Query("SQLServer_ServiceBrokerTasks", "select count(*) ServBrokerTasks from sys.dm_broker_activated_tasks"), Query("SQLServer_Endpoints", "select count(*) Endpoints from sys.endpoints where state =0"), Query("SQLServer_CDCEnabled", "select count(*) DBsWithCdc from sys.databases where is_cdc_enabled=1"), Query("SQLServer_CLR", "Select count(*) UserCLRObjects from sysobjects where ObjectProperty(id, 'IsMSShipped') =0 and (xtype ='FS' or type ='FT' or type ='TA' or type ='PC')"), Query("SQLServer_LinkedServers", "select count(*) LinkedServiers from sys.servers where is_linked = 1"), Query("SQLServer_ExternalAccessAssemblies", "select count(*) ExtAccAsmblyEnabled from sys.server_permissions where permission_name = 'External access assembly' and state='G'"), Query("SQLServer_DQSRoles", "exec sp_msforeachdb \"select '?' as dbName, count(name) as sqlServerDQSRoleCount from [?].sys.database_principals where name like 'dqs_%'\""), Query("SQLServer_FilestreamGroups", "exec sp_msforeachdb \"select '?' as dbName, count(type) as sqlServerFileStreamGroupCount from [?].sys.filegroups Where type = 'FD'\""), Query("SQLServer_DCUsers", "exec sp_msforeachdb \"select '?' as dbName, count(name) as sqlServerDCUserCount from [?].sys.database_principals where name like 'dc_%'\""), ]