In my last post I showed how to add a T-SQL Job step to an existing SQL Agent Job. The process is exactly the same for a PowerShell job step.
As before I gathered the required jobs using Get-SQLAgentJob command from the sqlserver module which you can get by installing the latest SSMS from https://sqlps.io/dl
This code was run on PowerShell version 5 and will not run on PowerShell version 3 or earlier as it uses the where method
I put all of our jobs that I required on the estate into a variable called $Jobs. (You will need to fill the $Servers variable with the names of your instances, maybe from a database or CMS or a text file and of course you can add more logic to filter those servers as required.
$Jobs = (Get-SQLAgentJob -ServerInstance $Servers).Where{$_.Name -like '*PartOfNameOfJob*' -and $_.IsEnabled -eq $true}
Of course to add a PowerShell Job step the target server needs to be SQL 2008 or higher. If you have an estate with older versions it is worth creating a SMO server object (you can use a snippet) and checking the version and then getting the jobs like this
foreach($Server in $Servers) { $srv = New-Object Microsoft.SqlServer.Management.Smo.Server $Server if($srv.VersionMajor -ge 10) { $Jobs = $srv.JobServer.Jobs
and you could choose to create a CmdExec Job step for earlier verions in an else code block.
Once I have the Jobs I can iterate through them with a foreach loop
foreach($Job in $Jobs)
Then we need to create a new job step which is done with the following code
$NewStep = New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep
To find out what is available for this object you can run
$NewStep | Get-Member -MemberType Property
We need to set the name, the parent (The job), the command, the subsystem, the on fail action, on success action and the id for the job step.
I set the command to a variable to make the code easier to read
$Command = "Get-Process"
the rest of the properties I fill in inside the loop. To find out what the properties can hold I look at MSDN for a Microsoft.SqlServer.Management.Smo.Agent.JobStep The ID property is the number of the job step starting at 1 so this example will add a new job step that will be the first to run
$Name = $Job.Name $JobServer = $srv.JobServer $Job = $JobServer.Jobs[$Name] $NewStep = New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep $NewStep.Name = 'a descriptive name for my PowerShell script' $NewStep.Parent = $Job $NewStep.Command = $Command $NewStep.SubSystem = 'PowerShell' $NewStep.OnFailAction = 'QuitWithFailure' $NewStep.OnSuccessAction = 'GoToNextStep' $NewStep.ID = 1
Once the object has all of the properties all we need to do is create it and alter the job
$NewStep.create() $Job.Alter()
and putting it all together it looks like this
foreach($Server in $Servers) { $srv = New-Object Microsoft.SqlServer.Management.Smo.Server $Server if($srv.VersionMajor -ge 10) { $Jobs = $srv.JobServer.Jobs.Where{$_.Name -like '*PartOfNameOfJob*' -and $_.IsEnabled -eq $true} foreach($Job in $Jobs) { $NewStep = New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep $NewStep.Name = 'a descriptive name for my PowerShell script' $NewStep.Parent = $Job $NewStep.Command = $Command $NewStep.SubSystem = 'PowerShell' $NewStep.OnFailAction = 'QuitWithFailure' $NewStep.OnSuccessAction = 'GoToNextStep' $NewStep.ID = 1 $NewStep.create() $Job.Alter() } } }
Happy Automating