dbatools icon indicating copy to clipboard operation
dbatools copied to clipboard

Add functionality equivalent to sp_detach_schedule

Open ReeceGoding opened this issue 7 months ago • 2 comments

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:

  1. Make a new cmdlet, Remove-DbaAgentJobSchedule.
  2. Add a new parameter to Set-DbaAgentJob, giving a list of schedules to remove.
  3. 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.

ReeceGoding avatar Jun 10 '25 21:06 ReeceGoding

@claude go forth and implement this request in dbatools style after researching and addressing each of Reece's questions

potatoqualitee avatar Oct 26 '25 10:10 potatoqualitee

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:

  1. SMO Method: Yes, there's a SMO method: JobSchedule.Drop(true) which keeps the shared schedule while removing the job association

  2. Existing Patterns:

    • Set-DbaAgentJob uses AddSharedSchedule() to attach schedules (lines 311-342)
    • Remove-DbaAgentSchedule completely deletes schedules (not just detaches)
    • The pattern shows separation between job-level and schedule-level operations
  3. Best Approach: Option 1 - Create a new cmdlet Remove-DbaAgentJobSchedule

    Reasoning:

    • Follows the existing naming pattern (e.g., Remove-DbaAgentJobStep exists)
    • Clear semantics: removes the schedule from the job (not the schedule itself)
    • Mirrors Set-DbaAgentJob which adds schedules via -Schedule parameter
    • More discoverable than a switch parameter
    • Aligns with SQL Server's sp_detach_schedule functionality

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: -WhatIf and -Confirm support
  • 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!


claude[bot] avatar Oct 26 '25 10:10 claude[bot]