Skip to content

Instantly share code, notes, and snippets.

@DamagedDingo
Created January 15, 2024 00:35
Show Gist options
  • Save DamagedDingo/5c0c7ecc6788772834cfefd827663e14 to your computer and use it in GitHub Desktop.
Save DamagedDingo/5c0c7ecc6788772834cfefd827663e14 to your computer and use it in GitHub Desktop.
function Get-MsalTokenByCertificate {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[switch]$ForceRefresh,
[Parameter(Mandatory = $false)]
[string]$tenantId,
[Parameter(Mandatory = $false)]
[string]$clientId,
[Parameter(Mandatory = $false)]
[string]$certificateThumbprint
)
# Check if a valid token already exists in memory and return it, unless ForceRefresh is specified
if ($null -ne $script:msalToken -and $script:msalToken.ExpiresOn -gt [DateTime]::UtcNow -and -not $ForceRefresh) {
Write-Verbose "A valid token already exists. Returning the existing token."
Write-Log -Message "A valid token already exists. Returning the existing token." -Type Info -Component 'Get-MsalTokenByCertificate'
return $script:msalToken
exit
}
# Check if the certificate exists in the local store and create it if it doesn't
if (-not($certificateThumbprint)) {
try {
$certificateThumbprint = (get-childitem Cert:\CurrentUser\My\ | Where { $_.Subject -like 'CN=EUC.Powershell' }).Thumbprint
}
catch {
New-SelfSignedPublicCertificate
$certificateThumbprint = (get-childitem Cert:\CurrentUser\My\ | Where { $_.Subject -like 'CN=EUC.Powershell' }).Thumbprint
Write-Host "New Certificate Thumbprint was created and added to the local store." -BackgroundColor Red -ForegroundColor DarkRed
get-childitem Cert:\CurrentUser\My\ | Where { $_.Subject -like 'CN=EUC.Powershell' }
Write-Host "The new certificate MUST be added to the App Registration in MS Entra before continuing." -BackgroundColor Red -ForegroundColor DarkRed
Write-Host "'ITS EUC Script (AAD,Intune) ReadWrite - Admin' \ 'Certificates & secrets'" -BackgroundColor Red -ForegroundColor DarkRed
}
}
# Load the certificate from the certificate store
Write-Verbose "Loading the certificate from the certificate store"
Write-Log -Message "Loading the certificate from the certificate store" -Type Info -Component 'Get-MsalTokenByCertificate'
$certStore = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList "My", "CurrentUser"
$certStore.Open("ReadOnly")
$cert = $certStore.Certificates | Where-Object { $_.Thumbprint -eq $certificateThumbprint }
$certStore.Close()
if ($null -eq $cert) {
Write-Error "Certificate with thumbprint $certificateThumbprint not found"
Write-Log -Message "Certificate with thumbprint $certificateThumbprint not found" -Type Error -Component 'Get-MsalTokenByCertificate'
return
}
# Create the MSAL client
Write-Verbose "Creating the MSAL client"
Write-Log -Message "Creating the MSAL client" -Type Info -Component 'Get-MsalTokenByCertificate'
$msalClient = [Microsoft.Identity.Client.ConfidentialClientApplicationBuilder]::Create($clientId).WithAuthority("https://login.microsoftonline.com/$($tenantId)").WithCertificate($cert).Build()
# Request the token
Write-Verbose "Requesting the token"
Write-Log -Message "Requesting the token" -Type Info -Component 'Get-MsalTokenByCertificate'
$scopes = [string[]] "https://graph.microsoft.com/.default"
$script:msalToken = $msalClient.AcquireTokenForClient($scopes).ExecuteAsync().Result
return $script:msalToken
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment