Automating Tasks With PowerShell
What we’re really talking about in this series is automation, specifically by using PowerShell. Now, in simple terms, automation is about removing the human, manual element in doing tasks. This will produce time savings for you as a DBA in the long run and provide better consistency in your environment than doing things manually. Better consistency means reduced or easier troubleshooting because your SQL Server environment will be more consistent with automation. All of this will make your SQL Servers easier to manage.
Imagine being able to migrate an entire SQL Server instance with a single command! You can do this with PowerShell. You want to copy logins from one server to another without installing sp_help_revlogin and working through the scripting process involved? You can do that with PowerShell. You want to copy DatabaseMail settings from one server to other servers without writing out all the T-SQL? You can do that with PowerShell!
With PowerShell you can get information faster than from a GUI, especially when that task needs to be done on multiple computers. These tasks include things like like search event logs, search the SQL Server Error Log, get the status of services, see sp_configure information and more.
You can also do things like copy SQL Server jobs from one server to another or export the results of sp_configure to a file. When doing an action like backing up a database, PowerShell also enables you to output the actions of the script itself and thereby create a self-documenting log that you can look at afterward to see exactly what the script did. With a module called DBATools, you can migrate an entire instance to a new SQL Server with a single, short command.
Getting Set Up for Using PowerShell
PowerShell is already installed on Windows. Different OS versions have different versions of PowerShell. There is a process to use for updating your PowerShell version. I’ll not be showing that process in this series though.
Also, in order to follow along in the series. You will need to get the DBATools module for PowerShell. Instructions for doing that are located at DBATools.io. The simple answer is to open PowerShell as an Administrator and run the below command. There are some things to consider and so that’s why the link to DBATools instructions on installation.
You will want the SQLServer module in order for some of these commands to work properly, and you may want to explore the more “native” way to use PowerShell with SQL Server, without the aid of the DBATools module. I think DBATools simplifies things so immensely that it is indispensable. However, you may be curious about what is in the SQLServer module for PowerShell. If so, you can add the module to your PowerShell by opening PowerShell as an administrator and running the following.
Install-Module -Name SqlServer
Once you have DBATools and the SQLServer module installed, you are ready to get started.
Finding Available PowerShell Commands
Get-Command: This cmdlet enables you to explore what is available to do in PowerShell. For instance, you might run the below to see what commands are available in PowerShell related to backups. Notice you can use asterisks as wildcards as well as specify a PowerShell module to look in for commands. If you don’t have the DBATools module, I urge you to get it installed and start using it, if for no other reason than that you will need it if you’re going to follow along with the examples!
Get-Command *Backup* -Module DBATools, SqlServer
The above command will output a long list of things. You can backup computer certificates, database certificates, find information about backup history and throughput, as well as a lot of other things beyond simply using PowerShell to make a database backup.
Maybe you’re interested in what is available for Logins or Database Mail. If so, try the below commands. Notice that the second command says “gcm”. What is that? Well, that is a shortened version, or alias, for Get-Command. Most, maybe all commands, have an alias you can use. Aliases provide a shorter way to write a command, but when someone else is looking at your code, then they have to know what your alias is for. Otherwise it will be harder to figure out what you’re code is doing.
Get-Command *Login* -Module DBATools, SqlServer
Getting Help with PowerShell Commands
From the above example where you are looking for commands containing the word “Login”, you should see something similar to the below if you have DBATools and the SQLServer module installed.
Let’s start simple and review Get-DbaLogin. In your PowerShell window run the command below.
Get-Help Get-DBALogin -Detailed
From this code you will get an output that provides a summary of what the cmdlet does, the syntax options it can be used with and a text description of what those syntax options do.
Let’s say that you’re interested in finding information about the Logins on your SQL Servers. If you just pass this command to PowerShell you will get a list of all the logins on the SQL instance with some properties. Of course, you will want to substitute your own valid SQL Server instance name.
Get-DbaLogin -SqlInstance MySQLInstanceName
The output will list the computer name, SQL Server instance name, name of the login, the login type, create date, the last login timestamp and some other useful properties.
Let’s suppose we only cared about the logins that weren’t system logins so we want to exclude logins like NT Service\SQLWriter and the ones whose name starts with ##. How do we do that? Well, look at the help output again and notice the -ExcludeFilter option. Add that to the earlier command, like so:
Get-DbaLogin -SqlInstance MYSQLServerInsstane -ExcludeFilter '##*', 'NT*'
Now let’s suppose that you are only interested in a couple of the properties that are output from this command. You’re interested in the login name and the last time that login accessed this SQL Server.
To get only those properties we can do what is called “piping”. This is where the “|” symbol is used to move PowerShell output from the left over to the right side of the script objects. This is often done for filtering or to pass along PowerShell output for further processing by other commands. PowerShell output looks like text, but it’s really .Net objects.
In the first example below, you’re passing all the objects left from Get-DbaLogin when the ones with ‘##*’ or ‘NT*’ are eliminated and then telling PowerShell to display only the Name and LastLogin objects.
In the second example, you will be sending the output of the command to a file.
Get-DbaLogin -SqlInstance MySQLServerInstance -ExcludeFilter '##*', 'NT*' | SELECT Name, LastLogin
Get-DbaLogin -SqlInstance Skolarlee-PC\KRONOS2017 -ExcludeFilter '##*', 'NT*' | SELECT Name, LastLogin | Out-File 'C:\DBATools\LoginsOutput.txt'
On my local PC this returns the sa account and my local Windows account along with the last time these accounts accessed the SQL Server. This sort of information is useful, probably in a number of scenarios, but let’s suppose that you’re doing an audit of SQL Server logins because you suspect you have a lot of left over, unused logins. You might want to examine them to see if you can drop users and logins that are no longer being used. This sort of thing makes your SQL Server easier to manage because you don’t have unused Logins and database users cluttering up your SSMS when you’re connected to a SQL Server.
Let’s suppose you don’t want or need to do something with this information right now, but you want to review it later, or provide it to someone else for review. What can you do? The simplest thing is to use the second command above to send the PowerShell objects to a text file by using the piping technique I mentioned earlier. The directory in the Out-File command needs to exist already but the command will create the text file for you. This information can be written to a share for your team to access later. You can also do things like email this output to the team using a PowerShell command for email. If you run GCM *mail* in PowerShell, you will find a command that lets you do this.
How To Script Out SQL Server Logins With PowerShell
Another powerful thing that can be done with a one line PowerShell script is scripting out your logins and users. This cmdlet from the DBATools module will create a script of your logins at the server level and their corresponding database users and all associated permissions. Look at the help for this command.
#Start by getting the help for the command
Help Export-DbaLogin -Detailed
Now that you have reviewed the help content, let’s try something.
Export-Dbalogin -SqlInstance MySQLServerInstanceNameHere -Path 'C:\DBATools\'
Now go to the C:\DBATools\ directory and double click the .sql file. SQL Server Management Studio will launch and prompt you to connect to a SQL instance. Once you do that, the script will load. Review the output and take a look at the Help output from PowerShell to see what else you can do with this. This command gives a DBA a great way to script out login and user information, and this can be helpful for migrations or for providing a history of changes to logins, users, and their permissions.
Next Steps To Take
- Explore more commands and the possibilities that they offer. Here is a place to start.
GCM *export* -Module DBATools
Help Export-DbaInstance -Detailed
Export-DbaInstance -SqlInstance MySQLServerInsanceNameHere -Path C:\DBATools\
2. Find a book or video series on PowerShell and consume that material.
3. Read some of the documentation and blogs over at dbatools.io .
4. If you would like help with anything in this post, or with something else related to SQL Server, reach out to me here, or on Twitter, and I’ll be glad to offer assistance.