Technical Article

Always ON Healthcheck Report

,

The below SQL and powershell script will help to get alwayson Health check Report

-----------GetAlwaysOnStatus.sql
if (SERVERPROPERTY('ishadrenabled') = 1)
Begin
select convert(Nvarchar(500),SERVERPROPERTY('servername')) as Servername, n.group_name AlwaysONGroup,n.replica_server_name,n.node_name NodeName,rs.role_desc Role,
db_name(drs.database_id) as 'DBName',drs.synchronization_state_desc State,drs.synchronization_health_desc Health
,getdate() as Rundate
from master.sys.dm_hadr_availability_replica_cluster_nodes n
join master.sys.dm_hadr_availability_replica_cluster_states cs
on n.replica_server_name = cs.replica_server_name
join master.sys.dm_hadr_availability_replica_states rs 
on rs.replica_id = cs.replica_id
join master.sys.dm_hadr_database_replica_states drs
on rs.replica_id=drs.replica_id
join master.sys.availability_group_listeners AS AGL ON AGL.group_id = rs.group_id
where n.replica_server_name = @@SERVERNAME
and rs.replica_id=drs.replica_id
End 
-------------TruncateTable
Truncate table dbadmin.dbo.DbadminDashboard_alwayson_status
--------------GetServerList
--Query to check All prod servers
--select  SRV.server_name from [ServerName].[msdb].[dbo].
--[sysmanagement_shared_registered_servers_internal] SRV join 
--[ServerName].[msdb].[dbo].[sysmanagement_shared_server_groups_internal] GRP
--on SRV.server_group_id=GRP.server_group_id
--where  substring(SRV.server_name,4,4) = 'PROD'
--and substring(SRV.server_name,1,3) in 
--( )
--Union 
--select  SRV.server_name from [ServerName].[msdb].[dbo].
--[sysmanagement_shared_registered_servers_internal] SRV join 
--[ServerName].[msdb].[dbo].[sysmanagement_shared_server_groups_internal] GRP
--on SRV.server_group_id=GRP.server_group_id
--and GRP.name  = 'XXX'
--order by SRV.server_name asc
--Query to check All Non-prod servers
select  SRV.server_name from [ServerName].[msdb].[dbo].
[sysmanagement_shared_registered_servers_internal] SRV join 
[ServerName].[msdb].[dbo].[sysmanagement_shared_server_groups_internal] GRP
on SRV.server_group_id=GRP.server_group_id
where  substring(SRV.server_name,4,4) = 'PROD'

--Union 
--select  SRV.server_name from [ServerName].[msdb].[dbo].
--[sysmanagement_shared_registered_servers_internal] SRV join 
--[ServerName].[msdb].[dbo].[sysmanagement_shared_server_groups_internal] GRP
--on SRV.server_group_id=GRP.server_group_id

--Query to check All servers
--select  SRV.server_name from [ServerName].[msdb].[dbo].
--[sysmanagement_shared_registered_servers_internal] SRV join 
--[ServerName].[msdb].[dbo].[sysmanagement_shared_server_groups_internal] GRP
--on SRV.server_group_id=GRP.server_group_id
--where  substring(SRV.server_name,1,3) in 
--()
--order by SRV.server_name asc

-------------MainPS.ps1
$cmsserver ='ServerName'
$cmsdb = 'dbadmin'
$defaultdb='Master'
$uname ='XXXXXX'
$pword = 'XXXXXXX'
# change this parameter if running for other things
$BaseDir='C:SQLServerReportMonitoringAlwaysOn' 
$Outpath = $BaseDir + "Output"
$LogFile = $BaseDir + 'LogFile.txt'
$FailedServers = $BaseDir + 'FailedServers.txt'
#$SuccessServers = $BaseDir + 'SuccessServers.txt'
"CMS Server -- " + $cmsserver | out-file $LogFile  -Width 180
"Output Directory --" + $Outpath | out-file $LogFile  -Width 180  -Append
"Base Directory --" + $BaseDir | out-file $LogFile  -Width 180 -Append
"Logfile --" + $LogFile | out-file $LogFile  -Width 180 -Append
"This file captures servers which are not reachable or have some issues.Please check them." + "`r`n" + "For detailed status,query table -- dbadmin.dbo.DbadminDashboard_alwayson_status " + "`r`n" | out-file $FailedServers  -Width 180


$SuccessServers = $BaseDir + 'SuccessServers.txt'
"This file captures servers which are reached successfully." + "`r`n" + "For detailed status,query table -- dbadmin.dbo.DbadminDashboard_SqlServices_Status " + "`r`n" | out-file $SuccessServers -Width 180

"SQL Server Processing - Started " | out-file $LogFile  -Width 180  -Append
Get-ChildItem -Path $Outpath *.csv | out-file $LogFile  -Width 180 -Append

"removing old files starts" | out-file $LogFile  -Width 180 -Append
Get-ChildItem -Path $Outpath *.csv | foreach { Remove-Item $_.FullName}
"removing old files done" | out-file $LogFile  -Width 180 -Append

$CurDate  =  (Get-Date -Format MM) + (get-Date -format dd) +  (get-Date -format yyyy) 
$CurDatetime  =  (Get-Date -Format MM) + (get-Date -format dd) +  (get-Date -format yyyy)  + (get-Date -format hh) + (get-Date -format mm)
$ServerNameFile= $BaseDir + "GetServerList.sql"
$GetQueryFile =$BaseDir + "GetAlwaysOnStatus.sql"
$ServerNameQuery = get-content "$ServerNameFile"
'ServerQuery  -- ' + $ServerNameQuery + "`r`n" | out-file $LogFile  -Width 180  -Append
$serverlist = Invoke-Sqlcmd -ServerInstance $cmsserver -Database $cmsdb -Inputfile $ServerNameFile -QueryTimeout 300 
$FailedServers = $BaseDir + 'FailedServers.txt'
ForEach ($instance in $serverlist)
{
$instance=$instance.Item(0) 
$servername = $instance.split("")  |Select-Object -Index 0  
"`r`n" + 'Checking Server --' + $servername   | out-file $LogFile  -Width 180  -Append
If (Test-Connection  -ComputerName $servername -quiet -BufferSize 32 -Count 1 )  
{
#move to fetch the data if ping succeeds
$servername + '            --Ping Succeeded'  | out-file $LogFile  -Width 180  -Append
try
{ 
#log start of process
# $instance= $instance + ",1433"
#"$Instance fetch starts at " + $CurDatetime    | out-file $LogFile  -Width 180  -Append 
$results=Invoke-Sqlcmd -ServerInstance $instance -Database $defaultdb  -Username $uname -Password $pword  -InputFile $GetQueryFile -QueryTimeout 300 
"Saving Success Backup Results in CSV format..."  +  $instance 
$CsvFilePath = $Outpath + "AlwaysONStatus_Report.csv"
$results | export-csv  $CsvFilePath   -NoTypeInformation -Append
#log end of process
"$Instance            --DataExtract Succeeded at " + $CurDatetime     | out-file $LogFile  -Width 180  -Append
"$Instance            --Succeeded "| out-file $SuccessServers -Width 180  -Append
} 

{
"$Instance            --DataExtract Failed at " + $CurDatetime     | out-file $FailedServers  -Width 180  -Append 
}
} 
#Catch the error if the ping test fails
else 
{
$servername + '            --Ping Failed '  | out-file $FailedServers  -Width 180  -Append
}
}

(Get-Content $csvFilePath) | Foreach-Object {$_ -replace "`"", ""} | Set-Content $CsvFilePath
"SQL Server Processing - COMPLETED"  +"`r`n"  | out-file $LogFile  -Width 180 -Append

----------------Mail.ps1
"Generating mail "
$BaseDir='D:PSScriptAlwaysOn'
$CsvFilePath='D:PSScriptAlwaysOnOutput*.csv'
$smtp='XXXXXXXXXXXXXXX'
$ToAddress='XXXXXXXXXXX'
$fromAddress='XXXXXXXXXXX'
$EmailSubject = "Dashboard_alwayson_final_status Reports" + " - " +'-' + $CurDate
$Body = "`r`n"  + "`r`n" + "Dashboard_alwayson_final_status Reports --" 
$files = get-childitem $CsvFilePath | where name -like "*.csv"
$attachments = $files.fullname
Send-MailMessage -to $ToAddress -From $fromAddress -SmtpServer $smtp -Subject $EmailSubject -BodyAsHtml $body -Attachments $attachments
"Mail sent"
"Dashboard_alwayson_final_status  Reports "
----------------CsvToTable.ps1
'table DbadminDashboard_alwayson_final_status truncation start'
#load data in table 
$BaseDir='C:SQLServerReportMonitoringAlwaysOn' 
$CsvFilePath=$BaseDir + 'Output*.csv'
$cmsserver ='CMSServerName'
$cmsdb = 'dbadmin'
$table = 'dbo.DbadminDashboard_alwayson_status'
$TruncateFile= $BaseDir + "TruncateTable.sql"
$results=Invoke-Sqlcmd -ServerInstance $cmsserver -Database $cmsdb -InputFile $TruncateFile -QueryTimeout 300
'table DbadminDashboard_alwayson_final_status truncation end'
'table DbadminDashboard_alwayson_final_status load start'
'table DbadminDashboard_alwayson_final_status load start'
$CSVImport = Import-CSV $CsvFilePath
ForEach ($CSVLine in $CSVImport)
{
$CSVServername = $CSVLine.Servername
$CSVgroup_name = $CSVLine.AlwaysONGroup
$CSVreplica_server_name = $CSVLine.replica_server_name
$CSVnode_name = $CSVLine.NodeName
$CSVrole_desc = $CSVLine.Role
$CSVDBName = $CSVLine.DBName
$CSVsynchronization_state_desc = $CSVLine.state
$CSVsynchronization_health_desc = $CSVLine.health

$SQLInsert = "USE $cmsdb
INSERT INTO $table (Servername,group_name,replica_server_name,node_name,role_desc,DBName,synchronization_state_desc,synchronization_health_desc) VALUES('$CSVServername','$CSVgroup_name', '$CSVreplica_server_name', '$CSVnode_name', '$CSVrole_desc', '$CSVDBName', '$CSVsynchronization_state_desc','$CSVsynchronization_health_desc')"
Invoke-SQLCmd -ServerInstance $cmsserver -Database $cmsdb -Query $SQLInsert 
}

'table DbadminDashboard_alwayson_final_status load end'

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating