Azure REST API Scopes

When working with the Azure REST API you need to provide the scope in all API requests, so Azure knows where you are looking. However, throughout their documentation that although they ask for the scope they do not explain or link to an explanation of what a scope is and what the formats are. Therefore, I have collected them and got a simple explanation for each of them.

As mentioned above, the scope is like a search filter and also part of the permissions. For example, if you was getting a list of Resources you might use the Resource Group scope to get only them Resources, or you might go for the Subscription scope to get all Resources in the requested Subscription. This might also be due to permissions, if the Service Principle account you are using doesn’t have access to the whole Tenant, but does to specific Subscriptions.

Scopes

Subscription scope

subscriptions/{subscriptionId}

Example:

subscriptions/d7f90b53-af20-4061-8206-f05e31852a44

Resource Group scope

subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}

Example:

subscriptions/d7f90b53-af20-4061-8206-f05e31852a44/resourceGroups/my-rg-2020

Providers scope

These scopes can vary depending on what the scope is for. For example this is the scope for the Billing Account:

providers/Microsoft.Billing/billingAccounts/{billingAccountId}

You can find all of the scopes by following https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations

Tenant scope

The Tenant scope is easist, as you just don’t put anything. For example getting a list of Role Definitions

The official URL is:

GET https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01

But to get the Role Definitions from the Tenant Level and below, you just remove the scope segment:

GET https://management.azure.com/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01

Deleting Recovery Service Vault Backup Server (MABS)

This is one of them quick shares to try help the world of Azure developers just a little bit.

While doing some Azure Development using the Microsoft Azure REST API, I got to a point to working in the Azure Recovery Service Vault. I was trying to delete a Back Up Server Agent using the API, which after a little bit of a hunt I found it is actually called ‘Registered Identities

This of course only has one endpoint to call, so it must just be that easy…
However when calling this API I would just get the following:

{
"error":
{
"code":"ServiceContainerNotEmptyWithBackendMessage",
"message":" There are backup items associated with the server. Stop protection and delete backups for each of the backup items to delete the server's registration. If the issue persists, contact support. Refer to https://aka.ms/DeleteBackupItems for more info. ",
"target":null,
"details":null,
"innerError":null
}
}

This was odd as I couldn’t find anything to imply a reason for this error. After then investigating the network traffic while deleting the resource in the Azure Portal, I found a slight difference which also fixed the issue. This was the version of the API.

In the documentation it is stated as ‘2016-06-01’ , but in the network traffic it had version ‘2019-05-13’. If you now change:

DELETE https://management.azure.com/Subscriptions/77777777-d41f-4550-9f70-7708a3a2283b/resourceGroups/BCDRIbzRG/providers/Microsoft.RecoveryServices/vaults/BCDRIbzVault/registeredIdentities/dpmcontainer01?api-version=2016-06-01

To

DELETE https://management.azure.com/Subscriptions/77777777-d41f-4550-9f70-7708a3a2283b/resourceGroups/BCDRIbzRG/providers/Microsoft.RecoveryServices/vaults/BCDRIbzVault/registeredIdentities/dpmcontainer01?api-version=2019-05-13

<p value="<amp-fit-text layout="fixed-height" min-font-size="6" max-font-size="72" height="80">It will now all work.It will now all work.

How to get Azure Backup Protection Containers?

When working with the Azure REST API, I had the requirement to get the Recovery Service Vaults Backup Protection Containers. Naturally, like many, I went to the Microsoft Azure REST API documentation website to learn how to call this API, but when following it I hit a few issues that was not clear and not part of the documentation. Here below are some of the issues I had, that I hope can solve yours… If your having any.

This is the link to the documentation if you don’t have it already to follow.
https://docs.microsoft.com/en-gb/rest/api/backup/backupprotectioncontainers/list

Get All Doesn’t Work

As you can see from the documentation you should be able to call the GET request for:

GET https://management.azure.com/Subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.RecoveryServices/vaults/{vaultName}/backupProtectionContainers?api-version=2016-12-01

This should be a non-filtered list of all the containers not matter their type. However, when calling this you will get the error saying you are missing required properties. With such a helpful message response, how could you not understand what is going wrong.

What I have found is you need to use the filter request, but it is still not that simple. From the example in the documentation you can use the Backup Management Type. However, if like me you want all the containers no matter the type then this isn’t the most helpful, so looking into the OData filters documentation you can use many other requests.

Instead of doing backupManagementType eq ‘AzureWorkload’ which is Backup Management Type equals Azure Workload, you can use ‘ne’ that is not equal to. With this you can put some random text in the string to say Get All Backup Protection Containers Where Backup Management Type Does Not Equal RandomWords. Makes sense yes? Well not for this API. This still results in the same error. I even tried to change the parameter it is searching on to something all valid containers should have like ‘registrationStatus’, but that didn’t work.

The only method I got this API call to work was to call it with the filter of Backup Management Type.

Trying to reduce code I added the Backup Models from the Nuget Package Microsoft.Azure.Management.RecoveryServices.Backup

Azure C# SDK missing options

As stated above you need to use the filter with Backup Management Type to get the Protected Containers, so to get all of them we need to call each type. As I don’t know all the types,  I found the Enum BackupManagementTypes in the above Nuget package that I can then loop through.

However, I am not sure if it is just out of date or that the Nuget package is in preview, but no all the types are in there. Therefore, I created my own using the values in the API Documentation.

/// <summary>
/// Azure Backup Management Types 
/// https://docs.microsoft.com/en-gb/rest/api/backup/backupprotectioncontainers/list#backupmanagementtype
/// </summary>
        public enum BackupManagmentTypes
        {
            AzureBackupServer,
            AzureIaasVM,
            AzureSql,
            AzureStorage,
            AzureWorkload,
            DPM,
            DefaultBackup,
            Invalid,
            MAB
        }

Then it can be  used like this:

foreach (var backupManagementTypeStr in Enum.GetValues(typeof(BackupManagmentTypes)))
{
	var urlWithFilter = $"{containerUrl}&$filter=backupManagementType eq '{backupManagementTypeStr}'";
}

Azure C# SDK incorrect format

With the Nuget package I thought I could the Desterilise the response into the class ProtectionContainerListResponse as this is what the documentation says the type is, but it failed as the model of this class follows ‘response.ItemList.ProtectionContainers’, whereas the expected response follows ‘response.values’

When looking at the response in the API Documentation I have also seen a pattern to the response types for the Recovery Service API. They all have a list with ‘nextlink’ and ‘values’, which values is a list of the response type. However, the types in the list also follow the same pattern with all the properties the same except what type the property ‘properties’ is. Therefore, you can make a generic response as below:

  /// <summary>
        /// API Response
        /// </summary>
        public class ResourceResponse<T> where T : class
        {
            /// <summary>
            /// The uri to fetch the next page of resources. Call ListNext() fetches next page of resources.
            /// </summary>
            public string nextLink { get; set; }
            /// <summary>
            /// List of resources.
            /// </summary>
            public List<ResourceDetails<T>> value { get; set; }
        }

        /// <summary>
        /// Resource Details
        /// </summary>
        public class ResourceDetails<T> where T : class
        {
            /// <summary>
            /// Optional ETag.
            /// </summary>
            public string eTag { get; set; }
            /// <summary>
            /// Resource Id represents the complete path to the resource.
            /// </summary>
            public string id { get; set; }
            /// <summary>
            /// Resource location.
            /// </summary>
            public string location { get; set; }
            /// <summary>
            /// Resource name associated with the resource.
            /// </summary>
            public string name { get; set; }
            /// <summary>
            /// resource properties
            /// </summary>
            public T properties { get; set; }
            /// <summary>
            /// Resource tags.
            /// </summary>
            public object tags { get; set; }
            /// <summary>
            /// Resource type represents the complete path of the form Namespace/ResourceType/ResourceType/...
            /// </summary>
            public string type { get; set; }
        }

How to build Azure Service Bus Relay Sender and Listener?

This is one of them, I tried to do and found it hard so here is how I did it, post. I was assigned to look into how to build a Sender and Listener using the Azure Service Bus Relay, so we could send data from Azure to On Premise securely. Now there might be debates on is this is secure and compared to other methods, but that is not for what I was asked and what this post is about.

Therefore I will demo how to create the Net TCP Relay in Azure, the code to a listener and the code for the sender in C#.net, but remember this is what worked for me and there are other protocols, technologies and languages this can be done in.

How to build the Service Bus Relay

First you need to get to the Azure Portal using ‘https://portal.azure.com‘. This will take you to the dashboard or to the login page, which will then take you there. You can create a new dashboard to put all your resources in one place, which is advised for organisation.

Click on the ‘New’ button in the side navigation, then search for ‘Relay’. This should then show in the results the Relay service with the blue icon. Click ‘Create’ on this and you will be promoted for the details of the relay.

v1

Add in the Azure name for the relay, this is the base URL for the service. Select your preferred Subscription, Resource group and Location as you see fit. Once the details are in and the fields have a green tick in for being ok, then press the ‘Create’ button. If you want this pinned on your dashboard, then don’t forget to check the ‘Pin to dashboard’ box.

v2

Once this is created then you can go to the Relay and you will see the Overview page of the new Relay as below.

v3

Now the method that I create this was using the ‘WCF Relay’ and it was a ‘NetTcp’ version. To do this click on the ‘WCF Relay’ menu in the side navigation below the ‘Overview’ item. This will load the list view of all the WCF Relays you have, which is none yet. Click on the ‘WCF Relay’ button at the top with the big plus symbol next to it.

Enter the name of the Relay, remember that you can have many of these so it doesn’t have to be to generic. The other details I left as they were and you will notice that ‘NetTcp’ is selected for ‘Relay Type’. Click ‘Create’ and now you have a Relay.

v4

Note that if you can’t see the Relay after pressing the button, then reload the screen and it will load in this time.

v5

Now you can move on to the code.

 

How to build a Relay Sender in C#.Net

A key part to the two code segments working together is that the interface they both use must match or the data will not get received or sent.

We start by creating the 3 variables that are needed for each Relay account. This is the Service Bus Key, the Namespace and the Relay name.

To get the Service Bus Key, go to the Relay account page and under ‘Properties’ on the side navigation there should be ‘Shared access policies’, click on this. You will know if you are on the correct page as there will already be a ‘RootManageShareAccessKey’, which new keys can be made to separate security, but for this POC I just used this one.
If you click on this you will see the keys associated with the policy. You need the ‘Primary key’, which you can copy and put into the variable below:

private string _serviceBusKey = "[RootManageShareAccessKey-PrimaryKey]";

The other two you can get from the WCF Relay Overview page. The Namespace is the name of the Relay Account and the Relay name is what the WCF Relay is called. These can also be taken from the ‘WCF Relay Url’ on the overview page.

http:// [NAMESPACE] .servicebus.windows.net/ [WCF RELAY NAME]

private string _namespace = "[Namespace]";
private string _relayName = "[WcfRelayName]";

Next we create the variable for the connection to the Relay, by creating a new Net TCP binding and the Endpoint. The scheme I used was ‘sb’ but this again can be changed.

var binding = new NetTcpRelayBinding();
var endpoint =
new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", _namespace, _relayName));

Visual Studio should help you import the correct variable, but if not then you need the following
• NetTcpRelayBinding
• Microsoft.Servicebus
• EndpointAddress

Now we connect these to the interface that is the same as the Listener and create the tunnel between them.

// Factory
var factory = new ChannelFactory<IMyService>(binding, endpoint);
factory.Endpoint.Behaviors.Add(
new TransportClientEndpointBehavior
{
TokenProvider =
TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey",
_serviceBusKey)
}
);

IMyService client = factory.CreateChannel();

From now on when you want to call a method to the listener, you use ‘client’ dot, the method or variable, for example.

client.CallMyService();

How to build a Relay Listener in C#.Net

Now to get this side working is very simple as it is all managed from the Web Configuration file (Web.config).

Step 1 is under the ‘Configuration > system.seriveModel > behaviors > endpointBehavoirs’
In this node add a new behavior called ‘ServiceBusBehavior’ and inside this you need a ‘transportClientEndpointBehavior’ with a sub node of a ‘tokenProvider’. In this you will have the ‘sharedAccessSignature’ which is the ‘RootManageSahredAccessKey’ mentioned before.

You can get this from the Service Bus Key, go to the Relay account page and under ‘Properties’ on the side navigation there should be ‘Shared access policies’, click on this. You will know if you are on the correct page as there will already be a ‘RootManageShareAccessKey’, which new keys can be made to separate security, but for this POC I just used this one.
If you click on this you will see the keys associated with the policy. You need the ‘Primary key’, which you can copy and put into the variable below:

<endpointBehaviors>
<behavior name="ServiceBusBehavior">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedAccessSignature keyName="RootManageSharedAccessKey" key="PRIMARY KEY"/>
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>

Step 2 is to create the new binding for the Net TCP connection under ‘Configuration > system.seriveModel > bindings’. Add in this a ‘netTcpRelayBinding’ node, with a ‘binding’ node. The name of this will be called ‘ServiceBinding’, but can be custom if you would like.

<bindings>
<basicHttpBinding>
<binding name="DefaultBinding" />
</basicHttpBinding>
<netTcpRelayBinding>
<binding name="ServiceBusBinding" />
</netTcpRelayBinding>
</bindings>

Step 3 is the connection settings for the Service Bus. Again you will need the ‘RootManageSahredAccessKey’ and also the Relay Namespace or the URL. The below sits under ‘Configuration > appSettings’, replacing the items in [] with the correct values.

<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString"
value="Endpoint=sb://[Namespace].servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[PrimaryKey]"/>
</appSettings>

Step 4 is the last on, ish. This is to bind the service to all the configurations we just made. To complete this step you would have needed to create the WCF service and the above bindings. Under the ‘Configuration > system.seriveModel > services’ add a new service node as below:

<service name="[WCF_Service]">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="DefaultBinding" contract="[WCF_Interface]"/>
<endpoint address="sb://[Namespace].servicebus.windows.net/[WCF_Relay]" binding="netTcpRelayBinding" behaviorConfiguration="ServiceBusBehavior"
contract="[WCF_Interface]" />
</service>

Replace the above variables as below:
• [WCF_Service] = the WCF service class
• [WCF_Interface] = the WCF service Interface
• [Namespace] = the Relay name
• [WCF_Relay] = the WCF Relay name

This one is an optional step, or more of a put it in if you want all the functionality. I would advise unless you know what you are playing with, then don’t touch it. In the ‘Configuration > system.seriveModel > extensions’ node you need to add the below, which are all the service bus extensions.

<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior"
type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="serviceRegistrySettings"
type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="tcpRelayTransport"
type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="httpRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="httpsRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="onewayRelayTransport"
type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="webHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ws2007HttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netOnewayRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netEventRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netMessagingBinding"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>

Side Note

To pass custom classes between the two you need to decorate the class with the data attributes, but also make sure you have a unique namespace on the contract. It doesn’t have to be a valid running namespace, just as long as they match and are unique.

[DataContract(Name= "CarClass",Namespace = "http://MyDomain.com/namespace/CarClass")]
public class CarClass
{
[DataMember]
public string CarName { get; set; }
[DataMember]
public string CarType { get; set; }
[DataMember]
public string CarSize { get; set; }
}

 

Azure Container with PowerShell

When I was trying to use PowerShell to action some Azure functionality, I found it very scattered and hard to get one answer, so here I give you the golden goose for Adding, Removing, Emptying and Copying files to an Azure Container using PowerShell.

The small print of this is of course there are probably more method of doing the same thing, but this is how it worked for me. Also this is not a demo of all the options and parameters the PowerShell commands can do, but what we need them to do. These scripts are set up to run with parameters passed in, but I have also put comments in there so you can run them hardcoded.

How to add a Azure Container?

The parameters required for this script are the Resource Group Name and Storage Account Name for the already built account, plus the new Container’s Name. You can see from below where we pass in the parameters, however in the static version we also need to Login to the required account and pass in the Subscription ID for the account as well.

You can get the Subscription ID by following the steps on this post.

## Get Parameters
Param(
    [string] $ResourceGroupName,
    [string] $StorageAccountName,
    [string] $StorageContainerName
)

## Static Parameters
#Login-AzureRmAccount
#Set-AzureRmContext -SubscriptionID 11111111-1111-1111-1111-111111111111
#$ResourceGroupName = "GroupName"
#$StorageAccountName = "AccountName"
#$StorageContainerName = "ContainerName"

Now we have all the details we can get the storage details from the account from the code below. This gets the storage Key to access the account details, then gets the storage account.

    $Keys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $StorageAccountName;

    $StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $Keys[0].Value;

You need the Storage Context for the future calls to create the container. Before we do create the new container, it is best to check if it already exists. In the circumstance I was in, I only wanted a warning flag so if it was already their then great I don’t need to create it, but just flag that detail to the console.

The first part then is an IF statement that attempts to get the Container, however if it does get anything then it falls into the else and writes a warning to the console. If it doesn’t then we use the parameters passed in to create the new Container, also note the ‘Permission’ argument I have set to ‘Container’, but this can also be set to the other options instead or created as a new parameter passed in.

if (!(Get-AzureStorageContainer -Context $StorageContext | Where-Object { $_.Name -eq $StorageContainerName })){
New-AzureStorageContainer -Context $StorageContext -Name $StorageContainerName -Permission Container;  
}
 else {
Write-Warning "Container $StorageContainerName already exists."
}

This is then all you need for creating a new Azure Container, and for the full example you can go here.

How to copy files to an Azure Container?

Following the life cycle after you create an Azure Container, you will want files into it. So we start as before, with all the parameters that are required. The additional one here is the ‘ArtifactStagingDirectory’, which will be the directory of where the contents is contained.

## Get Parameters
Param(
    [string] $ResourceGroupName,
    [string] $StorageAccountName,
    [string] $StorageContainerName,
    [string] $ArtifactStagingDirectory
)

Again we get the Storage Account context for future commands and then also get the paths for the files from the passed in directory.

$storageAccount = ( Get-AzureRmStorageAccount | Where-Object{$_.StorageAccountName -eq $StorageAccountName} )

$ArtifactFilePaths = Get-ChildItem -Path "$ArtifactStagingDirectory\**" -Recurse -File | ForEach-Object -Process {$_.FullName}

With the files paths we can then loop through each directory location to add to the Container. Within each loop we will set up the source path and pass it in, which you might notice we are using the ‘Force’ argument as we do not want a permission dialog box popping up especially if we are automating.

foreach ($SourcePath in $ArtifactFilePaths) {

$SourcePath
$SourcePath.Substring($ArtifactStagingDirectory.length)
    Set-AzureStorageBlobContent -File $SourcePath -Blob $SourcePath.Substring($ArtifactStagingDirectory.length) `
        -Container $StorageContainerName -Context $StorageAccount.Context -Force

}

This will get all the found files and folders into the Azure Container you have created. If you want to see the full version of how to copy files to an Azure Container go here.

How to empty an Azure Container?

Like in most cases, if in doubt then restart, so this is a script to do just that by emptying the Container of its contents. The set to this has one difference, which is the Containers are a comma separated string of the names instead. This is so you can empty or many Containers at the same time, like if you are cleaning out a whole deployment pipeline.

## Get Parameters
Param(
    [string] $ResourceGroupName,
    [string] $StorageAccountName,
    [string] $StorageContainerNames
)

As usual we get the Azure Storage Accounts context for later commands.

    $Keys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $StorageAccountName;

    $StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $Keys[0].Value;

For this one I am going to break it down by line instead of by statement. To get the full picture click on the link at the bottom to see the full version of this code.

We kick it off by looping each of the Container names:

$StorageContainerNames.Split(",") | ForEach {

We then need to check if the Container exists else we will try to delete content from a none existent Container.

if ((Get-AzureStorageContainer -Context $StorageContext | Where-Object { $_.Name -eq $currentContainer })){

If there is a Container, then we also need to check if there is a Blob to delete the content from.

$blobs = Get-AzureStorageBlob -Container $currentContainer -Context $StorageContext

if ($blobs -ne $null)
{

If all of these do come through then we get the go ahead to delete the contents, however we need to loop through each of the Blobs in the array to clear each Blob item.

foreach ($blob in $blobs) {

                    Write-Output ("Removing Blob: {0}" -f $blob.Name)
                    Remove-AzureStorageBlob -Blob $blob.Name -Container $currentContainer -Context $StorageContext

                }

In the result of this all the contents of the named Containers will be cleared out. As said before these are just snippets, but the full version of Emptying the Azure Container is here.

How to remove an Azure Container?

Just like the previous script, we have the same parameters as the rest and one of them that contains a comma separated string of Container Name. With these parameters we are looking to clear the whole thing out by deleting the Azure Container.

We start with the parameters, get the Storage Account context and loop through the Containers.

## Get Parameters
Param(
    [string] $ResourceGroupName,
    [string] $StorageAccountName,
    [string] $StorageContainerNames
)

$Keys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $StorageAccountName;

$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $Keys[0].Value;

$StorageContainerNames.Split(",") | ForEach {

For each container, you check if the Container exists before deleting it. Next is the final command to delete the Container, which you will also notice we use the ‘Force’ argument to prevent the authorization pop up showing and get the Container deleted.

Remove-AzureStorageContainer -Context $StorageContext -Name $currentContainer -Force;

The full layout of removing an Azure Container can be seen here.