i would like create a Generate-SummaryReports-CalculateAtIntervals toggle button which it is a background job that can be like a switch that can be turn on and off which allow the Generate-SummaryReports-CalculateAtIntervals be run like an background app but it still can allow user to do choose function .But currently the issue im facing is no matter how i trigger the Function Toggle-ReportGeneration it just wont trigger Generate-SummaryReports-CalculateAtIntervals to run , but it will show "Report generation is now turned ON.1" and "Report generation is now turned ON.3". Is there any way i can fix it or solve the issue
Function Toggle-ReportGeneration
$global:reportGenerationEnabled = $false
$global:reportJob = $null
# Function to toggle report generation on or off
Function Toggle-ReportGeneration {
# Invert the current state of reportGenerationEnabled
$global:reportGenerationEnabled = -not $global:reportGenerationEnabled
if ($global:reportGenerationEnabled) {
if ($global:reportJob -eq $null -or $global:reportJob.State -eq 'Completed') {
Write-Host "Report generation is now turned ON.1"
# If report generation is turned on, start the background job
$global:reportJob = Start-Job -ScriptBlock {
# Call the function directly within the background job
param($baselineFilePath)
while ($global:reportGenerationEnabled) {
Generate-SummaryReports-CalculateAtIntervals -baselineFilePath $baselineFilePath
Write-Host "Report generation is now turned ON.2"
Start-Sleep -Seconds 1 # Add a delay to prevent the loop from running too quickly
}
} -ArgumentList $global:baselineFilePath
# Display the message outside the background job's script block
Write-Host "Report generation is now turned ON.3"
} else {
Write-Host "Report generation is already running."
}
} else {
Write-Host "Report generation is now turned OFF."
# If report generation is turned off, stop the background job
if ($global:reportJob -ne $null) {
$global:reportJob | Stop-Job -PassThru | Remove-Job
$global:reportJob = $null
}
}
}
Generate-SummaryReports-CalculateAtIntervals
Function Generate-SummaryReports-CalculateAtIntervals {
param (
[string]$baselineFilePath,
[int]$lowSensitivityInterval = 15, # Time interval for low sensitivity in seconds
[int]$mediumSensitivityInterval = 10, # Time interval for medium sensitivity in seconds
[int]$highSensitivityInterval = 5 # Time interval for high sensitivity in seconds
)
Write-Host "Inside Generate-SummaryReports-CalculateAtIntervals function"
# Define start time
$startTime = Get-Date
Write-host "1"
# Infinite loop for continuous background job
while ($true) {
$currentTime = Get-Date
# Calculate elapsed time since start
$elapsedTime = $currentTime - $startTime
# Calculate the number of intervals completed for each sensitivity level
$lowIntervalsCompleted = [math]::Floor($elapsedTime.TotalSeconds / $lowSensitivityInterval)
$mediumIntervalsCompleted = [math]::Floor($elapsedTime.TotalSeconds / $mediumSensitivityInterval)
$highIntervalsCompleted = [math]::Floor($elapsedTime.TotalSeconds / $highSensitivityInterval)
# Calculate the next scheduled time for each sensitivity level
$nextLowReportTime = $startTime.AddSeconds(($lowIntervalsCompleted + 1) * $lowSensitivityInterval)
$nextMediumReportTime = $startTime.AddSeconds(($mediumIntervalsCompleted + 1) * $mediumSensitivityInterval)
$nextHighReportTime = $startTime.AddSeconds(($highIntervalsCompleted + 1) * $highSensitivityInterval)
# Find the next earliest report time
$nextReportTime = $nextLowReportTime
if ($nextMediumReportTime -lt $nextReportTime) {
$nextReportTime = $nextMediumReportTime
}
if ($nextHighReportTime -lt $nextReportTime) {
$nextReportTime = $nextHighReportTime
}
# Wait until the next report time for the earliest sensitivity level
$waitTime = $nextReportTime - $currentTime
if ($waitTime.TotalMilliseconds -gt 0) {
Start-Sleep -Milliseconds $waitTime.TotalMilliseconds
}
# Generate summary report for the sensitivity level that has reached its interval
if ($nextReportTime -eq $nextLowReportTime) {
# Log the start of the report generation
Write-Output "Generating Low sensitivity summary report at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
Generate-SummaryReport-AtIntervals -baselineFilePath $baselineFilePath -sensitivity "Low"
# Log the completion of the report generation
Write-Output "Low sensitivity summary report generation complete at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
}
if ($nextReportTime -eq $nextMediumReportTime) {
# Log the start of the report generation
Write-Output "Generating Medium sensitivity summary report at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
Generate-SummaryReport-AtIntervals -baselineFilePath $baselineFilePath -sensitivity "Medium"
# Log the completion of the report generation
Write-Output "Medium sensitivity summary report generation complete at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
}
if ($nextReportTime -eq $nextHighReportTime) {
# Log the start of the report generation
Write-Output "Generating High sensitivity summary report at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
Generate-SummaryReport-AtIntervals -baselineFilePath $baselineFilePath -sensitivity "High"
# Log the completion of the report generation
Write-Output "High sensitivity summary report generation complete at $(Get-Date)" | Out-File -Append -FilePath "summary_reports.log"
}
}
}
The main issue with your code is the use of
Start-Job, jobs are out of process so, it wouldn't be possible to see the$global:reportGenerationEnabledbeing updated to stop thatwhileloop. The next issue is that the job would never know whatGenerate-SummaryReports-CalculateAtIntervalsorGenerate-SummaryReport-AtIntervalsare because of what is mentioned before. You can use arunspaceto accomplish this task as these run in the same process in a different thread, however your code will require many modifications. I'll share a minimal example of how your code can work excluding the functionally of the functions mentioned before.Both functions must be passed to the runspace scope one way or the other, there are many different ways to do this, the above adds the functions to the runspace via its initial session state, you could however for simplicity, define them inside the script itself (inside
.AddScript).