2

I'm connecting to Microsoft Graph for some reports. However, if the report gets close to an hour, I want to automatically re-request a token. I'm able to get the script working in Visual Studio Code, but it doesn't update the token or TimeoutTimer variables in the normal shell. I want to be able to run this as a scheduled task since the run-time is looking at ~8 hours.

I'm assuming this is due to scoping, but I was hoping Global would work, except it's not. I've also tried setting a "state" variable using $job.Module.SessionState.PSVariable.Set() but haven't been able to get that to work (not really familiar, so just coming off some other things I've seen looking around).

    $Global:TimeoutTimer = New-Object timers.timer

    $Global:token = "none"

    $TimerAction = { 
        $Global:tokenRequest = Connect-MicrosoftGraphCustom "Secret Parameters"
        $Global:token = $Global:tokenRequest.access_token
        $Global:TimeoutTimer.Interval = ($Global:tokenRequest.expires_in * 1000) - 100000 
        Write-Host "Inside action: $($Global:TimeoutTimer.Interval)" -ForegroundColor Green
    }

    $job = Register-ObjectEvent -InputObject $Global:TimeoutTimer -EventName Elapsed -Action $TimerAction 
    $Global:TimeoutTimer.Enabled = $true

    sleep -Milliseconds 100

    $i = 0
    while ($i -le 5)
    {
        Write-host "Function Return: $($token)" -ForegroundColor Red
        Write-Host "Global Variable: $($Global:Token)" -ForegroundColor Gray
        Write-Host "Timer Expires in: $($TimeoutTimer.interval) or $($Global:TimeoutTimer.interval)" -ForegroundColor Blue
        sleep 3600
        $i++
    }

    $Global:timeoutTimer.Enabled = $false

I'm hoping to get some "Inside action: x" output and then some copies of the token as the loop processes. What I'm getting in the shell is just a bunch of "None" and "Timer expires in 100 or 100"

What can I do to get the value of token to update in the appropriate scope without reading a file each time I go to access the token variable?

1 Answer 1

1

Below is an example how you can change variable, even non-global. The idea is to create closure by using GetNewClosure and put token inside another object (in my case it is hashtable):

$timer = New-Object System.Timers.Timer(1000)

$tokenObj = @{}

$sb = {
    $random = New-Object System.Random
    $tokenObj['token'] = $random.Next(100)
}.GetNewClosure()

Register-ObjectEvent -InputObject $timer -EventName 'Elapsed' -Action $sb

$timer.Start()

for ($i = 0; $i -lt 20; $i++)
{
    Write-Host "Token value: $($tokenObj['token'])"
    Start-Sleep -Milliseconds 400
}
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! For others' reference, if you set the event to a variable, $job in my example code, you'll need to use $job.Module.SessionState.PSVariable.Set() to set the local scope copy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.