Functions/Alert-SdtDiskSpace.ps1
function Alert-SdtDiskSpace { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [Alias('ServerName','MachineName')] [string[]]$ComputerName, [Parameter(Mandatory=$false)] [string[]]$ExcludeDrive, [Parameter(Mandatory=$false)] [decimal]$WarningThresholdPercent = 80.0, [Parameter(Mandatory=$false)] [decimal]$CriticalThresholdPercent = 90.0, [Parameter(Mandatory=$false)] [string]$ThresholdTable = 'dbo.sdt_disk_space_threshold', [Parameter(Mandatory=$false)] [string[]]$EmailTo = @($SdtDBAMailId), [Parameter(Mandatory=$false)] [int]$DelayMinutes = 60 ) $isCustomError = $false <# #$errMessage = @() # Check for server connectivity $servers = @() $servers = $ComputerName $ComputerName = @() foreach($srv in $servers) { if(Test-Connection $srv -Count 2) { } } if(-not (Test-Connection $ComputerName -Count 2)) { Write-Verbose "Servers are connecting" } #> # Start Actual Work $blockDbaDiskSpace = { $ComputerName = $_ $FriendlyName = $ComputerName.Split('.')[0] $r = Get-DbaDiskSpace -ComputerName $ComputerName -EnableException $r | Add-Member -NotePropertyName FriendlyName -NotePropertyValue $FriendlyName $r | Add-Member -MemberType ScriptProperty -Name "PercentUsed" -Value {[math]::Round((100.00 - $this.PercentFree), 2)} $r } $jobs = @() $jobs += $ComputerName | Start-RSJob -Name {$_} -ScriptBlock $blockDbaDiskSpace -Throttle $SdtDOP "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","Waiting for RSJobs to complete.." | Write-Verbose $jobs | Wait-RSJob -ShowProgress -Timeout 1200 -Verbose:$false | Out-Null $jobs_timedout = @() $jobs_timedout += $jobs | Where-Object {$_.State -in ('NotStarted','Running','Stopping')} $jobs_success = @() $jobs_success += $jobs | Where-Object {$_.State -eq 'Completed' -and $_.HasErrors -eq $false} $jobs_fail = @() $jobs_fail += $jobs | Where-Object {$_.HasErrors -or $_.State -in @('Disconnected')} $jobsResult = @() $jobsResult += $jobs_success | Receive-RSJob -Verbose:$false if($jobs_success.Count -gt 0) { "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","Below jobs finished without error.." | Write-Output $jobs_success | Select-Object Name, State, HasErrors | Format-Table -AutoSize | Out-String | Write-Output } if($jobs_timedout.Count -gt 0) { "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(ERROR)","Some jobs timed out. Could not completed in 20 minutes." | Write-Output $jobs_timedout | Format-Table -AutoSize | Out-String | Write-Output "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","Stop timedout jobs.." | Write-Output $jobs_timedout | Stop-RSJob } if($jobs_fail.Count -gt 0) { "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(ERROR)","Some jobs failed." | Write-Output $jobs_fail | Format-Table -AutoSize | Out-String | Write-Output "--"*20 | Write-Output } $jobs_exception = @() $jobs_exception += $jobs_timedout + $jobs_fail [System.Collections.ArrayList]$jobErrMessages = @() if($jobs_exception.Count -gt 0 ) { $alertHost = $jobs_exception | Select-Object -ExpandProperty Name -First 1 $isCustomError = $true $errMessage = "`nBelow jobs either timed or failed-`n$($jobs_exception | Select-Object Name, State, HasErrors | Out-String)" $failCount = $jobs_fail.Count $failCounter = 0 foreach($job in $jobs_fail) { $failCounter += 1 $jobErrMessage = '' if($failCounter -eq 1) { $jobErrMessage = "`n$("_"*20)`n" | Write-Output } $jobErrMessage += "`nError Message for server [$($job.Name)] => `n`n$($job.Error | Out-String)" $jobErrMessage += "$("_"*20)`n`n" | Write-Output $jobErrMessages.Add($jobErrMessage) | Out-Null; } $errMessage += ($jobErrMessages -join '') #throw $errMessage } $jobs | Remove-RSJob -Verbose:$false $jobsResultFiltered = @() $jobsResultFiltered += $jobsResult | Where-Object {$_.PercentUsed -ge $WarningThresholdPercent} #$subject = "Alert-SdtDiskSpace - $(Get-Date -format 'yyyy-MMM-dd')" $subject = "Alert-SdtDiskSpace" $footer = "<p>Report Generated @ $(Get-Date -format 'yyyy-MM-dd HH.mm.ss')</p>" if($jobsResultFiltered.Count -gt 0) { $jobsResultFiltered | Add-Member -MemberType ScriptProperty -Name "Severity" -Value { if($this.PercentUsed -ge $CriticalThresholdPercent) {'CRITICAL'} else {'WARNING'} } $alertResult = @() $alertResult += $jobsResultFiltered | Select-Object @{l='Server';e={$_.FriendlyName}}, @{l='DiskVolume';e={$_.Name}}, Severity, ` @{l='FreePercent';e={"$($_.PercentFree) ($($_.Free)/$($_.Capacity))"}}, ` @{l='DashboardURL';e={"$SdtGrafanaBaseURL"}} "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","Below disk(s) are found with space issue - " | Write-Output $alertResult | ft -AutoSize | Out-String $alertServers = @() $alertServers += $alertResult | Select-Object -ExpandProperty Server -Unique $serverCounts = $alertServers.Count $criticalDisks = @() $criticalDisks += $alertResult | Where-Object {$_.Severity -eq 'CRITICAL'} $criticalDisksCount = $criticalDisks.Count $warningDisks = @() $warningDisks += $alertResult | Where-Object {$_.Severity -eq 'WARNING'} $warningDisksCount = $warningDisks.Count $title = "<h2>Alert-SdtDiskSpace - $(if($serverCounts -gt 1){"$serverCounts Servers"}else{"[$alertServers]"}) $(if($criticalDisksCount -gt 0){"- $criticalDisksCount CRITICAL"}) $(if($warningDisksCount -gt 0){"- $warningDisksCount WARNING"})</h2>" #$content = $alertResult | Sort-Object -Property Severity, Server | ConvertTo-Html -Fragment $params = @{ 'As'='Table'; 'PreContent'= '<h3 class="blue">Disk Space Utilization</h3>'; 'EvenRowCssClass' = 'even'; 'OddRowCssClass' = 'odd'; 'MakeTableDynamic' = $true; 'TableCssClass' = 'grid'; 'Properties' = 'Server', 'DiskVolume', @{n='Severity';e={$_.Severity};css={if ($_.Severity -eq 'CRITICAL') { 'red' }}}, 'FreePercent', 'DashboardURL' } $content = $alertResult | Sort-Object -Property Severity, Server | ConvertTo-EnhancedHTMLFragment @params $body = "$SdtCssStyle $title $content $footer" | Out-String if($criticalDisksCount -gt 0) { $priority = 'High' } else { $priority = 'Normal' } "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","Calling 'Raise-SdtAlert' to generate alert notification.." | Write-Output Raise-SdtAlert -To $EmailTo -Subject $subject -Body $body -Priority $priority -Severity High -BodyAsHtml -DelayMinutes $DelayMinutes } else { $content = '<p style="color:blue">Alert has cleared. No action pending</p>' $body = "$SdtCssStyle $content $footer" | Out-String "{0} {1,-10} {2}" -f "($((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')))","(INFO)","No space issue found. Calling 'Raise-SdtAlert' to clear active alert (if any).." | Write-Output Raise-SdtAlert -To $EmailTo -Subject $subject -Body $body -Priority 'Normal' -Severity High -BodyAsHtml -ClearAlert -DelayMinutes $DelayMinutes } if($isCustomError) { throw $errMessage } <# .SYNOPSIS Check Disk Space on Computer, and send Alert .DESCRIPTION This function analyzes disk space on Computer, and send an email alert for CRITICAL & WARNING state. .PARAMETER ComputerName Server name where disk space has to be analyzed. .PARAMETER ExcludeDrive List of drives that should not be part of alert .PARAMETER WarningThresholdPercent Used space warning threshold. Default 80 percent. .PARAMETER CriticalThresholdPercent Used space critical threshold. Default 90 percent. .PARAMETER ThresholdTable Table containing more specific threshold for server & disk drive at percentage & size level. .PARAMETER EmailTo Email ids that should receive alert email. .EXAMPLE Alert-SdtDiskSpace -ComputerName 'SqlProd1','SqlDr1' -WarningThresholdPercent 70 -CriticalThresholdPercent 85 Analyzes SqlProd1 & SqlDr1 servers for disk drives having used space above 70 percent. .LINK https://github.com/imajaydwivedi/SQLDBATools #> } |