How to find the superuser for a container in adls2 - azure

I have a container created by someone and I'm using it load the data. In the manage access tab I see my user name and also $superuser(Owner) and $superuser(Owning Group) with different level of ACLs set.
How to find who is the superuser for that container? I tried Get Properties API but still seeing the response as $superuser

You could use the Az powershell command to get $superuser(Owner), it returns the Object ID of the Owner, which could be a user, group, service principal in Azure AD.
Connect-AzAccount
$storageAccount = Get-AzStorageAccount -ResourceGroupName <group-name> -AccountName <storage-account-name>
$ctx = $storageAccount.Context
$filesystemName = "<container-name>"
$filesystem = Get-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName
$filesystem.Owner
If you want to get the details of the Object ID, you could use the AzureAD command below.
Connect-AzureAD
Get-AzureADObjectByObjectId -ObjectIds $filesystem.Owner
Update:
Yes, you could use the azure cli command az storage blob directory access show, first you need to add the storage-preview extension.
az extension add -n storage-preview
az login
az storage blob directory access show -d '/' -c '<container-name>' --account-name '<account-name>'
It also returns the Object ID of the $superuser(Owner), but in azure cli, there is no built-in command to get the directory object with Object ID, you can get the details about the object with az ad user show, az ad sp show, az ad group show, you need to know the type of the object previously.
If you don't know the type of the object, you can just use az rest to call Microsoft Graph to get the details.
az rest --method get --uri https://graph.microsoft.com/v1.0/directoryObjects/<Object ID>

Related

Az Powershell Module - says "Cannot find storage account with name xxx" but it exists

I've run into a snag with my powershell script that builds an azure function & all its dependencies.
This is what's happening: (i'm doing it manually here to demo...)
I request the storage account information like this:
PS C:\Users\me\> Get-AzStorageAccount -ResourceGroupName widget-resource-group
StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState EnableHttpsTrafficOnly LargeFileShares
------------------ ----------------- --------------- ------- ---- ---------- ------------ ----------------- ---------------------- ---------------
widgetx4ge6v27rlgdk widget-resource-group eastus Standard_LRS StorageV2 Hot 2022-03-10 2:00:26 PM Succeeded True
It comes back with the correct information. So then I try to get the connection string like this:
PS C:\Users\me> func azure storage fetch-connection-string widgetx4ge6v27rlgdk
Cannot find storage account with name widgetx4ge6v27rlgdk
But it says it can't find the storage account.
The actual code looks like this:
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# Get new connection string for the storage account.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
When the code runs, everything works until the call to "func azure storage fetch-connection-string".
Any tips on what I'm missing?
Edit 1
In case it helps, this logic works just fine when I run it against Tenant 1, Subscription A. But for Tenant 1, Subscription B it bombs.
I've made sure the service account principle it runs under is contributor on both subscriptions.
And for what it's worth, the script is able to create the resource group and many of the resources inside. It's just hat when I try to get the connection string, it bombs. It also bombs further down in the script when it tries to deploy the functions in my function app. The error message though is similar - it complains that it can't find the function app that I just finished creating.
Edit 2
So I figured out the problm but not sure how to fix it in a nice / simple way.
For 90% of the script, including login, i'm using the new Az Powershell modules. However, the "func azure" tool relies on login information provided by the az cli. (that seems to be cached??)
To get you on the same page, here's the relevant part of the code in the script:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AZ_DEPLOYMENT_CLIENT_ID, $Secure2
#Connect
Connect-AzAccount -ServicePrincipal -TenantId $AZ_TENANT_ID -Credential $Credential
#OPTIONAL - List the subscriptions available to the current User
Get-Azcontext -ListAvailable
#Set the subscription context to subscription 2
Set-Azcontext -Subscription $AZ_SUBSCRIPTION_ID -Tenant $AZ_TENANT_ID
#Create a new resource group
New-AzResourceGroup -Name $AZ_RESOURCE_GROUP_NAME -Location $AZ_RESOURCE_LOCATION -Force
New-AzResourceGroupDeployment -ResourceGroupName $AZ_RESOURCE_GROUP_NAME -TemplateFile (Join-Path $PSScriptRoot "./artifacts/widget-resources.json")
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# this is where it is failing because it is using a subscription that is visible to az cli.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
Here's what I did to troubleshoot from a powershell cli:
az account list
That returns this:
{
"cloudName": "AzureCloud",
"homeTenantId": "asdf-asdf-asdf-asdf-12312312313",
"id": "[guid]",
"isDefault": false,
"managedByTenants": [],
"name": "subscription-1",
"state": "Enabled",
"tenantId": "[our-tenant-id]",
"user": {
"name": "[another-guid]",
"type": "servicePrincipal"
}
}
When I ran the above command, it only returned one subscription called "subscription-1" for discussion purposes. It isn't/wasn't the one that the rest of the script was working with. The rest of script was dealing with subscription 2
As I test, I added the following lines of code just before call func azure storage:
az login --service-principal --username $AZ_APPLICATION_CLIENT_ID --password $AZ_SECRET --tenant $AZ_TENANT --allow-no-subscriptions
#set the subscription we want to use
az account set --subscription $subscription2
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
And now it finds the correct subscription and resource group / storage account. And now when I run az account list again, it shows me both subscriptions.
One addition comment / observation. Once the az login / az account set has been run with the desired subscription id, i've noticed that I can remove the az login and account set logic from the script and it just uses the cached values. I'm not saying this is what I want to do ... cuz I think it' best to be explicit. But just an observation which explains what bit me in the first place.
So my question is... is there anyway to avoid having to log in twice - once with az cli and another time with the Az Powerhsell modules?
I'm thinking of just abandoning the Az Powershell module and just rewriting everything in just az cli.
But asking the community to see if there's a better way to do this.
EDIT 3
Based on the docs for the azure core functions tools, technically I should be able to use the powershell modules or the cli:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash#publish
"You must have the Azure CLI or Azure PowerShell installed locally to be able to publish to Azure from Core Tools."
Yes, using a mix of azcli and azure powershell, as they are their seperate entities in their own right, you would need to login to each of them individually.
And yes, you are right its better to ditch of them and choose one or the other ! Just much cleaner that way
The issue was that the azure core functions tool is using the cached az account list to find my resources.
So in other words, unbeknownst to me, the func method was using az cli, whereas the rest of the script is using the new Az Powershell modules.
For now, I've just rewritten everything in az cli syntax, and am happy with that. But per the docs it seems that the azure core functions tools should be able to work with either az cli or az powershell. Will open a separate question that addresses that point. For now, my script is working again.

In Azure, is it possible to control access control (IAM) for a file shares using Powershell?

I have been trying to use Powershell to assign users access control privileges for a file share in Azure. What I have been doing is:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Login to Azure
az login
Get User Information and isolate the User Principle Name
$UPN = (Get-AzADUser -StartsWith $UserName).UserPrincipalName
Get the row that contains Scope
$TempScope = az storage share-rm show -g $ResourceGroup --storage-account $StorageAccount --name $FileShareName | Select-String -Pattern '/subscriptions' -CaseSensitive
Change that row to a string
$TempScope = $TempScope | foreach {$_.ToString()}
Remove the first 8 characters
$scope = $TempScope.Substring(9)
Get Name of Role
$FileShareRole = Get-AzRoleDefinition $RoleName
Assign the role to the target identity with the specified scope
New-AzRoleAssignment -SignInName $UPN -RoleDefinitionName $FileShareRole.Name -Scope $scope
It has not been giving the user access to the file share but instead to microsoft.storage/storageaccounts/fileservices/shares.
Yes, You can add Access Control to the file share. In the above-shared script, you are using the long approach to pull the resource ID of the file share. We have made some changes to the above script.
Here is the Modified script to add Access Control to the file Share:
$UserName="<UserName>"
$ResourceGroup="<RGName>"
$StorageAccount="<strgAccountName>"
$FileShareName="<FileShareName>"
$RoleName="Storage File Data SMB Share Reader"
$UPN = (Get-AzADUser -StartsWith $UserName).UserPrincipalName
$TempScope = az storage share-rm show -g $ResourceGroup --storage-account $StorageAccount --name $FileShareName --query id -o tsv
$FileShareRole = Get-AzRoleDefinition $RoleName
New-AzRoleAssignment -SignInName $UPN -RoleDefinitionName $FileShareRole.Name -Scope $scope
Here are the three Azure built-in roles for granting share-level permissions to users:
Storage File Data SMB Share Reader allows read access in Azure Storage file shares over SMB.
Storage File Data SMB Share Contributor allows read, write, and delete access in Azure Storage file shares over SMB.
Storage File Data SMB Share Elevated Contributor allows read, write, delete and modify NTFS permissions in Azure Storage file shares over SMB.

Fetch Azure API Management subscription key using azure cli

I am trying to get the subscription keys for my products as well as default subscription key using cli. I have gone through the documentation https://learn.microsoft.com/en-us/cli/azure/apim/api?view=azure-cli-latest , but right now I don't see any commands to get me the subscription key.
While I can see there are powershell way of getting it, we run the tasks in ubuntu pipeline, and the commands listed below is not working in the linux agent. It says Set-AzContext is not a known command
$subscriptionId = "id"
$RG = "rg"
$service = "apim-name"
Set-AzContext -Subscription $subscriptionId 
$apimContext = New-AzApiManagementContext -ResourceGroupName $RG -ServiceName $service
Get-AzApiManagementSubscriptionKey -Context $apimContext -SubscriptionId "master"
Update
I am able to fetch the details through powershell task for Azure in the DevOps pipeline. If there is no option in azure cli I will use this as a workaround.
Using az rest it is possible:
APIMID=`az apim show -n apimname -g resourcegroup --query id -o tsv`
az rest --method post --uri ${APIMID}/subscriptions/test-subscription/listSecrets?api-version=2021-08-01 --query primaryKey -o tsv
where test-subscription is the name of the subscription.
Currently it is not possible to fetch subscription key using AZ CLI commands. The PowerShell command used is the correct way to go. Just in case if it helps another way to get the subscription key is by using Management API call

Why no Azure Portal Activity Log events recorded for deleted Containers?

When I create a new Cosmos DB (SQL API) container, I see events "Write SQL Database" and "Write SQL Container" in the Azure Portal - Activity Log. However, I don't see any event logged when I delete the Container. Am I missing something, or perhaps can someone explain why delete events are not deemed relevant for logging?
Updated 0507:
I just got back from the support team, here are details:
If you want to audit various operations of end-users' performing, you need to disable the key-based metadata write access on your account.
Once disable it, Cosmos DB will prevent accessing the account via account keys, and only the user with the proper Role-based access control(RBAC) role and credentials can change to any resource within the account.
This is by-designed behavior, you can refer more detail on this documents:
The code below is used to enable sending delete container logs to Activity logs:
Disable key based metadata write access via CLI :
$subscriptionid = "xxx"
$resourceGroupName = "xxx"
$accountName = "xx"
$databaseName = "xx"
$containerName = "xx"
az account set --subscription $subscriptionid
az cosmosdb update --name $accountName --resource-group $resourceGroupName --disable-key-based-metadata-write-access true
delete SQL container via CLI
az cosmosdb sql container delete --account-name $accountName --resource-group $resourceGroupName --database-name $databaseName --name $containerName
Then in Activity logs:
Important Note: If you use azure cli to disable key based metadata write access, then you cannot use UI(azure portal) to delete a container, you should use azure cli to do it. And if you want to perform it via UI, you need to enable it via azure cli command by setting false to --disable-key-based-metadata-write-access

Get Managed Identity ObjectID of Logic App using Azure CLI/Powershell

I have a logic App with Managed Identity enabled. For automation purposes, I need to use either Azure CLI or Powershell to grab the objectID of the Logic App Managed Identity to grant it access to a keyvault.
I have done the same for Azure Data Factory using a Poweshell command like this:
(Get-AzureRMDataFactoryV2 -ResourceGroupName $ResourceGroup -Name $DataFactoryName).Identity
Tried something similar for logic app but it does not return the identity.
Looks like the Workflow object returned by Get-AzLogicApp doesn't have the identity property defined.
A workaround would be to use the Get-AzResource cmdlet instead.
$ID = (Get-AzResource -Name myLogicApp -ResourceType Microsoft.Logic/workflows).Identity.PrincipalId
Based on the previous answer by Joey Cai, you can do the following in AZ CLI also:
$ID = az resource show --name "myLogicApp" --resource-group "myResourceGroup" --resource-type "Microsoft.Logic/workflows" --query "identity.principalId" | ConvertFrom-Json

Resources