JWTDetails.psm1
function Get-JWTDetails { [cmdletbinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string]$token ) <# .SYNOPSIS Decode a JWT Access Token and convert to a PowerShell Object. JWT Access Token updated to include the JWT Signature (sig), JWT Token Expiry (expiryDateTime) and JWT Token time to expiry (timeToExpiry). .DESCRIPTION Decode a JWT Access Token and convert to a PowerShell Object. JWT Access Token updated to include the JWT Signature (sig), JWT Token Expiry (expiryDateTime) and JWT Token time to expiry (timeToExpiry). .PARAMETER token The JWT Access Token to decode and udpate with expiry time and time to expiry .INPUTS Token from Pipeline .OUTPUTS PowerShell Object .SYNTAX Get-JWTDetails(accesstoken) .EXAMPLE PS> Get-JWTDetails('eyJ0eXAiOi........XmN4GnWQAw7OwMA') or PS> 'eyJ0eXAiOi........XmN4GnWQAw7OwMA' | Get-JWTDetails aud : https://graph.microsoft.com iss : https://sts.windows.net/74ea519d-1234-4aa9-86d9-b7cab8204aaa/ iat : 1564472277 nbf : 1564472277 exp : 1564476177 acct : 0 acr : 1 aio : AVQAq/8MAAAAAzB0vSr6FzZdn+4Rl0mv/akAo4CoJGUOzDRebOAz2s8IgJyRK7IONYU/57PHkLZYUswizziQS7QQ5l9w0DrqH4urxrexTpLbagQHvJlEaD6c= amr : {pwd, mfa} app_displayname : Reporting appid : 2c29e80e-ec64-43f7-b07a-137ae9c1d70c appidacr : 1 ipaddr : 1.129.1.112 name : Darren J Robinson oid : 5fddc979-ef08-4947-abcd-2430bc1234e0 platf : 3 puid : C1373BFDAE1A48F6 scp : AuditLog.Read.All Directory.Read.All Reports.Read.All User.Read User.Read.All sub : _31PG9C137LXuAkWDB93YM_eoRl9auP21qHOn5hO-s9w tid : 74ea519d-9792-4aa9-c137-b7cab8204aaa unique_name : darren@mytenant.onmicrosoft.com upn : darren@mytenant.onmicrosoft.com uti : eoWKGl9uZ0Gnc13715Qdff ver : 1.0 wids : {4a5d8f65-41da-4de4-c137-f035b65339ca, c4e39bd9-c137-46d3-8c65-fb160df0071a, 5d6b6bb7-c137-4623-bafa-96380f352509} xms_tcdt : 1341026666 sig : PUpl4F61Ql12nfxkLDeTA2Tucb7KfzrfbmI1+gNDPFfbe8WD3wlfr0EK2M89JNPJ1Z8H7Z8/JVU9Jbat2u+657D8IM81+NhnCpMvEWyC5565ZmIgE3vQKlBK3wD24kSzEFj6J2yL Zou1u/NrBvEakiiZdCJRKOB9nf4/euHHfYJNSKtPhLiPImyc137JxbPUG/MPjAQBkBPuUCyYtmFoBynGvsoSVvzZ6JQS5O2nxZPAqOFUzj5q3fjhh/oqPpu/6Qw1bdt3O37HgMLn UrBK3psjwUfP/X6//L6S1FwomenNoFVeKcUNcM5Ne6loDwRSW1Ig8XHXmN4GnWQAw7OwMA== expiryDateTime : 30/07/2019 6:42:57 PM timeToExpiry : -00:32:56.1103767 .EXAMPLE PS> Get-JWTDetails($myAccessToken) or PS> $myAccessToken | Get-JWTDetails tenant_id : cd988f3c-710c-43eb-9e25-123456789 internal : False pod : uswest2 org : myOrd identity_id : 1c818084624f8babcdefgh9a4 user_name : adminDude strong_auth_supported : True user_id : 100666 scope : {read, write} exp : 1564474732 jti : 1282411c-ffff-1111-a9d0-f9314a123c7a sig : SWPhCswizzleQWdM4K8A8HotX5fP/PT8kBWnaaAf2g6k= expiryDateTime : 30/07/2019 6:18:52 PM timeToExpiry : -00:57:37.4457299 .LINK https://blog.darrenjrobinson.com https://blog.darrenjrobinson.com/jwtdetails-powershell-module-for-decoding-jwt-access-tokens-with-readable-token-expiry-time/ #> if (!$token.Contains(".") -or !$token.StartsWith("eyJ")) { Write-Error "Invalid token" -ErrorAction Stop } # Token foreach ($i in 0..1) { $data = $token.Split('.')[$i].Replace('-', '+').Replace('_', '/') switch ($data.Length % 4) { 0 { break } 2 { $data += '==' } 3 { $data += '=' } } } $decodedToken = [System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($data)) | ConvertFrom-Json Write-Verbose "JWT Token:" Write-Verbose $decodedToken # Signature foreach ($i in 0..2) { $sig = $token.Split('.')[$i].Replace('-', '+').Replace('_', '/') switch ($sig.Length % 4) { 0 { break } 2 { $sig += '==' } 3 { $sig += '=' } } } Write-Verbose "JWT Signature:" Write-Verbose $sig $decodedToken | Add-Member -Type NoteProperty -Name "sig" -Value $sig # Convert Expiry time to PowerShell DateTime $orig = (Get-Date -Year 1970 -Month 1 -Day 1 -hour 0 -Minute 0 -Second 0 -Millisecond 0) $timeZone = Get-TimeZone $utcTime = $orig.AddSeconds($decodedToken.exp) $hoursOffset = $timeZone.GetUtcOffset($(Get-Date)).hours #Daylight saving needs to be calculated $localTime = $utcTime.AddHours($hoursOffset) # Return local time, $decodedToken | Add-Member -Type NoteProperty -Name "expiryDateTime" -Value $localTime # Time to Expiry $timeToExpiry = ($localTime - (get-date)) $decodedToken | Add-Member -Type NoteProperty -Name "timeToExpiry" -Value $timeToExpiry return $decodedToken } Export-ModuleMember -Function 'Get-JWTDetails' |