Getting and creating stored access policy on a container results in a 404, resource not found - azure-storage

I have a Gen2 Azure storage account and try to create a stored access policy on a container using Powershell. I am signed into the account and the relevant subscription is selected. I save the context in a variable for further use by the following statements.
Connect-AzAccount
Set-AzContext -Subscription "<subscriptionid>"
$context = New-AzStorageContext -StorageAccountName "MyStorageAccount" -UseConnectedAccount
Creating a stored access policy failed so I added one manually through the portal and tried to get a list of the policies:
Get-AzStorageContainerStoredAccessPolicy -Container "MyContainer" -Context $context
This resulted in an error Get-AzStorageContainerStoredAccessPolicy: The specified resource does not exist., the same error that the "New-AzStorageContainerStoredAccessPolicy" command yielded. Adding the name of the existing policy with the -Policy parameter did not change the outcome, neither did changing the access level on the container.
I think I can also rule out typos as Get-AzStorageContainer "MyContainer" -Context $context gives me the details of the container as expected.
I am unclear as to what resource it is that does not exists, as the container clearly exists and it also contains at least one stored access policy. Can the container stored access policy command not be used on a Gen2 storage account or am I missing something else?

This is because Get/New-AzStorageContainerStoredAccessPolicy isn't supported by Oauth. You can find all operations supported by Oauth https://learn.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftstorage.
As a workaround, you can use connection string to do this:
Connect-AzAccount
Set-AzContext -Subscription "<subscriptionid>"
$context = New-AzStorageContext -ConnectionString "<Connection string>"
Get-AzStorageContainerStoredAccessPolicy -Container "<Container Name>" -Context $context
Same issue in Github: https://github.com/Azure/azure-powershell/issues/10391.

Related

Set-AzStorageContainerAcl error due supposed container not found but it really exists

I'm trying to update ACL through Azure PowerShell but I'm getting this weird error.
The script is pretty simple but don't understand what is wrong.
First I'm getting the Storage Container by name to be sure the
container already exists.
Then just trying to set ACL permission on
it but got an error saying the container doesn't exist.
Am I missing something?
Edit: Just to avoid confusion, I have full control on this storage account resource. I created it and I'm able to configure this setting through Azure portal but no with power shell.
Browse to Storage Account in the Azure Portal
Access Control (IAM)
Grant Access to this resource section (Add Role Assignments)
Role: Storage Blob Data Contributor
Assign Access to: Use the default values (I.e. User , Group , or Service Principal)
Select: User Name
Save
I tried to reproduce the same in my environment to apply ACL permissions:
Here is the script to apply the ACL permission to your container.
You can get the Azure Storage Account Key
Azure Portal > Storage accounts > YourStorageAccount >Access keys
#Install Storage Module
Install-Module Az.Storage
#Connect to Azure AD
Connect-AzureAD
#Set Context to Storage Account
$StorageContext = New-AzureStorageContext -StorageAccountName 'venkatsa' -StorageAccountKey 'StorageAccount-key'
$Container = Get-AzureStorageContainer -Name 'thejademo' -Context $StorageContext
#Get Container ACL Permissions
Get-AzStorageContainerAcl -Container "thejademo" -Context $StorageContext
#Set ACL permission to Container.
Set-AzStorageContainerAcl -Container "thejademo" -Permission Off -PassThru -Context $StorageContext
Applied ACL permission to my container

How can you create a new storage container on a storage account using CloudShell?

I've googled this for hours and found little code snippets in bash and powershell but the ones that don't error completely end up giving me a 403. Here's my script this far.
$resourceGroupName = "MyResourceGroup"
$storageAccountName = "MyStorageAcc"
$containerName = "mynewcontainer"
$storageAccKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -AccountName $storageAccountName)[0].value
$storagecontext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccKey
New-AzureStorageContainer -Name $containerName -Permission Container -Context $storagecontext
I originally didn't get the storage account key, but after that gave me a 403 I started looking into potential reasons for the error and many suggested getting the storage account key. However this still doesn't work. What am I missing?
Update
I found this: https://github.com/Azure/azure-cli/issues/9396, which suggests it's an issue with the ip address you're connecting from. However, I've added my ip address and still get the same issue.
Update 2
I couldn't find a sufficient way to do this through a script so decided to do it as part of the initial creation using the ARM template.
Make sure your user account login the Azure powershell(if using cloud shell, the account is which you login the portal) has the correct RBAC role e.g. Storage Account Contributor at your storage account/group/subscription, if not, follow this to add it.
Besides, you mixed the old AzureRM command New-AzureStorageContainer with the new Az command Get-AzStorageAccountKey, New-AzStorageContext, it may cause you to use a wrong context, change the last line as below.
New-AzStorageContainer -Name $containerName -Permission Container -Context $storagecontext

Get-AzRoleAssignment command returning users and service principles who are removed from RBAC Permissions

I am using Get-AzRoleAssignment to get RBAC details for Data Lake Storage Gen1 resource.
Command :
Get-AzRoleAssignment -ResourceGroupName "test" -ResourceName "testResource" -ResourceType "Microsoft.DataLakeAnalytics/accounts"
Above command gives us list of resources who have access to resource mentioned. Since first use of this command we have removed access for many resources but command still return names for those. I logged out and logged in multiple times to check if its caching issue but no use.

Enable diagnostics for Azure Storage Account using PowerShell commands

How to enable Diagnostics for existing Azure Storage Account using PowerShell?
Thank you
You can use PowerShell to configure Storage Metrics in your storage account by using the cmdlet Set-AzureStorageServiceMetricsProperty to change the current settings.
Example 1:
$context = New-AzureStorageContext -StorageAccountName <your storageacount name>
Set-AzureStorageServiceMetricsProperty -MetricsType Minute -ServiceType Blob -MetricsLevel ServiceAndApi -RetentionDays 5 -Context $context
I enabled the diagnostics like this:enable Blob metrics
If you want to enable the below Blob,Table,Queue logs, you can use the cmdlet Set-AzureStorageServiceLoggingProperty to change the current settings.
Example 2:
$context = New-AzureStorageContext -StorageAccountName <your storageacount name>
Set-AzureStorageServiceLoggingProperty -ServiceType Queue -Context $context -LoggingOperations read,write,delete -RetentionDays 5
I enabled the Queue logs like this:
enable Queue logs
Update: If you just want to enable storage of diagnostic logs in a storage account,use this command:
Set-AzureRmDiagnosticSetting -ResourceId [your resource id] -StorageAccountId [your storage account id] -Enabled $true
See more details about Set-AzureRmDiagnosticSetting ,refer to this:
learn.microsoft.com/en-us/powershell/module/azurerm.insights/set-azurermdiagnosticsetting?view=azurermps-4.3.1

Create AD application with VSTS task

I am trying to create a VSTS task, which should create an AD application.
Taken the DeployAzureResouceGroup as a sample, I have created to following script:
[CmdletBinding()]
param()
Trace-VstsEnteringInvocation $MyInvocation
Import-VstsLocStrings "$PSScriptRoot\Task.json"
$connectedServiceNameSelector = Get-VstsInput -Name "connectedServiceNameSelector" -Require
$connectedServiceName = Get-VstsInput -Name "connectedServiceName"
$connectedServiceNameClassic = Get-VstsInput -Name "connectedServiceNameClassic"
$domains = (Get-VstsInput -Name "domains").Split(";")
$appName = Get-VstsInput -Name "appName"
if($connectedServiceNameSelector -eq "ConnectedServiceNameClassic")
{
$connectedServiceName = $connectedServiceNameClassic
$action = $actionClassic
$resourceGroupName = $cloudService
}
Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_
Initialize-Azure
# Import the loc strings.
Import-VstsLocStrings -LiteralPath $PSScriptRoot/Task.json
# Import all the dlls and modules which have cmdlets we need
Import-Module "$PSScriptRoot\DeploymentUtilities\Microsoft.TeamFoundation.DistributedTask.Task.Deployment.Internal.psm1"
Import-Module "$PSScriptRoot\DeploymentUtilities\Microsoft.TeamFoundation.DistributedTask.Task.Deployment.dll"
# Load all dependent files for execution
. "$PSScriptRoot\Utility.ps1"
try
{
Validate-AzurePowerShellVersion
$azureUtility = Get-AzureUtility "$connectedServiceName"
Write-Verbose "Loading $azureUtility"
. "$PSScriptRoot\$azureUtility"
Write-Output "test"
Write-Output "Creating a new Application in AAD (App URI -)" -Verbose
$azureAdApplication = New-AzureRmADApplication -DisplayName "test" -IdentifierUris "https://app.com" -HomePage "https://app.com"
$appId = $azureAdApplication.ApplicationId
Write-Output "Azure AAD Application creation completed successfully (Application Id: $appId)" -Verbose
Write-Verbose "Completing Azure Resource Group Deployment Task" -Verbose
}
catch
{
Write-TaskSpecificTelemetry "UNKNOWNDEP_Error"
throw
}
When I use a Service principal as Service Endpoint user, I got the error Resource me not found.
When I use my custom AD account, I got the error:Run Login-AzureRmAccount to login.
What am I doing wrong? How can I get this script working?
If you don't need Powershell scripting, go install Azure AD Application Management extension from https://marketplace.visualstudio.com/items?itemName=RalphJansen.Azure-AD-Application-Management
You can add new tasks from pipeline GUI for managing AD applications.
If you do need Powershell scripting, then things get tricky.
Get Powershell code from https://stackoverflow.com/a/51848069/1548275 as a base. The difference is, that if you're not running your code from an extension, you don't have Get-VstsInput nor Get-VstsEndpoint available to execute.
Also, you don't have AzureAD module cmdlets to run. You need to get the Nuget-package, unzip it to your own repo and have it as part of your scripts to be later Import-Module in a pipeline task.
Finally, you need an auth token for Graph API. As the extension code shows, you will need 3 variables:
$tenantId = (Get-AzureRmSubscription).TenantId
$clientId = (Get-AzureRmADServicePrincipal -DisplayName "Your Project Service Connection name from Azure AD App Registrations").ApplicationId.Guid
$clientSecret = 'hard-coded, reset SPN password'
As you can see, an extension would have access to all three, but regular script (to my knowledge) doesn't.
SPN password reset is covered in The Net. Briefly, it is something like this:
$clientId = (Get-AzureRmADServicePrincipal -DisplayName "Your Project Service Connection name from Azure AD App Registrations").Id.Guid
$password = ConvertTo-SecureString –asplaintext –force "oh, this is very secret!"
New-AzureRmADSpCredential -ObjectId $clientId -Password $password
Also: Update the plaintext password into Azure DevOps project settings, Service Connections for Pipeline to know about the update.