Use app-only authentication with the Microsoft Graph PowerShell SDK
In the previous blog post I have showed you how to interactively log in into the Microsoft Graph API. You had to enter a username, a password, and you had to enter a second factor. This is typically not want you want if you want to automate things. But there is another way to get access to the Microsoft Graph API.
Create an app registration
To get access, you have to register an app in your AzureAD. Go to your Azure portal and select “App registration” from the “Manage” section. Add a new registration by clicking to “New registration”.
Give your registration a meaningful name. Usually, only accounts in your AzureAD should be able to use this app.
The next step is to add permissions. This is equivalent to defining permission scopes during an interactive login. Make sure that you only follow the least-privilege method. In contrast to delegate access, this login type is truly limited to the permissions you grant in this step.
Select “Microsoft Graph” from the list.
Choose “Application permissions”.
Then select the necessary permissions.
Grant the permissions and select “Grant admin consent”. This step is pretty important. You, the admin, consent to the selected permissions. There is no further question to consent to the enduser.
Login with a client secret
But before we can use, we have to add something to use in the authentication process. There are two different methods to authenticate:
- Certificate, or
- client secret
A client secret is okay for test or dev environments. But I would not recommend the usage in a prod environment. You have to add this secret to a script or something, which is hard to protect. Create a new client secret. Please note, that a client secret has a lifetime. And make sure that you copy it. Tge client secret will be hidden later!
Make sure that you give your client secret a descriptive name.
The usage of a client secret is a two-step process. We need to get an access token, using the client secret, and use the token to connect to the Graph API. To get an access token, you need to install the Microsoft Authentication Libraries (MSAL) PowerShell module.
Install-Module MSAL.PS -Scope CurrentUser
Then we can aquire the token.
$AppId = '525b0e65-xxxx-xxxx-xxxx-7f8c32536247'
$TenantId = 'ffbc872a-xxxx-xxxx-xxxx-d81b43c67ffe'
$ClientSecret = 'NmO8Q~PPzVqZnxxxxxxxxi0vfRBhj8_xxxxxxx'
$Token = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force)
Connect-Graph -AccessToken $MsalToken.AccessToken
As you can see, this service principal login was made by the client secret.
Login with a certificate
Something more appropriate for a prod environment, is to use a certificate for the login. You can create a self-signed certificate, or use any other kind of X.509 certificate to authenticate. I used a S/MIME certificate in this case.
Make sure that you only upload the public key!! The certificate with the private key must be stored in the computer or user certificate store on the machine from which you want to access.
Upload the public key of a certificate.
Next step is to use the certificate hash during the login process:
Connect-MgGraph -ClientId 525b0e65-xxxx-xxxx-xxxx-7f8c32536247 -TenantId ffbc872a-xxxx-xxxx-xxxx-d81b43c67ffe -CertificateThumbprint DC427652498895A6F453671275BC69B352F3510A
Same result, a successful login, but different authentication method.
As already mentioned: I would prefer certificate over client secret. :)