azure powershell generating Account key error - powershell

I want to create a container through Windows PowerShell and therefore try to obtain the account key via
$storageAccountKey = Get-AzureRmStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName | %{ $_.Key1 }
Getting the error
New-AzureStorageContext : Cannot validate argument on parameter 'StorageAccountKey'. The argument is null or empty. Provide an argument that is not null or empty, and then try the
command again.

This should work
$storageAccountKey = Get-AzureRmStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName | ? { $_.KeyName -eq 'Key1' } | % { $_.Value }
The problem is that the result is not a hashtable but a .NET generic list so it is not possible to access the value directly via the key name.

Related

I am trying to write a script that will backup Azure Files for each storage account that starts with a certain letter

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.

Azure storage table entries deletion

I have some existing data in Azure table storage.So when I deploy csv file ,the latest changes are deploying but the data which is existed in the azure table storage is not overwriting or old data is not deleting.for ex:I have 3 rows of data in azure storage existing,when I deploy csv file which is having 5 rows,the5 rows data is deploying and old data of 3 rows is not deleting.It should be overwrite but its not happening.Please help me. – Subscription Details:
$subscriptionName = "Tech Enabled Solutions"
$resourceGroupName = "abc"
$storageAccountName = "defghi"
$location = "North Central US"
$tableName = "TestTable"
# Get the storage key for the storage account
$storageAccountKey = "12345678990"
# Get a storage context
$ctx = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey
$table = Get-AzureStorageTable -Name $tableName -Context $ctx -ErrorAction Ignore
#If the table exists, start deleting its entities.
if ($table -ne $null)
{
$table=Get-AzureStorageTableRowAll -table $table | Remove-AzureStorageTableRow -table $table -Context $ctx
}
The Get-AzureStorageTableRowAll command is in AzureRmStorageTable Module, so install it before call command.
Add this command to your script to install that module:
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser
Install-Module -Name AzureRmStorageTable -Force -Verbose -Scope CurrentUser

SAS token error in Azure

I am generating SAS token from PowerShell but when I am trying to access that token from Azure Storage explorer, it is giving problem "Authentication Error. Signature fields not well formed."
here is the full Powershell command :-
Parameter required
$StorageAccountName = 'XXXXXX'
$ResourceGroup = 'remoteaccess'
$ContainerName = "vhds"
Powershell Cmd
$AzStrAct = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $ResourceGroup
$AzStrKey = Get-AzureRmStorageAccountKey -Name $StorageAccountName -ResourceGroupName $ResourceGroup
$AzStrCtx = New-AzureStorageContext $StorageAccountName -StorageAccountKey $AzStrKey[0].Value
Get-AzureStorageContainer -Name $ContainerName -Context $AzStrCtx
$ContainerSASTokenURI = New-AzureStorageContainerSASToken -Name $ContainerName -Permission "rwdl" -StartTime "2017-04-12" -ExpiryTime "2017-04-16" -Context $AzStrCtx -FullUri
Write-Host "The SAS Token of container as below:"
$ContainerSASTokenURI
output
https://XXXXXXX.blob.core.windows.net/vhds?sv=2015-04-05&sr=c&sig=XXXXXXXXXXXXXXXXXXXXXXXX&st=2017-04-1
1T18%3A30%3A00Z&se=2017-04-15T18%3A30%3A00Z&sp=rwdl
I test with your script, and it works for me, my Azure storage explorer version is 0.8.12, I suggest you upgrade Azure storage explorer's version to 0.8.12.

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
}

Azure: How to check storage account exists in Azure with Get-AzureStorageAccount

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