We have taken on new Customers, some know what they have in their SQL Server Estate, Some Don’t. Typically when we onboard a new client, we get a list of server names and we agree to support them (or at least the sales team agrees and the database administrators then have to figure out what the client actually has on them.)
Enter Due Diligence Checks; this is a recent PowerShell script I’ve written (Work in progress) to check for the following things;
- How many AvailblityGroups There are and the number of databases in the AAG’s
- Clusters
- How many databases are Mirroring
- How many databases are LogShipping
- If Replication is installed and how many publications it’s running
- Total Number of databases on the instance
- TotalDatabaseSize
- OtherComponents (SSRS/SSAS/SSIS)
I’m all about being open source so if this script can help you great! if you want to make it better go ahead, but throw some suggestions in the comments so I can see your improvements! it requires a config csv and an input file for the server list.
This was a quick first draft so there are issues with it but the basics are there. – unfortunately, WordPress removed the formatting!
#####################################################
### ###
### 18/03/2019 Created by Luke Salter ###
### ###
########################################################## Declare Variables###$Instances = get-content “.\Instances.txt”$Config = import-csv “.\config.csv”$SendMailFrom = $Config.SendMailFrom$SendMailTo = $Config.SendMailTo$SendMailcc = $Config.SendMailCC$UseMailServer = $Config.SMTPServer$CustomerName = $Config.CustomerName$reporttitle = “- Due Diligence Report”$outputFile = “.\” + $CustomerName + “_DueDiligence.csv”$myServerList = @()##### Functions###function AvailabilityGroups {## Connects to SQL using SQLCMD and pulls back number of AAG’s & Databases in those AAG’s$GLOBAL:AAG = “”TRY {$GLOBAL:AAG= Invoke-Sqlcmd -Query “select cast((select count(distinct(group_id)) from sys.dm_hadr_database_replica_states) as varchar) + ‘ ‘ + ‘Availability Group(s)’ + ‘ ‘ + cast((select count(distinct(database_id)) from sys.dm_hadr_database_replica_states) as varchar) + ‘ ‘ + ‘Databases'” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:AAG = $GLOBAL:AAG | Add-Member @{Column1=””} -PassThru}if($GLOBAL:AAG.Column1 -eq ‘0 Availability Group(s) 0 Databases’){$GLOBAL:AAG.Column1=”}}function Clustering {$GLOBAL:Cluster=””TRY {$GLOBAL:Cluster= Invoke-Sqlcmd -Query “declare @nodeList varchar(128) select @nodeList = coalesce(@nodeList+’, ‘,”) + NodeName from sys.dm_os_cluster_nodes select isnull(@nodeList,”)” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:Cluster= $GLOBAL:Cluster | Add-Member @{Column1=””} -PassThru}}function Mirroring {$GLOBAL:Mirroring=””TRY {$GLOBAL:Mirroring=Invoke-Sqlcmd -Query “select cast((select Count(Distinct(database_id)) from sys.database_mirroring where mirroring_role is not null) as varchar) + ‘ ‘ + ‘Databases'” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:Mirroring = $GLOBAL:Mirroring | Add-Member @{Column1=””} -PassThru}if($GLOBAL:Mirroring.Column1 -eq ‘0 Databases’){$GLOBAL:Mirroring.Column1=”}}function LogShipping {$GLOBAL:LogShipping=””TRY {$GLOBAL:LogShipping=Invoke-Sqlcmd -Query “select cast((select count(Primary_Database) from msdb.dbo.log_shipping_primary_databases) as varchar) + ‘ ‘ + ‘Databases'” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:LogShipping = $GLOBAL:LogShipping | Add-Member @{Column1=””} -PassThru}if($GLOBAL:LogShipping.Column1 -eq ‘0 Databases’){$GLOBAL:LogShipping.Column1=”}}function Replication {$GLOBAL:Replication=””TRY {$GLOBAL:Replication=Invoke-Sqlcmd -Query “select cast((select count(publication_id) from mspublications) as varcharr) + ‘ ‘ + ‘Publications'” -Server $Instance -Database DISTRIBUTION -ErrorAction Stop}CATCH {$GLOBAL:Replication = $GLOBAL:Replication | Add-Member @{Column1=””} -PassThru}}function DatabaseCount {$GLOBAL:DatabaseCount=””TRY {$GLOBAL:DatabaseCount=Invoke-Sqlcmd -Query “select cast((select count(name) from sys.databases where name not in (‘master’,’msdb’,’tempdb’,’model’,’distribution’))as varchar) + ‘ ‘ + ‘Databases'” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:DatabaseCount = $GLOBAL:DatabaseCount | Add-Member @{Column1=””} -PassThru}if($GLOBAL:DatabaseCount.Column1 -eq ‘0 Databases’){$GLOBAL:DatabaseCount.Column1=’No databases!’}}function TotalDatabaseSize {$GLOBAL:TotalDatabaseSize=””TRY {$GLOBAL:TotalDatabaseSize=Invoke-Sqlcmd -Query “select cast((select convert(decimal(10,2),(sum(size * 8.00) / 1024.00 / 1024.00)) from master.sys.master_files)as varchar) + ‘ ‘ + ‘GB'” -ServerInstance $Instance -ErrorAction Stop}CATCH {$GLOBAL:TotalDatabaseSize= $GLOBAL:TotalDatabaseSize | Add-Member @{Column1=””} -PassThru}}function OtherComponents {$Server=$Instance.Split(‘\’) ## Split for named instances$GLOBAL:OtherComponents=”TRY {IF (Get-WMIObject -class Win32_Service -computerName $Server[0] -ErrorAction Stop | Where-Object { $_.name -like “*MSSQLServerOLAPService*” }) {$GLOBAL:OtherComponents = $GLOBAL:OtherComponents+ ‘ SSAS ‘}IF (Get-WMIObject -class Win32_Service -computerName $Server[0] -ErrorAction Stop | Where-Object { $_.name -like “*MsDtsServer*” }) {$GLOBAL:OtherComponents = $GLOBAL:OtherComponents+ ‘ SSIS ‘}IF (Get-WMIObject -class Win32_Service -computerName $Server[0] -ErrorAction Stop | Where-Object { $_.name -like “*ReportServer*” }) {$GLOBAL:OtherComponents = $GLOBAL:OtherComponents+ ‘ SSRS ‘}}CATCH{if(!$GLOBAL:OtherComponents){$GLOBAL:OtherComponents=’Unable To Connect’}}}##### MAIN###foreach ($Instance in $Instances){write-host “$Instance : Running…” -ForegroundColor “Green”## Runs FunctionsPush-LocationAvailabilityGroupsClusteringMirroringLogShippingReplicationDatabaseCountTotalDatabaseSizeOtherComponentsPop-Location## Pool Function Results into Array$myObj = “” | Select-Object InstanceName, SupportCover, SupportTime, ServerTier, Environment, AvailabilityGroups , Clustering, Mirroring, LogShipping, Replication, DatabaseCount, TotalDatabaseSize, OtherComponents$myObj.InstanceName = $Instance$myObj.SupportCover = ‘Comprehensive or Reactive’$myObj.SupportTime = ’24/7/365 or Business Hours’$myObj.ServerTier = ‘Production / Dev / QA / Test’$myObj.Environment = ‘PaaS / IaaS / On-prem’$myObj.AvailabilityGroups = $AAG.Column1$myObj.Clustering = $Cluster.Column1$myObj.Mirroring = $Mirroring.Column1$myObj.LogShipping = $Logshipping.Column1$myObj.Replication = $Replication.Column1$myObj.DatabaseCount = $DatabaseCount.Column1$myObj.TotalDatabaseSize = $TotalDatabaseSize.Column1$myObj.OtherComponents = $OtherComponents$myServerList += $myObj}## Output Array to CSV File$myServerList | Export-CSV $outputFile -notypeinformationwrite-host “File created!” -ForegroundColor “Green”$subject = $customername$subject += ” – “$subject += $reporttitle$emailoutput = “<font face=calibri><br>”$emailoutput += $subject$emailoutput += ” attached.<br><br><b>End Of Line.</b><br></font>”Send-MailMessage -from $sendmailfrom -to $sendmailto -subject $subject -body $emailoutput -BodyAsHtml -dno onSuccess, onFailure -smtpServer $usemailserver -Attachments $outputFilewrite-host “Email sent!” -ForegroundColor “Green”