Closed antondreyer closed 2 years ago
There's a loop in the script to get a refreshed token after 59 minutes.
$TimeRightNow = (Get-date)
if($TimeRightNow -ge $TokenExpiredDate){
$body = @{
client_id = $AppId
scope = "https://graph.microsoft.com/.default"
client_secret = $AppSecret
grant_type = "client_credentials"
}
$Params = @{
'Uri' = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
'Method' = 'Post'
'Body' = $Body
'ContentType' = 'application/x-www-form-urlencoded'
}
# Get OAuth 2.0 Token
try{
$Refreshtoken = Invoke-RestMethod @Params
}
catch{
Write-Host "An error occurred:"
Write-Host $_ -ForegroundColor Red
Write-ErrorLog 'An error occurred: {Error}' -PropertyValues $_
}
# Unpack Access Token
if ($null -ne $Refreshtoken) {
$Token = $Refreshtoken.access_token
Write-Host "Token Refreshed at $TimeRightNow" -ForegroundColor Red
}
else {Write-Host "Not refreshed, Token is empty" -ForegroundColor Red}
$TokenExpiredDate = (Get-date).AddMinutes($TimeToRefreshToken)
}
#### END of Check if token is older than 50 minutes and request a refresh token #######
Looking at the code, it seems like it works for once through the refresh loop but maybe fails after that. Perhaps if you chance the unpack access token code to that shown below it will work for multiple loops.
# Unpack Access Token
if ($null -ne $Refreshtoken) {
$Token = $Refreshtoken.access_token
Write-Host "Token Refreshed at $TimeRightNow" -ForegroundColor Red
$TokenCreationDate = (Get-Date)
$TokenExpiredDate = (Get-Date).AddMinutes($TimeToRefreshToken)
Unfortunately still the same result
# Unpack Access Token
if ($null -ne $Refreshtoken) {
should $Refreshtoken not perhaps be set to null somewhere so it can evaluate true on the next run?
Also not sure if "$TokenCreationDate = (Get-Date)" serves any purpose? Doesnt seem to be used anywhere
It's no excuse, but another contributor added that piece of code. I will get to testing and refining it some time. Finding 40K teams to test it against might be a challenge...
I did some testing...
I moved the code to get an access token into a function
`function GetAccessToken {
$AppId = "828e1143-88e3-492b-bf82-24c4a47ada63" $TenantId = "b662313f-14fc-43a2-9a7a-d2e27f4f3478" $AppSecret = 'sK78Q~EYQVuAU5EURRtTZhl4uH-e-WAinDEfqaMW'
$uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $body = @{ client_id = $AppId scope = "https://graph.microsoft.com/.default" client_secret = $AppSecret grant_type = "client_credentials" }
$tokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
$Token = ($tokenRequest.Content | ConvertFrom-Json).access_token
Return $Token } `
and then replaced all the code that's currently in place to check for token renewal with:
$TimeNow = (Get-Date)
if($TimeNow -ge $TokenExpiredDate){
$Token = GetAccessToken
$TokenExpiredDate = (Get-date).AddMinutes($TimeToRefreshToken)
Write-Host "Requested new access token - expiration at" $TokenExpiredDate
}
#### END of Check if token is older than 50 minutes and request a refresh token #######
I changed the token renewal check to 3 minutes and the script ran as expected with renewal happening on schedule. You can apply the change to your script and try it out or wait until I get done with another change that I want to make (sometime soon).
I've updated the script to V5.5. This version includes the changes to improve token handling.
Good day, and thanks for the script. I think I am running into an issue where the Token isn't refreshing a second time - it's on a tenant with 50k+ teams
After about an hour I can see it saying it refreshed the token, and then after another hour it starts returning "The remote server returned an error: (401) Unauthorized."
By limiting the number of groups it loops through to 10 I did get a successful run, so i don't think its graph permissions
Does the script handle multiple refreshes of the token in all the loops that take a long time?