internal/Register-DbaMaintenanceTask.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
function Register-DbaMaintenanceTask {
    <#
  .SYNOPSIS
   Allows scheduling maintenance tasks, that are perfomed in the background.
   
  .DESCRIPTION
   Allows scheduling maintenance tasks, that are perfomed in the background.
  
   All scriptblocks scheduled like this will be performed on a separate runspace and have access to all internal dbatools commands.
   None of the scriptblocks will affect the main session (so you cannot manipulate variables, etc.)
   
  .PARAMETER Name
   The name of the task.
   Must be unique, otherwise it will update the existing task.
   
  .PARAMETER ScriptBlock
   The task/scriptblock that should be performed as part of the maintenance.
   It will have all of dbatools including internal commands available.
   
  .PARAMETER Once
   Whether the interval should be performed only once.
   
  .PARAMETER Interval
   The interval at which the task should be repeated.
   
  .PARAMETER Delay
   How far after the initial registration should the maintenance script wait before processing this.
   This can be used to delay background stuff that should not content with items that would be good to have as part of the module import.
   Some library specific items can be moved to maintenance if their processing would take too much time on original import, even if it is desirable to have them available as soon as possible.
   
  .PARAMETER Priority
   How important is this task?
   If multiple tasks are due at the same maintenance cycle, the more critical one will be processed first.
   
  .PARAMETER Silent
   This parameters disables user-friendly warnings and enables the throwing of exceptions.
   This is less user friendly, but allows catching exceptions in calling scripts.
   
  .EXAMPLE
   PS C:\> Register-DbaMaintenanceTask -Name 'value1' -ScriptBlock $ScriptBlock -Once
 #>

    
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [string]
        $Name,
        
        [Parameter(Mandatory = $true)]
        [System.Management.Automation.ScriptBlock]
        $ScriptBlock,
        
        [Parameter(Mandatory = $true, ParameterSetName = "Once")]
        [switch]
        $Once,
        
        [Parameter(Mandatory = $true, ParameterSetName = "Repeating")]
        [System.TimeSpan]
        $Interval,
        
        [System.TimeSpan]
        $Delay,
        
        [Sqlcollaborative.Dbatools.Maintenance.MaintenancePriority]
        $Priority = "Medium",
        
        [switch]
        $Silent
    )
    
    #region Case: Task already registered
    if ([Sqlcollaborative.Dbatools.Maintenance.MaintenanceHost]::Tasks.ContainsKey($Name.ToLower())) {
        $task = [Sqlcollaborative.Dbatools.Maintenance.MaintenanceHost]::Tasks[$Name.ToLower()]
        if ($task.ScriptBlock -ne $ScriptBlock) { $task.ScriptBlock = $ScriptBlock }
        if (Test-Bound -ParameterName Once) { $task.Once = $Once }
        if (Test-Bound -ParameterName Interval) {
            $task.Once = $false
            $task.Interval = $Interval
        }
        if (Test-Bound -ParameterName Delay) { $task.Delay = $Delay }
        if (Test-Bound -ParameterName Priority) { $task.Priority = $Priority }
    }
    #endregion Case: Task already registered
    
    #region New Task
    else {
        $task = New-Object Sqlcollaborative.Dbatools.Maintenance.MaintenanceTask
        $task.Name = $Name.ToLower()
        $task.ScriptBlock = $ScriptBlock
        if (Test-Bound -ParameterName Once) { $task.Once = $true }
        if (Test-Bound -ParameterName Interval) {
            if ($Interval.Ticks -le 0) {
                Stop-Function -Message "Failed to register task: $Name - Interval cannot be 0 or less" -Category InvalidArgument 
                return
            }
            else { $task.Interval = $Interval }
        }
        if (Test-Bound -ParameterName Delay) { $task.Delay = $Delay }
        $task.Priority = $Priority
        $task.Registered = Get-Date
        [Sqlcollaborative.Dbatools.Maintenance.MaintenanceHost]::Tasks[$Name.ToLower()] = $task
    }
    #endregion New Task
}