Connect-AzAccount - how to avoid azure device authentication? - azure

I have installed the PowerShell 6.1.3 version and
I want to get a connection to the Azure account using the following Azure PowerShell command:
Connect-AzAccount -Tenant <tenantId> -Subscription <subId>
After entering this command I get the warning with the url and some code.
Then I have to go to the URL and enter the code there. After that, I get a connection to the Azure account.
Are there any ways to avoid this confirmation?
I've also tried to do it using the following command:
az login -u <username> -p <password>
This command only returns some account information(subscriptionId, tenantId etc) but it doesn't install a connection to this account.

1.To login with the user account, try the command as below, make sure your account doesn't enable the MFA(Multi-Factor Authentication).
$User = "xxx#xxxx.onmicrosoft.com"
$PWord = ConvertTo-SecureString -String "<Password>" -AsPlainText -Force
$tenant = "<tenant id>"
$subscription = "<subscription id>"
$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User,$PWord
Connect-AzAccount -Credential $Credential -Tenant $tenant -Subscription $subscription
2.You can also use a service principal to login, use the command as below.
$azureAplicationId ="Azure AD Application Id"
$azureTenantId= "Your Tenant Id"
$azurePassword = ConvertTo-SecureString "strong password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
See a similar issue I answered here, it use the old AzureRM module, for Az, just change the last line.
If you are not familiar with service principal, Also see : How to: Use the portal to create an Azure AD application and service principal that can access resources, the application id and authentication key are the Azure AD Application Id and strong password you need.

You have 2 options.
Sign in with credentials (Requires Az.Accounts v 1.2.0 or higher)
You can also sign in with a PSCredential object authorized to connect to Azure. The easiest way to get a credential object is with the Get-Credential cmdlet. When run, this cmdlet will prompt you for a username/password credential pair.
$creds = Get-Credential
Connect-AzAccount -Credential $creds
Sign in with a service principal
Service principals are non-interactive Azure accounts. Like other user accounts, their permissions are managed with Azure Active Directory. By granting a service principal only the permissions it needs, your automation scripts stay secure.
To learn how to create a service principal for use with Azure PowerShell, see Create an Azure service principal with Azure PowerShell.
Source: https://learn.microsoft.com/en-us/powershell/azure/authenticate-azureps?view=azps-1.3.0

If Multi Factor Enabled then also below logic should work
$clientId = "***********************"
$clientSecret = "********************"
$tenantId = "***********************"
$tempPassword = ConvertTo-SecureString "$clientSecret" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($clientId ,
$tempPassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal

Related

Connect-AzAccount with Azure Devops Pipeline?

I am finding difficulties in finding the best and secure way to use connect-azaccount with azure devops pipeline. I have in the pipeline the following this simple powershell script which is used to create azure resources. Just to simplify things I only used the creation of a resource group:
$Location = "Location Name"
$resourceGroupName = "Resource Group Name"
try {
#Creation of Resource Group
$resourceGroup = Get-AzResourceGroup -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if($null -eq $resourceGroup)
{
New-AzResourceGroup -Name $resourceGroupName -Location $Location
}
else
{
Write-Host "The ResourceGroup with the name: $resourceGroupName already exists."
}
}
catch
{
Write-Host "Error occurred: $_"
}
The problem here is when the pipeline is being run and it reaches the Powershell task, it gives me an error, Error occurred: Run Connect-AzAccount to login.
My issue here is that I honestly don't know which way is the most secure way to connect without typing any user credentials. It should directly connect and create the resources. Note that I am using Multi-Factor Authentication. In order to achieve that I found several solutions but I need help in choosing the best way. I found several solutions by adding a powershell task in the Yaml file. Here is the Yaml showing the powershell task to run the script:
- task: PowerShell#2
inputs:
filePath: '$(Pipeline.Workspace)/Deploy/functionapp.ps1'
Option 1:
Connect-AzAccount -Tenant 'xxxx-xxxx-xxxx-xxxx' -SubscriptionId 'yyyy-yyyy-yyyy-yyyy'
Now the problem here is that the Tenant ID and Subscription are going to be visible in the code and that is a very bad practice
Option 2 is to use the following script:
$User = "xxx#xxxx.onmicrosoft.com"
$PWord = ConvertTo-SecureString -String "<Password>" -AsPlainText -Force
$tenant = "<tenant id>"
$subscription = "<subscription id>"
$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User,$PWord
Connect-AzAccount -Credential $Credential -Tenant $tenant -Subscription $subscription
This is very similar to the first, but if I am not mistaken it is limited to a specific user.
Option 3 is to use a service principal:
$azureAplicationId ="Azure AD Application Id"
$azureTenantId= "Your Tenant Id"
$azurePassword = ConvertTo-SecureString "strong password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
I don't know if creating a service principal will incur any costs and what steps should I do to make it work.
I am honestly new to all this, can someone please provide me what are the exact steps to achieve this. Thank you for your answers :)
The most secure way is to create an Azure Resource Manager service connection and use it in your pipeline. You can create it using automated way, or manually using previously created service principal.

Connect-ADAccount with service principal: Insufficient privileges to perform requested operation

I need to be able to run Connect-ADAccount in a non-interactive mode, invite a user to my AD, assign some resource permissions to this new user.
So I have:
Created a service principal.
Created a certificate using the following code:
Connect-AzureAD
$Certname = Read-Host "Enter Certificate Name"
$Cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname $Certname -Provider “Microsoft Enhanced RSA and AES Cryptographic Provider”
$pw = ConvertTo-SecureString -String "Pazzword" -Force -AsPlainText
$thumbprint = $Cert.Thumbprint
Export-PfxCertificate -cert cert:\localMachine\my\$thumbprint -FilePath $env:USERPROFILE\Desktop\$Certname.pfx -Password $pw
Get-PfxCertificate -FilePath $env:USERPROFILE\Desktop\$Certname.pfx | Export-Certificate -FilePath
$env:USERPROFILE\Desktop\OutputCert.crt -Type Cert
Uploaded it manually.
Gave owner permissions to my service principal.
Now I am able to run the following code but it would fail on the New-AzureADMSInvitation step.
Connect-AzureAD -TenantId $ObjectId -ApplicationId $AppId -CertificateThumbprint $thumb
New-AzureADMSInvitation -InvitedUserDisplayName $userName -InvitedUserEmailAddress $userEmail -InviteRedirectUrl 'https://portal.azure.com/' -SendInvitationMessage $true
I am not sure what would be the required permissions in this case.
New-AzureADMSInvitation : Error occurred while executing NewAzureADMSInvitation
Code: Unauthorized
Message: Insufficient privileges to perform requested operation by the application '00000003-0000-0000-c000-000000000000'. ControllerName=MSGraphInviteAPI, ActionName=CreateInvite [...]
New-AzureADMSInvitation invoke Create invitation MS Graph API in the backend.
POST https://graph.microsoft.com/v1.0/invitations
You need to add one of the following application permission when using service principal:
User.Invite.All,
User.ReadWrite.All,
Directory.ReadWrite.All
Please navigate to App registration > your app > add API Permissions > Microsoft Graph API > Select the previous in Application Permission. And also remember to grant admin consent for your tenant.

How do I get groups from AAD using Powershell Function App?

I want to get all users from certain groups in AAD using Powershell with a Function app, but I keep getting permission errors and I don't know how to assign them.
$groupsAD = [System.Collections.ArrayList]#()
$groupsAD.Add('Group1')
$groupsAD.Add('Group2')
foreach ($groupAD in $groupsAD) {
$group = Get-AzADGroup -DisplayName $groupAD
# further code
}
The error:
[Error] ERROR: Insufficient privileges to complete the
operation.Exception :Type : System.ExceptionMessage :
Insufficient privileges to complete the operation.HResult :
-2146233088CategoryInfo : InvalidOperation: (:) [Get-AzADGroup], ExceptionFullyQualifiedErrorId :
Microsoft.Azure.Commands.ActiveDirectory.GetAzureADGroupCommandInvocationInfo
:MyCommand : Get-AzADGroupScriptLineNumber : 16OffsetInLine
: 14HistoryId : 1ScriptName :
C:\home\site\wwwroot\HttpTrigger1\run.ps1Line : $group =
Get-AzADGroup -DisplayName $groupADPositionMessage : At
C:\home\site\wwwroot\HttpTrigger\run.ps1:16 char:14+ $group =
Get-AzADGroup -DisplayName $groupAD
When creating this function locally it works fine after I authenticate with Connect-AzAccount.
Also tried to create an identity and authenticate it with it, but as far as I know it's for Azure resources not AAD.
For this problem, here provide two solutions for your reference:
1. If you use username/password to do authentication in Connect-AzAccount command, you need to make sure the user account has required permission for get AD group. Then use the code below in your function:
$User = "{username}"
$PWord = ConvertTo-SecureString -String "{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
Connect-AzAccount -Credential $Credential
$group = Get-AzADGroup -DisplayName "{group name}"
2. If you do not want to use username/password to do authentication in your function. You can use service principal to do it.
First you need to register an app in your Azure AD, I registered an app named "huryGetToken6" in my Azure AD.
Then click "Certificates & secrets" tab, new client secret. Copy the client secret to your notepad.
Then add the permission to the registered app, do it with the steps in below screenshots.
Please do not forget click "Grant admin consent for xxx" after add the permissions to registered app.
After that, you can use the code below in your function to get AD group:
$username = "{client id/application id}"
$password = "{client secret}"
$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd
Connect-AzAccount -Credential $Credential -Tenant "{tenant id}" -ServicePrincipal
$group = Get-AzADGroup -DisplayName "huryGroup"
For the params in above commands, you can find the client id/application id and tenant id on the "Overview" page of your registered app.

login to azure account without popup using powershell

I'm trying to create Azure VM using powershell.I have also the script to create it.
First I need to login into Azure account :
Login-AzureRMAccount
This gives a pop-up to enter the credentials.
Second I need to run the below script:
$UserName = "username"
$Password = ConvertTo-SecureString "password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($UserName, $Password)
New-AzureRmVm `
-ResourceGroupName "RG1" `
-Name "VM1" `
-ImageName "Image1" `
-Location "West US" `
-Credential $psCred
This is creating the VM successfully.
But now , I need to make these scripts run automatically, when ever there is requirement. The problem I'm facing is, the login step gives a popup to enter the credentials which I do not want. So I have tried something like this, but didn't work.
$username = "loginname#organization.com"
$SecurePassword = ConvertTo-SecureString "password" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username, $SecurePassword)
Login-AzureRmAccount -Credential $cred
The error message it is giving is :
Login-AzureRmAccount : accessing_ws_metadata_exchange_failed: Accessing WS metadata exchange failed: The underlying connection was closed: An unexpected error occurred on a send.
At line:4 char:1
+ Login-AzureRmAccount -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Connect-AzureRmAccount], AadAuthenticationFailedException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand
Can anyone tell me what this means and how to rectify this? Thanks!
If you are planning to automate any services into Azure using PowerShell, then I'd recommend connecting azure using Service Principal rather than your own credentials, it will be a secure way to connect.
What is Service principal?
An Azure service principal is a security identity used by user-created
apps, services, and automation tools to access specific Azure
resources. Think of it as a 'user identity' (username and password or
certificate) with a specific role, and tightly controlled permissions.
It only needs to be able to do specific things, unlike a general user
identity. It improves security if you only grant it the minimum
permissions level needed to perform its management tasks.
Follow this tutorial to create a service principal
I also have published a sample PowerShell workflow into Microsoft gallery for creating Service Principal you can also follow that.
Once you created your service principal, you can use the below PowerShell commands to login into azure without any popup's
$applicationId = "<service prinicple application id>";
$securePassword = "<service prinicple password>" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $securePassword
Connect-AzureRmAccount -ServicePrincipal -Credential $credential -TenantId "<your tenantid>"
Update1:
For some reason/bug the above will get fails. Refer this github issue
To solve this
Add the two lines before the script
Import-Module -Name AzureRM.Profile
Remove-AzureRmAccount
Update 2:
AzureRM will no longer receive new cmdlets or features. However, the AzureRM module is still officially maintained and will get bug fixes through December 2020.
You have to use the new Azure PowerShell Az module
Basically you can achieve this for all of your PowerShell sessions by adding the Logging in part as part of the $PSProfile. I use this trick to skip the login popup, so whenever i open powershell my account is automatically logged in.
Open Windows PowerShell as an administrator
Type Notepad $profile
A notepad file will be opened and here you can paste the below code to
log in automatically whenever it is opened.
$username = “”
$password = “”
$securepasswd = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($username, $ securepasswd)
Connect-AzureRmAccount -Credential $cred

Login-AzureRmAccount from VS Code terminal

When I try to login to Azure RM from VS Code terminal it just hangs. No prompt with login / password is shown.
Is there any way to get logged in from that terminal? Otherwise running / debugging Azure PS scripts becomes more complicated than it should be :)
The login window pops-up in the background... if you minimize all your windows you'll eventually find it.
You need to wait for a moment, then you could see the login page.
According to your description, I suggest you could select Non-interactive login. You could create a service principal that can access resource. Please refer to this link:Use portal to create an Azure Active Directory application and service principal that can access resources. You will get clientid and client secret. You could use the following code to login your Azure account.
$subscriptionId=""
$tenantid=""
$clientid=""
$password=""
$userPassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientid, $userPassword
Login-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionId $subscriptionId -Credential $userCredential

Resources