Here is a work-around solution I put in place to delay a script/function to run (this could probably be improved, but I thought I would toss it out there).
There are two (possibly more) scenarios where this could be needed:
1) Hybrid AD/AAD where you make an adjustment to an attribute, need to wait for the AAD Connect sync to occur before running the next step.
2) Are re-homing Azure geolocation data, and may need to wait for MS before proceeding to the next step.
To overcome this I did the following:
- Created a virtual attribute (edsva-delayedFunction)
- When needing to run a delayed script/function I populate edsva-delayed function with <time to run>;<complete function from library scripts>;<admin email that submitted the request>
- 10/07/20 08:00:00;move-mailbox <user>;admin@acme.com
- I then have a scheduled workflow (every 15 minutes) that fires a script that will:
- Lookup users with edsva-delayedFunction
- See if the time is later than the current time of the script run
- Run the function section of the line
- Email the admin listed that the script has run (still to build out)
- Remove the entry from edsva-delayedFunction
I had to use a scheduled workflow over the scheduled task so I could load all my function libraries required. Below are two functions you could use to perform this. These scripts will allow for multiple delayedFunctions to be listed for a user, and that entry is removed as it is run. If someone has better ideas to delay "next steps" please let me know:
#### Function to Populate edvsa-delayedFunction #### function ars-addDelayedFunction { param ( $objUPN, $function, $delay, $adminEmail ) $arsServer = "<ars.acme.com>" $timeZoneID = "Atlantic Standard Time" #use the time zone of the server that will be running the scripts $timeZoneOffset = (get-timezone -Name $timeZoneID).baseUtcOffset.hours $now = ((get-date).ToUniversalTime()).AddHours($timeZoneOffset) if (!$delay) {$delay = "45"} <# ## Connect to ARS Server (used if testing off the ARS server) if ($ARS.ManagedDomains.Capacity -ne "EDMS://$arsServer/DC=ACME,DC=com") { $script:ARS = Connect-QADService -Service $arsServer -Proxy } #> $sched = $now.AddMinutes($delay).ToString("MM/dd/yyyy HH:mm") [string]$attrib = $sched + ";" + $Func + ";" + $adminEmail $objUser = Get-QADUser $objUPN -IncludedProperties "edsva-DelayedFunction" $objUserAttrib = $objUser."edsva-DelayedFunction" if ($objUserAttrib) { $objUserAttrib = $objUserAttrib + "|" + $attrib } else { $objUserAttrib = $attrib } set-qaduser $objUPN -ObjectAttributes @{"edsva-DelayedFunction" = $objUserAttrib} | Out-Null } #### Scheduled Script to run from Workflow #### function onInit($Context) { $Context.UseLibraryScript("Function Library1") $Context.UseLibraryScript("Function Library2") } function ars-delayedScripts($Request) { ## Get Users with edsva-functionsToRun attribute set $objUsers = Get-QADUser -IncludedProperties edsva-DelayedFunction -SizeLimit 0 -LdapFilter '(edsva-DelayedFunction=*)' ## Process Users foreach ($objUser in $objUsers) { Write-Host "Processing: $($objUser.DisplayName)" [System.Collections.ArrayList]$functionsToRemove = @() if ($objUser.'edsva-DelayedFunction' -like "*|*") { [System.Collections.ArrayList]$functionList = ($objUser.'edsva-DelayedFunction').split("|") | Sort-Object } else { $functionList = ($objUser.'edsva-DelayedFunction') } $functionsToRun = $functionList foreach ($functionToRun in $functionsToRun) { Write-Host "" Write-Host "Checking: $functionToRun" $now = Get-Date [datetime]$runtime = $functionToRun.Split(";")[0] [string]$toRun = $functionToRun.Split(";")[1] if ($now -gt $runtime) { Write-Host "Running: $toRun" Write-Host "Removing: $functionToRun" $sb = [scriptblock]::Create($toRun) &$sb $functionsToRemove.Add($functionToRun) } } if ($functionsToRemove.count -ge 1) { if (($functionsToRemove.Count -eq 1) -and ($functionList.count -eq 1)) { [string]$newobjUserAttrib = $null } else { $functionsToRemove | ForEach-Object { $functionList.Remove($_) } if ($functionList.Count -gt 1) { [string]$newobjUserAttrib = $functionList -join "|" } else { [string]$newobjUserAttrib = $functionList } } $objUser | set-qaduser -ObjectAttributes @{"edsva-DelayedFunction" = $newobjUserAttrib} | Out-Null } } }