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 = “SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo”
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 & “\root\default: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 & “\root\default: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

What to do if database mail is not working.

Mail was not being sent. First I queried

SELECT * FROM msdb.dbo.sysmail_event_log

and saw in the description field

“The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 1 (2009-03-31T12:24:10). Exception Message: Could not connect to mail server. (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [ip address]:[port number]). )”

Running

EXEC msdb.dbo.sysmail_help_status_sp ;

returned “inactive”

Some websites suggested that the people trying to send mail need to be in the msdb role DatabaseMailUserRole, so I checked that

EXEC msdb.sys.sp_helprolemember ‘DatabaseMailUserRole’ ;

but then I remembered I am a sysadmin and am not able to send mail.

Then I practically ran this

select name , is_broker_enabled from sys.databases

and this and then could send mail:

alter database msdb set single_user with rollback immediate
alter database msdb set enable_broker
alter database msdb set MULTI_USER

These procedures may be helpful too:

exec msdb..sysmail_help_principalprofile_sp
EXEC msdb.dbo.sysmail_help_queue_sp @queue_type = ‘mail’ ;
exec msdb..sysmail_stop_sp
exec msdb..sysmail_start_sp

Except the jobs still could not send mail. For some reason sql server agent did not have database mail set up. After pointing and clicking to get that together I thought I was done, except now I got this error:

The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 1 (2009-07-06T14:10:00). Exception Message: Cannot send mails to mail server. (The specified string is not in the form required for an e-mail address.). )

This error was because the operators were defined with mapi names and not full email addresses.

Whew done!

I was asked to trace department’s access to a certain sql server here.

To create a trace that is run by sql server, open profiler and define your trace. Then, while it is not running, you can script it by going to the File-Script Trace menu and save the sql.

Either make a stored procedure which contains the sql or just paste in into a job step. Have your job run when sql server agent starts or set your procedure as a startup procedure with sp_procoption.

Once the trace is running you can check on it with:
SELECT * FROM ::fn_trace_getinfo ([the trace id])

Stop it with:
exec msdb..sp_trace_setstatus [the trace id] , 0 — stop the trace
exec msdb..sp_trace_setstatus [the trace id] , 2 — close and delete the trace defination

I also added the following so if there was an existing output file it would be renamed.
exec master..xp_cmdshell ‘ren [path to your trace output] “%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%-[some common name]“‘

Also, I increased sp_trace_create’s parameters @options to rollover to a new file and @maxfilesize to a much larger file size just in case.

Later I will import the results into sql server and total the cpu, duration, and reads and writes by workstation.

There is a column name and defination change and lots of code has to be examined. The developers were worried about looking through the many DTS packages. Happily the contents can be queried using sql-dmo.

The short of it is looping through all the DTS packages, one at a time setting a reference to is with the DTS.Package2 object, and then looping through the tasks and the task’s properties.

I made a table to insert each package’s, task’s, and property’s values, including the server too and then was able to query for the column in questio. Woo-hoo!

This came in handy for looking for code within view, procedures, etc:
exec sp_msforeachdb ‘use [?] ; select distinct db_name(), name from sysobjects so join syscomments sc on so.id = sc.id where sc.text like ”%<>%”’

One of my friends asked me how I found a job so fast after such a long vacation. Here is what I wrote to her:

  • Does your resume shout out that you meet the job poster’s qualifications requirements? 
    Here is my resume; do a search for ”sql server dba” at dice.com or some other site and see how I basically show how I’ve done what they’re asking for. Of course I am not a 100% match for every post…. but you get the picture.
  • Are you doing the “linked in” thing and looking there too?
    Read this for some ideas.
  • Are you really taking honest time every day to do EVERYTHING you can to get a job? This is a serious question that you have to answer by taking some time and being sincere with yourself.
    For example, here is one thing you can do: volunteer at a place where you’d like to work for a day or two a week. Or offering to work for cheap for a week so they can see how much they need you if the interview doesn’t go well.
  • Do a search on “interview questions” and be an expert at interviewing. This REALLY REALLY helped me when I got a call back (I also searched for interview questions for my field and studied hard; people dig small facts).

Good luck to everyone with their search.

I really like sp_msforeachdb. For example, here is the sql to my regular maintenance jobs:

  • exec sp_MSforeachdb ‘DBCC CHECKDB(?) with NO_INFOMSGS, ALL_ERRORMSGS’
  • exec sp_msforeachdb ‘if db_id(”?”) <> db_id(”master”) and db_id(”?”) <> db_id(”tempdb”) begin use [?];exec sp_dbreindex_or_indexdefrag;end’
  • exec sp_msforeachdb ‘if db_id(”?”) <> db_id(”master”) and db_id(”?”) <> db_id(”tempdb”) begin use [?];exec sp_updatestats;end’

Yesterday I was reducing the number of vlfs and to check I’d covered all databases I ran:

  • sp_msforeachdb ‘use ?;select db_name();dbcc loginfo’

See what I mean?

The only hitch is if your database name has a reserved character – here there are some with a dash – you’ll need to do [?] instead of just ?.

In my combing through of the sql servers I found a startup stored procedure on one of the sql servers here. I didn’t recognize the tables it created or its name, so I asked around: no one else knew anything either. How to gracefully deal with this? Simply remove its startup property creates a timebomb. I decided to alert the production services manager, who gets all the issue emails, send what to do if there is a complaint and I am not available, and then drop what the procedure creates and hold my breath.

use tempdb
go
drop table <<table name>>
drop table <<table name>>
 
– remove it as a startup procedure
use master
go
exec sp_procoption @procname = ‘<<proc name>>’, @optionname = ‘startup’, @optionvalue = ‘false’
go
 
– shows that there are no startup procedures
select name from sysobjects where type = ‘p’ and OBJECTPROPERTY(id, ‘ExecIsStartup’) = 1

– So, if people complain, then run 
exec master..<<proc name>>
exec sp_procoption @procname = ‘<<proc name>>’, @optionname = ‘startup’, @optionvalue = ‘true’

We have a lot of jobs owned by many different accounts due to the currently lax security. Before cleaning up the local admins group and removing all sysadmin role members it is important to make sure the jobs that are currently running with elevated privileges remain running with elevated privileges. Something like this site explains it well enough.

select sj.name , sl.name
from msdb..sysjobs sj join master..syslogins sl on sj.owner_sid = sl.sid
where sl.name <> ‘sa’

How to generate the sql to make those jobs be owned by sa:

select ‘exec sp_update_job @job_name = ”’ + sj.name + ”’ , @owner_login_name = ”sa”’
from msdb..sysjobs sj join master..syslogins sl on sj.owner_sid = sl.sid
where sl.name <> ‘sa’

I configured 3 of the development sql servers to use the available memory last night. 2 had 8gb; 1 had 4. The one with 4 just required adding the /3GB and a restart; for the other two I modified the boot.ini, restarted the server, and then ran sp_configure to set the max memory and to enable awe. They only claimed 3gb of the available memory though.

After some searching I found hotfix 899761 is needed for sql server 2000 sp4.  If the sql server version is 8.00.039 and it isn’t using all the available memory, apply the hotfix and get to 8.00.040. How long has sp4 been out and where have I been? A story for another time.

I’ve been referring to this article for years to find what combo of PAE and 3GB to use.

The first time I did this on Windows Server 2003 I remember crapping in my pants because I couldn’t figure out why sql server didn’t grab the memory like it did with Windows 2000.

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

Next Page »

Follow

Get every new post delivered to your Inbox.