If you need to reset a VPN-Gateway, an Azure Runbook is a good way of implementation. And the command to reset is very simple: Reset-AzVirtualNetworkGateway

But if the runbook was called several times, for example from several alerts, the reset would also be triggered several times. A second reset process does not disturb the current process, but causes errors in the audit log (red frame):

It therefore makes sense to check whether a reset process is already running before starting a reset. Unfortunately, the command itself does not return a status and the gateway does not change to a resetting status. To find out whether the gateway is currently performing a reset, the audit log can be checked directly with Get-AzLog (line 41):

#Requires -Module Az.Account
#Requires -Module Az.Network
#Requires -Module Az.Monitor

[OutputType([String])]

param (
    [Parameter(Mandatory=$false)] 
    [String]  $AzureConnectionAssetName = "AzureRunAsConnection",

    [Parameter(Mandatory=$true)] 
    [String] $ResourceGroupName,

    [Parameter(Mandatory=$true)] 
    [String] $VpnGwName

)

Write-Output "start resetting VPN..."

try {
    # Connect to Azure using service principal auth
    $ServicePrincipalConnection = Get-AutomationConnection -Name $AzureConnectionAssetName         
    Write-Output $ServicePrincipalConnection
    Write-Output "Logging in to Azure..."
    #$Null = Add-AzAccount -ServicePrincipal -TenantId $ServicePrincipalConnection.TenantId -ApplicationId $ServicePrincipalConnection.ApplicationId -CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint
    $Null = Connect-AzAccount -ServicePrincipal -TenantId $ServicePrincipalConnection.TenantId -ApplicationId $ServicePrincipalConnection.ApplicationId -CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint
    Write-Output "Logged in to Azure..."
}catch {
    if(!$ServicePrincipalConnection) {
        throw "Connection $AzureConnectionAssetName not found."
    } else {
        throw $_.Exception
    }
}

$subid = $ServicePrincipalConnection.SubscriptionId
$resourceid = "/subscriptions/$subid/resourceGroups/$ResourceGroupName/providers/Microsoft.Network/virtualNetworkGateways/$VpnGwName";
#Write-Output $resourceid
Write-Output "Getting Logs for $resourceid"
$logs = Get-AzLog -ResourceId $resourceid -StartTime (Get-Date).AddHours(-1)

if($logs.Count -ge 1 -and $logs[0].OperationName.value -eq "Microsoft.Network/virtualNetworkGateways/reset/action" -and $logs[0].Status.value -eq "Accepted")
{
    Write-Output "Gateway is currently resetting..."    
}
else
{
    # no log entry since an hour,
    # or last log entry was something else
    # or last log entry with reset was "failed" or "succeded"
    Write-Output "Get Gateway..."
    $gw = Get-AzVirtualNetworkGateway -Name $VpnGwName -ResourceGroupName $ResourceGroupName
    Write-Output "Reset Gateway..."
    Reset-AzVirtualNetworkGateway -VirtualNetworkGateway $gw
}

Write-Output "...finished"

The state of the reset command changes from Accepted to Started and from there to Succeeded or Failed. If a reset is currently active, the last entry is of type Microsoft.Network/virtualNetworkGateways/reset/action and the status is Accepted. This case is dealt with accordingly in line 43.

The file Reset-VPN-Gateway.ps1 can be found at GitHub.