Are you an MSP with GDAP partners? Do you want to leverage powershell automations through MSGraph, Exchange Online, or other Enterprise Applications? Are you tired of manually pulling the credentials for that tenant and entering an MFA code? Do you have concerns about the security of programmatic access to your sub-tenants?
Well look no further!
This is a module/class meant to ease the process of interacting with these applications by streamlining access token creation. This leverages GDAP partner relationships as well as azure key vaults to securely store information.
I rely heavily upon a blog here for instructions on how to setup the app registration And here for instructions on how to setup the azure key vault
Powershell 7 of course
You will need a certificate in the cert:\currentuser\my\ store on the device that you want to securely access the keyvault from. If you are unfamiliar please follow along here to create the certification and keyvault. I have 2 notes on the this tutorial.. I would recommend creating the certificate as non-exportable to prevent propogation or security issues if it is leaked, there is also a few typos for .ApplicationId that should be .AppId.
This module assumes you already have your azure key vault setup with these keys:
PartnerCenterRefreshToken
AutomationsAppID
AutomationsAppSecret
All of these are generated by following the above tutorial. You can stop after giving the proper consent to your app registration. Right before "Configuring GDAP Relationships" if everything is already setup. But it won't hurt to keep going for better understanding.
Once you have them simply create the secrets directly in the azure portal, they must be titled exactly as above :D
You're smart, you'll figure it out.
Once you have all of that you are 90% there to using this bad boy.
Clone the repo to your directory of choosing. Now we code:
PS C:\Users\jon> using module 'repopath\jons-secure-graph-wrapper\SAW.psm1'
$SAW = [SAW]::new()
#alternatively SAW ([string]$KvName, [string]$KvCName, [string]$KVSPApplicationId, [string]$TenantId, [string]$AppDisplayName)
$SAW = [SAW]::new('MSP-CredsKeyVault','CN=MSPKV','12345678-1234-1234-1234-123456789012','87654321-4321-4321-4321-210987654321',' MSP Automations')
$grants = @(
@{
enterpriseApplicationId = "00000003-0000-0000-c000-000000000000"
scope = "Directory.Read.All,Directory.AccessAsUser.All"
},
@{
enterpriseApplicationId = "00000002-0000-0ff1-ce00-000000000000"
scope = "Exchange.Manage"
}
)
$SAW.ConsentToApp($CustomerTenantId, $grants)
$SAW.RevokeAppAccess($CustomerTenantId)
$scope = 'https://graph.microsoft.com/Device.ReadWrite.All'
$graphToken = $SAW.GetMicrosoftToken($CustomerTenantId,$scope)
$headers = @{ "Authorization" = "Bearer $($graphToken.Access_Token)" }
$Devices = (Invoke-RestMethod -Uri 'https://graph.microsoft.com/beta/devices' -Headers $headers -Method Get -ContentType "application/json").value
$Devices.count
$token = $SAW.GetMicrosoftToken($CustomerTenantId, 'https://outlook.office365.com/.default')
Connect-ExchangeOnline -DelegatedOrganization $CustomerTenantId -AccessToken $token.Access_Token -ShowBanner:$false