Query whether Azure App Services has backup setup - azure

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:

Related

Error result using New-AzApplicationInsightsContinuousExport - Can not perform requested operation on nested resource. Parent resource

I am trying to use the New-AzApplicationInsightsContinuousExport in the powershell since the Continuous Export feature is currently not available unless we migrate the current resource for application insight in workspace-based application resource. Unfortunately we do not have the authority to do it for now so thats why we are using the alternative method through powershell. I followed the instructions and created the sample storage creation found in the document of microsoft. Then after that used the sample command "New-AzApplicationInsightsContinuousExport". Did change the value based on the settings we have and execute it. But I encountered an error which is "Can not perform requested operation on nested resource. Parent resource". Been trying to find how to solve but unfortunately, I am stuck. Would someone help or direct me what should I do on this? Thanks! I posted the image of the command i executed.
enter image description here
enter image description here
I tried different approach of values that on the parameters that I think might work but its not working also. I also checked the "appinsighttest1" storage account configuration that was created by checking the settings, network, keys and other that might enable/visible for the command to work. My idea is the reason that it is not found maybe i have to enable something the storage account configuration. But right now i cant get it to work.
Error result using New-AzApplicationInsightsContinuousExport - Can not perform requested operation on nested resource. Parent resource:
"Parent resource 'test' not found: It means that no application insight resource with the name "test" has been created in Azure. You must first create an application insight in Azure Portal before using New-AzApplicationInsightContinuousexport.
I created in my environment as shown:
Using MSDoc as a reference, I tried in my environment with few modifications and successfully enabled continuous export with the respective command.
Script to run:
$context = $context = New-AzStorageContext -StorageAccountName "xxxstorageaccountname" -StorageAccountKey "xxxStorageaccountkey=="
$sastn = New-AzStorageContainerSASToken -Name <container> -Context $context -ExpiryTime (Get-Date).AddYears(50) -Permission w
$SASuri = "https://<storageaccount>.blob.core.windows.net/<containername>" + $sastn
New-AzApplicationInsightsContinuousExport -ResourceGroupName "<ResourceGroupName>" -Name "<applicationinsightname>" -DocumentType "Request","Trace", "Custom Event" -StorageAccountId "/subscriptions/<subscriptionID>/resourcegroups/<ResourceGroupName>/providers/Microsoft.Storage/storageAccounts/<storageaccount>" -StorageLocation EastUS -StorageSASUri $SASuri -DestinationType Blob
Output:
Note: This error might occur when you do not have enough right (access) to give/modify the permissions or roles. Assign "Storage Blob Data Owner" role for the storage account.

Az Powershell Module - says "Cannot find storage account with name xxx" but it exists

I've run into a snag with my powershell script that builds an azure function & all its dependencies.
This is what's happening: (i'm doing it manually here to demo...)
I request the storage account information like this:
PS C:\Users\me\> Get-AzStorageAccount -ResourceGroupName widget-resource-group
StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState EnableHttpsTrafficOnly LargeFileShares
------------------ ----------------- --------------- ------- ---- ---------- ------------ ----------------- ---------------------- ---------------
widgetx4ge6v27rlgdk widget-resource-group eastus Standard_LRS StorageV2 Hot 2022-03-10 2:00:26 PM Succeeded True
It comes back with the correct information. So then I try to get the connection string like this:
PS C:\Users\me> func azure storage fetch-connection-string widgetx4ge6v27rlgdk
Cannot find storage account with name widgetx4ge6v27rlgdk
But it says it can't find the storage account.
The actual code looks like this:
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# Get new connection string for the storage account.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
When the code runs, everything works until the call to "func azure storage fetch-connection-string".
Any tips on what I'm missing?
Edit 1
In case it helps, this logic works just fine when I run it against Tenant 1, Subscription A. But for Tenant 1, Subscription B it bombs.
I've made sure the service account principle it runs under is contributor on both subscriptions.
And for what it's worth, the script is able to create the resource group and many of the resources inside. It's just hat when I try to get the connection string, it bombs. It also bombs further down in the script when it tries to deploy the functions in my function app. The error message though is similar - it complains that it can't find the function app that I just finished creating.
Edit 2
So I figured out the problm but not sure how to fix it in a nice / simple way.
For 90% of the script, including login, i'm using the new Az Powershell modules. However, the "func azure" tool relies on login information provided by the az cli. (that seems to be cached??)
To get you on the same page, here's the relevant part of the code in the script:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AZ_DEPLOYMENT_CLIENT_ID, $Secure2
#Connect
Connect-AzAccount -ServicePrincipal -TenantId $AZ_TENANT_ID -Credential $Credential
#OPTIONAL - List the subscriptions available to the current User
Get-Azcontext -ListAvailable
#Set the subscription context to subscription 2
Set-Azcontext -Subscription $AZ_SUBSCRIPTION_ID -Tenant $AZ_TENANT_ID
#Create a new resource group
New-AzResourceGroup -Name $AZ_RESOURCE_GROUP_NAME -Location $AZ_RESOURCE_LOCATION -Force
New-AzResourceGroupDeployment -ResourceGroupName $AZ_RESOURCE_GROUP_NAME -TemplateFile (Join-Path $PSScriptRoot "./artifacts/widget-resources.json")
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# this is where it is failing because it is using a subscription that is visible to az cli.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
Here's what I did to troubleshoot from a powershell cli:
az account list
That returns this:
{
"cloudName": "AzureCloud",
"homeTenantId": "asdf-asdf-asdf-asdf-12312312313",
"id": "[guid]",
"isDefault": false,
"managedByTenants": [],
"name": "subscription-1",
"state": "Enabled",
"tenantId": "[our-tenant-id]",
"user": {
"name": "[another-guid]",
"type": "servicePrincipal"
}
}
When I ran the above command, it only returned one subscription called "subscription-1" for discussion purposes. It isn't/wasn't the one that the rest of the script was working with. The rest of script was dealing with subscription 2
As I test, I added the following lines of code just before call func azure storage:
az login --service-principal --username $AZ_APPLICATION_CLIENT_ID --password $AZ_SECRET --tenant $AZ_TENANT --allow-no-subscriptions
#set the subscription we want to use
az account set --subscription $subscription2
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
And now it finds the correct subscription and resource group / storage account. And now when I run az account list again, it shows me both subscriptions.
One addition comment / observation. Once the az login / az account set has been run with the desired subscription id, i've noticed that I can remove the az login and account set logic from the script and it just uses the cached values. I'm not saying this is what I want to do ... cuz I think it' best to be explicit. But just an observation which explains what bit me in the first place.
So my question is... is there anyway to avoid having to log in twice - once with az cli and another time with the Az Powerhsell modules?
I'm thinking of just abandoning the Az Powershell module and just rewriting everything in just az cli.
But asking the community to see if there's a better way to do this.
EDIT 3
Based on the docs for the azure core functions tools, technically I should be able to use the powershell modules or the cli:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash#publish
"You must have the Azure CLI or Azure PowerShell installed locally to be able to publish to Azure from Core Tools."
Yes, using a mix of azcli and azure powershell, as they are their seperate entities in their own right, you would need to login to each of them individually.
And yes, you are right its better to ditch of them and choose one or the other ! Just much cleaner that way
The issue was that the azure core functions tool is using the cached az account list to find my resources.
So in other words, unbeknownst to me, the func method was using az cli, whereas the rest of the script is using the new Az Powershell modules.
For now, I've just rewritten everything in az cli syntax, and am happy with that. But per the docs it seems that the azure core functions tools should be able to work with either az cli or az powershell. Will open a separate question that addresses that point. For now, my script is working again.

Use Powershell with Azure to retrieve the ConnectionString of an AuthoriztionRule of a Service Bus Topic

I'm a bit of an Azure & Powershell newbie.
I'm trying to write PowerShell scripts to create an environment that can be published to from Azure DevOps.
As part of that, I'm creating a Service Bus with multiple topics. Each of the topics will have multiple Authorization Rules - one for publication and one for subscription.
I have the scripts for this working. However, I need to get the connection strings for these rules and save them to a key vault, to make them available to apps.
This is where I have become stuck.
This is similar to my existing code:
New-AzServiceBusTopic -ResourceGroupName myResourceGroup -Namespace myServiceBus -EnablePartitioning $false -Name myTopic
New-AzServiceBusAuthorizationRule `
-ResourceGroupName myResourceGroup `
-Namespace myServiceBus `
-Topic myTopic`
-Name myTopic.pub `
-Rights #("Send")
In the Azure Portal, I would click into the Service bus and Topic, select Shared Access Policies and click on the policy. It would show me the SAS Policy with the Primary Connection String.
Is there any way in PowerShell to get the Primary Connection String?
Thanks
If you have azure powershell Az.ServiceBus module installed, you can directly use this command: Get-AzServiceBusKey.
For example:
Get-AzServiceBusKey -ResourceGroup Default-ServiceBus-WestUS -Namespace SB-Example1 -Name AuthoRule1

Error 403 on Creating Azure Storage Blob Container (Storage Firewall Enabled

Update:
After the comment from Maurad I found a log that shows me that the "CreateContainer" operations seems to be running under a different IP 🤔🤔
Any idea why this would happen?
Original Post:
I have an azure storage account with the Firewall enabled and I am trying to create a blob container in the account using a VSTS build pipeline.
The pipeline is ran by a Microsoft hosted agent, and because of that it is part of my process to add the IP of the machine to the firewall before creating the container, and removing it just after.
The problem is that I am getting an error 403 when I ran the create blob command.
I've tried adding a wait time after adding the ip to the firewall but, even if I wait for 5 minutes, I still get the 403.
This is the script that I am running:
$MyIP = (Invoke-WebRequest 'https://ifconfig.me/ip' -Method Get).Content
Try {
Add-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName `
-Name $StorageAccountName `
-IPAddressOrRange $MyIP
$ctx = (Get-AzStorageAccount -ResourceGroupName $ResourceGroupName `
-Name $StorageAccountName).Context
New-AzStorageContainer -Name $ContainerName `
-Context $ctx
}
Finally {
Remove-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName `
-Name $StorageAccountName `
-IPAddressOrRange $MyIP
}
and this is the result I get (you can see the ip of the agent is properly added)
Action IPAddressOrRange
------ ----------------
Allow 127.0.0.1
Allow 104.40.203.123 # This is the build agent IP
New-AzStorageContainer: C:\Users\Desktop\Test.ps1:15
Line |
15 | New-AzStorageContainer -Name $ContainerName `
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| This request is not authorized to perform this operation. HTTP Status Code: 403 - HTTP Error Message:
| This request is not authorized to perform this operation.
ErrorCode: AuthorizationFailure
| ErrorMessage: This request is not authorized to perform this operation.
| RequestId:9112d81a-e01e-002a-7935-331d33000000
Time:2020-05-26T08:11:04.9195569Z
Action IPAddressOrRange
------ ----------------
Allow 127.0.0.1
Remark: Disabling the firewall works, but I cannot do that in prod
I have an answer from Microsoft on this subject.
What is happening is that when we create an Azure DevOps organization, we need to inform a region for it, but these regions are a subset of the Azure regions.
Whenever I ran a pipeline using a Microsoft Hosted Agent, that agent is spun up on some Azure region.
If the agent is located in the same region as the storage account, then the communication will happen using private IPs, which are not supported on the Storage Account whitelisting, thereby you have the error.
So that is it, there is no workaround to fix this using Microsoft Hosted Agents.
Alternative
As suggested by Microsoft, you will have to use a Self-hosted agent to ensure that this problem won't happen. No other known alternative.
Long Term Solution
There is a feature request to include Azure DevOps as one of the possible selections for "Trusted Services" on Storage account. This will fix the problem in a proper way, however there is no timeline for this feature to be implemented.
Hopefully this will help someone else with the same problem.
🤷‍♀️

How do I get the deployment id of an Azure VM?

I created a VM in Windows Azure and some networking people are asking me for the deployment id. I cannot see this property anywhere on the portal. How can I get the deployment id of a Windows Azure VM? I just created the VM through the portal.
One way is to:
Go to https://resources.azure.com and log in
Search for the name of your VM and click to open details. It should return JSON information about the VM.
In the JSON data, search for deploymentId (it should be under the hardwareProfile section in the JSON)
You can see the deployment ID in the virtual machine's Dashboard tab. Refer to the screenshot-
Here's how you can do it via Powershell:
First log in to azure:
login-AzureRmAccount
Then get a reference to the virtual machine. In my case, I have a virtual machine called malcolms-dad in the resource group breaking-bad:
$vm = (Get-AzureRmResource -ResourceGroupName breaking-bad -ResourceName malcolms-dad -ResourceType MicrosoftClassicComputer/virtualMachines)
Now you have the reference, you can query for the deployment id property:
$vm.Properties.HardwareProfile.DeploymentId
Note that we had to pass in the -ResourceType parameter into the Get-AzureRmResource query. This might seem superfluous, but if you omit the parameter the command returns an object without the Properties field.

Resources