Authenticate with Azure AD account while using Read-SqlTableData to read AzSQL tables - powershell

What other properties does one need to add to the ConnectionContext while connecting to AzSQL using an AzAD account?
$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') "<>.database.windows.net"
$srv.ConnectionContext.LoginSecure = $false
$srv.ConnectionContext.Authentication = [Microsoft.SqlServer.Management.Common.SqlConnectionInfo+AuthenticationMethod]::ActiveDirectoryPassword
$srv.ConnectionContext.Login = "<>#<>.onmicrosoft.com"
$srv.ConnectionContext.Password = "<>"
$srv.ConnectionContext.Connect()
Error :
MethodInvocationException: Exception calling "Connect" with "0" argument(s): "Failed to connect to server <>.database.windows.net."
The ActiveDirectoryPassword method works fine from SSMS. I'm trying to run Read-SqlTableData instead of invoking a TSQL query.
Read-SqlTableData -InputObject $srv.Databases["TestDB"].Tables["TestTable"] -TopN 5
Expecting screenshot or screenclip GIF that the answer code is working for an AzAD userid on AzSQL using Read-SqlTableData.

As discussed in person, this is just because the Read-SqlTableData has not been updated (yet) to support an -AccessToken parameter.
I've already had a few requests for other cmdlets as well... so I'll try to get it as soon as I can.

Please make sure to login as administrator .The user must have azure ad admin role for server to connect.
And make sure the user has diretory readers role from azure portal IAM access control.
Also Ensure that you've assigned an AAD admin for the SQL Server.
Try to create a service principal in azure ad if not already present and then give db_reader or db_writer or db_owner permissions granted .
CREATE USER [user or msi] FROM EXTERNAL PROVIDER;
ALTER ROLE [db_datareader] ADD MEMBER <Azure_AD_principal_name> --Grant the user db_datareader permissions on that database
GO
or write permission if required
ALTER ROLE [db_datawriter] ADD MEMBER <Azure_AD_principal_name>;
Or owner permission if required
ALTER ROLE [db_owner] ADD MEMBER <Azure_AD_principal_name>
Or Create Azure AD users in azure sql DB using service principals - Azure SQL Database | Microsoft Docs
Please check below references:
Adding a new user with specific permissions to an Azure Sql Database
using Active Directory Integrated Authentication - Stack Overflow
Connect an Azure App Registration to Azure SQL Database via
Powershell - Stack Overflow

Related

Unable to automate AD user creation in Azure SQL database

I'm trying to set up automated pipeline for database creation and need to open access for all users of some AD group. Last part is done through CREATE USER [Group Name] FROM EXTERNAL PROVIDER;
In order to execute this command, one needs to be logged in with AAD and the only Azure DevOps task used to execute SQL scripts (SqlAzureDacpacDeployment#1) has limited options to sign with AD. Currently it supports sign in with AD username/password and AD Integrated. User/password option is not possible as we use two factor authentication. And the latter requires self-hosted agent for pipeline which we do not have.
Additionally, there is one more sign in option that look promising (Service Principal: Uses the Authentication data from Azure Subscription), but after trying it failed miserably with error:
##[error]Principal 'web-API' could not be created. Only connections established with Active Directory accounts can create other Active Directory users.
Are the any other options we could use to create AD users in Azure SQL database? Any help would be appreciated.
How to solve above error ?
Please follow below steps:
Step 1: Go to Azure portal and find out your SQL server resource and you will find Active director left side under settings. Please click Set Admin. Now your Active Directory user account becomes Admin to the SQL server.
Step 2: Now use SSMS login with Active directory authentication if Multi-factor Authentication (MFA) is enabled. Otherwise, you can choose either 'Active directory - Integrated' or 'Active Directory - Password.'
Step 3: Create new logins which you can see in the below code:
CREATE USER [User1#Domain.com]
FROM EXTERNAL PROVIDER
WITH DEFAULT_SCHEMA = dbo;
add user to roles for the particular database
ALTER ROLE dbmanager ADD MEMBER [User1#Domain.com];
ALTER ROLE loginmanager ADD MEMBER [User1#Domain.com];
Note : If you add a domain user that is configured for MFA, then for that user to log on using SSMS they should select the SSMS authentication option Azure Active Directory - Universal with MFA.
Regarding SqlAzureDacpacDeployment#1 follow this Link.
For more detail information refer this:
https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-overview?view=azuresq
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-user-transact-sql?view=sql-server-ver15
https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-mfa-ssms-overview?view=azuresql

Create Service Principle Connection from Crystal Reports to Azure Synapse Analytics

I have data held in an Azure Data Lake Gen 2 storage container. I would like to provision this data for an existing report authored in Crystal Reports using SQL on demand.
During development I used my own Azure AD login via an ODBC connection on my local machine. I have access to the Synapse environment and also the data lake. This worked successfully and although slow, pulled all information required.
To deploy this solution correctly I need to remove my AAD creds and use a provisioned service principle. I have given the service principle to read from the data lake and also added the principle to the SQL database. Now I am stuck on how to use the principle to connect to Crystal Reports.
I have tried the same authentication type as with my AAD but now I am using a clientID not a email. So when the system prompts for connection details it wants you to sign in and does not accept the clientID.
Does anyone have any suggestions on how to connect to Crystal Reports using this way or any other way?
Also: My org does not want this user or app reg to have restricted permissions so therefore adding them to the RBAC "synapse admin" wont work.
Thanks
Tom
Found a way around this.
Create a service account user on Azure Portal. Head to Synapse Analytics and open blank SQL script to give the user minimal permissions.
*USE [master]*
CREATE LOGIN [serviceaccountsynapseuser#company.onmicrosoft.com] FROM EXTERNAL PROVIDER
GRANT CONNECT ANY DATABASE TO [serviceaccountsynapseuser#company.onmicrosoft.com]
GRANT SELECT ALL USER SECURABLES TO [serviceaccountsynapseuser#company.onmicrosoft.com]
*USE [Reporting] (Serverless SQL DB)*
CREATE USER [serviceaccountsynapseuser#company.onmicrosoft.com] FROM EXTERNAL PROVIDER
ALTER ROLE db_datareader ADD MEMBER [serviceaccountsynapseuser#company.onmicrosoft.com]
Finally head to the storage account and give the user storage blob reader role.

Unable to execute Get-AzADUser as Managed Identity in Powershell

I am unable to execute this line as a System Managed Identity on an Azure VM Powershell -
Connect-AzAccount -Identity #--To connect using managed identity of the VM
$user = Get-AzADUser -ObjectId '****'
$user comes out to be null if I am using Managed Identity whereas I am getting valid $user if I use my microsoft account to connect.
How do I identify whether an object ID is an AAD User using Managed Identity running powershell on a VM?
The use case is I need to automatically remove users having access to AKV in production. For that I need to know if an object id belongs to a user and proceed with deleting role as needed.
If you execute Get-AzADUser directly, you will get this error Insufficient privileges to complete the operation.
This is because you didn't assign an AAD role (for example User Administrator) to the managed identity of the VM. So it has no access to the AAD user.
You can assign the AAD role like this:
Azure Portal -> Azure Active Directory -> Roles and administrators -> enter "user admin" -> click on "User administrator".
Click on "Add assignments" -> Select member(s) -> enter the name of your VM or object id of the managed identity.
Then the managed identity of the VM can get the users through Get-AzADUser.
I raised a request to AAD Admin of my tenant to provide Directory.Read.All permissions to the Managed Identity App ID in Azure AD Graph (not Microsoft Graph).
Once the Managed Identity got the Admin Consent for this permission, I was able to get the users using Get-AzADUser.

Cannot connect to Azure SQL using PowerShell in an MSI enabled function app

Recently created a function app running. The function app hosts a C# and PowerShell function which works as expected with MSI enabled
PowerShell code below, full code in Github
Write-Output "PowerShell Timer trigger function executed at:$(get-date)";
# Get MSI AUTH
$endpoint = $env:MSI_ENDPOINT
$secret = $env:MSI_SECRET
$sqlTokenURI = "https://database.windows.net&api-version=2017-09-01"
$header = #{'Secret' = $secret}
$authenticationResult = Invoke-RestMethod -Method Get -Headers $header -Uri ($endpoint +'?resource=' +$sqlTokenURI)
# CONNECT TO SQL
$SqlServer = $env:SQL_SERVER_NAME
$SqlServerPort = 1433
$Database = "azuredwmonitordb"
$Conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=tcp:$($SqlServer),1433; Initial Catalog=$($Database);")
$Conn.AccessToken = $authenticationResult.access_token
# Open the SQL connection
$Conn.Open()
$Cmd=new-object system.Data.SqlClient.SqlCommand("SELECT ##SERVERNAME", $Conn)
$Cmd.CommandTimeout=120
# Execute the SQL command
$Ds=New-Object system.Data.DataSet
$Da=New-Object system.Data.SqlClient.SqlDataAdapter($Cmd)
[void]$Da.fill($Ds)
# Output the count
$Ds.Tables.Column1
# Close the SQL connection
$Conn.Close()
Both functions implement the same logic:
Retrieve Auth token from the provider
Connect to the Azure SQL server using the token
However when using the PowerShell function, the first step step one works but on attempt to establish a connection in the second step, I'm getting the following error:
Exception while executing function: Functions.dm_pdw_exec_sessions. Microsoft.Azure.WebJobs.Script: PowerShell script error. System.Management.Automation: Exception calling "Open" with "0" argument(s): "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.". .Net SqlClient Data Provider: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON
I have seen this in the past where AAD auth is not enabled properly for the Azure SQL server (user not in master) but this is not the case here.
The problem is in the resource URI - it is missing a forward slash. Instead of:
https://database.windows.net
It should be
https://database.windows.net/
So change your $sqlTokenURI to this and it should work:
$sqlTokenURI = "https://database.windows.net/&api-version=2017-09-01"
This authentication scenario is currently not supported.
FAQs and known issues with Managed Service Identity (MSI) for Azure Active Directory
Does MSI work with the Active Directory Authentication Library (ADAL) or the Microsoft Authentication Library (MSAL)?
No, MSI is not yet integrated with ADAL or MSAL. For details on acquiring an MSI token using the MSI REST endpoint, see How to use an Azure VM Managed Service Identity (MSI) for token acquisition.
Web Apps User Voice feedback
If we want to use AAD token to access Azure SQL, we need to Provision an Azure Active Directory administrator for your Azure SQL Database server. And create a contained database user representing an application that connects using an Azure AD token.
CREATE USER [appName] FROM EXTERNAL PROVIDER;
My Azure account is not global admin, I find that I can't create the user. If you are the global admin azure account ,you could have a try. I am going to get some help from microsoft azure team, if any response, I will update here.
You also could give your feedback to Azure team.
Following is my test steps.
1.After enable the Azure Function, we could find it create the AD Application but it isnot under my registried App, more detail please refer to the screenshot.
2.Provision an Azure Active Directory administrator for your Azure SQL Database server
3.Connect to Azure Sql and create a contained database user representing an application
Creating [tomtestmsi]...
(62,1): SQL72014: .Net SqlClient Data Provider: Msg 33130, Level 16, State 1, Line 1 Principal 'xxxx' could not be found or this principal type is not supported.
(62,0): SQL72045: Script execution error. The executed script:
CREATE USER [xxxx] FOR EXTERNAL PROVIDER;
An error occurred while the batch was being executed.

How can I grant my application full access to the AAD Graph API for my tenant? [duplicate]

This question already has an answer here:
Insufficent privileges when accessing azure graph api users list
(1 answer)
Closed 5 years ago.
I have registered an AAD Application in my Tenant/Directory, and I want to call the Graph API in the App Only Context. (Using the Client Credential Flow)
When making certain AAD Graph API calls, I get the error:
"odata.error":{
"code":"Authorization_RequestDenied",
"message":{
"lang":"en","value":"Insufficient privileges to complete the operation."
}
}
I want to give this application full access to the Graph API in the context of my tenant.
Or
I want to grant this application permissions to my tenant which are not currently supported with the permissions exposed by the AAD Graph API.
You can elevate the level of access an Application has in your tenant by adding the service principal of that application to the Company Administrator Directory Role. This will give the Application the same level of permissions as the Company Administrator, who can do anything. You can follow these same instructions for any type of Directory Role depending on the level of access you want to give to this application.
Note that this will only affect the access your app has in your tenant.
Also you must already be a Company Administrator of the tenant to follow these instructions.
In order to make the change, you will need to install the Azure Active Directory PowerShell Module.
Once you have the module installed, authenticate to your tenant with your Administrator Account:
Connect-MSOLService
Then we need to get the Object ID of both the Service Principal we want to elevate, and the Company Administrator Role for your tenant.
Search for Service Principal by App ID GUID:
$sp = Get-MsolServicePrincipal -AppPrincipalId <App ID GUID>
Search for Directory Role by Name
$role = Get-MsolRole -RoleName "Company Administrator"
Now we can use the Add-MsolRoleMember command to add this role to the service principal.
Add-MsolRoleMember -RoleObjectId $role.ObjectId -RoleMemberType ServicePrincipal -RoleMemberObjectId $sp.ObjectId
To check everything is working, lets get back all the members of the Company Administrator role:
Get-MsolRoleMember -RoleObjectId $role.ObjectId
You should see your application in that list, where RoleMemberType is ServicePrincipal and DisplayName is the name of your application.
Now your application should be able to perform any Graph API calls that the Company Administrator could do, all without a user signed-in, using the Client Credential Flow.
Let me know if this helps!