Tag: dbatools

  • Easy Database Space with dbatools

    One of the things that I’ve seen DBAs query for is free space in a database. In fact, this is one of the most common questions posted on SQLServerCentral by newbies that are trying to manage their instances and ensure they don’t use too much space or run out of space.

    The most common way to do this is with sp_spaceused. This system stored procedure has been around for a long time and is commonly used. However, it’s cumbersome to me. I get two result sets, I get data formatted in both MB and KB, it’s hard to use for multiple databases, and incorporating it with some automated tracking gets annoying. Not hard, just annoying.

    Get-DbaDatabaseFreespace

    Enter dbatools. One of the cmdlets included is Get-DbaDatabaseFreespace and this does exactly what you’d expect. This takes the name of an instance as a parameter, and when you run it, you get a bunch of information about your databases and their space usage.

    2016-12-29 09_17_01-powershell

    These are good numbers, but with PoSh, I can easily just get the data I want. For example, I can add a –Databases parameter and see specific databases.

    2016-12-29 09_31_21-powershell

    I can also limit reformat the data in a table and limit what’s returned:

    2016-12-29 09_32_29-powershell

    This flexibility to easily see data is one thing that I like about PosH. I could pipe this into a filter and look for those items that are of a certain size, or have a certain percentage value.

    Putting this into a report, or even an alert that might get sent to DBAs is a great way to keep an eye on space and ensure that you don’t run out of space. Of course, tracking this over time is easier with a tool like SQL Monitor, but for quick checks, this dbatool is very handy.

    If you haven’t played with these, I’d recommend you do this. This collection makes working with SQL Server and PoSh much easier.

  • Easily Move Databases with Copy-SqlDatabase

    One of the things that people have asked to be implemented for many years is an easy way to copy databases. SSIS has the Copy Database Task, but that has been problematic over time. As a result, while easy, it’s cumbersome to take a backup of a database, copy it to a new instance, and restore it. Or use the detach/copy/attach/attach method.

    dbatools gives us a nice, easy Posh command to perform this task: Copy-SqlDatabase. I made a quick test recently to see how this works. Using the –Whatif option, I tried to copy a database from one instance to another on my main computer.

    My first attempt didn’t do well.

    2016-11-22 10_32_58-powershell

    I was thinking there would be a default method, but there isn’t. You must specify using the backup/restore method or the detach/attach method. I decided to try the detach/attach method.

    2016-11-22 10_31_08-powershell

    As you can see, this looks to detach and then reattach the database, so let’s try it. First, check my QA instance. There is no DBAAdmin database.

    2016-11-22 10_31_42-SQLQuery1.sql - localhost_SQL2016.DBAAdmin (PLATO_Steve (67))_ - Microsoft SQL S

    This is a small database with just a few procs and tables in it. When I remove the –Whatif option, it works.

    2016-11-22 10_31_28-powershell

    I saw the green PoSh flash in the middle as the file was copied from one location to the next using the BITS method. When I looked in my SQL2016_qa instance, I saw the database and objects.

    2016-11-22 10_31_54-SQLQuery1.sql - localhost_SQL2016.DBAAdmin (PLATO_Steve (67))_ - Microsoft SQL S

    All in all, this took about two minute for me to move this database. Certainly that is about the time of a backup, but I did this with one command, and it felt much, much easier.

    There was a downside for me. I need to double check this, but I didn’t get the database re-attached at the source, and I had to do that myself. The files were there, just not attached. Perhaps it’s just me, so I’ll retest when I get the chance, but it seems to be a minor bug.

    I also tried the backup/restore option here. I had to provide a fileshare, which I chose to be my local D: drive. Note, this has to be provided or a popup will appear. This also has to be \\server\share, not d:

    2016-11-22 10_51_03-powershell

    This worked, with the new database appearing on my second instance.

    2016-11-22 10_50_47-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63)) - Microsoft SQL Ser

    The backup was also removed from my drive:

    2016-11-22 10_51_25-EVO850_500 (D_)

    Overall, this is handy, and I’ll likely use this as my default method for moving databases between instances.

  • Moving Tasks with Copy-SqlJob

    More dbatools experimentation for me. This is a great set of Powershell cmdlets that solve simple, handy problems. In this post, I want to look at Copy-SqlJob, which will allow me to easily move jobs from one instance to another.

    The Job Subsystem

    Jobs in SQL Server are part of the SQL Agent subsystem, which means they’re a part of SQL Server, but not really. Maybe the one part of the jobs that is really complex is getting the code for the job. You either need to use an SMO interface and script out the job, or you can decode the tables in msdb. Neither of which is handy.

    We do need to move jobs, though. Perhaps the most common places I need to copy jobs around is for a DR (disaster recovery) situation. Clustering will move jobs from node to node as it covers the instance, but all the other technologies (AGs, Log Shipping, Mirroring), all of these only work with databases. So items like jobs need to be manually moved.

    That’s not good.

    Over time, we’ll edit, add, change jobs, but I’ve never seen anyone do a great job of actually ensuring the DR systems are up to date with jobs, logins, etc. all the time. There’s too much of a manual process.

    That can change with Copy-SqlJob. I can now not only copy particular jobs between an instance, I can use a –Force command to ensure the copy takes place. This means that I can easily ensure the most recent version of my job is copied over. Or I can just skip this, and if the job exists, it’s not copied.

    Running the Cmdlet

    It’s easy to use this cmdlet. It can use Windows Auth or SQL Auth. It’s up to you. The documentation leaves something to be desired, so you’ll need to use the PowerShell Get-Help to learn what parameters exist.

    For a simple copy, I’ll move all jobs from one instance to another. Here are the jobs on my primary SQL Server 2016 instance.

    2016-11-22 09_11_09-SQLQuery1.sql - localhost_SQL2016.DBAAdmin (PLATO_Steve (66))_ - Microsoft SQL S

    These are administrative, backup jobs and index jobs from Ola Hallengren. I don’t have these on my QA instance, which isn’t good.

    2016-11-22 09_11_25-SQLQuery1.sql - localhost_SQL2016.DBAAdmin (PLATO_Steve (66))_ - Microsoft SQL S

    Suppose this is a new instance and I want to add them? I can use Copy-SqlJob, but I want to know what will happen. I’ll use the –Source and –Destination parameters and then include a –Whatif. This gives me a list of jobs that will be copied, and those that won’t be.

    2016-11-22 09_21_13-powershell

    If I use the –Force parameter, you’ll see that all jobs are copied.

    2016-11-22 09_22_25-powershell

    Well, not copied, but they will be.

    I could limit this to specific jobs. For example, let me just copy over these jobs

    • DatabaseBackup – SYSTEM_DATABASES – FULL
    • DatabaseBackup – USER_DATABASES – FULL

    When I run the command with the –Jobs parameter, I see just these jobs moved:

    2016-11-22 09_45_14-powershell

    Let’s actually do that. Once I remove the “”-Whatif” and run the command, I see this:

    2016-11-22 10_09_21-SQLQuery1.sql - localhost_SQL2016.DBAAdmin (PLATO_Steve (66))_ - Microsoft SQL S

    Note, this doesn’t actually move the dependent objects. Meaning the first job uses this procedure:  [dbo].[DatabaseBackup]

    I’d have to make sure this is copied separately for the job to actually run and succeed. Right now it will fail with an error that an object can’t be found. However, if you have jobs that you are using in a DR situation, this ensures the job itself is moved over.

    Rather than copy the syspolicy_purge_history job, I’ll exclude it. I can do that with the –Exclude parameter. Note that the two jobs I’ve already copied are shown as warnings.

    2016-11-22 10_11_39-powershell

    All the parts of the job itself are copied. The description, the owner, the comments, the schedule, the steps. Everything is copied, which makes this perfect for ensuring that when you deploy a job, it can be deployed to all of the places you need it deployed by copying it from the source.

    Of course, you’ll also want to ensure you use some method to disable the jobs on the DR instances (along with re-enabling them on failover).

  • Quick PoSh Kills with Stop-DbaProcess

    I’ve been trying to get used to using the dbatools cmdlets in PoSh. They help me learn some PowerShell, but they also make some things easier. As a part of my practice, I’m documenting the various items I’ve played with. This post looks at Stop-DbaProcess.

    Killing Spids

    At first I didn’t think much of this cmdlet, because I need to know a spid right? The time it takes me to run sp_WhoIsActive or sp_who2, find a spid, and decide to kill it is most of the time. A quick “kill xx” is easy in SSMS.

    This cmdlet does more, which makes it really handy for me. I know it’s just issuing a kill in the background, but it does have some features that perhaps make this more enticing, especially during times where I might need to quiesce  a server and remove a number of users.

    The first thing that comes to mind is that I can quickly kill all the users using a particular program. For example, I had a demo app with a generic connection to SQL Server. When I ran it, there were multiple connections to SQL Server. If this had been behaving badly, perhaps with a long running query, I’d have had to kill both of these to ensure I got the right one. In a demo, perhaps “kill 60” and “kill 62” is quick enough.

    2016-11-21 16_47_25-SQLQuery1.sql - localhost_SQL2016.sandbox (PLATO_Steve (66))_ - Microsoft SQL Se

    I could have done this, though.

    2016-11-21 16_47_18-powershell

    Way more typing, right? Sure it is. There’s an advantage, which I could have used more than a few times in my career. I didn’t have to look up the Spid with PoSh. In various jobs where I’ve had poorly behaving applications, I’d have to get a list of processes, find the numbers, and kill each of them individually. Easy as a one-off, harder (and annoying) when you are interrupting work regularly to repeat a tedious process.

    With Sop-DbaProcess, I can keep this script ready and have it kill all the connections using that program name, whether there is 1 or 100.

    What’s more, I have more options to exclude particular spids or logins, limit this to databases, run across multiple hosts, etc.

    Simple, easy, and useful in some situations. I wouldn’t kill a single process with this, but I’d certainly want to use this if I had to repeat myself over and over.

    Give dbatools a try and see where you might start finding PoSh to be useful while administering SQL Server.