Browsing: Useful Scripts

List All Database Users With Permissions

Hi there! In this blog post, we will explore a SQL query that allows you to list all database users with Permissions in SQL Server. As a DBA you must be able to identify which users have access to specific databases and what permissions they possess.

Understanding Database Users and Permissions

Before we dive into the SQL query, first let’s clarify the concepts of database users and permissions.

Database Users:

A database user is an individual or application that interacts with a SQL Server database.
Each user account is mapped to a Windows login or a SQL Server login.
Users are associated with roles and are granted permissions to perform specific actions within the database.

Permissions:

In SQL Server, permissions are used to control access to database objects, such as tables and views. Each user in a database has a set of permissions that determine what they are able to do within the database, such as SELECT, INSERT, UPDATE, DELETE, and EXECUTE.

Query to List All Database Users With Database Role Permissions

USE TestDB  -- Change the db Name
GO
SELECT
       ServerName=@@servername, Dbname=db_name(db_id()),p. name as UserName, 
       p. type_desc as TypeOfLogin, pp. name as DatabaseRoleAssigned, pp. type_desc as TypeOfRole
       FROM sys.database_role_members roles
       JOIN sys.database_principals p ON roles.member_principal_id = p.principal_id
       JOIN sys.database_principals pp ON roles.role_principal_id = pp.principal_id
       WHERE p. type_desc NOT IN('DATABASE_ROLE','ASYMMETRIC_KEY_MAPPED_USER')
       AND p. name NOT IN ('sys','INFORMATION_SCHEMA','guest','dbo')

Output:

List All Database Users Permission

Generally speaking the above output is neat. Point often overlooked is we only got the details of the users which are part of any database roles. In other words I still need to know about users having Execute permission to any Stored Procedure, SELECT/INSERT/UPDATE permission on specific table etc.

Given these points let’s look into the below query.

Query To List All Database Users With Permissions:

USE TestDB  -- Change the db Name
GO
SELECT
   @@servername as SQLInstanceName,
   Dbname=db_name(db_id()),
   u.name as 'UserName',
   u.type_desc as LoginType,
   p.permission_name as 'Permission',
   o.name as 'ObjectName',
   o.type_desc as 'ObjectType'
FROM
sys.database_permissions p
INNER JOIN
sys.objects o ON p.major_id = o.object_id
INNER JOIN
sys.database_principals u ON p.grantee_principal_id = u.principal_id

Output:List All User Permissions

As can be seen in the above example output the query shows the permissions on specific objects. Hence you need these two queries to List All Database Users With Permissions.

Important to realize the following points:
  • The queries returns information about the database roles and permissions on database-level. Therefore it will not return information about server-level permissions.
  • Both the queries returns information about SQL and Windows users but does not include permission of roles. Hence If you want to see the permissions of database roles please feel free to tweak the query.
  • These will only shows the permissions for the specific connected database . Hence to check the permissions for all users in all databases, run the query against each database individually or modify the query. You can refer the link Retrieve all permissions for a user in all user databases which provides assigned database roles for a login in all databases.

Conclusion:

In summary managing permissions in SQL Server is a crucial aspect of database administration. Hence I have provided a simple introduction of users and permissions before diving into the query.
With this in mind, you can easily use the queries to list all database users and their permissions. This will certainly help you maintain a secure and compliant database environment.
Regularly reviewing and auditing permissions is essential to ensure data integrity and security in your SQL Server databases.

{ Add a Comment }

Query To List All Orphaned Logins In SQL Server

Hi there, being a DBA you must be dealing with orphaned users often but rarely with orphaned logins. In this article I am gonna provide you a script to list all orphaned logins in a SQL Server Instance.

Introduction:

First of all let us understand what are orphaned logins in SQL Server. The logins which does not have access to any database or server roles. Now next question is how orphaned login occurs in SQL Server Instance. In general it happens when you migrate or decommission database(s).

Few of the reasons are mentioned as follows:

  • Migration of database(s) leaving the associated logins.
  • Decommission of database(s) leaving the associated logins.
  • Deleting a server or database role that the login is a member of.
  • Moving user account from one domain to another.

Over time your server can become cluttered with orphaned logins and make it difficult for DBAs to manage. Hence it is important to regularly check and remove them. Obviously you need to follow the process as per your organization.

Query to list all orphaned logins in SQL Server:

DECLARE @dbname VARCHAR(50)  
DECLARE @statement NVARCHAR(MAX)

CREATE TABLE #database_sids
(
    [sid] int NOT NULL
);

DECLARE db_cursor CURSOR 
LOCAL FAST_FORWARD
FOR  
SELECT name
FROM master.sys.databases
WHERE  state_desc='online' 
OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @dbname  
WHILE @@FETCH_STATUS = 0  
BEGIN

SELECT @statement = 'select sid from ['+@dbname +'].sys.database_principals where sid is not Null and type!=''R'''

INSERT INTO #database_sids ([sid])
EXEC sp_executesql @statement

FETCH NEXT FROM db_cursor INTO @dbname  
END  
CLOSE db_cursor  
DEALLOCATE db_cursor

SELECT sp.name
    , sp.type_desc
FROM sys.server_principals sp
WHERE NOT EXISTS (
    SELECT 1
    FROM #database_sids ds
    WHERE ds. sid = sp. sid
    )
    AND sp.[type_desc] NOT IN (
          N'SERVER_ROLE'
        , N'CERTIFICATE_MAPPED_LOGIN'
        , N'ASYMMETRIC_KEY_MAPPED_LOGIN'
        )
        AND sp.name not in(
       SELECT P.name 
       FROM sys.server_role_members RM
       INNER JOIN sys.server_principals P ON RM.member_principal_id = P.principal_id)

drop table #database_sids

Sample Output:

Orphaned Logins

First thing to remember is not to delete them immediately. As can be seen in the above example, ‘NT AUTHORITY\SYSTEM’. That’s a critical account to verify before deleting. Hence it is important to realize that though the logins are Orphaned you need to do a though check before taking any action.

Conclusion:

In summary orphaned logins can occur due to number of reasons. Primary reasons being database migration, decommission or moving user from one domain to another. Point often overlooked is Orphaned Logins can pose security risk and hinder SQL Server management. However it is possible to identify and address them as per your organization standards. I hope the above script can help in your journey. Please let me know by leaving your comments below.

{ Add a Comment }

Creating a Calendar Table in SQL Server

Introduction

A calendar table is useful for any SQL Server database, as it allows for easy querying and reporting of date-based data. Reporting often requires aggregating or returning data based on date attributes such as weekdays, holidays, quarters, or time of year. Creating a calendar table can save time, improve performance, and increase consistency in data. In this guide, we will walk through the process of creating a calendar table in SQL Server, including the necessary code and best practices for maintaining and using the table.

You can change some of these details to experiment on your own.

Why Use a Calendar Table?

There are several benefits to using a calendar table in your SQL queries. First and foremost, a calendar table can greatly simplify date-based queries. Without a calendar table, you may have to use complex logic to extract the year, month, day, etc. from a date field. With a calendar table, you can simply join to it and use the pre-calculated date fields.

Another benefit of a calendar table is that it can be used to quickly fill in missing dates in your data. If you have a sales table that only has entries for dates when there were actual sales, a calendar table can be used to fill in the missing dates and show “zero” sales for those dates. This can be particularly useful when creating graphs or charts that need to have a consistent X-axis.

Finally, a calendar table can be used to quickly apply filters to your data based on dates. For example, you can use a calendar table to easily filter your data to only show records from the current month, or the last 30 days.

Step 1: Create the Table Structure

The first step in creating a calendar table is to create the table structure. We will be using the following code to create the table. You can also include other columns such as quarter or fiscal year, depending on your specific requirements.

CREATE TABLE tblCalendar(
       [Date] Date NOT NULL,
       [Day] char(10) NOT NULL,
       [DayOfWeek] tinyint NOT NULL,
       [DayOfMonth] tinyint NOT NULL,
       [DayOfYear] smallint NOT NULL,
       [PreviousDay] date NOT NULL,
       [NextDay] date NOT NULL,
       [WeekOfYear] tinyint NOT NULL,
       [Month] char(10) NOT NULL,
       [MonthOfYear] tinyint NOT NULL,
       [QuarterOfYear] tinyint NOT NULL,
       [Year] int NOT NULL,
       [IsWeekend] bit NOT NULL,
    )
 
ALTER TABLE tblCalendar
ADD CONSTRAINT PK_CalendarDate PRIMARY KEY (Date); 

You should add a primary key to ensure the data is unique and can be easily searched.

Step 2: Populate the Table with Data

Once the table structure is created, it’s time to populate it with data. You can use a series of INSERT statements to add data for a specific range of dates. In the below example I am inserting 365 days of data starting from 1st Jan’23.

DECLARE @StartDate DATE
DECLARE @EndDate DATE
SET @StartDate = '2023-01-01' --Put the start date as per your requirement
SET @EndDate = DATEADD(d, 365, @StartDate) --Change the no. of days as needed
WHILE @StartDate <= @EndDate
      BEGIN
             INSERT INTO tblCalendar values
             (
                   @StartDate,
                              CONVERT(CHAR(10), DATENAME(WEEKDAY, @StartDate)),
                              CONVERT(Tinyint,DATEPART(WEEKDAY, @StartDate)),
                              CONVERT(Tinyint,DATEPART(DAY, @StartDate)),
                              CONVERT(smallint, DATEPART(DAYOFYEAR, @StartDate)),
                              DATEADD(day, -1, CONVERT(DATE, @StartDate)),
                              DATEADD(day, 1, CONVERT(DATE, @StartDate)),
                              CONVERT(tinyint, DATEPART(WEEK,@StartDate)),
                              CONVERT(CHAR(10), DATENAME(MONTH, @StartDate)),
                              CONVERT(TINYINT, DATEPART(MONTH, @StartDate)),
                              CONVERT(TINYINT, DATEPART(QUARTER,@StartDate)),
                              CONVERT(INT, DATEPART(YEAR,@StartDate)),
                              CASE 
                                   WHEN CONVERT(Tinyint,DATEPART(WEEKDAY, @StartDate)) in (1,7)
                                   THEN 1
                                   ELSE 0 
                                 END
             )
             
             SET @StartDate = DATEADD(dd, 1, @StartDate)
      END

Sample Output:

Calendar Table In SQL Server

Next Steps:

To ensure that the calendar table is as efficient as possible, it’s important to set up appropriate indexes and constraints once the table grows considerably large.

Conclusion:

Creating a calendar table in SQL Server can greatly improve performance and simplify your code when joining data on date-related attributes in reporting, analytics, or OLTP use cases. These tables also make it easier for reporting engines to consume the data and increase maintainability by keeping a single copy of calendar data in one place, reducing the risk of coding errors when working with complex date calculations

You can also refer the following link for more idea https://www.sqlshack.com/designing-a-calendar-table/

You may also like the below articles:

Script To List SQL Agent Jobs and Schedules

Script to Change SQL Agent Job Schedule

Script to Find Agent Job in Execution

 

 

{ Add a Comment }

Powershell Script to Create Folders

This article will help you with Powershell Script to Create Folders. Being DBA you may get into many situations when you need to create many folders.

Let me give a scenario. You have a SQL Instance of around 100 databases and need to create directory with the database names.

Powershell Script to Create Folders

Go to Start > Search and type “Powershell”. You can use any of the highlighted option.

Powershell Script to Create Folders

Here in this example I’ll be showing the example from first option. i.e. PowerShell ISE. Right Click > Run As Administrator

Powershell Script to Create Folders

The one liner code is as follows. Here I am creating a new folder named “folder” in the path ‘C:\BackupData\’
New-item -Path 'C:\BackupData\folder' -ItemType Directory

The following screen shot shows how it looks in the console.

Powershell Script to Create Folders

Now lets see how you can use this to create multiple folders.
First create a folder list in a notepad and save it in a notepad. In this example the file is “FolderNames.txt”
Powershell Script to Create Folders

$foldername= Get-Content -Path 'C:\Temp\Test\FolderNames.txt' #Provide the Path where the list is kept
$dirpath='C:\Temp\Test' #The Path where you need to create the folders
foreach ($folder in $foldername)
{
New-Item -ItemType Directory -Path $dirpath\$folder
} 

Copy the code in the PowerShell ISE and click on the Play button to execute it. The folder names will be displayed in the bottom section as you can see in the below screen shot.
Powershell Script to Create Folders

Validate the path:
Powershell Script to Create Folders

{ Add a Comment }

Powershell Script to Validate SQL Servers

This article is about a Powershell script to Check SQL Server Database Status and Services remotely. This will help in validating SQL Server after Windows patching.

To put in another way, DBAs are responsible for validating SQL Servers after server maintenance. Usually DBAs need to do a sanity check of the SQL Server after planned or unplanned maintenance.

The most common checks while doing a SQL Server validation:
  1. Validate SQL Services are up and running
  2. SQL Databases are online
  3. There is no error in the error log
  4. Authentication protocol after the restart (Kerberos Or NTLM)

Now imagine if you have a large number of servers, how much time you need to spend on such activity. The below simple yet effective powershell script will save a lot of time.

Powershell script to Check SQL Server Database Status and Services:
###########################################################################################################
#Objective: To Check SQL Service status, Database status, Errors in Errorlog and Authentication protocol  #
#Author: Tridib Dev                                                                                       #
#Source:https://sqlgeekspro.com/                                                                          #
#Parameter: SQL Instance Name                                                                             #
###########################################################################################################
param ([parameter(Mandatory = $true)] $SQLServer)
        
Write-host 'SQL Service Status for: ' $SQLServer
Write-host '---------------------------------------------'
Write-host " "
Get-WmiObject -Class Win32_Service -ComputerName $SQLServer | Where-Object {$_.Name -like "*SQL*"} | Format-List -Property Displayname, state, startName
Import-Module SQLPS -DisableNameChecking
$q1 = "select name as DatabaseName, state_desc as Status from sys.databases where state_desc <> 'online'"
$q2 = @"
CREATE TABLE #ErrorLog(
   LogDate DATETIME,
   ErrorSource NVARCHAR(MAX),
   ErrorMessage NVARCHAR(MAX)
)

INSERT INTO #ErrorLog(LogDate,ErrorSource,ErrorMessage)
       EXEC xp_readerrorlog 0,1, "Error"
select LogDate, ErrorMessage from #ErrorLog 
drop table #ErrorLog
"@
$q3 = "select auth_scheme from sys.dm_exec_connections where session_id=@@spid"

$r1 = Invoke-Sqlcmd -ServerInstance $SQLServer $q1
$r2 = Invoke-Sqlcmd -ServerInstance $SQLServer $q2
$r3 = Invoke-Sqlcmd -ServerInstance $SQLServer $q3

write-host 'Database status'
Write-host '-----------------'
Write-host " "
Write-host $r1.itemArray
Write-host '-----------------'
write-host 'ErrorLog:-'
Write-host '-----------------'
Write-host " "
Write-host $r2.itemArray
Write-host '-----------------'
Write-host " "
Write-host 'Authentication Type'
Write-host '-----------------'
Write-Host $r3.itemArray

Sample Output:
Powershell to Check SQL Database Status
SQL Service Status

 

Powershell to Check SQL Database Status
Database Status, ErrorLog and Authentication Protocol

Note: You can run the script in PowerShell ISE or download it from ValidateSQLServerThe output will be in console. I have written this script keeping it simple and have not used advanced modules so that you don’t have to install any modules. You just need SQLPS module.
Hope this will help in saving lot of your time in validating SQL Servers after any maintenance. You may also like Powershell Script to find SQL Instance Name for a Remote Server

{ Add a Comment }

PowerShell Script to find SQL Instances on remote server

This article is about a PowerShell script to find sql instances on remote server. Not to mention the remote server can be standalone or Cluster.
When I got the requirement to develop the script, I thought it is not a big deal. Generally speaking, PowerShell will have some direct commands to do so and my script is few searches away.
But when I put my feet in, I got to know it was not as easy as I thought.
Especially the real challenge comes in when you have to list the SQL Instances for a SQL Cluster. The script should be intelligent enough to find out if the server is cluster or standalone and accordingly list the SQL Instances.

Note:The script should run from a server where FailOver Clustering Feature is installed.

PowerShell script to find sql instance name on remote server
Param(
    [Parameter(Mandatory=$true)]
     $ComputerName
)

if ((Get-WMIObject -Class MSCluster_ResourceGroup -ComputerName $ComputerName -Namespace root\mscluster -ErrorAction SilentlyContinue) -ne $null)
 {  
    Import-Module FailoverClusters
    get-clusterresource -Cluster $ComputerName  -ErrorAction SilentlyContinue|
    where-object {$_.ResourceType -like “SQL Server”} | 
    get-clusterparameter VirtualServerName,InstanceName | group-object ClusterObject | 
    select-object @{Name = “SQLInstance”;Expression = {[string]::join(“\”,($_.Group | select-object -expandproperty Value))}} 
    } 
else {
$SQLInstances = Invoke-Command -ComputerName $ComputerName {
(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances
}
    foreach ($sql in $SQLInstances) {
       [PSCustomObject]@{
           ServerName = $sql.PSComputerName
           InstanceName = $sql
       }
   }  
   } 

Not to mention, you can execute it from PowerShell ISE or from PowerShell Command prompt. Let’s see both examples.

Execute The Script Through Windows PowerShell ISE:

PowerShell Script to find SQL Instances on remote serverOnce you execute the script you’ll be prompted to provide the Server Name as you can see in the last line in above screen shot.
Sample OutPut:PowerShell Script to find SQL Instances on remote server

Execute the Script from Windows PowerShell Command Prompt:PowerShell Script to find SQL Instances on remote server

Only difference is to provide the server name while running the script as shown in the screen shot. Also the SQL Instance “PC01” is a cluster. Hence you don’t have to bother if the server is standalone or cluster. Hope this helps.
Let me know if you have any questions or comments.

{ 2 Comments }

Script To List SQL Agent Jobs and Schedules

This article is to keep a handy script to list SQL Agent Jobs and Schedules. In the previous article I had provided  a script to change the job schedule. This script may be very next one you need.

Once we changed the job schedules in all SQL Servers in the environment, we needed a script to verify. There are many scripts available in the net. Hence I kind of tweaked one of the script. It’s been long time and hence not able to provide the original source.

Note:Please change the Job Names in the Where clause of the query to verify the job schedule of the jobs you made changes to.

Query to get list of jobs in sql server with schedules
SELECT	 [JobName] = [jobs].[name]
		,[Enabled] = CASE [jobs].[enabled] WHEN 1 THEN 'Yes' ELSE 'No' END
		,[Scheduled] = CASE [schedule].[enabled] WHEN 1 THEN 'Yes' ELSE 'No' END
		,[Occurs] = 
				CASE [schedule].[freq_type]
					WHEN   1 THEN 'Once'
					WHEN   4 THEN 'Daily'
					WHEN   8 THEN 'Weekly'
					WHEN  16 THEN 'Monthly'
					WHEN  32 THEN 'Monthly relative'
					WHEN  64 THEN 'When SQL Server Agent starts'
					WHEN 128 THEN 'Start whenever the CPU(s) become idle' 
					ELSE ''
				END
		,[Occurs_detail] = 
				CASE [schedule].[freq_type]
					WHEN   1 THEN 'O'
					WHEN   4 THEN 'Every ' + CONVERT(VARCHAR, [schedule].[freq_interval]) + ' day(s)'
					WHEN   8 THEN 'Every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' weeks(s) on ' + 
						LEFT(
							CASE WHEN [schedule].[freq_interval] &  1 =  1 THEN 'Sunday, '    ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] &  2 =  2 THEN 'Monday, '    ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] &  4 =  4 THEN 'Tuesday, '   ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] &  8 =  8 THEN 'Wednesday, ' ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] & 16 = 16 THEN 'Thursday, '  ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] & 32 = 32 THEN 'Friday, '    ELSE '' END + 
							CASE WHEN [schedule].[freq_interval] & 64 = 64 THEN 'Saturday, '  ELSE '' END , 
							LEN(
								CASE WHEN [schedule].[freq_interval] &  1 =  1 THEN 'Sunday, '    ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] &  2 =  2 THEN 'Monday, '    ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] &  4 =  4 THEN 'Tuesday, '   ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] &  8 =  8 THEN 'Wednesday, ' ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] & 16 = 16 THEN 'Thursday, '  ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] & 32 = 32 THEN 'Friday, '    ELSE '' END + 
								CASE WHEN [schedule].[freq_interval] & 64 = 64 THEN 'Saturday, '  ELSE '' END 
							) - 1
						)
					WHEN  16 THEN 'Day ' + CONVERT(VARCHAR, [schedule].[freq_interval]) + ' of every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' month(s)'
					WHEN  32 THEN 'The ' + 
							CASE [schedule].[freq_relative_interval]
								WHEN  1 THEN 'First'
								WHEN  2 THEN 'Second'
								WHEN  4 THEN 'Third'
								WHEN  8 THEN 'Fourth'
								WHEN 16 THEN 'Last' 
							END +
							CASE [schedule].[freq_interval]
								WHEN  1 THEN ' Sunday'
								WHEN  2 THEN ' Monday'
								WHEN  3 THEN ' Tuesday'
								WHEN  4 THEN ' Wednesday'
								WHEN  5 THEN ' Thursday'
								WHEN  6 THEN ' Friday'
								WHEN  7 THEN ' Saturday'
								WHEN  8 THEN ' Day'
								WHEN  9 THEN ' Weekday'
								WHEN 10 THEN ' Weekend Day' 
							END + ' of every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' month(s)' 
					ELSE ''
				END
		,[Frequency] = 
				CASE [schedule].[freq_subday_type]
					WHEN 1 THEN 'Occurs once at ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':')
					WHEN 2 THEN 'Occurs every ' + 
								CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Seconds(s) between ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
					WHEN 4 THEN 'Occurs every ' + 
								CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Minute(s) between ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
					WHEN 8 THEN 'Occurs every ' + 
								CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Hour(s) between ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
								STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
					ELSE ''
				END
FROM	 [msdb].[dbo].[sysjobs] AS [jobs] WITh(NOLOCK) 
		 LEFT OUTER JOIN [msdb].[dbo].[sysjobschedules] AS [jobschedule] WITh(NOLOCK) 
				 ON [jobs].[job_id] = [jobschedule].[job_id] 
		 LEFT OUTER JOIN [msdb].[dbo].[sysschedules] AS [schedule] WITh(NOLOCK) 
				 ON [jobschedule].[schedule_id] = [schedule].[schedule_id] 
		where [jobs].[name] in ('1_DBA job Name', '11_DBA job Name') -- Change the job names or add/remove as applicable
GO

Again please change the values for Where clause. I know it is a long query hence mentioning it again.

The OutPut of the above query

List SQL Agent Jobs And Schedules
The query provides details on how the jobs are scheduled. If you want to to list the schedules of all the SQL Agent Jobs then just remove the where clause.

{ Add a Comment }

Script to Change SQL Agent Job Schedule

This article is about a simple script to change sql agent job schedule. Now most you may be thinking why do you need a script while you can change it through SSMS.

But if you get an issue like sql server agent job is not running as per standard schedule. And the issue is on 100s of SQL Instances, you definitely prefer a query to do it on one shot.

Now let me tell you what made me develop this simple query which helped big time. Someone ran a script to create DBA maintenance job automatically.

Of course all went well until we realized two jobs were running thrice a week. The maintenance jobs should run on weekends only and hence the below query helps achieving the same.
You can use SQL Server’s Central Management Server (CMS) to execute the query in all SQL Instances at one shot.

Alter SQL Job Schedule Using Script

NOTE: Please don’t copy paste the query and run without reading the comments. You need to change few parameter values as per your requirements.

The below query is an example to change the job schedule of the SQL Agent Job “1_DBA job Name” to run Weekly Once on Saturday.

DECLARE @schid INT

SELECT @schid = sjc.schedule_id
FROM msdb..sysjobs AS sjob
INNER JOIN msdb..sysjobschedules AS sjc ON sjob.job_id = sjc.job_id
INNER JOIN msdb..sysschedules AS sch ON sjc.schedule_id = sch.schedule_id
WHERE sjob.name = '1_DBA job Name' -- Change The Job Name

EXEC msdb..sp_update_schedule @schedule_id = @schid
	,@freq_type = 8  --The value indicates when a job is to be executed. Refer Table_1
	,@freq_interval = 64 -- Refer Table_2 below and change it as per your requirement
freq_type: The value indicates frequency of a job is to be executed
Script to Change SQL Agent Job Schedule
Table_1

freq_interval: The days that a job will execute.

Script to Change SQL Agent Job Schedule
Table_2

Please refer the Microsoft article Microsoft Documentation to understand and use different schedule options.
If you have some basic T-SQL knowledge you must be thinking this could have been achieved just by running sp_update_schedule. Well that is true if you have unique schedule name for the SQL Agent Job you are trying to change the schedule. If not this simple query will help.

The very next step would be to verify the changes you just made. Here is a script to achieve the same.>>Continue

{ Add a Comment }

Script to Delete SQL Agent Jobs Continues

<< Previous
This article is in continuation of Script to Delete SQL Agent Jobs. If you have landed here directly you might want to check the above article if the first script helps.
Anyways in this continuation article I am going to provide you the script to Delete SQL Agent Jobs in a scenario when you need to delete all the jobs except the default one “syspolicy_purge_history”.

Script to Delete All SQL Agent Jobs except the default one:
DECLARE @SQLStatement VARCHAR(200)
DECLARE @jobName SYSNAME
   DECLARE c1 CURSOR FOR
   SELECT name FROM msdb.dbo.sysjobs_view WHERE name <> 'syspolicy_purge_history' 
   OPEN c1
   FETCH NEXT FROM c1 INTO @jobName
     IF @@CURSOR_ROWS=0
     PRINT 'No Job found! Please re-check LIKE operator.'
     WHILE @@fetch_status=0
    BEGIN
       SET @SQLStatement= 'EXEC msdb.dbo.sp_delete_job @job_name =''' + @jobName + ''', @delete_unused_schedule=1' 
       PRINT(@SQLStatement)
     --EXEC (@SQLStatement)   --Uncomment to Execute
       FETCH NEXT FROM c1 INTO @jobName
    END
   CLOSE c1
   DEALLOCATE c1

The result set will provide you with the SQL delete statements if you run the above query as is. All you need to do is copy the output and  execute them in the SSMS.

Sample result set as shown in the following screenshot:
Delete SQL Agent Jobs
Delete SQL Agent Jobs

There is another way to execute the query. You can directly delete the jobs without generating the delete statements. If you have little T-SQL knowledge you can modify the same query to do it. If you are an accidental DBA, no worries just remove the -- sign from the statement EXEC (@SQLStatement) and comment the statement PRINT(@SQLStatement). I have explained this already in the previous article so if you can refer that.

Now let’s talk about a scenario when you need to delete all sql agent jobs except the replication, mirroring, log shipping or except few jobs.
Yes, you got it right. All you need to do is modify the where condition. Let me show you an example of Deleting All SQL Agents Jobs except the replication ones. The below query shows example of jobs related to transaction replication and the default one “syspolicy_purge_history".

Script To Delete All SQL Agent Jobs Except Few:
DECLARE @SQLStatement VARCHAR(200)
DECLARE @jobName SYSNAME
   DECLARE c1 CURSOR FOR
   SELECT name FROM msdb.dbo.sysjobs_view WHERE name not in
('syspolicy_purge_history' 
,'Agent history clean up: distribution' 
,'Distribution clean up: distribution' 
,'Expired subscription clean up' 
,'INDSBLRHT0VR72-AdventureWorks2017-2' --Change the job name as per your environment
,'INDSBLRHT0VR72-AdventureWorks2017-Adven_Pub-2' --Change the job name as per your environment
,'INDSBLRHT0VR72-AdventureWorks2017-Adven_Pub-INDSBLRHT0VR72-5' --Change the job name as per your environment
,'Reinitialize subscriptions having data validation failures' 
,'Replication agents checkup' 
,'Replication monitoring refresher for distribution' 
)

   OPEN c1
   FETCH NEXT FROM c1 INTO @jobName
     IF @@CURSOR_ROWS=0
     PRINT 'No Job found! Please re-check LIKE operator.'
     WHILE @@fetch_status=0
    BEGIN
       SET @SQLStatement= 'EXEC msdb.dbo.sp_delete_job @job_name =''' + @jobName + ''', @delete_unused_schedule=1' 
       PRINT(@SQLStatement)
     --EXEC (@SQLStatement)   --Uncomment to Execute
       FETCH NEXT FROM c1 INTO @jobName
    END
   CLOSE c1
   DEALLOCATE c1

Another way of achieving the same end result is using the first query and filter out the jobs from the result set.
Hope this helps. Feel free to leave your comments.
You also might find the below scripts useful:

Query To Retrieve All Permissions for a user in Selective databases
Script to Rename SQL Agent Jobs
Script to get SQL Cluster Failover Time and Node Name
Script to find the SQL Agent Job Name in Execution
List all permissions for a user in all or selective databases

{ Add a Comment }

Script to Delete SQL Agent Jobs

This article is about a simple script to delete SQL Agent Jobs. Recently I had faced a situation when I had to remove more than 100 SQL Agent jobs.

First of all let me tell you that there may be different scenarios when you may need to delete all SQL Agent jobs, few of them or all except few required jobs etc. I have tried to include couple of queries in this article.

I had blog about renaming several SQL Agent jobs. All I have done is little modification in the query.

Script To Delete SQL Agent Jobs Having Particular Naming Convention
DECLARE @SQLStatement VARCHAR(200)
DECLARE @jobName SYSNAME
   DECLARE c1 CURSOR FOR
   SELECT name FROM msdb.dbo.sysjobs_view WHERE name LIKE '%DBA%' --Change the LIKE Operator as applicable
   OPEN c1
   FETCH NEXT FROM c1 INTO @jobName
     IF @@CURSOR_ROWS=0
     PRINT 'No Job found! Please re-check LIKE operator.'
     WHILE @@fetch_status=0
    BEGIN
       SET @SQLStatement= 'EXEC msdb.dbo.sp_delete_job @job_name =''' + @jobName + ''', @delete_unused_schedule=1' 
       PRINT(@SQLStatement)
     --EXEC (@SQLStatement)   --Uncomment to Execute
       FETCH NEXT FROM c1 INTO @jobName
    END
   CLOSE c1
   DEALLOCATE c1

 

The following screenshot shows SQL Agent Jobs having naming convention like ‘1_DBA job Name’, ‘2_DBA job Name’ and so on. This is just for example, you may have different names in your environment.

Script to rename SQL Agent Jobs

Besides that there  is another way you can use this query. The result set will provide you with the SQL delete statements if you run the above query as is. Therefore all you need to do is copy the output and  execute them in the SSMS.

The following screen shot shows the result set:

Script to Delete SQL Agent Jobs
Now lets talk about the other way of using the query. If you uncomment the statement EXEC (@SQLStatement) and comment the PRINT(@SQLStatement) statement and then execute the query it will directly delete the jobs.

The output will not provide any sql statements as shown in the following screen shot. Therefore you should run the query this way only if you are pretty sure what you are doing.

Script to Delete SQL Agent Jobs
Script to Delete SQL Agent Jobs

Now lets see another scenario like when you need to delete all the jobs except the default one ‘syspolicy_purge_history’ job Click Next Page >>

{ Add a Comment }