I created a powershell script to connect to my sharepoint site online.
Having enabled two-factor authentication, I set a password for the app for authentication and used it in the Connect-PnpOnline command.
$securePassword = ConvertTo-SecureString "myappapassword" -AsPlainText -Force
$credentials = New-Object PSCredential ("my#username.com", $securePassword)
Connect-PnPOnline -Url $TenantSiteURL$SiteRelativeURL -Credentials $credentials
On the local computer I don't get any errors, but when I try to run it in Azure Function I get:
Error validating credentials due to invalid username or password
Below are the few workaround to solve the above issue:
Please make sure that you have uploaded your pnp powershell module to Azure function .
By Navigating to Azure function >Advance tool>Kudu console> wwwroot folder > Create new folder copy and paste your modules that have in your local.
Add your service account user name and password in configuration of Azure function.
Try to replace the following cmd in your cmdlt:
$Credential = New-Object System.Management.Automation.PSCredential($serviceAccountEmail, $SecurePassword)
To use managed identity you can refer this Blog
For more information please refer the below links :
MS DOC: Connect-PnpOnine, Granting access via Azure AD App-Only
MS Q&A: Connecting with PnP PowerShell(without username and password)
Related
Currently I am using username and password to connect SPO Service uisng below code :
$psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($UserName, $Password)
Connect-SPOService -Url "https://$OrganizationName-admin.sharepoint.com" -Credential $psCred
Now i want to use ClientId and client secret of my App and remove username and password. I have given Global Administrator roles for my app also. So based on my application ClientId and clientsecret i want to execute my PowerShell scripts now. Can someone help me on this.
As #AnsumanBal-MT suggested posting it as an answer to help other community members .
"
SPO is only for user with Sharepoint Admin or global admin access so it uses MFA for authentication to the sharepoint url.
Instead of that we can use PnP which allow us to use any form of authentication .We can't use client id in SPO .
Based on the MS DOC For example:
Connect-PnPOnline
[-ReturnConnection]
[-Url] <String>
[-Credentials <CredentialPipeBind>]
[-CurrentCredentials]
[-CreateDrive]
[-DriveName <String>]
[-ClientId <String>]
[-RedirectUri <String>]
[-AzureEnvironment <AzureEnvironment>]
[-TenantAdminUrl <String>]
[-TransformationOnPrem]
[<CommonParameters>]
For more information please refer this MS DOC: Granting access using SharePoint App-Only
I have a PowerShell script that logs into Azure subscription with the command Connect-AzAccount using user's credentials.
The code is the following:
$userPassword='password'
$userName="username"
$tenantId="########-####-####-####-############"
$subscriptionId="########-####-####-####-############"
$azureSecpassword = $userPassword | ConvertTo-SecureString -asPlainText -Force
$azureCredential = New-Object System.Management.Automation.PSCredential($userName, $azureSecpassword)
Connect-AzAccount -Credential $azureCredential -Tenant $tenantId -SubscriptionId $subscriptionId
The code above works without any user interaction.
Few days ago the customer enabled the multi-factor authentication for the users.
How can I keep a fully automated login process (without user interactions) with the multi-factor authentication?
Best Regards.
This is a common question. Unfortunately, the answer is No. If the account is MFA-enabled, you could just login with an interactive way.
In such a case, we choose to use the service principal to login with non-interactive in general.
$azureAplicationId ="Azure AD Application Id"
$azureTenantId= "Your Tenant Id"
$azurePassword = ConvertTo-SecureString "client secret" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Reference - Sign in with a service principal.
If you must log in as a user, there might be 2 optional approaches.
1. If you will run the script locally or in a specific PC
You can Persist Azure user credentials. You can enable auto save, or manually save the context to a file, and then use it in another PS session.
If you enabled auto save, then you can directly get the context as following:
Get-AzContext
# If you have more than one contexts, you can choose one by specifing the name
Get-AzContext -Name 'CSP Azure (e5b0****-****-****-****-5e5f****4c68) - jack#h****a.onmicrosoft.com'
If you want to manually do it, here is the sample:
# Interactively log for one time
Connect-AzAccount
# Save the context
Save-AzContext -Path D:\ctx.dat
And in another PS session, you can:
Import-AzContext -Path D:\ctx.dat
2. Use refresh token to acquire token, and connect to Azure
You can get the refresh token from the auto saved Azure context (usually at C:\Users\<UserName>\.Azure\TokenCache.dat).
Open the dat file with notepad, and you will get the refresh token:
Then you can get a new token in PowerShell with that refresh token, and connect to Azure:
Clear-AzContext
$tenantId = "e4c9ab4e-****-****-****-230b****57fb"
$subscriptionId = "e5b0fcfa-****-****-****-5e5f****4c68"
$refreshToken = 'AQABAAAAAAAP0****a lot of characters here*****0A9FWoB8mvDtoWRJHBVO7GJzodLKYmNIAA'
$url = "https://login.microsoftonline.com/" + $tenantId + "/oauth2/token"
$body = "grant_type=refresh_token&refresh_token=" + $refreshToken
$response = Invoke-RestMethod $url -Method POST -Body $body
$AccessToken = $response.access_token
Connect-AzAccount -AccountId "the user id, jack#h****a.onmicrosoft.com" -AccessToken $AccessToken -Tenant $tenantId -SubscriptionId $subscriptionId
How can I keep a fully automated login process (without user interactions) with the multi-factor authentication?
You can't do this with a user account--that's the whole point of multi-factor authentication.
Instead, Azure AD supports authenticating with a service principal (instead of a user principal, like you're doing currently), and Azure supports granting access to Azure resources to service principals.
MFA requirements (and other conditional access policies) do not apply to service principals (often referred to as an Azure AD "app"), and service principals support more secure methods of authentication for automation scenarios (e.g. public/private key pairs).
So, what you should do:
Ensure the machine running this script is secure. Anyone with access to the machine has the same amount of access as the script.
Create an application identity and associate credentials with it.
Note: It is strongly recommend you use certificate-based authentication for your service principal, instead of password-based. It is a very insecure practice to have any kind of secret stored in a PowerShell script!
Grant the service principal the minimum level of access to Azure resources, to allow it to complete the required task.
Update your script to use the app's identity (service principal) instead of the user's identity. It's even simpler than using a user account:
$tenantId = "########-####-####-####-############"
$subscriptionId = "########-####-####-####-############"
$appId = "########-####-####-####-############"
$thumbprint= "##############"
Connect-AzAccount -ServicePrincipal -TenantId $tenantId -ApplicationId $appId -CertificateThumbprint $thumbprint
Note: If this script is running on a VM in Azure, you should forget step 2, and simply enable a managed identity and use that.
In an application, I'm currently using PowerShell and MSOnline module (Connect-MsolService and Get-MsolUser) to get a list of AD users. A global admin provides his username and password and the application is able to get a list of all users under that tenant.
That works fine... As long as the password is not an app password. When an app password is used then the following is what the global admin gets to see:
Authentication Error: Bad username or password
My question is: Is there any other method, which uses PowerShell, but doesn't have to, to get the list of users in AD, but which works with app password? I know of Graph API, but that's not a fit for the project right now.
If I understand you correctly, you want to use the AD App and its password(secret) to list the users.
You could use the Az powershell module to do that, login with the service principal and list users via Get-AzADUser. Also, make sure your AD App(service principal) has the admin role like User administrator or Global administrator.
$azureAplicationId ="<AD App Application id>"
$azureTenantId= "<tenant id>"
$azurePassword = ConvertTo-SecureString "<password>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Get-AzADUser
Update:
Currently, use app password of MFA enabled user to connect MSOL powershell is not supported, for more details see this link.
App passwords are NOT supported, simply use Connect-MsolService without any parameter to trigger the ADAL dialog and complete the 2FA challenge as normal.
Previously, I was able to login to the azure subscription via powershell using the below code.
$azureAccountName ="username"
$azurePassword = ConvertTo-SecureString "Password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Login-AzureRmAccount -Credential $psCred
Recently, Microsoft introduced MFA (Multi-Factor Authentication) and now the above code fails as we now have to verify the login via a code received on the mobile number registered at the time of profile creation.
I do not want the interactive login but the automatic one which my code was earlier able to do.
Any suggestions?
As a workaround, I think you can use service principal instead of your Microsoft account.
About create Azure service principal, we can follow this article via Azure portal to create it.
Then use PowerShell like this:
$subscriptionId="5384xxxx-xxxx-xxxx-xxxx-xxxxe29axxxx"
$tenantid="1fcf418e-66ed-4c99-9449-d8e18bf8737a"
$clientid="1498b171-e1ca-451f-9d7a-8ef56a178b89" #appid
$password="7db814b1-xxxx-4654-xxxx-1d210cb546f9"
$userPassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientid, $userPassword
Add-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionId $subscriptionId -Credential $userCredential
In this way, we can use powershell to login it.
This is not posible (at least to my knowledge).
Use an application password.
I've highlighted a couple things from the Microsoft documentation here, but the short version is that an app password is basically your personal back door to bypass MFA. Note that for that reason an organization can restrict users from being able to create app passwords.
An app password is a long, randomly generated password that you provide only once instead of your regular password when signing in to an app or device that doesn't support two-step verification.
https://learn.microsoft.com/en-us/azure/active-directory/user-help/multi-factor-authentication-end-user-app-passwords
Certain non-browser apps, such as Outlook 2010, doesn't support two-step verification. This lack of support means that if you're using two-step verification, the app won't work. To get around this problem, you can create an auto-generated password to use with each non-browser app, separate from your normal password.
You're given an app password during your initial two-step verification registration. If you need more than that one password, you can create additional passwords, based on how you use two-step verification
Use one app password per device, not per app. For example, create a single password for all the apps on your laptop, and then another single password for all the apps on your desktop.
There's a limit of 40 passwords per user. If you try to create one after that limit, you'll be prompted to delete an existing password before being allowed to create the new one.
I need to wire up a stateless worker ad-hoc to perform a long running job based off a user action that self destructs when its done. I am trying to run New-AzureRmResourceGroupDeployment from within a PoSh Function App and cannot figure out how to authenticate to Azure from within the PoSh script.
I tried this:
$accountName = "myID#mydomain.com"
$pwd = ConvertTo-SecureString "password" -AsPlainText -Force
$cred = new-object PSCredential($accountName, $pwd)
Add-AzureRmAccount -Credential $cred
New-AzureResourceGroupDeployment -ResourceGroupName yadda yadda
And I get an error message that I need to use an Organization ID (which I am, our Azure AD is federated and we use AD Sync (and SiteMinder w/o WS-* if that matters)):
Add-AzureRmAccount : -Credential parameter can only be used with Organization ID credentials. For more information, please refer to http://go.microsoft.com/fwlink/?linkid=331007&clcid=0x409 for more information about the difference between an organizational account and a Microsoft account.
I tried "Login-AzureRMAccount -Credential $cred" with similar results.
If I do the Add- or Login- cmdlets from a PoSh window on my local machine (which is member joined to AD) with the -Credential flag I get a similar error. If I run the cmdlets without the credential I am prompted for credentials through an interactive ID/PW window (I do not have to enter my password once I type in my ID).
Does anyone know how I can do the authentication? I would be okay with authenticating like above, some sort of pass through credential from our web layer, or even an Option C I don't know about.
You will need to use service principal for authentication. A sample with instructions can be found here.
Azure Function role like permissions to Stop Azure Virtual Machines
For that you would need to use Service Principal auth. I don't think there is any sense of copypasting Azure Doc's to this answer, just consult this document:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal