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.
Related
function Set-StorageAccounttoPolicy {
$storageaccounts= Get-AzStorageAccount | where {$_.StorageAccountName.StartsWith('p')}
Get-AzRecoveryServicesVault -Name xyztestvault | Set-AzRecoveryServicesVaultContext
$policy=Get-AzRecoveryServicesBackupProtectionPolicy -Name testpolicy
foreach($storage in $storageaccounts) {
$storagename= $storage.StorageAccountName
$resourcegroup= $storage.ResourceGroupName
if($storage.PrimaryEndpoints.File -ne $null)
{
$fileshares= Get-AzRmStorageShare -ResourceGroupName $resourcegroup -StorageAccountName
$storagename
foreach($file in $fileshares)
{
Enable-AzRecoveryServicesBackupProtection -StorageAccountName $storagename -Name
$file.Name -Policy $policy
}
}
}
}
I keep getting an error "Enable-AzRecoveryServicesBackupProtection : 'containerName' cannot be null.", but this storage account has not been assigned to a recovery vault or policy yet. How can I fix this?
Have you double checked the $storagename variable to just make sure it isn't actually null? Also, double check to see if the current storage account/container is tied to a RSV. Because, if it is, it won't allow you to run the Enable-AzRecoveryServicesBackupProtection cmdlet.
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:
I want to upscale and downscale my Azure Analysis Services with PowerShell (Automation Runbook), but changing the Tier (Sku) doesn't seem to work. However there are no errors. Any suggestions?
# PowerShell code
# Connect to a connection to get TenantId and SubscriptionId
$Connection = Get-AutomationConnection -Name "AzureRunAsConnection"
$TenantId = $Connection.TenantId
$SubscriptionId = $Connection.SubscriptionId
# Get the service principal credentials connected to the automation account.
$null = $SPCredential = Get-AutomationPSCredential -Name "SSISJoost"
# Login to Azure ($null is to prevent output, since Out-Null doesn't work in Azure)
Write-Output "Login to Azure using automation account 'SSISJoost'."
$null = Login-AzureRmAccount -TenantId $TenantId -SubscriptionId $SubscriptionId -Credential $SPCredential
# Select the correct subscription
Write-Output "Selecting subscription '$($SubscriptionId)'."
$null = Select-AzureRmSubscription -SubscriptionID $SubscriptionId
# Get variable values
$ResourceGroupName = Get-AutomationVariable -Name 'ResourceGroupName'
$AnalysisServerName = Get-AutomationVariable -Name 'AnalysisServerName'
# Get old status (for testing/logging purpose only)
$OldAsSetting = Get-AzureRmAnalysisServicesServer -ResourceGroupName $ResourceGroupName -Name $AnalysisServerName
try
{
# changing tier
Write-Output "Upgrade $($AnalysisServerName) to S1. Current tier: $($OldAsSetting.Sku.Name)"
Set-AzureRmAnalysisServicesServer -ResourceGroupName $ResourceGroupName -Name $AnalysisServerName -Sku "S1"
}
catch
{
Write-Error -Message $_.Exception
throw $_.Exception
}
Write-Output "Done"
# Get new status (for testing/logging purpose only)
$NewAsSetting = Get-AzureRmAnalysisServicesServer -ResourceGroupName $ResourceGroupName -Name $AnalysisServerName
Write-Output "New tier: $($NewAsSetting.Sku.Name)"
using Set-AzureRmAnalysisServicesServer
There was a little bug in the PowerShell AzureRM.AnalysisServices module. It has been fixed in 0.4.0 (Thursday, June 08 2017)
Now the code finally works: http://microsoft-bitools.blogspot.com/2017/06/schedule-upscaledownscale-azure.html
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
}
I am building a power shell script to automate the setup of a website environment in Azure. This web uses an account storage. I want to the script not to create the account storage if exists.
I thought that using Get-AzureStorageAccount this way may work but it does not:
Write-Verbose "[Start] creating $Name storage account $Location location"
$storageAcct = Get-AzureStorageAccount –StorageAccountName $Name
if (!$storageAcct)
{
$storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
if ($storageAcct)
{
Write-Verbose "[Finish] creating $Name storage account in $Location location"
}
else
{
throw "Failed to create a Windows Azure storage account. Failure in New-AzureStorage.ps1"
}
}
else
{
Write-Verbose "$Name storage account in $Location location already exists, skipping creation"
}
The issue is I don't know how to handle the return of Get-AzureStorageAccount.
Thank you very much in advance!
I would suggest using the Test-AzureName cmdlet to determine if it exists. So, something like this.
if (!(Test-AzureName -Storage $Name))
{
Write-Host "Creating Storage Account $Name"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}
You can use Test-AzureName for other services too, such as Cloud Services, WebSites, and ServiceBus. It returns True if it exists, False otherwise.
Get-AzureRmStorageAccountNameAvailability -Name "accountname"
Try this:
$Name = "myStorageAccount"
$Location = "myLocation"
Write-Host "[Start] creating $Name storage account $Location location"
try{
Get-AzureStorageAccount –StorageAccountName $Name -ErrorAction Stop | Out-Null
Write-Host "$Name storage account in $Location location already exists, skipping creation"
}
catch{
Write-Host "[Finish] creating $Name storage account in $Location location"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
}
Test-AzureName didn't work with our build agents and we already had a try/catch in code so a second one would require building it out as a function. I opted for that standard get and check if null, use -ErrorAction Ignore to stop it throwing an exception
# Check for storage account and create if not found
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -ErrorAction Ignore
if ($StorageAccount -eq $null)
{
New-AzureRmStorageAccount -Location "West Europe" -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -SkuName Standard_LRS -Kind Storage
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG
}
#Rick Rainey's solution works if you're logged in using Add-AzureAccount. However, Azure and powershell have a conflicting and confusing suite of login accounts (Windows Live versus AD) and login mechanisms (Classic: Add-AzureAccount; Resource manager: Login-AzureRmAccount). Some Azure powershell cmdlets require a specific login; further, some require a specific account type!
To clear through this thicket of complicated, undocumented, and confusing permission issues, we always use an AD account, logging in via Login-AzureRmAccount. We also use Azure resource manager (ARM) resources and cmdlets, following Microsoft's movement to ARM as its recommended and strategic approach. However, #RIck's solution is one which the ARM login doesn't work with. :-( So you need another approach, which is #Darren's (for storage). However, for a generic replacement for Test-AzureName I'd suggest Find-AzureRmResource. In the case of storage
$StorageObject = Find-AzureRmResource -ResourceType "Microsoft.Storage/storageAccounts" | Where-Object {$_.Name -eq $storageName}
if ( !$StorageObject ) {
$storageLocation = (Get-AzureRmResourceGroup -ResourceGroupName $resourceGroup).Location
$storageType = "Standard_LRS"
New-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageName -Location $storageLocation -Type $storageType
}
You should use the latest Powershell module Az.
if ($(Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName) -eq $null)
{
# does not exist
}
With the current Az module for PowerShell Version 7, the Get-AzStorageAccountNameAvailability cmdlet might offer a more efficient solution as it was designed specifically for this task. Here is an example:
# ... declare variables and specify values ...
$checkNameAvail = (Get-AzStorageAccountNameAvailability -Name $storageAccountName) | `
Select-Object NameAvailable
if ($checkNameAvail.NameAvailable)
{
Write-Host 'Account name available! Please wait while your resource is being created'
# Create account. Variables used in this example would have been declared earlier in the script.
$storageAccount = (New-AzStorageAccount -ResourceGroupName $resourceGroupName `
-AccountName $storageAccountName `
-Location $location `
-SkuName $skuType `
-AllowBlobPublicAccess $false -EnableHttpsTrafficOnly $true)
# ...
}
else
{
# This section of the script executes if the name is not available
Write-Host "The name <$storageAccountName> is not available. Suggest a new globally unique name!"
}
The condition above will return False, and execute the else statement because the boolean value returned by the cmdlet is in [0] as shown in the PowerShell command-line test below. The availability information (boolean) can thus be stripped from the object returned by the cmdlet and (as in this example) used as a condition in the rest of the script.
PS C:\> Get-AzStorageAccountNameAvailability -Name testaccount1
NameAvailable Reason Message
------------- ------ -------
False AlreadyExists The storage account named testaccount1 is already taken.
Use the error variable
Get-AzStorageAccount -ResourceGroupName 'RG-QA-TEST' -Name 'staccountfor12334ff' -ErrorVariable ev1 -ErrorAction SilentlyContinue
if ($ev1) {
Write-Host "-------------------------- Creating OEM Storage"
//create storage account
}
I had this challenge when setting up Azure storage accounts for Static website hosting using Powershell in Octopus Deploy.
Here's how I fixed it:
Using the Az module for Azure Powershell I did the following:
# Define Variables
$RESOURCE_GROUP_NAME = my-resource-group
$LOCATION = northeurope
$STORAGE_ACCOUNT_NAME = myapplication
$SKU_NAME = Standard_GRS
$STORAGE_KIND = StorageV2
# Check Storage Account and Create if not Found
$STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -Name $STORAGE_ACCOUNT_NAME -ErrorAction Ignore
if ($STORAGE_ACCOUNT -eq $null) {
Write-Host 'Creating storage account'
New-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -AccountName $STORAGE_ACCOUNT_NAME -Location $LOCATION -SkuName $SKU_NAME -Kind $STORAGE_KIND
Write-Host "$STORAGE_ACCOUNT_NAME storage account successfully created"
}
else {
Write-Host "$STORAGE_ACCOUNT_NAME storage account already exists"
}
Note:
-ErrorAction Ignore - This ignores the exception that would arise if the storage account does not exist
Write-Host " " - Double quotes were used to allow for string interpolation since we are connecting strings and variables.
That's all.
I hope this helps