Skip to content

Instantly share code, notes, and snippets.

@JKerens
Created August 4, 2022 17:44
Show Gist options
  • Select an option

  • Save JKerens/94c19c4a751f8f8c0839795bdb2ded26 to your computer and use it in GitHub Desktop.

Select an option

Save JKerens/94c19c4a751f8f8c0839795bdb2ded26 to your computer and use it in GitHub Desktop.
PowerShell tasks with a wrapper that monitors metrics of interest while a long task is running
#requires -Module Az.Sql
#requires -Module Az.Monitor
<#
.DESCRIPTION
When running a reindex on a Sql database sometime the fragmentation is so bad it will grow the database to the max size before finishing.
This example shows how to attach monitoring to an action.
.EXAMPLE
$db = Get-AzSqlDatabase -ResourceGroupName <ResourceGroupName> -ServerName <ServerName> -DatabaseName <DatabaseName>
$db | Invoke-MonitoredSqlCommand
#>
function Invoke-MonitoredSqlCommand {
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Microsoft.Azure.Commands.Sql.Database.Model.AzureSqlDatabaseModel]$Database,
[Parameter(Mandatory = $false)]
[int]$LoopsCount = 5,
[Parameter(Mandatory = $false)]
[int]$SleepInSeconds = 2
)
$LoopsCount = 5
MonitorDatabase -Database $Database {
(1..$LoopsCount) | ForEach-Object {
<# Simulate some work being done #>
Write-Progress -Id 1 -Activity $Database.DatabaseName -PercentComplete ($_/$LoopsCount * 100)
Start-Sleep -Seconds $SleepInSeconds
}
return $Database
}
}
function MonitorDatabase {
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNull()]
[ScriptBlock] $Command,
[Parameter(Mandatory = $true)]
[ValidateNotNull()]
[Microsoft.Azure.Commands.Sql.Database.Model.AzureSqlDatabaseModel]$Database
)
$monitorJobName = "$($Database.DatabaseName)-monitor".ToLower()
$monitorJob = Start-Job -Name $monitorJobName -WorkingDirectory $PSScriptRoot -ScriptBlock {
param([string]$scriptRoot, [string]$resourceId)
while ($true) {
$log = Join-Path $scriptRoot "report.log"
<# Get storage percentage on the Sql database to see if we need to scale up #>
$metrics = Get-AzMetric -ResourceId $resourceId -MetricName "storage_percent"
$data = $metrics.Data `
| Where-Object { $null -ne $_.Maximum } `
| Sort-Object Timestamp `
| Select-Object TimeStamp, Maximum -Last 1
<# Currently just logging for the PoC #>
"[{0}]: {1}%" -f $data.TimeStamp,$data.Maximum | Out-File -FilePath $log -Append
Start-Sleep -Seconds 2
}
} -ArgumentList $PSScriptRoot,$Database.ResourceId
try {
return Invoke-Command $Command
}
finally {
<# Always remove this job when done. Similar to IDisposable #>
$monitorJob | Stop-Job
$monitorJob | Remove-Job
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment