PowerShell script exchange
Post Reply
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

Objective
Create a script that will automatically stagger periodic backup jobs so that they are less likely to occur at the same time by adding some randomization as to how often the backup job is supposed to run.

Blog Describing Script
Learn more about my script at https://www.jasonpearce.com/2015/03/12/ ... owershell/.

Brief Explanation
Use the Get-Random cmdlet with -Minimum and -Maximum parameters to modify these backup job parameters:

Code: Select all

$jobScheduleOptions = New-VBRJobScheduleOptions
$jobScheduleOptions.OptionsPeriodically.FullPeriod
$jobScheduleOptions.OptionsPeriodically.HourlyOffset
$jobScheduleOptions.RetryTimeout
$jobScheduleOptions.LatestRun
$jobScheduleOptions.NextRun
By somewhat randomizing those backup job schedule parameters, I'm able to have some jobs run every 600 minutes, others every 800 minutes, and most others somewhere in between. If my SLA is to backup at least once a day, I easily meet that objective and don't have to micromanage the schedule of when each job runs.

Problem
The script works well. All of the above objects receive semi-random values. Veeam even begins performing backups following my scripted NextRun schedule. Once the backup runs, Veeam then automatically modifies the next NextRun schedule, which I assume is LastRun + FullPeriod + rounded up to HourlyOffset. All good.

The problem occurs once the FullPeriod crosses over into the next day. When that happens, Veeam appears to incorrectly calculate the NextRun schedule and instead configures NextRun to occur on the HourlyOffset between midnight and 1 am (example below). This causes all of my previously randomized and staggered backup jobs to overlap and run between midnight and 1 am.

My Big Question
How do I correct this behaviour? How do I have my randomized periodic backup jobs always wait the entire FullPeriod before running again, even if the NextRun carries over into the following day?

Script: Randomizing Veeam Backups
Here's the actual script.

Code: Select all

# Randomize Veeam Backups, a Veeam PowerShell script (Version 2)
# This script will add randomness to Veeam backup jobs by configuring them to use different periodic backup intervals
# Run this on a Veeam Backup and Replication version 8 update 1 server
# You could even copy and paste it into Veeam Backup and Replication > Menu > PowerShell
# Written by Jason Pearce of www.jasonpearce.com in March 2015
# Use at your own risk, freely share, and comment on improvements

# BEGIN Random variables #####################

# RandomFullPeriod: Variable for Schedule > Run the job automatically > Periodically every XX minutes. Must be a value between 0 and 999.
# Key: 1-8 hours 1h=60min, 2h=120min, 3h=180min, 4h=240min, 5h=300min, 6h=360min, 7h=420min, 8h=480min
# Key: 9-16 hours 9h=540min, 10h=600min, 11h=660min, 12h=720min, 13h=780min, 14h=840min, 15h=900min, 16h=960min
$RandomFullPeriodMinimum = 540
$RandomFullPeriodMaximum = 960

# RandomHourlyOffset: Variable for Schedule > Run the job automatically > Periodically every > Schedule > Start time within an hour. Must be a value between 0 and 59.
$RandomHourlyOffsetMinimum = 0
$RandomHourlyOffsetMaximum = 59

# RandomRetryTimeout: Variable for Schedule > Automatic Retry > Wait before each retry attempt for. Must be a value between 0 and 59.
$RandomRetryTimeoutMinimum = 10
$RandomRetryTimeoutMaximum = 50

# END Random variables #######################

# BEGIN Other variables ######################

# BackupRetention: Variables for RetainDays (amount of restore points) and RetainCycles (amount of days for Deleted VMs retention period).
$RetainDays = 14
$RetainCycles = 14

# Get All, Some, or One backup jobs.
# You MUST uncomment and modify one of these lines to target one or more backup jobs.
# Only one line should begin with "$jobs =". These are just four helpful examples.
#By-All# $jobs = Get-VBRJob | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-PREFIX# $jobs = Get-VBRJob -Name "Test-*" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-LIST# $jobs = Get-VBRJob -Name "Test-1","Test-2" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-NAME# $jobs = Get-VBRJob -Name "Test-Job" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name

# END Other variables ########################

# BEGIN foreach loop #########################

# Make the following changes to all backup jobs
foreach ($job in $jobs) {

	# BEGIN Job Options ######################

		# Read current job settings
		$jobOptions = Get-VBRJobOptions -Job $job

		# Set more Job Advanced Storage Options 
		$jobOptions.BackupStorageOptions.RetainCycles = $RetainCycles
		$jobOptions.BackupStorageOptions.RetainDays = $RetainDays

		# Apply these additional Backup Mode settings
		$jobOptions = Set-VBRJobOptions -Job $job -Options $jobOptions

	# END Job Options ########################

	# BEGIN Job Schedule Options #############

		# Create a new job schedule 
		$jobScheduleOptions = New-VBRJobScheduleOptions

		# Enable Periodically Schedule
		$jobScheduleOptions.OptionsPeriodically.Enabled = $true

		# Configure Periodic Schedule in Minutes (0 = Hours, 1 = Minutes)
		$jobScheduleOptions.OptionsPeriodically.Kind = 1

		# Disable Other Schedules
		$jobScheduleOptions.OptionsDaily.Enabled = $false
		$jobScheduleOptions.OptionsMonthly.Enabled = $false
		$jobScheduleOptions.OptionsContinuous.Enabled = $false

		# Generate random number for FullPeriod (Minimum and Maximum variables are defined above)
		$RandomFullPeriod = Get-Random -Minimum $RandomFullPeriodMinimum -Maximum $RandomFullPeriodMaximum

		# Create a random FullPeriod offset
		$jobScheduleOptions.OptionsPeriodically.FullPeriod = $RandomFullPeriod

		# Generate random number for HourlyOffset (Minimum and Maximum variables are defined above)
		$RandomHourlyOffset = Get-Random -Minimum $RandomHourlyOffsetMinimum -Maximum $RandomHourlyOffsetMaximum

		# Create a random HourlyOffset
		$jobScheduleOptions.OptionsPeriodically.HourlyOffset = $RandomHourlyOffset

		# Generate random number for RetryTimeout (Minimum and Maximum variables are defined above)
		$RandomRetryTimeout = Get-Random -Minimum $RandomRetryTimeoutMinimum -Maximum $RandomRetryTimeoutMaximum

		# Create a random RetryTimeout
		$jobScheduleOptions.RetryTimeout = $RandomRetryTimeout
		
		# Do some math to randomly stagger LatestRun (past) and NextRun (future), while correctly calculating the FullPeriod difference
		$RandomlyStagger = Get-Random -Minimum 1 -Maximum 9
		$jobScheduleOptions.LatestRun = (Get-Date).AddMinutes(-([math]::Round($RandomFullPeriod * $RandomlyStagger * .1)))
		$jobScheduleOptions.NextRun = (Get-Date).AddMinutes([math]::Round($RandomFullPeriod * (10 - $RandomlyStagger) * .1))

		# Apply the new job schedule
		Set-VBRJobScheduleOptions -Job $job -Options $jobScheduleOptions

	# END Job Schedule Options ###############

	# Report which jobs received these changes
	Write-Host "Changed settings for" $job.Name
}
# END foreach loop ###########################
# END Randomize Veeam Backups script #########

Script: Reporting on Randomized Values
I also wrote a small script to just report on the new randomized values.

Code: Select all

# BEGIN REPORT ###############################
# Optionally Report New Job Schedule Options #
# Safe to delete this report #################

# Get all enabled backup jobs.
$jobs = Get-VBRJob -Name "*" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name

# BEGIN foreach loop #########################
foreach ($job in $jobs) {

	# Report which jobs have what schedules
	Write-Host "------------------------------------"
	Write-Host "Job Schedule settings for" $job.Name

	# Get job schedule
	$ReportJobScheduleOptions = Get-VBRJobScheduleOptions -Job $job
	
	# Report on a few values
	Write-Host "FullPer: " $ReportJobScheduleOptions.OptionsPeriodically.FullPeriod
	Write-Host "HourOff: " $ReportJobScheduleOptions.OptionsPeriodically.HourlyOffset
	Write-Host "LateRun: " $ReportJobScheduleOptions.LatestRun
	Write-Host "NextRun: " $ReportJobScheduleOptions.NextRun
	Write-Host ""

}
# END foreach loop ###########################

# Write current date and time
Get-Date

# END REPORT #################################
In the morning, the results correctly look like this:

Code: Select all

------------------------------------
Job Schedule settings for Job-1
FullPer:  838
HourOff:  41
LateRun:  3/18/2015 1:43:04 PM
NextRun:  03/19/2015 03:41:04

------------------------------------
Job Schedule settings for Job-2
FullPer:  700
HourOff:  44
LateRun:  3/18/2015 4:02:05 PM
NextRun:  03/19/2015 03:42:05

------------------------------------
Job Schedule settings for Job-3
FullPer:  796
HourOff:  24
LateRun:  3/18/2015 6:03:06 PM
NextRun:  03/19/2015 07:19:06

------------------------------------
Job Schedule settings for Job-4
FullPer:  665
HourOff:  53
LateRun:  3/18/2015 12:56:07 PM
NextRun:  03/19/2015 00:02:07

------------------------------------
Job Schedule settings for Job-5
FullPer:  860
HourOff:  48
LateRun:  3/18/2015 2:58:08 PM
NextRun:  03/19/2015 05:18:08

But by the evening, when the FullPeriod crosses over into the next day, the NextRun schedules are incorrectly calculated and instead all appear between midnight and 1 am. How do I fix this? What's wrong with my script?

Here's an example of the randomized jobs being scheduled for midnight to 1 am even though the FullPeriod should have them run sometime later.

Code: Select all

------------------------------------
Job Schedule settings for Job-1
FullPer:  572
HourOff:  7
LateRun:  3/18/2015 7:11:10 PM
NextRun:  03/19/2015 00:07:00
------------------------------------
Job Schedule settings for Job-2
FullPer:  889
HourOff:  48
LateRun:  3/18/2015 3:37:14 PM
NextRun:  03/19/2015 00:48:00
------------------------------------
Job Schedule settings for Job-3
FullPer:  911
HourOff:  43
LateRun:  3/18/2015 3:54:12 PM
NextRun:  03/19/2015 00:43:00
------------------------------------
Job Schedule settings for Job-4
FullPer:  595
HourOff:  31
LateRun:  3/18/2015 8:21:16 PM
NextRun:  03/19/2015 00:31:00
------------------------------------
Job Schedule settings for Job-5
FullPer:  926
HourOff:  19
LateRun:  3/18/2015 3:45:20 PM
NextRun:  03/19/2015 00:19:00

The above jobs should instead have the following NextRun times (e.g. LatestRun + FullPeriod + rounded to HourlyOffset).

Code: Select all

Job 1 
NextRun: 03/19/2015 04:43:10 (rounded up to 05:07 thanks to HourlyOffset)

Job 2 
NextRun: 03/19/2015 06:26:14 (rounded up to 07:48 thanks to HourlyOffset)

Job 3 
NextRun: 03/19/2015 07:05:12 (rounded up to 07:43 thanks to HourlyOffset)

Job 4 
NextRun: 03/19/2015 06:16:16 (rounded up to 06:31 thanks to HourlyOffset)

Job 5 
NextRun: 03/19/2015 07:11:20 (rounded up to 08:19 thanks to HourlyOffset)

Thank you for your help.
nefes
Veeam Software
Posts: 643
Liked: 162 times
Joined: Dec 10, 2012 8:44 am
Full Name: Nikita Efes
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by nefes »

This situation is expected. You are trying to make schedule random, while product trying to make it predictable, so there is conflict.
Previously if you schedule to run job every 3 hours with 7 minutes offset, you will never say for sure, when it will run two weeks later, since it depends on the time you edit schedule, Backup console downtime and so on.
In v8 you are sure, that every day it will start at 12:07AM, 3:07AM, 6:07AM and so on.

Could you please explain your case, why you want to start jobs at random times? Maybe we could help you to achieve your goal in some other way.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

I don't want to a) have all of the jobs attempt to run at the same time or same hour and b) don't want to micromanage the schedules trying to find the best times to create/start a job and what its periodic FullPeriod value should be.

I do want to create jobs with a policy. Something like: Backup these objects four to six times a day while paying attention to all other jobs on all other backup servers so that not too many backup jobs run at the same time.

My randomly stagger script is only random when the job is created. After creation, my expectation is for Veeam 8 to be as predictable as Veeam 7 and have Job 1 backup every 671 minutes, Job 2 backup every 423 minutes, and Job 3 backup every 580 minutes; regardless if it is a new day or not.

Ignoring my configured schedule and shifting all jobs on all servers to backup between midnight and 1 am is not a desired behavior.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

With Veeam BR version 7, the Edit Backup Job > Schedule > Run the job automatically > Periodically every XX Hours field was a plain-text input field that would accept any positive whole-number value. This worked well for us.

Veeam BR version 8 changed. The field is now a pull-down menu with a more limited set of options: 1, 2, 3, 4, 6, 8, 12, and 24 hours.

Previously with Veeam BR 7, when we created a new backup we tried to meet one of two service level agreements: 1) Tier 1 should be backed up twice a day, 2) everything else should be backed up once a day.

Creating a backup job was then rather easy.

If it was a Tier 1 backup job...
* Flip a coin
* If tails, configure the job to backup every 11 hours
* If heads, configure the job to backup every 13 hours

If it was a Tier 2+ backup job...
* Flip a coin
* If tails, configure the job to backup every 23 hours
* If heads, configure the job to backup every 25 hours

Using this simple workflow, half of our jobs would slightly shift to occur slightly less than once a day or half-day, while others would shift to occur slightly greater than once a day or half-day. The result was we did not have to micromanage when each backup job was to occur or even when we created the backup job. By slightly shifting periodic backup schedules, rarely would many jobs attempt to run at the same time.

One very importance difference with Veeam BR 7 is that periodic schedules that crossed over into the next calendar day did not reset to begin between midnight and 1 am (the way Veeam BR 8 appears to be doing).

With Veeam BR 8 you removed hours that do not evenly divide into 24. So I'm attempting to adjust by using Periodically every XXX Minutes instead, which appears to accept any positive whole number value between 1 and 1440. If I wanted backup jobs to periodically occur for a time period greater than once a day, I appears we no longer have that option using either Hours or Minutes with Veeam BR 8. We actually have that use case. With Veeam BR 7, we had some jobs that ran every 35 or 45 hours.

We can adjust to some of Veeam BR 8 new scheduling limitations. I can accommodate lowering the periodic frequency of all jobs to occur at least once every 24 hours (no more 25, 35, or 45 hour jobs). I can accommodate your desire to simplify the hourly options by accepting only 8 values instead of the full 24 values by switching to minutes instead.

What is negatively affecting our production infrastructure is the inability of Veeam BR 8 to calculate a NextRun time into the following day. With Veeam BR 8, all of our backup jobs end up running every morning at the same time between midnight and 1 am. This puts unnecessary strain on the source infrastructure.

Lastly, we are a hospital. Just about every system is in use every minute of the day. We don't have off-hours. Performing backup jobs at night is no better than performing backup jobs during the day. By forcing all of our Veeam BR 8 jobs to run a midnight is no different than if you forced all of our jobs to run at noon. End-users (doctors, nurses, clinicians) will always be somewhat affected by backup jobs at any hour of the day -- which is why we want all jobs to be staggered, so that no single hour has a high concentration of backup jobs running at the same time.

The scheduling modification changes to Veeam BR 8 appear to conflict with our objectives. I thought my script would help our situation, but it appears there might not be anything I can do to override Veeam BR 8 from wanting to run all jobs at midnight (other than manually micromanaging when we create each job by reviewing the schedule of all other backup jobs on all other servers to try to find the least-busy window to fit in a new job).

If I cannot script my objectives, I welcome other suggestions.
nefes
Veeam Software
Posts: 643
Liked: 162 times
Joined: Dec 10, 2012 8:44 am
Full Name: Nikita Efes
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by nefes »

So am I correct, that your main consideration is performance hit when several jobs are running at the same time?
What is the main problem for you: source datastore, target repository, network?
It it always recommended to set up job concurrency for performance considerations.
Say no matter if all jobs will be started at the same time, if all of them are pointed to the same repository and that repository is limited to 1 task at the time.
In that case jobs started simultaneously will work one by one, waiting each other and consuming only little resources on backup console.

You could also look into network traffic throttling, datastore latency control and similar features, or any combination of them to achieve your goal.

Also I wanted to stress out, that midnight is not taken as the time when systems aren't in use, but just as the easy-to-understand constant, where we start to measure time periods.

At last, if you still want to stick to random nature of start time, you may want to schedule your script in Windows Scheduler to modify start time of your jobs every day.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

I have many concerns and frustrations about the new Veeam 8 periodic schedule requirement that all jobs must be run between midnight and 1 am. Among them are:

* Jobs take longer to run when all of them are trying to run at the same time. The longer a job runs, the larger the vSphere snapshot grows. The larger the vSphere snapshot grows, the longer vSphere must quiesce the virtual machine when it commits the snapshot. The longer a virtual machine is quiesced, the greater chance that end-user applications experience a disruption in performance.

* Windows 2012 R2 deduplication for the backup repositories. It does better when data is written gradually over a longer period of time instead of in large chunks all at once. When its written all at once, we have an increased risk that the backup repository will run out of space because Windows 2012 R2 decuplication did not have enough time to deduplicate the volume due to the large and sudden increase in newly written data

I'm out of time and will have to return to write more.
tsightler
VP, Product Management
Posts: 6011
Liked: 2843 times
Joined: Jun 05, 2009 12:57 pm
Full Name: Tom Sightler
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by tsightler »

Perhaps I'm oversimplifying the issue here (I've tried to read through this and understand it all but it's a lot of text and I might have interpreted something incorrectly), however, it sounds like the basic problem is that even if you schedule a job to run every 621 minutes, it doesn't really do this. If this 621 minutes crosses a day boundary it will basically schedule the job to run between 12-1AM, and then run every 621 minutes from that point. I don't see how this isn't a bug if that's the case.

I mean, sure, when using the periodically every hour you can set a specific minute and be predictable and, while that's a change, it can be worked around by doing periodically every X minutes like mentioned. But it sounds like there's some kind of bug where this doesn't work correctly when the time period crosses the midnight boundary. If I say that a job should run every 621 minutes it should run every 621 minutes regardless of whether it crosses midnight or not.

I'll try to reproduce this over the weekend in my lab if my understanding is correct.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

I have received an official answer from Veeam Support. I also eventually found an answer in their documentation.

Answer:
http://helpcenter.veeam.com/backup/80/v ... b=periodic
"Veeam Backup and Replication always start counting defined intervals from 12:00 AM. For example, if you configure to run a job with a 4-hour interval, the job will start at 12:00 AM, 4:00 AM, 8:00 AM, 12:00 PM, 4:00 PM and so on."
Loss of Functionality:
This is an unwanted change from Version 7 to Version 8. According to Veeam Support, this change is hard coded and does not come with a GUI or PowerShell means of enabling or disabling.

In previous versions, Veeam BR 7 would not reset the clock when a new day began. If we wanted to job to run every 9 hours and created the job at 9:30 am on a Monday, the job would run at the following times:
* Mon at 10:00
* Mon at 19:00
* Tue at 04:00
* Tue at 13:00
* Tue at 22:00
* Wed at 07:00
* Wed at 04:00

But with Veeam BR 8, this same job would run every 9 hours until entering the next day; immediately run a backup to begin the day, and then nine hours later until the next day occurred:
* Mon at 10:00
* Mon at 19:00
* Tue at 00:00
* Tue at 9:00
* Tue at 18:00
* Wed at 00:00
* Wed at 09:00
* Wed at 18:00

This causes all of our backup jobs (all but one are using the periodic schedule) to attempt to run at midnight.

While we do have limits in place on the quantity of maximum concurrent tasks that could be run against the repository, we never hit those limits with Veeam 7 (because our jobs were nicely staggered throughout the day). But with Veeam 8, we hit those limits every day and generate backup job errors every day.

I'm frustrated by this new Veeam BR 8 feature and that there isn't a way to opt in or opt out. There should be a check box that says "Reset periodic schedules at the beginning of each day" and a PowerShell value to set as either $true or $false.

Version 8 Scheduling Limitations
The Veeam BR 8 scheduling change is much more limiting that what Veeam BR 7 offered. With Veeam BR 8, there's no easy way to create the following schedules:

Discontinued: Schedule a Job to Run every 5, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, or 23 hours
If you want to schedule a job to run every X hours, the only valid options are now values that can evenly divide into 24 (e.g. 1, 2, 3, 4, 6, 8, 12, and 24). The only option is to switch to minutes and calculate the desired value.

Discontinued: Schedule a Job to Run every 32, 64, 96 hours
If you want to schedule a job to run every 1.5 days or 3 days (or any value greater than a day), there is no option. You may not enter a value in hours or minutes that exceeds either 24 or 1440.

Why would one want these unusual schedules?
I have several reasons.

Hospital: For starters, I work for a hospital. There's never a good time to perform backups, so we just perform them all the time (day or night). I'd never schedule all backups to occur on the same hour due to normal resource constraints. But with Version 8, every job now runs at midnight.

Job Duration: While we don't care when an individual job runs, we do care how long it takes for it to run. Jobs that take the least amount of time to run have the smaller vSphere snapshots and thus are less noticeable to end users. When all jobs attempt to run at the same time, they take longer to complete and cause more noticeable performance disruptions.

Windows Deduplication: Our backup repositories are on Windows 2012 R2 servers with volume deduplication enabled (to dedupe accross jobs). If jobs are evenly staggered, writes to the backup repositories are written throughout the day, giving Windows Deduplication to time to free up some capacity. When jobs run all at once, we have an increased risk that the repository will fill before deduplication and do its job.

Convenience: We have multiple Veeam backup servers and repositories, each running a portion of our backup jobs. Micromanaging when jobs are scheduled to run is cumbersome as we attempt to find windows that have the lowest quantity of other jobs occurring. My randomization script makes this much easier for the team, as some jobs will run more frequently than others. Random Chance does an excellent job of spacing out our backup jobs so that only a few occur at the same time, even across several servers.

Highly Available Applications: Microsoft Clusters, Exchange Database Availability Groups, and many other systems often have two or more redundant servers for high availability. Customers might prefer backing up the pairs using different and somewhat random schedules.

Very Low Priority Jobs: We have some servers that rarely change, and are mostly read-only. There's no need to back them up every day. Backing them up every three days better suits their rate of change.

Setting Limits: We want some job concurrency, just not all jobs at the same time. Setting a repository to limit only one task at a time would prevent us from backing up an application server and database server at the same time (having a restore point that is about the same time). I'm

Closing
Those are a most of my reasons. Having the ability to stagger when periodic backups occur so that jobs rarely overlap was a feature of Veeam BR 7 that we leveraged, but lost with Veeam BR 8.
tsightler
VP, Product Management
Posts: 6011
Liked: 2843 times
Joined: Jun 05, 2009 12:57 pm
Full Name: Tom Sightler
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by tsightler »

I agree that this seems like a pretty big restriction, I'm amazed I haven't run across it in the field already. I mean, I know I have customers running backups every 4 hours. Now suddenly they'll lose 3/4 of their scheduling window. I'm also surprised that this applies to jobs scheduled with an interval measured in minutes as I wouldn't expect that to be limited by any hourly rules.

I am wondering if there might be a workaround. Perhaps you could do something with a post-job script that takes a parameter (number of minutes) and manually updates the start time of the job to a specific time.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

Since the new Veeam 8 scheduler has reduced functionality and now incorrectly calculates the Next Run time (by design) when beginning a new day, I've written the following script to prevent several hundred backups from running between midnight and 1 am. I then created a Windows Task Scheduler to run this script at 23:55 and 00:05 each day. Hopefully, my script will correctly calculate the Next Run and prevent all backup jobs from running at the same time.

Code: Select all

# Fix Veeam Backups Next Run, a Veeam PowerShell script (Version 1)
# This script will properly set the Next Run schedule when entering a new day so that all jobs don't run between midnight and 1 am
# A Windows Task Scheduler must be configured to run this script on each Veeam Backup Repository server -- running at 11:55 pm each evening
# Run this on a Veeam Backup and Replication version 8 update 1 server
# You could even copy and paste it into Veeam Backup and Replication > Menu > PowerShell
# Written by Jason Pearce of www.jasonpearce.com in March 2015
# Use at your own risk, freely share, and comment on improvements

# BEGIN Script ###############################

# Enable Veeam PowerShell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

# BEGIN variables ############################

# Get All, Some, or One backup jobs.
# You MUST uncomment and modify one of these lines to target one or more backup jobs.
# Only one line should begin with "$jobs =". These are just four helpful examples.
#By-All# $jobs = Get-VBRJob | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-PREFIX# $jobs = Get-VBRJob -Name "Test-*" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-LIST# $jobs = Get-VBRJob -Name "Test-1","Test-2" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name
#By-NAME# $jobs = Get-VBRJob -Name "Test-Job" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name

# END variables ##############################

# BEGIN foreach loop #########################

# Make the following changes to all backup jobs
foreach ($job in $jobs) {

	# BEGIN Job Schedule Options #############

		# Get Current Job Schedule Options
		$currentJobScheduleOptions = Get-VBRJobScheduleOptions -Job $job
		
		# Create a new job schedule 
		$newJobScheduleOptions = New-VBRJobScheduleOptions

		# Enable Periodically Schedule
		$newJobScheduleOptions.OptionsPeriodically.Enabled = $currentJobScheduleOptions.OptionsPeriodically.Enabled

		# Get Current Periodic Schedule Kind (0 = Hours, 1 = Minutes)
		$newJobScheduleOptions.OptionsPeriodically.Kind = $currentJobScheduleOptions.OptionsPeriodically.Kind

		# Get Current Other Schedules
		$newJobScheduleOptions.OptionsDaily.Enabled = $currentJobScheduleOptions.OptionsDaily.Enabled
		$newJobScheduleOptions.OptionsMonthly.Enabled = $currentJobScheduleOptions.OptionsMonthly.Enabled
		$newJobScheduleOptions.OptionsContinuous.Enabled = $currentJobScheduleOptions.OptionsContinuous.Enabled

		# Get Current FullPeriod offset
		$newJobScheduleOptions.OptionsPeriodically.FullPeriod = $currentJobScheduleOptions.OptionsPeriodically.FullPeriod

		# Get Current HourlyOffset
		$newJobScheduleOptions.OptionsPeriodically.HourlyOffset = $currentJobScheduleOptions.OptionsPeriodically.HourlyOffset

		# Get Current RetryTimeout
		$newJobScheduleOptions.RetryTimeout = $currentJobScheduleOptions.RetryTimeout
		
		# Do some math to calculate the desired NextRun value by adding FullPeriod to LastRun
		$newJobScheduleOptions.LatestRun = $currentJobScheduleOptions.LatestRun
		$newJobScheduleOptions.NextRun = ($currentJobScheduleOptions.LatestRun).AddMinutes($currentJobScheduleOptions.OptionsPeriodically.FullPeriod)

		# Apply the new job schedule
		Set-VBRJobScheduleOptions -Job $job -Options $newJobScheduleOptions

	# END Job Schedule Options ###############

	# Report which jobs received these changes
	Write-Host "Changed settings for" $job.Name
}
# END foreach loop ###########################
# END script #################################
Here's how I create a Schedule Task, which is done on each Veeam BR 8 Repository Server.

* Copy script to C:\Scripts\fix-veeam-backup-nextrun-for-new-days-by-jason-pearce.ps1
* Windows Task Scheduler > Create Task
* General > Name > Veeam Fix Next Run
* General > Description: With Veeam 8, all periodic backups run at midnight. This script changes the Next Run date/time so that it is not reset at midnight and will continue into the next day.
* General > Use the following user account > I use my Veeam Service Account, which has local admin rights
* General > Run with highest privileges
* Triggers > New
* Triggers > Begin the task > On a schedule
* Triggers > Start > Daily at 11:55 pm
* Triggers > Repeat task every 10 minutes for a duration of 15 minutes
* Triggers > Enabled
* Actions > New
* Actions > Action > Start a program
* Actions > Program > PowerShell
* Actions > Add arguments > C:\Scripts\fix-veeam-backup-nextrun-for-new-days-by-jason-pearce.ps1
* Conditions/Settings/History no change, use defaults

You may manually run the task to test (right-click on schedule > run). You know it ran correctly if you watch Veeam Backup and Replication > Jobs > Next Run column. My script does not round up/down the seconds. If the script ran, your Next Run times should have something other than :00 for seconds.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce »

I wrote more about how to fix the Veeam BR 8 periodic scheduler via Veeam PowerShell so that it runs on a more predictable schedule (instead of resetting at midnight each day). You'll find my script in the "Fixing Veeam Backup v8 Periodic Scheduling" article at https://www.jasonpearce.com/2015/03/23/ ... cheduling/. I hope it will be helpful.
jasonpearce
Influencer
Posts: 23
Liked: 5 times
Joined: Mar 11, 2015 2:31 pm
Full Name: Jason Pearce
Contact:

Re: Randomly Stagger Periodic Backup Jobs

Post by jasonpearce » 1 person likes this post

After upgrading to Veeam Backup and Replication 9, I decided to re-write my PowerShell scripts that randomly stagger the periodic schedules of one or more Veeam backup jobs.

More info: https://www.jasonpearce.com/2016/10/02/ ... schedules/

Code: Select all

# This script will randomly stagger Veeam 9 backup schedules for one or more jobs 
# Only schedule-related settings are modified. The script does not enable or disable job options.
# Run this on a Veeam Backup and Replication version 9 server
# You could even copy and paste it into Veeam Backup and Replication > Menu > PowerShell
# Written by Jason Pearce of www.jasonpearce.com in September 2016
# Use at your own risk, freely share, and comment on improvements

##############################################
# ENABLE Veeam PowerShell Snap-In ############
##############################################

# Add Veeam snap-in if required
if ((Get-PSSnapin -Name VeeamPSSnapin -ErrorAction SilentlyContinue) -eq $null) {add-pssnapin VeeamPSSnapin}


##############################################
# DEFINE User Preferences ####################
##############################################

# Target: Using the names of backup jobs (wildcards, prefix, suffix), define which jobs this script should target
#$Jobs = Get-VBRJob -Name "ExampleJob" #(one specific job)
#$Jobs = Get-VBRJob -Name "Prefix-*" #(one or more jobs)
#$Jobs = Get-VBRJob -Name "*-Suffix" #(one or more jobs)
$Jobs = Get-VBRJob -Name "TestJob"
#$Jobs = Get-VBRJob -Name "*" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name #(all enabled backup jobs)
#$Jobs = Get-VBRJob -Name "*-by-folder" | Where-Object { $_.IsBackup -eq $true -and $_.IsScheduleEnabled -eq $true } | Sort Name

# Frequency: How many times per day should each job run? (e.g. minum frequency of backups)
$BackupFrequencyPerDay = 4

# Retention: How many days of restore points should be retained? (e.g. the oldest restore point). Leave black if you do not want it modified.
$BackupRetentionInDays = 7

# --------------------------------------------
# Decide what to Randomize (set $True or $False). 
# The script will randomize each schedule, but does not Enable or Disable the backup job option.
# --------------------------------------------

# Randomize Synthetic Full Backups Periodically schedule?
$RandomizeSyntheticFull = $True

# Randomize Active Full Backup schedule (both Monthly On and Weekly On)?
$RandomizeActiveFull = $True

# Randomize Storage-Level Corruption Guard schedule (both Monthly On and Weekly On)?
$RandomizeStorageLevelCorruptionGard = $True

# Randomize Full Backup File Maintenance schedule (both Monthly On and Weekly On)?
$RandomizeFullBackupFileMaintenance = $True

# Randomize Periodically Every X Minutes schedule? (this is the main purpose of the script)
$RandomizePeriodicallyEvery = $True

# Randomize Time Periods schedule? (this adds a random Denied offset to each day to prevent all Periodic jobs from running at midnight)
$RandomizeTimePeriods = $True

# Randomize Start Time Within An Hour schedule? (instead of starting at :00, jobs will stagger start at :09, :17, :41, etc. minutes after the hour)
$RandomizeStartTimeWithinHour = $True

# Randomize Automatic Retry Wait in minutes (wait before each retry attempt for X minutes)
$RandomizeAutomaticRetryWait = $True

##############################################
# CALCULATE User Preferences #################
##############################################

# Frequency Quantity Calculation: Create a range of how many times per day each job should run (e.g. +-0.9)
$MinNumBackupsPerDay = $BackupFrequencyPerDay - 0.9
$MaxNumBackupsPerDay = $BackupFrequencyPerDay + 0.9

# Frequency Minutes Calculation: Converting the quantity range into minutes (e.g. backup every 200 to 300 minutes)
$MinutesInADay = 1440
$MinBackupRangeInMinutes = [math]::Round($MinutesInADay/$MaxNumBackupsPerDay)
$MaxBackupRangeInMinutes = [math]::Round($MinutesInADay/$MinNumBackupsPerDay)

# Retention Calculation: Should be ($BackupFrequencyPerDay x $BackupRetentioninDays)
# GUI > Edit Backup Job > Storage > Retention Policy > Restore points to keep on disk
$RetainCycles = $BackupFrequencyPerDay * $BackupRetentioninDays


##############################################
# BEGIN Script ###############################
##############################################


##############################################
# BEGIN Random variables                     #
##############################################

# RandomFullPeriod: Variable for Schedule > Run the job automatically > Periodically every XX minutes. Must be a value between 0 and 1440.
$RandomFullPeriodMinimum = $MinBackupRangeInMinutes
$RandomFullPeriodMaximum = $MaxBackupRangeInMinutes

# RandomHourlyOffset: Variable for Schedule > Run the job automatically > Periodically every > Schedule > Start time within an hour. Must be a value between 0 and 59.
$RandomHourlyOffsetMinimum = 0
$RandomHourlyOffsetMaximum = 59

# RandomRetryTimeout: Variable for Schedule > Automatic Retry > Wait before each retry attempt for. Must be a value between 0 and 59.
$RandomRetryTimeoutMinimum = 30
$RandomRetryTimeoutMaximum = 59

# RandomMidnightDelay: Variable to prevent all periodic backup jobs from running at midnight (Schedule Denied).
$RandomMidnightDelay0Hours = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay1Hours = "1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay2Hours = "1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay3Hours = "1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay4Hours = "1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay5Hours = "1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
$RandomMidnightDelay6Hours = "1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"

# RandomPermitDeny: Default schedule settings for documentation purposes.
#$RandomPermitDenyDefault = "<scheduler><Sunday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Sunday><Monday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Monday><Tuesday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Tuesday><Wednesday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Wednesday><Thursday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Thursday><Friday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Friday><Saturday>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</Saturday></scheduler>"

# Every Day Number in the Month
$EveryDayNumberInMonth = "First","Second","Third","Fourth","Last"

# Every Day of the Week
$EveryDayOfWeek = "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"

# Every Month of the Year
$EveryMonthOfYear = "January","February","March","April","May","June","July","August","September","October","November","December"

# Random Day Number in the Month (mostly here for copy/paste reference in the foreach loop, because we'll want uniquely random results each time)
$RandomDayNumberInMonth = Get-Random -Input "First","Second","Third","Fourth","Last"

# Random Day of the Week (mostly here for copy/paste reference in the foreach loop, because we'll want uniquely random results each time)
$RandomDayOfWeek = Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"

# Random Month of the Year (mostly here for copy/paste reference in the foreach loop, because we'll want uniquely random results each time)
$RandomMonthOfYear = Get-Random -Input "January","February","March","April","May","June","July","August","September","October","November","December"

# Script Name
$scriptName = "RandomizeBackupJobSchedules"

# Start Time
$starttime = Get-Date -uformat "%m-%d-%Y %I:%M:%S"

# Report Header
Clear-Host
Write-Host "********************************************************************************"
Write-Host "$scriptName`t`tStart Time:`t$starttime"
Write-Host "********************************************************************************`n"
 

##############################################
# BEGIN foreach loop                         #
##############################################

# Make the following changes to all backup jobs
foreach ($job in $jobs) {

# Notice: State which job is being updated
Write-Host "Setting job options on "$job.Name -ForegroundColor Yellow

#--------------------------------------------------------------------
# Retention Policy
if ($BackupRetentionInDays -ne $null) {

# BEGIN Job Options ######################

# Read current job settings
$jobOptions = Get-VBRJobOptions -Job $job

# Set Job Advanced Backup Storage Options 
$jobOptions.BackupStorageOptions.RetainCycles = $RetainCycles

# Apply these additional Backup Mode settings
$jobOptions = Set-VBRJobOptions -Job $job -Options $jobOptions

}

#--------------------------------------------------------------------
# Randomize Synthetic Full Backups Periodically
if ($RandomizeSyntheticFull -eq $True) {

# Set-VBRJobAdvancedBackupOptions: Customizes advanced job backup settings.
Set-VBRJobAdvancedBackupOptions -Job $job -TransformToSyntethicDays (Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday") | Out-Null

}

#--------------------------------------------------------------------
# Randomize Active Full Backup
if ($RandomizeActiveFull -eq $True) {

# Set-VBRJobAdvancedBackupOptions: Customizes advanced job backup settings.
Set-VBRJobAdvancedBackupOptions -Job $job -FullBackupDays (Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday") -Months $EveryMonthOfYear -DayNumberInMonth (Get-Random -Input "First","Second","Third","Fourth","Last") -DayOfWeek (Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday") | Out-Null

}

#--------------------------------------------------------------------
# Randomize Storage-Level Corruption Guard
if ($RandomizeStorageLevelCorruptionGard -eq $True) {

# Set-VBRJobOptions: Applies custom job settings. Acts like a catch all for settings not in other Veeam 9 PowerShell Cmdlets.

# Get current job settings
$jobOptions = Get-VBRJobOptions $job

# Define new randomized job settings
$jobOptions.GenerationPolicy.RecheckDays = Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
$jobOptions.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayNumberInMonth = Get-Random -Input "First","Second","Third","Fourth","Last"
$jobOptions.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayOfWeek = Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
$jobOptions.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.Months = $EveryMonthOfYear

# Apply these additional Backup Mode settings
Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null

}

#--------------------------------------------------------------------
# Randomize Full Backup File Maintenance
if ($RandomizeFullBackupFileMaintenance -eq $True) {

# Set-VBRJobOptions: Applies custom job settings. Acts like a catch all for settings not in other Veeam 9 PowerShell Cmdlets.

# Get current job settings
$jobOptions = Get-VBRJobOptions $job

# Define new randomized job settings
$jobOptions.GenerationPolicy.CompactFullBackupDays = Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
$jobOptions.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayNumberInMonth = Get-Random -Input "First","Second","Third","Fourth","Last"
$jobOptions.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayOfWeek = Get-Random -Input "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
$jobOptions.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.Months = $EveryMonthOfYear

# Apply these additional Backup Mode settings
Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null

}

#--------------------------------------------------------------------
# Randomize Periodically Every X Minutes
if ($RandomizePeriodicallyEvery -eq $True) {

# Create a new job schedule
$jobScheduleOptions = Get-VBRJobScheduleOptions -Job $job

# Disable Other Schedules
$jobScheduleOptions.OptionsDaily.Enabled = $false
$jobScheduleOptions.OptionsMonthly.Enabled = $false
$jobScheduleOptions.OptionsContinuous.Enabled = $false

# Enable Periodically Schedule
$jobScheduleOptions.OptionsPeriodically.Enabled = $true

# Configure Periodic Schedule in Minutes (0 = Hours, 1 = Minutes)
$jobScheduleOptions.OptionsPeriodically.Kind = 1

# Generate random number for FullPeriod (Minimum and Maximum variables are defined above)
$RandomFullPeriod = Get-Random -Minimum $RandomFullPeriodMinimum -Maximum $RandomFullPeriodMaximum

# Create a random FullPeriod offset
$jobScheduleOptions.OptionsPeriodically.FullPeriod = $RandomFullPeriod

# Do some math to randomly stagger the NextRun (future), while correctly calculating the FullPeriod difference
$RandomlyStagger= Get-Random -Minimum 1 -Maximum $RandomFullPeriod
$jobScheduleOptions.NextRun= ($jobScheduleOptions.LatestRunLocal).AddMinutes($RandomlyStagger)

# Apply the new job schedule
Set-VBRJobScheduleOptions -Job $job -Options $jobScheduleOptions | Out-Null

}

#--------------------------------------------------------------------
# Randomize Time Periods schedule (e.g. midnight "run all jobs" avoidance)
if ($RandomizeTimePeriods -eq $True) {

# Create a new job schedule
$jobScheduleOptions = Get-VBRJobScheduleOptions -Job $job

# Generate random Midnight Delay (Schedule Denied) for each day. Variables up to $RandomMidnightDelay6Hours are already created above.
$RandomMidnightDelaySun = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelayMon = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelayTue = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelayWed = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelayThu = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelayFri = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours
$RandomMidnightDelaySat = Get-Random $RandomMidnightDelay0Hours,$RandomMidnightDelay1Hours,$RandomMidnightDelay2Hours,$RandomMidnightDelay3Hours,$RandomMidnightDelay4Hours

# Create a random Midnight Delay (Schedule Denied) for the full week
$RandomMidnightDelay = "<scheduler><Sunday>" + $RandomMidnightDelaySun + "</Sunday><Monday>" + $RandomMidnightDelayMon + "</Monday><Tuesday>" + $RandomMidnightDelayTue + "</Tuesday><Wednesday>" + $RandomMidnightDelayWed + "</Wednesday><Thursday>" + $RandomMidnightDelayThu + "</Thursday><Friday>" + $RandomMidnightDelayFri + "</Friday><Saturday>" + $RandomMidnightDelaySat + "</Saturday></scheduler>"

# Apply the random Midnight Delay (Schedule Denied)
$jobScheduleOptions.OptionsPeriodically.Schedule = $RandomMidnightDelay

# Apply the new job schedule
Set-VBRJobScheduleOptions -Job $job -Options $jobScheduleOptions | Out-Null

}

#--------------------------------------------------------------------
# Randomize Start Time Within An Hour schedule
if ($RandomizeStartTimeWithinHour -eq $True) {

# Create a new job schedule
$jobScheduleOptions = Get-VBRJobScheduleOptions -Job $job

# Generate random number for HourlyOffset (Minimum and Maximum variables are defined above)
$RandomHourlyOffset = Get-Random -Minimum $RandomHourlyOffsetMinimum -Maximum $RandomHourlyOffsetMaximum

# Create a random HourlyOffset
$jobScheduleOptions.OptionsPeriodically.HourlyOffset = $RandomHourlyOffset

# Apply the new job schedule
Set-VBRJobScheduleOptions -Job $job -Options $jobScheduleOptions | Out-Null

}

#--------------------------------------------------------------------
# Randomize Automatic Retry Wait in minutes
if ($RandomizeAutomaticRetryWait -eq $True) {

# Create a new job schedule
$jobScheduleOptions = Get-VBRJobScheduleOptions -Job $job

# Generate random number for RetryTimeout (Minimum and Maximum variables are defined above)
$RandomRetryTimeout = Get-Random -Minimum $RandomRetryTimeoutMinimum -Maximum $RandomRetryTimeoutMaximum

# Create a random RetryTimeout
$jobScheduleOptions.RetryTimeout = $RandomRetryTimeout

# Apply the new job schedule
Set-VBRJobScheduleOptions -Job $job -Options $jobScheduleOptions | Out-Null

}

# Report which jobs received these changes
Write-Host "Changed settings for" $job.Name

}
# END foreach loop ###########################
# END Backup Settings Script #################

 
#--------------------------------------------------------------------
# Outputs
 
Write-Host "`nProcessing Complete" -ForegroundColor Yellow
 
 
$finishtime = Get-Date -uformat "%m-%d-%Y %I:%M:%S"
Write-Host "`n`n"
Write-Host "********************************************************************************"
Write-Host "$scriptName`t`tFinish Time:`t$finishtime"
Write-Host "********************************************************************************"
 
# Prompt to exit script - This leaves PS window open when run via right-click
Write-Host "`n`n"
Write-Host "Press any key to continue ..." -foregroundcolor Gray
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Post Reply

Who is online

Users browsing this forum: No registered users and 18 guests