Add functionality equivalent to sp_detach_schedule
Summarize Functionality
We have a wealth of cmdlets for managing Agent Job schedules:
- New-DbaAgentSchedule creates them
- Remove-DbaAgentSchedule destroys them
- Set-DbaAgentSchedule updates them at the job level. You can also use it to disable schedules, but I'm fairly sure that SQL Server doesn't support disabling shared schedules for just one job.
- Set-DbaAgentJob attaches them.
But suppose that I wish detach a schedule from a job. Aside from writing the T-SQL yourself and using Invoke-DbaQuery, I know of no solution to this within dbatools.
The problem that made me discover this issues was as follows:
- Job A and job B share a schedule.
- Job A is bugged and must not run until it is fixed
- Strict rules prevent disabling or deleting job A
- I could not disable or delete the schedule for job A, because it is shared with job B and I didn't want to damage job B
- Detaching the shared schedule from job A was allowed, and therefore my only choice
If dbatools has an alternative solution, then I would love to hear it.
Is there a command that is similiar or close to what you are looking for?
Yes
Technical Details
A wrapper for sp_detach_schedule should do it, but I am not totally sure where it should be put. I see three options:
- Make a new cmdlet,
Remove-DbaAgentJobSchedule. - Add a new parameter to
Set-DbaAgentJob, giving a list of schedules to remove. - Add a new parameter to
Set-DbaAgentSchedule, giving a switch for something like-Detach.
I do not know if what we want already exists in SMO. I barely trust myself to check. This is the best I found.
@claude go forth and implement this request in dbatools style after researching and addressing each of Reece's questions
Claude finished @potatoqualitee's task —— View job • claude/issue-9687-20251026-1026 • Create PR ➔
Implementation Complete! ✓
I've successfully implemented the requested functionality to detach schedules from jobs.
Task List
- [x] Read repository guidelines
- [x] Research existing agent schedule cmdlets
- [x] Examine SMO RemoveSharedSchedule method
- [x] Decide on implementation approach
- [x] Implement the functionality
- [x] Create comprehensive tests
- [x] Commit and push changes
Research Findings
Based on my analysis of the existing codebase:
-
SMO Method: Yes, there's a SMO method:
JobSchedule.Drop(true)which keeps the shared schedule while removing the job association -
Existing Patterns:
-
Set-DbaAgentJobusesAddSharedSchedule()to attach schedules (lines 311-342) -
Remove-DbaAgentSchedulecompletely deletes schedules (not just detaches) - The pattern shows separation between job-level and schedule-level operations
-
-
Best Approach: Option 1 - Create a new cmdlet
Remove-DbaAgentJobScheduleReasoning:
- Follows the existing naming pattern (e.g.,
Remove-DbaAgentJobStepexists) - Clear semantics: removes the schedule from the job (not the schedule itself)
- Mirrors
Set-DbaAgentJobwhich adds schedules via-Scheduleparameter - More discoverable than a switch parameter
- Aligns with SQL Server's sp_detach_schedule functionality
- Follows the existing naming pattern (e.g.,
Implementation Details
Created two files:
-
public/Remove-DbaAgentJobSchedule.ps1- New cmdlet to detach schedules from jobs -
tests/Remove-DbaAgentJobSchedule.Tests.ps1- Comprehensive unit and integration tests
The cmdlet supports:
- Multiple identification methods: Detach schedules by name, UID, or ID
- Batch operations: Process multiple schedules and jobs at once
-
Pipeline support: Accepts job objects from
Get-DbaAgentJob -
Safety features:
-WhatIfand-Confirmsupport - Proper error handling: Clear messages when schedules aren't found
- Clean output: Returns status information for each detach operation
Example Usage
# Detach a schedule from a job (schedule remains available for other jobs)
Remove-DbaAgentJobSchedule -SqlInstance sql1 -Job 'Job1' -Schedule 'SharedSchedule'
# Detach multiple schedules
Remove-DbaAgentJobSchedule -SqlInstance sql1 -Job 'Job1' -Schedule 'Schedule1', 'Schedule2'
# Use pipeline input
Get-DbaAgentJob -SqlInstance sql1 -Job 'Job1' | Remove-DbaAgentJobSchedule -Schedule 'SharedSchedule'
# Detach using schedule UID (when multiple schedules share the same name)
Remove-DbaAgentJobSchedule -SqlInstance sql1 -Job 'Job1' -ScheduleUid 'bf57fa7e-7720-4936-85a0-87d279db7eb7'
This directly addresses your use case where Job A and Job B share a schedule, and you need to detach it from Job A without affecting Job B!