Azure Powershell - Check to see if resource exists

2019-06-22 12:54发布

问题:

I'm using Powershell to automate setting up my Azure environment - to create storage account, database, website, etc.

In development, I want to provision and a tear down a lot. Very often, I want to run my provisioning script and create a azure asset if it doesn't already exist

However, I haven't found an elegant way of doing this. Some of the "Get" cmdlets throw exceptions if the item doesn't exist, and catching it is a bit of a hack:

try {
    $storageAcct = Get-AzureStorageAccount -StorageAccountName $Name
    Write-Verbose "Storage Account already exists"
} catch {
    $storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}

What's more, with some commands, I can't catch the exception at all and I don't know why:

try {
        $cache = Get-AzureRedisCache -ResourceGroupName $resourceGroupName -Name $cacheName
} catch {
       //Even with an exception, never arrives here.
}

Is there a better way to do this?

回答1:

You should use Test-AzureName for this instead of Get-AzureStorageAccount.

if (!Test-AzureName -Storage $Name)
{
   # create the storage account.
}

This will work for Cloud Services, Web Apps, and Service Bus namespaces too. For your database, you will have to resort back to your existing approach.

**

Added the following to address questions about v2 (ARM) resources:

**

For v2 resources (ARM), the story is mostly the same. For example, the DNS name for a v1 or v2 storage account will be the same, such as contoso.blob.core.windows.net. The same holds for Azure Web Apps (formerly Azure Web Sites), where you would have a DNS name such as contoso.azurewebsites.net. So, in other words, Test-AzureName would work just as well for these resources in ARM.

One notable difference is the DNS name for virtual machines. In v1, virtual machines are contained in a cloud service and get a DNS name such as contoso.cloudapp.net. For v2 virtual machines, the public DNS name is provided by the Public IP Address resource, for which the DNS name for a virtual machine in East US (for example) would be contoso.eastus.cloudapp.azure.com. To test for the availability of this DNS name, you should use the Test-AzureRmDnsAvailability cmdlet. For example,

if (Test-AzureRmDnsAvailability -DomainNameLabel "contos0" -Location "East US")
{
  # Assign DNS name to Public IP Address resource here.
}


回答2:

Try this:

if(!(Get-AzureRmStorageAccountNameAvailability -Name $storageName))
{
    New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageName -SkuName Standard_LRS
}


回答3:

I usually go for the following (works for pretty much any resource in Azure, just replace the "Get" module and parameters):

function Test-AzureStorageAccountExists {
     Param(
        [string]$resourceGroupName,
        [string]$storageAccountName
     )

     $SA = Get-AzureRmStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroupName -ErrorVariable notPresent -ErrorAction SilentlyContinue
     if ($notPresent) {return $false}
}


回答4:

something like this ?

if(
 Get-AzureStorageAccount | Where {$_.Label -match $name} | measure |select -expand count -eq 0) {

    $storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}


回答5:

I needed to check for the existing of a variable in the Azure Automation account using Get-AzureRmAutomaitonVariable before deciding if it needed to be created. user888734's solution of using a "catch" helped me get past this issue which I was blocked on for 2 days :-)

try {
    $existingVariable = Get-AzureRMAutomationVariable -ResourceGroupName $resourceGroup -AutomationAccountName $automationAccountName -Name $variable
} catch {
    New-AzureRmAutomationVariable -ResourceGroupName $resourceGroup -AutomationAccountName $automationAccountName -Name $variable -Value $value -Encrypted $False
}


回答6:

Maybe you can use the cmdlet Get-AzureRmResource. If the resource exists, it returns the information about the specified resource including the resource type; If not, it return $null. e.g.:

$MyRes=Get-AzureRmResource -ResourceName "MyResourceName" -ResourceGroupName 
"MyResourceGroupName"
if ($null == $MyRes) {
  # Not existing
}