W_W
W_W

Reputation: 537

Azure Powershell to check resource names

Random generated resource names can be rejected by Azure. Is there any Powershell cmdlet to check those names?

I know there is a Test-AzureName. But it only works with a limited type of resources. Not enough for my use case. (Storage, SQL, DNS, Public IP)

And I know there is this REST-API. But when I call it through Invoke-RestMethod, it returns an error: {"error":{"code":"AuthenticationFailed","message":"Authentication failed. The 'Authorization' header is missing."}}

I'm not very good at Powershell, can someone point me out Azure Powershell cmdlet to do such a task or help me to get the REST-API work?

Thanks!

Upvotes: 0

Views: 8825

Answers (3)

Martin Schvartzman
Martin Schvartzman

Reputation: 111

As mentioned above, most of the providers have an API called checkNameAvailability (https://learn.microsoft.com/en-us/search/?search=checkNameAvailability&scope=REST) that you could use to see of a name is already taken or is globally unique. I've wrapped up some of these in a PowerShell function. See https://secureinfra.blog/2019/11/07/test-azure-resource-name-availability/

Upvotes: 0

Eric
Eric

Reputation: 1009

The core of the question is how to construct authentication http header for the Invoke-Rest to fulfill Azure requirement. You can do it as follows

  1. Create application in Azure Default Active Directory
  2. Save the application client id and secret key
  3. Grant the application proper privilege to the resource group
  4. Add "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" in your Powershell context
  5. Call Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext method AcquireTokenAsync for the token
  6. Contruct auth header by the token from step 5
  7. Pass header and rest uri to Invoke-Rest cmdlet

More detail you can reference How to authenticate Azure Rest API with Azure Service Principal by Powershell for complete sample code.

Upvotes: 0

Jack Zeng
Jack Zeng

Reputation: 2267

The Invoke-RestMethod with "Check resource name" REST API is good enough for your case. But, you need to do some preparation.

First, You need to create an Active Directory application.

  1. Login to your Azure Accout in the Classic Portal.
  2. Select Active Directory from the left pane, can click your default Directory.
  3. Click Application, and click Add in the bottom pane.
  4. You should create a WEB APPLICATION AND/OR WEB API. For NAME, SIGN-ON URL, and APP ID URI, enter anything suitable because it doesn't matter in this case. I enter "https://localhost" for SIGN-ON URL and APP ID URI when testing.
  5. Click OK to create.
  6. After the Creation, click CONFIGURE of your application. Scroll down to the Keys section and select how long you would like your password to be valid.
  7. Save and get the key for your client. In this page, you can get your client id and key. Copy and save them somewhere else, because you will need them later.
  8. In the Configure Page, under the permissions to other applications, click Add application.
  9. Select Windows Azure Service Management API, and click OK to Add.
  10. Add the Access Azure Service Management as organization users (preview) delegated permission to the service management API.
  11. Save the change.

For more information about this, see Create Active Directory application and service principal using portal

the following script will give you proper headers for the REST API.

try{
    $subscription = Get-AzureRmSubscription
}
catch{
    Login-AzureRmAccount
    $subscription = Get-AzureRmSubscription
}

$tenantId = $subscription.TenantId

#these are the client id and key you get from the above steps.
$clientId = "<your client id>"
$key = "<your key>"

$authUrl = "https://login.windows.net/${tenantId}"
$AuthContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]$authUrl

$cred = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential $clientId,$key
$result = $AuthContext.AcquireToken("https://management.core.windows.net/",$cred)
$authHeader = @{
'Content-Type'='application/json'
'Authorization'=$result.CreateAuthorizationHeader()
}

$URI = "https://management.azure.com/providers/microsoft.resources/checkresourcename?api-version=2014-01-01"
Invoke-RestMethod -Uri $URI -Method POST -Headers $authHeader -Body "{'Name':'<the name you want to test>','Type':'<the resource type you want to test>'}"

Upvotes: 7

Related Questions