Category Archives: Database Administration

For this T-SQL Tuesday we are asked to look into our crystal SQL Server ball and predict what will be happening at the time of T-SQL Tuesday #200. I went to the garage, dug that thing out, cleaned it up, and boy it had a lot to say!

Assuming we’re all friends here, and there is some fun to be had with this…

T-SQL and JSON had a baby. All queries in SSMS resemble a hybrid of the two languages.

SSDT has been replaced by VSDT. Nothing has really changed but the acronym. As always, you can still expect some things to break when you do updates.

Microsoft bought NHibernate. You still have all the same issues as before but now you post them to Microsoft Party (it replaced Collaborate…after that replaced Connect) and actually watch them not get fixed. And you can’t post work-arounds in MS Party (so it’s not much of a party).

MS NHibernate still generates SQL queries that are long and redundant, but it’s not handling the TSQL-JSON baby very well. So there’s that.

Microsoft acquired ActiveBatch and it is now called SQL Server Batch and has replaced SQL Server Agent for scheduling jobs in SQL Server 2026. Consequently, companies have been reluctant to upgrade from SQL Server 2023 (especially the ones that have used ActiveBatch).

For the companies that are upgrading, they have found that calling PowerShell scripts from scheduled tasks to be a good way to bypass using SQL Server Batch. Increase the in the demand for DBA’s with extensive PowerShell experience sky rockets!

The rumors back in 2018 proved to be unfounded – DBA’s are still in high demand. All the talk of SQL Server tuning itself turned out to be DTA 2.0.

Microsoft brought back the MCM. And then killed it again the next year.

Azure has been replaced by Rainbow. Data is no longer in the “cloud” – it is in “rainbows.” Pricing is based on the colors of the rainbow and the color names are garnet, citron, lemon, lime, azure, and violet.

PASS still exists. Due to some bylaw changes, elections have not been held since 2019. Grant Fritchey [B|T] is still president and attends meetings remotely from his nursing home.

Just kidding – Grant’s not in a nursing home. That’s just where he says he is. There was some backlash when PASS did away with SQL Saturday events. Grant’s really in witness protection and goes by the name Thomas LaRock [B|T].

Thanks to Adam Machanic [B|T] for hosting the T-SQL Tuesday this month, and for coming up with this whole thing to inspire all of us to write more and continue to share knowledge. While there was absolutely no knowledge in this post, I do hope that I got a giggle from at least one person.

When I was growing up I remember my mom talking about an old, scary, movie that she saw when she was young. In the movie some teenagers were making prank phone calls saying “I saw what you did and I know who you are.” One of the calls happened to be made to a guy that just killed his wife. Joan Crawford played a woman that was romantically inclined to said murderer. She eventually meets her demise when he stabs her because she knew about the first murder.

How every DBA feels when there is blocking

While blocking in SQL server might not be a felony offense (it isn’t…but it should be – WHO’S WITH ME?) as the DBA you not only want to know what is being blocked, but also who is doing the blocking and what in the H-E-Double-Hockey-Sticks they are doing.

At SQL Saturday Orlando I talked about this very thing and the query I defer to for the information.

IMA GONNA HUNT U DOWN!

It might look complicated but it is actually very simple – query sys.sysprocesses with a cross apply using the sql_handle to get the text of the query, and then an outer apply with the same query again but you are joining to the blocking spid so you can get the text for the query that is doing the blocking. Beyond that, you can filter on various columns and refine your output

WHY ARE YOU BLOCKING YOURSELF? WHY ARE YOU BLOCKING YOURSELF? WHY ARE YOU BLOCKING YOURSELF?

Of course, I know you can’t run this without the code (and I know that’s why you’re here…because I SAW WHAT YOU DID!)

Transact-SQL

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

SELECTx.textASblocking_text

,x.nt_username

,x.nameASblocking_db

,st.text

,a.nt_username

,d.nameASblocked_db

,a.status

,a.*

FROMmaster.sys.sysprocessesa

INNERJOINsys.databasesdONa.dbid=d.database_id

CROSSAPPLYsys.dm_exec_sql_text(a.sql_handle)ASst

OUTERAPPLY (SELECTblock.text,aa.nt_username,aa.spid,dd.name

FROMmaster.sys.sysprocessesaa

INNERJOINsys.databasesddONaa.dbid=dd.database_id

CROSSAPPLYsys.dm_exec_sql_text(aa.sql_handle)ASblock

WHEREa.blocked=aa.spid)x

WHERE1=1

--AND a.hostname LIKE 'SOME-HOSTNAME%'

--AND a.program_name LIKE 'Some program name%'

--AND a.dbid = ????

--AND a.spid IN (???)

--and a.status not like 'sleeping%'

----AND (st.text LIKE '%text string you want to isolate%')

---and a.blocked != 0

--AND (a.nt_username LIKE '??????%')

If you are looking for a good way to troubleshoot blocking I hope this helps. If you have some folks running queries that are making you stabby, run this, find out what is going on, and then remove their access try to help them so they aren’t making you stabby any more. Then tell them they need to buy you a beverage because they are still alive.

I discovered something last week – I had not blogged about little things that I thought I had blogged about. What the heck does that mean? It means that I tried to reference my blog for something because I thought “I totally blogged about that”…and found out that was not the case.

Starting now, I am fixing this situation. There was something that popped up today that called for a PowerShell script and the Get-ADGroupMember cmdlet – get a list of users from a list of groups. Some users are in there more than once so this needs to be a distinct list, unless you are into manually cleaning up things like this, and then I will be sad for you. Because that is kinda sad.

I originally wrote a script with two arrays (one for the initial list and one for the de-duped list of users), but even though this is quick and dirty, that was a little too dirty. Enter the Group-Object cmdlet – it takes this list of names and groups them. No black magic this time. Just a cmdlet, that comes baked into PowerShell giving me what I need.

What? You wanted the code too? Oh, OK.

PowerShell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<#

Name: activedirectory get list of users from multiple groups.ps1

Author: Amy Herold

Date: 24 October 2017

Purpose: Get distinct list of users from multiple AD groups.

#>

$groups=@('Admins','Managers','Some Other Group')

$people=New-ObjectSystem.Collections.ArrayList;

$people.Clear();

#--------------get list of users from list of groups--------------

foreach($gin$groups)

{

$people.Add(@(Get-ADGroupMember-Identity$g|selectname))|Out-Null;

}

#------------use group-object and get a distinct list of names--------------

$people.Name|Group-Object|selectname

There you have it – quick, dirty and to the point. Enjoy. 🙂

UPDATE: Mathias Jessen tweeted a one liner for this….so no need for the one array! Woohoo!

PowerShell

1

('Admins','Managers','Some Other Group'|Get-ADGroupMember|Group-Object-PropertyName-NoElement).Name

I was trying to do this but was also just trying to get it done, and if in doubt, I slap things in arrays. Thanks Mathias!

This Saturday will mark the fourth year that I will be speaking at SQL Saturday Baton Rouge at LSU. Out of all the SQL Saturday events I have participated in since 2014, Baton Rouge is one of the few that I have been to every year since. Houston is another one…and actually, these may be the only ones only because they have had an event every year.

Not only am I speaking on Automation with PowerShell and Deadlocks and Blocking, but I am also participating in a panel discussion on Careers in IT. I’m excited to be invited along with some of the other speakers to be a part of this. Looking back on my own school days, I knew I would have a career in IT, but little did I know I would detour from a path in development to the world of SQL Server, and becoming a DBA.

How do they make this happen? Work. Lots of hard work. After helping with SQL Saturday Dallas 2015, joining the NTSSUG board in 2016, and then having an organizing role in 2016, I found out how much goes into the planning of these events. If you have attended a SQL Saturday or you are going to in the future, be sure to say “THANK YOU!” to all the organizers and sponsors. If you want to get more involved in the SQL Server community, SQL Saturday is a great way to do that – just show up at the event, find an organizer and tell them that the SQL Kitten sent you to be their humble servant volunteer for the day…or you could just say you want to volunteer and leave out the other stuff because it might make it weird.

After whining about not blogging enough, I am going to do something about this. Whether it is PowerShell or SQL, simple or complex, I know that others can benefit from my knowledge and expand their skill sets.

And you are like “That’s great Amy…where’s the PowerShell we are here for?” Ok, Ok….keep your drawers on! 😉

Recently I was tasked with gathering the system information from all of the servers at a client. Another opportunity for some PowerShell dominance.

get_sysinfo.ps1

PowerShell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<#

Name: get_sysinfo.ps1

Author: Amy Herold

Date: 03 May 2017

Purpose: Get the system information from a list of computers/servers, doing one machine at a time and outputting server name

when you can't connect. Output information to a NFO file with the name of the machine.

Notes: Get your list of servers and update the $servers variable below. Make sure they are also formatted the same way as in the sample.

Update the $path variable with where you want to save the NFO files.

#>

<#------------variables you need to change---------------#>

$servers=@('server1','server2');

$path='C:\Where_You_Want_The_Files\system_info\';

<#-------------------------------------------------------#>

foreach($sin$servers)

{

#------as long as we can connect to the machine, get the system info--------

if((Test-Connection-Cn$s-BufferSize16-Count1-ea0-quiet))

{

$filepath=$path+$s+'.NFO';

$cmd="C:\windows\system32\msinfo32.exe";

$args="/computer $s /nfo $filepath /categories +all";

#if you can connect to the server, gather and save sysinfo

Start-Process$cmd$args-Wait;

}

else

{

"Cannot connect - $s"

}

}

With this script you can generate system information files and save them to a specified location. It makes sure a connection can be made to the server first, and then outputs the file. The files are created one at a time, so if you pass in a longer list of servers, you shouldn’t crash your machine. From my testing, this will take some time to run as these files don’t output quickly. Despite that, the output is worth it. This can be modified to pull your list of servers from a file or from a Central Management Server (CMS) instance.