Create Azure website with Standard pricing tier via Powershell - powershell

I'm trying to fix my continious deployment scenario and for this to work an Azure website has to exist and be able to swap between the Staging and Production. We want this website to work in the Standard pricing tier.
The script I have at the moment creates a new ResourceGroup, Hosting Plan and after these are created, the website itself. The problem I'm facing is the website is always in Free mode. I should be able to fix this by using the Set-AzureResource cmdlet, but this one is throwing an message telling me I should specify the Location. Problem with this is this specific cmdlet doesn't has a Location parameter.
Set-AzureResource : {
"Error": {
"Code": "LocationRequired",
"Message": "The location property is required for this definition.",
"Target": null,
"Details": null
}
}
This is the (simplified) script I'm using to create all of the resources:
#Create the resource group
New-AzureResourceGroup -Location $location -Name $resourceGroupName -Force
#Create the hosting plan
$hostingPlanParameters = #{"name" = $hostingPlanName; "sku" = "Standard"; "computeMode" = "Standard"; "workerSize" = "0"; "numberOfWorkers" = "1"}
New-AzureResource -ApiVersion 2014-04-01 -Name $hostingPlanName -ResourceGroupName $resourceGroupName `
-ResourceType Microsoft.Web/serverFarms -Location $location `
-PropertyObject $hostingPlanParameters -Verbose -Force
#Create the website
$analyticsSite = #{"sku" = "Standard"; "webHostingPlan" = $hostingplan; "computeMode" = "Standard"; }
New-AzureResource -Name $label -ResourceType Microsoft.Web/sites `
-ResourceGroupName $resourceGroupName -Location $location `
-ApiVersion $apiVersion -PropertyObject $analyticsSite -Force
Set-AzureResource -Name $label -ResourceType Microsoft.Web/sites `
-ResourceGroupName $resourceGroupName -ApiVersion $apiVersion `
-PropertyObject $analyticsSite -Force
I've read the website should inherit the sku of the specified hosting plan, so I should not need to update it. This does not appear to work for my above script. The hosting plan is specified, but the settings aren't inheritted.
The created hosting plan properties look like this:
PropertiesText : {
"name": "devHostingPlanWestEU10",
"sku": "Standard",
"workerSize": 0,
"workerSizeId": 0,
"numberOfWorkers": 1,
"currentWorkerSize": 0,
"currentWorkerSizeId": 0,
"currentNumberOfWorkers": 1,
"status": 0,
"webSpace": "ResourceGroupWestEU10-WestEuropewebspace",
"subscription": "ad7add9b-8b7a-45df-8e95-0e7fccbr78a5",
"adminSiteName": null,
"hostingEnvironment": null,
"maximumNumberOfWorkers": 0,
"planName": null,
"perSiteScaling": null,
"hostingEnvironmentId": null
}
This looks kind of ok to me.
Once the website is created, these properties are printed:
PropertiesText : {
"name": "Testert10",
"state": "Running",
"hostNames": [
"testert10.azurewebsites.net"
],
"webSpace": "ResourceGroupWestEU10-WestEuropewebspace",
...
"repositorySiteName": "Testert10",
"owner": null,
"usageState": 0,
"enabled": true,
...
"computeMode": null,
"serverFarm": "Default1",
"serverFarmId": null,
"lastModifiedTimeUtc": "2015-05-21T11:52:30.773",
"storageRecoveryDefaultState": "Running",
"contentAvailabilityState": 0,
"runtimeAvailabilityState": 0,
"siteConfig": null,
"deploymentId": "Testert10",
"trafficManagerHostNames": null,
"sku": "Free",
"premiumAppDeployed": null,
"scmSiteAlsoStopped": false,
"targetSwapSlot": null,
"hostingEnvironment": null,
"microService": "WebSites",
"gatewaySiteName": null,
"kind": null,
"cloningInfo": null,
"hostingEnvironmentId": null
}
As you can see, the computeMode, serverFarm, hostingEnvironment and sku aren't set with the properties I set in the $analyticsSite object.
Therefore I probably need to update the resource, but this throws the error mentioned above.
I've also tried using the New-AzureWebsite, using Troy Hunt's blogpost as an example. However, this post also relies on using the Set-AzureResource, so I'll fall into the same problem. A different problem with this example is you can't control on which resource group and hosting plan the site is created which will cause a bit of trouble when searching for the site.

This is possible so easily in the new RM cmdlets. Make sure that you have the latest version of Azure PowerShell first.
First create an App service plan that defines the Standard Price tier, then create a web app with the app service plan.
function Create-AppServicePlan()
{
#https://msdn.microsoft.com/en-us/library/mt619306.aspx
$resource = Find-AzureRmResource -ResourceNameContains $ServicePlanName -ResourceGroupNameContains $ResourceGroupName -ResourceType "Microsoft.Web/ServerFarms"
if(!$resource)
{
# Specify the Tier type that you would like
$servicePlan = New-AzureRmAppServicePlan -ResourceGroupName $ResourceGroupName -Name $ServicePlanName -Location $WebAppLocation -Tier Standard -NumberofWorkers 1 -WorkerSize "Small"
}
}
Next create the web app with the app service plan as a parameter.
function Create-AzureRmWebApp()
{
#https://msdn.microsoft.com/en-us/library/mt619250.aspx
$resource = Find-AzureRmResource -ResourceNameContains $WebAppName -ResourceGroupNameContains $ResourceGroupName -ResourceType "Microsoft.Web/sites"
if(!$resource)
{
$webApp = New-AzureRmWebApp -ResourceGroupName $ResourceGroupName -Name $WebAppName -Location $WebAppLocation -AppServicePlan $ServicePlanName
}
}
This is the full working script that is verified working.
$ServicePlanName = "PSScriptAppServicePlann"
$WebAppName = "WebAppByPSlooksCool"
$ResourceGroupName = "MyResourceGroup"
$WebAppLocation = "australiaeast"
$ErrorActionPreference = "Stop"
# Step 1: Create the application service plan
Create-AppServicePlan
# Step 2: Create the web app using the service plan name.
Create-AzureRmWebApp
function Create-AzureRmWebApp()
{
#https://msdn.microsoft.com/en-us/library/mt619250.aspx
$resource = Find-AzureRmResource -ResourceNameContains $WebAppName -ResourceGroupNameContains $ResourceGroupName -ResourceType "Microsoft.Web/sites"
if(!$resource)
{
$webApp = New-AzureRmWebApp -ResourceGroupName $ResourceGroupName -Name $WebAppName -Location $WebAppLocation -AppServicePlan $ServicePlanName
}
}
function Create-AppServicePlan()
{
#https://msdn.microsoft.com/en-us/library/mt619306.aspx
$resource = Find-AzureRmResource -ResourceNameContains $ServicePlanName -ResourceGroupNameContains $ResourceGroupName -ResourceType "Microsoft.Web/ServerFarms"
if(!$resource)
{
# Specify the Tier type that you would like
$servicePlan = New-AzureRmAppServicePlan -ResourceGroupName $ResourceGroupName -Name $ServicePlanName -Location $WebAppLocation -Tier Standard -NumberofWorkers 1 -WorkerSize "Small"
}
}

The problem is that you created your site in a default free App Service Plan (aka Server Farm or Web Hosting Plan - they're all the same thing), called "Default1". Yet the App Service Plan you scaled to the Standard size was a different one called "devHostingPlanWestEU10".
To create a site in a pre-existing App Service Plan use the following command:
(split into multiple lines for readability)
New-AzureResource
-Name <YourSiteName>
-Location "West US"
-ResourceGroupName <YourResourceGroupName>
-ApiVersion 2014-11-01
-ResourceType "Microsoft.Web/sites"
-PropertyObject #{ "serverFarm" = "<Your service plan name>" }

With the New Azure Resource Manager Cmdlet. You can create a new App Service Plan and Pass it to the New-AzureRmWebApp Cmdlet.
New-AzureRmAppServicePlan -Name StdPlan -Location <"Location"> -ResourceGroupName <"ResourceGroupName"> -Tier Standard
New-AzureRmWebApp -ResourceGroupName <"ResourceGroupName"> -Name <"WebAppname"> -Location <"Location"> -AppServicePlan StdPlan
Reference Article: https://learn.microsoft.com/en-us/azure/app-service-web/app-service-web-app-azure-resource-manager-powershell

Related

Create Incremental Azure Storage Accounts on every run

Looking for a script to autogenerate a new storage account
with a prefix dev something like dev01.... and when i rerun the template should increment as dev02.. on second run and so on.
I tried giving the parameters / using default templates in github.
Issue is if i pass on a value under the value the system deploys it fine ,if i give the same name it would rerun and update the existing storage.
Instead i would like it to check if storage account exists and if not create a new account , please advise any pointers if any
Sample Parameters.Json file im using :
"parameters": {
"storageAccountName": {
"value": "dev01"
},
I recommand that you could use the Azure powershell script to customize your logic to do that.
The following is the demo code:
$resourceGroup = "rgName"
$storageAccount = "accountName"
$location = "Central US"
$SkuName = "Standard_LRS"
$kind = "StorageV2"
$i = 0;
while(1)
{
$storage = Get-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccount
if($storage -ne $null)
{
$i++
$storageAccount = $storage.StorageAccountName + $i
$storage = New-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccount -SkuName $SkuName -Location $location -Kind $kind
}
else
{
$storage = New-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccount -SkuName $SkuName -Location $location -Kind $kind
$storageAccount = $storageAccount +$i;
}
if ($storage -ne $null)
{
break;
}
}
Task:

Why would Test-AzureName always return false?

Running this script in Azure:
Write-Host "Running ps_example.ps1"
$resourceGroupName = 'myGroupName'
$storageName = "psexample"
$storageType = "Standard_LRS"
$location = "centralus"
if (Test-AzureName -Storage $storageName) {
Write-Host "Use existing storage account - $storageName"
} Else {
Write-Host "Make new storage account - $storageName"
New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageName -Type $storageType -Location $location
}
The first run shows:
Running ps_example.ps1
Make new storage account - psexample
The second run shows:
Running ps_example.ps1
Make new storage account - psexample
The storage account named psexample is already taken.
Why? That would seem to indicate that if (Test-AzureName -Storage $storageName) always returns false.
If I tell Azure to use powershell 1, the version is 1.113.5. Requesting version 2.0 results in 2.0.11. The behavior is the same for both.
EDIT:
Running this:
$result = Test-AzureName -Storage $storageName
Write-Host $result
always prints False, whether psexample exists or not.
You are combining RM and SM cmdlets in Azure. Test-AzureName is a Service Management cmdlet, while New-AzureRmStorageAccount is a Resource Manager cmdlet.
You may want to try to use
if ((Get-AzureRmStorageAccountNameAvailability -Name $storageName).NameAvailable) {
Write-Host "Make new storage account - $storageName"
New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageName -Type $storageType -Location $location
} Else {
Write-Host "Use existing storage account - $storageName"
}
to check for the name or you can create your storage account with:
New-AzureStorageAccount
Depending on what you want to use, SM or RM.

AzureRM Web App - How to control the slot setting with Powershell

I would like to set the connection strings and app settings of my Azure web app using powershell. And I would like those settings to stick with the slot, and not with the app when it is swapped.
The code for app settings looks like this and it works:
$PropertiesObject = #{"SMTPUser"="myuser"; "SMTPPassword"="secretpwd";}
$webAppName = "mywebapp"
$slotName = "demo"
$resourceGroupName = "myResourceGroup"
New-AzureRmResource -PropertyObject $PropertiesObject -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites/slots/config -ResourceName $webAppName/$slotName/appsettings -ApiVersion 2015-08-01 -Force
$stickSlotConfigObject = #{"connectionStringNames"=#(); "appSettingNames" = #("SMTPUserName","SMTPPassword");}
$result = Set-AzureRmResource -PropertyObject $stickSlotConfigObject -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites/config -ResourceName $webAppName/slotConfigNames -ApiVersion 2015-08-01 -Force
This works. When I go to the slot blade of the web app in the Azure portal, the "Slot Setting" check box is checked as I want it to be.
I'm struggling with how to set the connection strings to also have the "slot setting" box checked. I tried the following,
$PropertiesObject = #{
AzureWebJobsStorage = #{
Type = "Custom";
Value = "somestring"
};
Common = #{
Type = "SQLAzure";
Value = "somedatabasestring"
};
};
$webAppName = "mywebapp"
$slotName = "demo"
$resourceGroupName = "myResourceGroup"
New-AzureRmResource -PropertyObject $PropertiesObject -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites/slots/config -ResourceName $webAppName/$slotName/appsettings -ApiVersion 2015-08-01 -Force
$stickSlotConfigObject = #{"appSettingNames"=#();"connectionStringNames"=#("AzureWebJobsStorage","Common"); }
$result = Set-AzureRmResource -PropertyObject $stickSlotConfigObject -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites/config -ResourceName $webAppName/appsettings -ApiVersion 2015-08-01 -Force
This did not work. I got the following error:
New-AzureRmResource : {"Code":"BadRequest","Message":"The parameter properties has an invalid value.","Target":null,"Details":[{"Message":"The parameter properties has an invalid value."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","Message":"The parameter properties has an invalid value.","ExtendedCode":"51008","MessageTemplate":"The parameter {0} has an invalid value.","Parameters":["properties"],"InnerErrors":null}}],"Innererror":null}
I tried another tweak (which I forgot) and it said that the $PropertiesObject object was not in the right format.
How do I code it in Powershell so that I can check the slot setting check box of a web app connection string (or configure it as "sticky"?
Please have a try with the following code to set connection string as sticky setting for slot. It works correctly for me. More info about automating Azure WebApps with PowerShell ARM way please refer to the document.
$connectionString = #{}
$webAppName = "Web AppName"
$resourceGroup ="Resource Group Name"
$slotName ="slot Name"
$connectionString.Add("AzureWebJobsStorage", #{ value = "The Actual connecting string here" ; Type = 3 }) #Custom
$connectionString.Add("Common", #{ value = "The Actual connecting string here" ; Type = 2 }) #Azure SQL
Login-AzureRmAccount
# creat slot connection string
New-AzureRmResource -PropertyObject $connectionString `
-ResourceGroupName $resourceGroup `
-ResourceType "Microsoft.Web/sites/slots/config" `
-ResourceName "$webAppName/$slotName/connectionstrings" `
-ApiVersion 2015-08-01 -Force
# set connection string as sticky setting
$stickSlotConfigObject = #{"connectionStringNames" = #("AzureWebJobsStorage","Common")} #connection string Name
Set-AzureRmResource -PropertyObject $stickSlotConfigObject `
-ResourceGroupName $resourceGroup `
-ResourceType Microsoft.Web/sites/config `
-ResourceName $webAppName/slotConfigNames `
-ApiVersion 2015-08-01 -Force
There are now two new cmdlets to control the slot settings: Get-AzureRmWebAppSlotConfigName and Set-AzureRmWebAppSlotConfigName
For instance, I wanted to make sure that my connection strings weren't a slot config so I executed:
Set-AzureRmWebAppSlotConfigName -ResourceGroupName MyRg -Name MyWebApp -RemoveAllConnectionStringNames
$resourceName = $webappname + “/slotconfigname”
$stickySlot = Get-AzureRmResource -ResourceName $resourceName -ResourceGroupName -ResourceType “Microsoft.Web/Sites/config” -ApiVersion “2015-08-01”
You can then check the existing ones by:
$stickySlot.Properties.AppSettingNames
Here you need to different approaches. If these are empty from the get go, you need to create a new array with settings:
$settings = #(“AppSetting1, “AppSetting2”)
$stickySlot.Properties.AppSettingNames = $settings
If there already are other values, and you want to keep them:
$stickySlot.Properties.AppSettingNames += “AppSetting1”
$stickySlot.Properties.AppSettingNames += “AppSetting2”
Then after that is done:
Set-AzureRmResource -ResourceName $resourceName -ResourceGroupName -ResourceType “Microsoft.Web/Sites/config” -Properties $stickySlot.Properties -ApiVersion “2015-08-01"
Taken from: https://msftplayground.com/2016/02/adding-azure-app-service-application-settings-powershell/

Add a Azure WebApp to an Existing VPN using a Point-to-Site connection (RM Powershell)

I have hunted around for an answer to this, but I am not having much luck. All the articles I can find are either setting up a Point-to-Site or are instructions for classic Azure, not Azure 2.0 (Resource Group)
Currently, we are dialing up a whole new resource group everytime we do a new built. This consists of Web apps and SQL DBs. When we have a new build we start up the new and del the old resource group. Simple. To minimize the start-up time we have a static resource group that isn't deleted that houses the VPN connection to our on Prem resources.
The problem I'm having is when I add the new websites using AzureRM Powershell cmd's to the Point-to-site it says it's successful. The Azure Portal says its good but it does let me communicate. If I remove and add it from one of the 8 WebApps they all start working.
I am out of ideas. Any help would be greatly appreciated.
Azure VPN
Below is the function I have put togeather from what I can find out there.
function AddExistingVnet{
param(
[string] $subscriptionId,
[string] $resourceGroupName,
[string] $webAppName
)
$Vnet = Get-AzureRmVirtualNetwork | Where-Object {$_.ResourceGroupName -like "*Static*"}
IF($Vnet.Name.count -gt 1) {write-host 'Two or networks have been returned. Unable to continue ' return}
$gatewaySubnet = $vnet.Subnets | Where-Object { $_.Name -eq "GatewaySubnet" }
$vnetName = $vnet.Name
$uriParts = $gatewaySubnet.IpConfigurations[0].Id.Split('/')
$gatewayResourceGroup = $uriParts[4]
$gatewayName = $uriParts[8]
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $gatewayName
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -Force
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri
}
New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -WarningAction silentlyContinue -Force
}
So after 2 weeks of going back and forth with Microsoft (had a really good guy Charles) we managed to find the problem.
When requesting
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
It was giving me an output of:
"https://mdsbrketwprodsn1prod.blob.core.windows.net/cmakexe/xxx~xxx/amd64/xxxx~xxxx&sp=r&fileExtension=.exe"
For some reason (that Microsoft could explain) why it kept adding in " to the beginning and end of the variable.
I find it odd that it lets the script work with " and allows the WebApps to join to the VPN.
Any why here is the fix which basicly removes the " from the begining and end of $packageUri :
$packageUri = $packageUri.ToString();
$packageUri = $packageUri.Substring(1, $packageUri.Length-2);
So hope that helps someone else out there who is banging there head agaist the same problem.
Here is the complete function if any one is intrested:
function AddExistingVnet{
param(
[string] $subscriptionId,
[string] $resourceGroupName,
[string] $webAppName
)
$Vnet = Get-AzureRmVirtualNetwork | Where-Object {$_.ResourceGroupName -like "*Static*"}
IF($Vnet.Name.count -gt 1) {write-host 'Two or networks have been returned. Unable to continue ' return}
$gatewaySubnet = $vnet.Subnets | Where-Object { $_.Name -eq "GatewaySubnet" }
$vnetName = $vnet.Name
$uriParts = $gatewaySubnet.IpConfigurations[0].Id.Split('/')
$gatewayResourceGroup = $uriParts[4]
$gatewayName = $uriParts[8]
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $gatewayName
$webApp = Get-AzureRmResource -ResourceName $webAppName -ResourceType "Microsoft.Web/sites" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName
$location = $webApp.Location
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -Force
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
$packageUri = $packageUri.ToString();
$packageUri = $packageUri.Substring(1, $packageUri.Length-2);
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri.ToString()
}
$date = Get-Date -format "HH:mm tt"
New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -WarningAction silentlyContinue -Force
}
Enjoy

Azure Powershell - Check to see if resource exists

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?
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.
}
Try this:
if(!(Get-AzureRmStorageAccountNameAvailability -Name $storageName))
{
New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageName -SkuName Standard_LRS
}
It is my solution with new Azure PowerShell Az module
$StorageAccountName = "Storage account name"
$ResourceGroupName = "Resource group name"
$StorageAccount = Get-AzStorageAccount -Name $StorageAccountName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
if($StorageAccount -eq $null){
$storage = New-AzStorageAccount -ResourceGroupName $ResourceGroupName -StorageAccountName $StorageAccountName -Location "westeurope" -SkuName Standard_LRS -Kind StorageV2
}
else{
Write-Host "$StorageAccountName already exist"
}
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}
}
something like this ?
if(
Get-AzureStorageAccount | Where {$_.Label -match $name} | measure |select -expand count -eq 0) {
$storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}
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
}
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
}