Created
August 4, 2022 17:44
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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