Skip to content

Commit 31ec022

Browse files
Merge pull request #294 from RandomNoun7/tickets/master/MODULES-8692-get-agent-jobs-task
(MODULES-8692) Get Agent Jobs Task
2 parents a087e1a + 1724f89 commit 31ec022

File tree

3 files changed

+265
-1
lines changed

3 files changed

+265
-1
lines changed

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ Use the `detailed` parameter to return more detailed information including the S
11371137
This is an
11381138
optional parameter which will accept either `true` or `false`. Its default value is false.
11391139

1140-
* **enbabled**
1140+
* **enabled**
11411141

11421142
Set this parameter to true to enable a login and set to false to disable it.
11431143
This is an optional boolean parameter. The return value will be an element in the json return
@@ -1161,6 +1161,27 @@ It will not inspect and return to you what the state of a property was before ta
11611161
Use this parameter especially when using the `fuzzy_match` parameter to ensure you are affecting
11621162
only the logins you intend to.
11631163

1164+
#### sqlserver::get_sqlagent_jobs
1165+
1166+
##### parameters
1167+
1168+
* **instance_name**
1169+
1170+
The name of the instance to get job information from. Leave this variable blank to return information from all instances by default.
1171+
Named instances can be referred to by either the short name of the instance, or by `<COMPUTERNAME>\<INSTANCE_NAME>`. Specifying an instance name will access only that instance.
1172+
Pass the values `.`, `MSSQLSERVER`, or the node name to query only the default instance.
1173+
This is an optional parameter which will accept a single string or array of strings as input.
1174+
1175+
* **job_name**
1176+
1177+
The name of a job, or the pattern to match on a jobs name.
1178+
This is an optional parameter which will accept a single string or array of strings as input.
1179+
1180+
* **exact_match**
1181+
1182+
Set this to true to change the behavior of the `job_name` parameter so that only jobs with names exactly matching one of the provided job_names is returned in the result set.
1183+
This is an optional parameter which will accept either `true` or `false`. It's default value is false.
1184+
11641185
### Microsoft SQL Server terms
11651186

11661187
Terminology differs somewhat between various database systems; please refer to this list of terms for clarification.

tasks/get_sqlagent_jobs.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"puppet_task_version": 1,
3+
"supports_noop": false,
4+
"input_method": "powershell",
5+
"description": "Return information about SQL Agent jobs and job steps.",
6+
"parameters": {
7+
"instance_name": {
8+
"description": "The instance to get job information from",
9+
"type": "Optional[Variant[Array[String],String]]"
10+
},
11+
"job_name": {
12+
"description": "The name or the pattern to match of the job to search for.",
13+
"type": "Optional[Variant[Array[String],String]]"
14+
},
15+
"exact_match": {
16+
"description": "Use only exact name matches for the job_name parameter instead of the default fuzzy matching."
17+
}
18+
}
19+
}

tasks/get_sqlagent_jobs.ps1

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
[CmdletBinding()]
2+
param (
3+
# Instance name to return jobs from
4+
[Parameter(Mandatory=$false)]
5+
[string[]]
6+
$instance_name,
7+
8+
# Name of job or match pattern
9+
[Parameter(Mandatory=$false)]
10+
[string[]]
11+
$job_name,
12+
13+
# Use exact name matches only for the -job_name parameter.
14+
[Parameter(Mandatory=$false)]
15+
[switch]
16+
$exact_match
17+
)
18+
19+
function Get-SQLInstances {
20+
param(
21+
[string[]]$instance_name
22+
)
23+
24+
$instancesHolder = New-Object System.Collections.Generic.List[System.Object]
25+
$stringsToReturn = New-Object System.Collections.Generic.List[System.Object]
26+
27+
# The default instance is referred to in its service name as MSSQLSERVER. This
28+
# leads many SQLSERVER people to refer to it as such. They will also connect
29+
# to it using just a '.'. None of these are its real name. Its real instance
30+
# name is just the machine name. A named instances real name is the machine
31+
# name a, '\', and the instance name. This little foreach ensures that we are
32+
# referring to these instances by their real names so that proper filtering
33+
# can be done.
34+
35+
foreach ($name in $instance_name) {
36+
switch ($name) {
37+
{($_ -eq 'MSSQLSERVER') -or ($_ -eq '.')} { [void]$instancesHolder.add($env:COMPUTERNAME) }
38+
{$_ -eq $env:COMPUTERNAME} { [void]$instancesHolder.add($_) }
39+
{$_ -notmatch '\\'} { [void]$instancesHolder.add("$env:COMPUTERNAME\$_") }
40+
default { [void]$instancesHolder.add($name) }
41+
}
42+
}
43+
44+
$instanceStrings = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances
45+
46+
# The registry key does not return the real instance names. Again we must
47+
# normalize these names into their real names so that comparisons can be done
48+
# properly.
49+
50+
foreach ($string in $instanceStrings) {
51+
switch ($string) {
52+
'MSSQLSERVER' { $string = $env:COMPUTERNAME }
53+
Default {$string = "$env:COMPUTERNAME\$string"}
54+
}
55+
56+
if ((-not [string]::IsNullOrEmpty($instancesHolder))-and(-not [string]::IsNullOrWhiteSpace($instancesHolder))) {
57+
foreach ($instance in $instancesHolder) {
58+
if ($instance -eq $string) {
59+
[void]$stringsToReturn.add($string)
60+
}
61+
}
62+
}
63+
else {
64+
[void]$stringsToReturn.add($string)
65+
}
66+
}
67+
68+
if($stringsToReturn.count -gt 0){
69+
Write-Output $stringsToReturn
70+
} else {
71+
throw "No instances were found by the name(s) $instance_name"
72+
}
73+
}
74+
75+
function Get-ServerObject {
76+
param(
77+
[string]$instance
78+
)
79+
80+
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
81+
82+
Write-Output (New-Object Microsoft.SqlServer.Management.Smo.Server -ArgumentList $instance)
83+
}
84+
85+
function Select-Job {
86+
param(
87+
[PSObject]$job,
88+
[string[]]$jobsToMatch,
89+
[switch]$exact_match
90+
)
91+
92+
93+
# This function takes a single SQLServer job object and compares it against
94+
# the list of names passed into the -job_name parameter of the script to
95+
# determine if this is a job the user is interested in seeing. If it does
96+
# not pass the filter represented by that parameter the job is discarded.
97+
98+
foreach ($paramJob in $jobsToMatch) {
99+
if ($exact_match) {
100+
if ($paramJob -eq $job.name) {
101+
Write-Output $job
102+
}
103+
}
104+
else {
105+
# Match is a regex operator, and it doesn't like the '\' in domain names.
106+
if ($job.name -match [regex]::escape($paramJob)) {
107+
Write-Output $job
108+
}
109+
}
110+
}
111+
}
112+
113+
function New-CustomJobObject {
114+
param(
115+
[psobject]$job
116+
)
117+
118+
$customObject = @{
119+
name = $job.name
120+
description = $job.description
121+
enabled = $job.isEnabled
122+
ownerLoginName = $job.ownerLoginName
123+
instance = $job.parent.name
124+
lastRunDate = $job.lastRunDate
125+
lastRunOutcome = [string]$job.lastRunOutcome
126+
currentRunStatus = [string]$job.currentRunStatus
127+
currentRunStep = $job.currentRunStep
128+
startStepID = $job.startStepID
129+
currentRunRetryAttempt = $job.currentRunRetryAttempt
130+
nextRunDate = $job.nextRunDate
131+
dateCreated = $job.dateCreated
132+
dateLastModified = $job.dateLastModified
133+
emailLevel = $job.emailLevel
134+
operatorToEmail = $job.operatorToEmail
135+
operatorToNetSend = $job.operatorToNetSend
136+
operatorToPage = $job.operatorToPage
137+
category = $job.category
138+
steps = New-Object System.Collections.Generic.List[System.Object]
139+
}
140+
141+
foreach($step in $job.jobSteps){
142+
$step = @{
143+
name = $step.name
144+
type = [string]$step.subsystem
145+
databaseName = $step.DatabaseName
146+
lastRunDate = $step.lastRunDate
147+
lastRunDurationSeconds = $step.LastRunDuration
148+
lastRunOutcome = [string]$step.LastRunOutcome
149+
lastRunRetries = $step.lastRunRetries
150+
onFailAction = [string]$step.onFailAction
151+
onFailStep = $step.onFailStep
152+
onSuccessAction = [string]$step.onSuccessAction
153+
onSuccessStep = $step.onSuccessStep
154+
retryAttempts = $step.retryAttempts
155+
retryIntervalMinutes = $step.retryInterval
156+
}
157+
[void]$customObject.steps.add($step)
158+
}
159+
160+
Write-Output $customObject
161+
}
162+
163+
$error = @{
164+
_error = @{
165+
msg = ''
166+
kind = 'puppetlabs.task/task-error'
167+
details = @{
168+
detailedInfo = ''
169+
exitcode = 1
170+
}
171+
}
172+
}
173+
174+
$return = @{jobs = New-Object System.Collections.Generic.List[System.Object]}
175+
176+
$jobs = New-Object System.Collections.Generic.List[System.Object]
177+
178+
try {
179+
$SQLInstances = Get-SQLInstances -instance_name $instance_name
180+
}
181+
catch {
182+
$error._error.msg = 'Cannot detect SQL instance names.'
183+
$error._error.details.detailedInfo = $_
184+
return $error | ConvertTo-JSON
185+
}
186+
187+
foreach ($instance in $SQLInstances) {
188+
try {
189+
$sqlServer = Get-ServerObject -instance $instance
190+
}
191+
catch {
192+
$error._error.msg = "Cannot connect to SQL Instance: $instance"
193+
$error._error.details.detailedInfo = $_
194+
return $error | ConvertTo-JSON
195+
}
196+
197+
foreach($currentJob in $sqlserver.jobserver.jobs){
198+
if($MyInvocation.BoundParameters.ContainsKey('job_name')){
199+
if($selectedJob = (Select-Job -job $currentJob -jobsToMatch $job_name -exact_match:$exact_match)){
200+
[void]$jobs.add((New-CustomJobObject -job $selectedJob))
201+
}
202+
} else {
203+
[void]$jobs.add((New-CustomJobObject -job $currentJob))
204+
}
205+
}
206+
}
207+
208+
$return.jobs = $jobs
209+
210+
return ($return | ConvertTo-JSON -Depth 99)
211+
212+
<#
213+
.SYNOPSIS
214+
This script connects to a SQL instance running on a machine and returns
215+
information about SQL agent jobs and job steps.
216+
.DESCRIPTION
217+
This script will connect to SQL instances running on a machine and return
218+
information about agent jobs and job steps configured on the instance. This
219+
script only connects to instances on a local server. It will always return
220+
data in JSON format.
221+
.PARAMETER instance_name
222+
The name of the instance running on a machine that you would like to connect to.
223+
Leave blank to get the default instance MSSQLSERVER.
224+
#>

0 commit comments

Comments
 (0)