Notification when Azure database matching a defined name is still running - azure

I want to receive a notification when there is an Azure database running that matches a defined name pattern. What script can I use to check for existence of a database by name pattern?
For example when are debugging live issues we will often use the Copy feature from Azure to back up our production database onto a dev server. The databases are always named with a *_copy suffix. Occasionally we forget to delete these databases when we are finished with them, so they continue to be billed.
We would like a daily notification if there are any running *_copy databases running.

The script below will give you a list of databases with "copy" at the end of the name. Put it inside a Runbook to send you a daily report of the databases.
$ListServers = Get-AzSqlServer | Select-Object ResourceGroupName, ServerName
Foreach ($Server in $ListServers){
Get-AzSqlDatabase -ResourceGroupName $Server.ResourceGroupName -ServerName $Server.ServerName `
| Where-Object {$_.DatabaseName -like "*copy"} `
| Select-Object ResourceId
}

Related

How do I parse Kusto Query output into Automation Script (Powershell or Python)

I have a Kusto query that will output for me processes from my VMs (whether they are stopped or not).
Here is the query:
ConfigurationData
| project Computer, SvcName, SvcDisplayName, SvcState, TimeGenerated, _ResourceId
| distinct Computer, SvcName, SvcDisplayName, SvcState, TimeGenerated , _ResourceId
| where SvcName =~ "{process_name}"
| where SvcState != "Running"
I need to parse the ComputerName (Computer) to an Automation Script so that it simply turns on the process that is not running.
How can I achieve this?
Would it be wiser to just run the KQL code in the automation script directly? But then, how can I trigger it? It needs to check every 5 mins whether the process is running. I suppose I could do a scheduling task.
I'm still trying to work at ways of parsing the KQL output to an automation script
One way is doing with Kusto query, the other way which I do is by using PowerShell commands as below and I followed SO-thread:
$vm = Get-Azvm -Status
foreach($emos in $vm)
{
$sc = Get-AzVM -ResourceGroupName $emos.ResourceGroupName -Name $emos.Name -Status
if($sc.Statuses.DisplayStatus[1] -eq "VM running")
{
Write-Output "Already started" + $emos
}
else{
Write-Output "Started now" + $emos
Start-AzVM -ResourceGroupName $emos.ResourceGroupName -Name $emos.Name
}
And you can schedule a recurrence in Automation as below after creating the above job in run book as below:
Or else you can use the above PowerShell Script in Azure PowerShell Functions, after that you can use timer Trigger function.
I would start by fixing the KQL query.
It is not retrieving services that are currently not running, it retrieves services that in some point in time were not running.
You should retrieve the last record for each service (running on a specific computer).
ConfigurationData
| where SvcName =~ "{process_name}"
| project Computer, SvcDisplayName, SvcState, TimeGenerated, _ResourceId
| summarize arg_max(TimeGenerated, *) by Computer
| where SvcState != "Running"

Query whether Azure App Services has backup setup

Can anyone suggestion a way to query App Services backup status?
For example, Let say I have a lot of App Services in Azure, different resource groups, instead of clicking through each one and check if backup is setup or not. I want to have a query so I can execute it and return the result?
Thanks in advance.
Based on the above shared requirement , we have written the below PowerShell script to pull the backup details of a webapp. the below script will check whether if there is backup enabled or not for a particular web under resource group.
if backup not enabled scrip will through an error -->
Get-AzWebAppBackupConfiguration : Operation returned an invalid status code 'NotFound'
if backup is enabled scrip will return -->
webappName,storageaccounturi of the backup where it is stored
$RGName='<ResourceGroupName>' ##Pass your ResourceGroupName
$list= Get-AzWebApp -ResourceGroupName $RGName
$listarray=$list
foreach($list in $listarray){
$config=Get-AzWebAppBackupConfiguration -ResourceGroupName $RGName -Name $list.name
Write-Host $config.Name,$config.StorageAccountUrl| Format-Table -AutoSize
}
Here is the sample output for reference:

Azure Powershell cmd-let - Get-AzureRmLog doesn't show "Microsoft.Authorization/" logs

I have prepared Azure PowerShell script for catching RBAC changes information from Azure Activity Logs. When I am testing this script on my test subscription, script works fine. Problem is when I used connect-azurermaccount -subscription command and switched to the prod subscription. In the Azure activity log blade I saw that there were some logs related to RBAC changes, log names like "Create role assignment". I was testing with commands like below:
Get-AzureRmLog -StartTime (Get-Date).AddDays(-10) |
Where-Object {$_.Authorization.Action -like
"Microsoft.Authorization/roleAssignments/*"}
and
Get-AzureRmLog -StartTime 2019-09-01T10:30 | Where-Object {$_.Authorization.Action -like "*Microsoft.Authorization/*"}
I didnt see any output in the console. When I logged to the Azure portal and opened Activity log I was able to see logs related to RBAC changes, log names --> "Delete role assignment", "Create role assignment". I was testing mentioned commands with string "Microsoft.Compute":
Get-AzureRmLog -StartTime (Get-Date).AddDays(-10) |
Where-Object {$_.Authorization.Action -like
""*Microsoft.Compute/*""}
and
Get-AzureRmLog -StartTime 2019-09-01T10:30 | Where-Object {$_.Authorization.Action -like "*Microsoft.Compute/*"}`
I could see the logs information in the output. I am not sure what is wrong and what should I correct. Why can't I use this filter in my prod subscription --> "Microsoft.Authorization/", I would like to highlight that on my test subscription script worked perfectly fine.
If you want to get the logs related to RBAC changes, you can use the following the script to get it.
Connect-AzureRmAccount
Get-AzureRmLog -ResourceProvider Microsoft.Authorization -StartTime (Get-Date).AddMonths(-1)
For more details, please refer to
https://learn.microsoft.com/en-us/powershell/module/azurerm.insights/get-azurermlog?view=azurermps-6.13.0
Update
If you want to use Azure rest api to get the logs related to RBAC changes, you need to use the rest api as below:
Method : GET
URL:https://management.azure.com/subscriptions/<subscription id>/providers/microsoft.insights/eventtypes/management/values
Params:
api-version = 2017-03-01-preview
$filter = eventTimestamp ge 'your strat time' and resourceTypes eq 'microsoft.authorization/roleassignments'
Header:
Authorization : Bearer access_token
For example:
According to my test, if the numbers of your log are too big, the results will be paged. If you want to get the other pages' results, we need to send request to the nextlink which is a parameter in the result.

Azure Powershell : Find the creator of a virtual machine

I want to retrieve the creator of a virtual machine under Azure using azure rm powershell cmdlt or an api whitxh could return this type of information.
I used the "Get-AzureRmVM" command and the "GET https://management.azure.com/subscriptions/subscriptionId/resourceGroups/resourceGroupName/providers/Microsoft.Compute/virtualMachines/vmName?api-version=2018-06-01" api but both of them don't return information about the creator of the VM
You can use the Get-AzLog command to look for the caller value in the Azure Activity logs.
Examples can be found here:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-audit#powershell
You can also set up alerts in Azure Monitoring that can send you an email or text message everytime a VM is created.
https://learn.microsoft.com/en-us/azure/azure-monitor/platform/alerts-overview
Example
# Requires the AZ module be installed on your machine. You can get this by running Install-Module 'AZ'
Connect-AzAccount # after calling this a browser window opens, allowing you to log into Azure through the UI under the relevant credentials; on successful login the token for this session is returned to your PowerShell session
# Sets your scope to the subscription you're interested in
Set-AzContext -Subscription 'myAzSubscription'
# Fetches (successful) events in the past 2 weeks
# Filters for those related to VM write events (which includes creating VMs, though sadly we can't just VM creations)
# groups by resource id (i.e. VM).
# Note: The Get-AzLog function can return a maximum of 100,000 events (and this count is based on the filters provided as parameters; filters applied to the results of the cmdlet won't impact this limit), so if things have been particularly busy some of the log may be truncated. If that's a common issue for you, try narrowing the event's time window or restricting queries to specific resource groups.
$events = Get-AzLog -StartTime ((Get-Date).AddDays(-14)) -ResourceProvider 'Microsoft.Compute' -Status 'Succeeded' -MaxRecord 100000 |
Where-Object {$_.Authorization.Action -eq 'Microsoft.Compute/virtualMachines/write'} |
Group-Object -Property #{E={$_.Authorization.Scope}}
# For each VM get the first event with a human caller (i.e. ignore system generated events) and return that caller's name. Filter out events that didn't have a human caller as irrelevant
$events |
Select-Object Name, #{N='InitiatedBy'; E = {
$_.Group |
Sort-Object SubmissionTimestamp |
Select-Object -ExpandProperty 'caller' |
Where-Object{$_ -like '*#*'} |
Select-Object -First 1
} } |
Where-Object InitiatedBy |
Format-Table -AutoSize
This information is not exposed in Azure API (unfortunately). Your only option is to take a look at activity logs of the resource and find the very first write operation to the resource, unfortunately resources do not expose creation time either, so you cannot be sure you will find proper creator, because activity logs only go back 90 days.

What am I Missing in PowerShell in Azure Automation that prevents Start-AzureVM from working?

I have the following PS script that runs fine locally:
Get-AzureVM | Where-Object { $_.Name -eq "my-server-selector" } | select name | ForEach-Object {
Write-Output $_.Name
Start-AzureVM $_.Name $_.Name
}
In the context of my local PS console, I add my subscription info and the code executes without a problem; all VMs are printed to the output and the servers are started up.
When I move it to the cloud I need to do a few other things, namely, bring the subscription in scope. I do that by creating the credential asset in the portal, adding the account to my script via said credentials, then selecting the correct subscription in the script. I also wrap it in a workflow (there are aspects I intent to parametrize at a later date).
The final code is as follows:
workflow StartServer
{
$credential = GetAutomationPSCredential -Name "credential-asset-name"
Add-AzureAccount -Credential $credential
Select-AzureSubscription -SubscriptionName "subscription-name"
Write-Output "Starting the server."
Get-AzureVM | Where-Object { $_.Name -Contains "my-server-selector" } | select name | ForEach-Object {
Write-Output $_.Name
Start-AzureVM $_.Name $_.Name
}
Write-Output "Execution Complete."
}
If I remove the Start-AzureVM command, the workflow runs as expected. I get a listing of all the matching VMs printed out. If I attempt to put the command back in, I get the following error:
Parameter set cannot be resolved using the specified named parameters.
So, things I think I know:
the credentials are working as I'm getting the correct list of VMs
the subscription is being correctly set, as it's dumped to the output
the inner part of the script works on a local powershell console without any changes
Can anyone provide any ideas as to what needs to be done differently in an Azure Automation workflow to get this to work?
The fix was to be more explicit in the naming of parameters, both in the filter for the Where-Object as well as in the call to Start-AzureVM. I'm not sure why this would make a difference; as I said, the call to write the names of the servers worked without the explicit parameter name, but low and behold, here it works with it set.
The final code of the inner block is as follows:
Get-AzureVM | Where-Object -FilterScript { $_.Name -Contains "my-server-selector" } | select name | ForEach-Object {
Write-Output $_.Name
Start-AzureVM -ServiceName $_.Name -Name $_.Name
}
Thanks to #DexterPOSH on Twitter for the direction on -FilterScript.
Please take a look at http://azure.microsoft.com/blog/2014/11/25/introducing-the-azure-automation-script-converter/ which talks about this exact issue. When authoring Powershell in the ISE to move into Azure Automation, make sure you are testing / writing as Powershell Workflow in the ISE, since Powershell workflow has some differences vs Powershell script.
Or, if you need to take PS script and use it in Azure Automation, make sure you import the script, not copy paste it in. Azure Automation will then convert the PS script to PS Workflow for you. The link above has more details on this.

Resources