Runbook Error when trying to read table with VM power states, stoped VMs that are recorded as stop and deleting the rows after the fact.
This is an after updates update manager post-script to shut down vms after they are started for updates if they were off before pre-script. Thus, keeping the environment as it was before processing updates. This is also run on a portal.azure.com personal account.
-MAIN ERROR:
Failed
The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
-Checked Permissions confirmed contributor for the automation account on the two subscriptions and contributor on the storage account.
Sanitized/initial run book script is as follows:
Note: the areas with multiple ###### is where I think the issue lays, but, running out of debugging...
# Parameters
$StorageAccountName = "xxxxxxxxxxx" # Your storage account name
$TableName = "VMPowerStateLog" # The table name to log data
$StorageAccountKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Import necessary modules
Import-Module Az.Accounts -ErrorAction Stop
Import-Module Az.Resources -ErrorAction Stop
Import-Module Az.Storage -ErrorAction Stop
Import-Module AzTable -ErrorAction Stop # Ensure AzTable module is imported
# Authenticate to Azure Environment using the managed identity of the automation account
Connect-AzAccount -Identity -EnvironmentName AzureCloud
# Create a storage context
$StorageContext = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
# Retrieve the storage table as an object
$StorageTable = Get-AzStorageTable -Name $TableName -Context $StorageContext -ErrorAction Stop
# Get all subscriptions
$subscriptions = Get-AzSubscription
# Looping through each subscription
foreach ($subscription in $subscriptions) {
$SubscriptionId = $subscription.Id
# Set subscription context to the current subscription to facilitate looping.
Set-AzContext -SubscriptionId $SubscriptionId
Write-Output "Processing Subscription: $SubscriptionId"
# Retrieve all entities/rows from the table related to the current subscription
$entities = Get-AzTableRow -Table $StorageTable.CloudTable | Where-Object { $_.PartitionKey -eq $SubscriptionId }
# Loop through each entity and process the VM shutdown
foreach ($entity in $entities) {
$vmName = $entity.VMName
$initialState = $entity.InitialState
$resourceGroupName = $entity.ResourceGroupName
###############
# Debug: Log VM details
Write-Output "Processing VM: $vmName in RG: $resourceGroupName with initial state: $initialState"
###############
# Process VMs based on their initial state
if ($initialState -eq "PowerState/running") {
Write-Output "VM: $vmName was originally running. No action needed."
} elseif ($initialState -match "deallocated" -or $initialState -match "stopped") {
try {
###############
Write-Output "Stopping VM: $vmName (was originally stopped or deallocated) in Resource Group: $resourceGroupName"
# Attempt to stop VM
Stop-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Force -ErrorAction SilentlyContinue
Write-Output "VM: $vmName has been stopped or deallocated."
###############
} catch {
Write-Output "Failed to stop VM: $vmName - Error: $_"
}
} else {
Write-Output "VM: $vmName is in an unexpected initial state: $initialState"
}
# Remove the entity (row) from Azure Table at the Storage Account
try {
###############
Write-Output "Deleting log entry for VM: $vmName with PartitionKey: $($entity.PartitionKey) and RowKey: $($entity.RowKey)"
Remove-AzTableRow -Table $StorageTable.CloudTable -PartitionKey $entity.PartitionKey -RowKey $entity.RowKey
Write-Output "Log entry for VM: $vmName deleted successfully."
###############
} catch {
Write-Output "Error deleting row entry for VM: $vmName"
}
}
Write-Output "Finished processing Subscription: $Subscript