SSRS Subscription Owners

We have to be sure subscription owners are not going to leave and make the subscriptions they own fail. Here is a way to make this information visible easily. For the reporting group I made a stored procedure which takes as arguments the current owner, desired owner, and other info to do the work.

SELECT
c.Name as report_name,
s.SubscriptionID,
so.UserID as subscription_owner_id,
so.UserName,
s.description,
RS.scheduleid,
‘update s set ownerid=”<<new owner id>>” from Subscriptions s where SubscriptionID=”’+cast(s.SubscriptionID as varchar(100))+”” as [command to update subscription]
FROM
ReportServer.dbo.[Catalog] c
JOIN ReportServer.dbo.Subscriptions s ON c.ItemID = s.Report_OID
JOIN ReportServer.dbo.ReportSchedule rs ON c.ItemID = rs.ReportID
AND rs.SubscriptionID = s.SubscriptionID
JOIN ReportServer.dbo.Users so on s.OwnerID = so.UserID

Posted in SQL, SSRS | 2 Comments

What is Tidal Enterprise Scheduler?

Tidal Enterprise Scheduler is a Cisco product which allows for many things SQL Agent can’t easily do, such as allowing for cross server job dependencies; removal of a single job execution without cancelling the entire schedule; file triggered events; passing parameters from one job to another; job queues; exposing a variety job events including sending alerts when a job takes longer than a defined time or the usual duration; built in gui for viewing future job runs; defining maintenance windows; and no doubt more.

It has a database back end so queries can be written for getting information not as easily found through the gui. That said, like with querying anything directly, it is not so straightforward to the first timer.

While I am not the foremost TES expert by any means, I do have a small library which I’ll share in future posts and also elaborate more on the features and frustrations I’ve experienced as a TES admin.

Posted in SQL, Tidal Enterprise Scheduler | Leave a comment

Making SSMS Work for You

I love taking advantage of the customizable keyboard shortcuts in SSMS. You can put in stored procedures to be run when you press certain key combinations. For example, I have sp_helptext run when I press CTRL+5 and an expanded version of sp_who2 when I press CTRL+3. This way, when I highlight an object, I can simply press CTRL+5 to see the text. You can get to to the Options window in SSMS by clicking on Tools / Options / Keyboard. ALT+1 by default is sp_help.

Posted in Configuration, DBA | Leave a comment

Meetings

We had a discussion at work about meetings, specifically the level of detail needed during round robins being used as an FYI technique. I like the idea that it is a formal time to bring up some ad hoc topic. How are we to catch dependencies if we don’t have any idea of what is going on? On the other hand, I am not a big fan of listing off items for the sake of someone hearing me speak. That is a recipe for phones coming out of pockets. These days we are all so specialized: network people; SAN people; desktop support people; server admins; dbas; virtual machine admins; share point admins; telecom; exchange admins; etc. The chance that everyone needs to listen to the details of what I am up to on a weekly or biweekly schedule is pretty slim.

Posted in Leadership | Leave a comment

Weather Check

A favorite sanity barometer is how many emails are in my inbox. No joke: I know everything is copasetic when I have no more than 50. Too many more and it is time to stop, prioritize and communicate.

Posted in Leadership, Other Things | Leave a comment

Data Compression

If you’re not compressing your tables and indexes, read this: http://www.brentozar.com/archive/2009/08/sql-server-data-compression-its-a-party/. We were able to add a complete additional dev region with the disk savings. And backups are compressable too!

Posted in DBA | Leave a comment

Where Are All The People Who Want to be a DBA?

I have never met anyone who took me up on learning to be a dba. I really like the work myself, figure others would too, and have gone through some genuine lengths to provide opportunities. For example, I volunteered at the local library’s computer department for a year, hoping I’d meet someone. It was great helping people with job applications, itunes questions and some Excel tips. I helped one kid with his resume and he actually got a job! Except there it is: no one was interested.

I’ve brought home old computers from work hoping to teach the local kids how to take it apart and put back together again to help get them work. No one was interested.

Over the years at work I’ve offered to give people projects and teach them how. For example, there are regular audits I like to do to check that jobs which claim to be working are truly doing what was asked. I configured SQL Event Notifications to log blocking (and a host of other interesting events) and it is helpful to run an query on what procedures are causing the most blocking and get to work! Making sure that file growth is appropriate for the file size and that the tran log VLF count is acceptable. These areas can lead to so many conversations about many things.

I really don’t understand. The internet is full of people asking how to become a dba and yet I don’t know any of them?

Posted in DBA | 2 Comments

Local Policy Settings

I have a bunch of sql servers and don’t know whether the required local policies are in place to take advantage of the available memory. I first thought checking who could do what could be found via WMI but nothing surfaced. In my search I did find 2 new things: 1) the MS tool Scriptomatic 2.0 which will generate WMI scripts and 2) something called secedit. In the end I used ntrights.exe in a batch file as follows. As written it requires 2 parameters, the windows user requiring the permissions and server to apply the permissions.

@ECHO OFF
IF “%1” == “” GOTO MISSINGINPUT
IF “%2” == “” GOTO MISSINGINPUT
@ECHO ON
:: Act as part of the operating system
ntrights -u %1 -m \%2 +r SeTcbPrivilege 
:: Lock pages in memory            
ntrights -u %1 -m \%2 +r SeLockMemoryPrivilege
:: Log on as a batch job           
ntrights -u %1 -m \%2 +r SeBatchLogonRight
:: Logon as a service
ntrights -u %1 -m \%2 +r SeServiceLogonRight
:: Replace a process-level token   
ntrights -u %1 -m \%2 +r SeAssignPrimaryTokenPrivilege
pause
exit

:MISSINGINPUT
@ECHO OFF
ECHO You must specify the windows user to apply these permissions
ECHO You must specify the server on which to apply these permissions
pause
exit

Posted in DBA | Leave a comment

Having a number two for log backups

The server which holds the production log backups was not reponding yesterday. It was a pain to go into the tran log backup jobs and manually change them to a new share until the problem was resolved, so I decided to add a fallback step if the default maintainence job failed.

The sql below is heavily inspiried and the error handling at the end totally copied from Tara Kizer’s blog. The big insight was I didn’t know backup and restore commands worked with parameters for the database and destination. 

I didn’t add sql to get rid of old files as it is for when we’re problems and while hopefully that isn’t for too long I’d rather not have to be wondering if the log backups are being deleted.

create proc p_backup_logs (
 @dbname sysname = ‘all’
 , @path varchar ( 1000 )
 )
as

/*
 Make a step 2 for those convienent maintainence plans in case they fail so the
 log backups still occure.
 */

set nocount on

create table #databases ( name sysname )
create table #output ( output varchar ( 8000 ) )

declare @rc int
 , @sql varchar ( 8000 )
 , @name sysname — used in the cursor for holding sysdatabase.name
 , @filename varchar ( 255 )

— @path must have a at the end
if right ( @path , 1 ) <> ”
 set @path = @path + ”

— check if this sql server can access the passed path
set @sql = ‘dir “‘ + @path + ‘”‘
insert into #output
exec master..xp_cmdshell @sql

if exists ( select * from #output where output like ‘%Access is denied.%’ )
begin
 set @rc = 1
 goto exit_procedure
end

if exists ( select * from #output where output like ‘%The filename, directory name, or volume label syntax is incorrect.%’ )
begin
 set @rc = 2
 goto exit_procedure
end

— populate a table with online databases that are not in simple recovery
insert into #databases
select name
from master..sysdatabases
where 1 =
 case when @dbname = ‘all’ then 1
  when name = @dbname then 1
  else 0
 end
 and databasepropertyex ( name , ‘Recovery’ ) <> ‘simple’
 and databaseproperty ( name , ‘IsOffline’ ) = 0
 and databaseproperty ( name , ‘IsShutDown’ ) = 0
 and name not in ( ‘master’ , ‘model’ , ‘msdb’ , ‘resource’ )

— something is wrong if no databases fit the criteria so raise an error
if @@rowcount = 0
begin
 set @rc = 3
 goto exit_procedure
end

declare cur cursor for select name from #databases
open cur
fetch next from cur into @name

while @@fetch_status = 0
begin
 — create a subdirectory for each database
 set @sql = ‘mkdir ‘ + @path + @name
 exec master..xp_cmdshell @sql

 truncate table #output
 
 — make a name with yyyymmddhhmmss added on
 set @filename = @path + @name + ” + @name + ‘_’ + convert ( char ( 8 ) , getdate() , 112 ) + replace ( convert ( varchar ( 8 ) , getdate() , 108 ) , ‘:’ , ” ) + ‘.trn’
 — Brackets and quotename didn’t work… set @name = quotename ( @name )

 backup log @name to disk = @filename
 restore verifyonly from disk = @filename
 
 fetch next from cur into @name
end

deallocate cur

exit_procedure:

if @rc <> 0
begin
 DECLARE @rm varchar(500)
 DECLARE @error table (returnCode int PRIMARY KEY CLUSTERED, returnMessage varchar(500))

 INSERT INTO @error(returnCode, returnMessage)
 SELECT  1, ‘Access denied in passed path ‘ UNION ALL
 SELECT  2, ‘Bad folder specified in passed path’ UNION ALL
 SELECT  3, ‘No databases to backup’

 set @rm = ( select returnMessage FROM @error WHERE returnCode = @rc )

 RAISERROR(@rm, 16, 1)
end

drop table #databases
drop table #output

return

Posted in Day to day | Leave a comment

Changing The Port Used By SQL Server

We need to change the port sql server uses from the default to… something else. Towards that end I want to make aliases on all the end user computers and other sql servers so they can still connect without problems.

Thank you to microsoft’s scripting guy and this article.

First I made a file with all the computers in the domain. Save this as getadcomputers.ps1 and then run it within powershell like this: .getadcomputers.ps1 > .computer.txt

# run as the following to save all the AD registered computers
# .getadcomputers.ps1 > .computer.txt

$strCategory = “computer”

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = (“(objectCategory=$strCategory)”)

$colProplist = “name”
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

$colResults = $objSearcher.FindAll()

foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}

Then I added that to a friendly Access table, decided what computers to exclude, and made a routine to loop through and create the aliases.

Sub AddRegKey()

‘ Loops through the table sfhpComputers and
‘ 1. checks if the keypath & value exists
‘ 2. if yes then logs a message and continues
‘ 3. if not then adds the key and checks the add worked and logs a message

Dim strKeyRoot, strKeyPath, strValueName, strData, strValue, strType
Const HKEY_LOCAL_MACHINE = &H80000002
strKeyRoot = “HKEY_LOCAL_MACHINE”
strKeyPath = “SOFTWAREMicrosoftMSSQLServerClientConnectTo”
strValueName = “newAliasName”
strData = “DBMSSOCN,fullSQLServerName,NewPortNumber”
strType = “REG_SZ”
Dim rs As DAO.Recordset

Set rs = CurrentDb.OpenRecordset(“select name, Note1, Note2 from Computers”)

With rs
Do While Not .BOF And Not .EOF
strComputer = !Name

‘ Check if the key exists
Set objregistry = GetObject(“winmgmts:\” & _
strComputer & “rootdefault:StdRegProv”)
objregistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

If Not IsNull(strValue) Then
.Edit
!Note1 = “The registry key ” & strValueName & ” – ” & strData & ” already exists.”
!Note2 = Null
.Update
GoTo nextComputer
End If
‘ End check if the key exists

‘ Begin code to add registry key
shellcmd = “reg.exe add \” & strComputer & “” & strKeyRoot & “” & strKeyPath & ” /v ” & strValueName & _
” /t ” & strType & ” /d ” & strData

output = Shell(shellcmd)
‘ End code to add registry key

‘ Now check the key was added
Set objregistry = GetObject(“winmgmts:\” & _
strComputer & “rootdefault:StdRegProv”)

.Edit

If Err = 462 Then
!Note1 = “Computer ” & strComputer & ” does not exist.”
!Note2 = output
GoTo nextComputer
End If

objregistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

If IsNull(strValue) Then
!Note1 = “ERROR: The registry key ” & strValueName & ” – ” & strData & ” not added successfully.”
!Note2 = output
Else
!Note1 = “The registry key ” & strValueName & ” – ” & strValue & ” added successfully.”
!Note2 = output
End If

.Update

nextComputer:
.MoveNext
Loop
End With
End Sub

Posted in Configuration, DBA | Leave a comment