Connecting to SQL Server from PowerShell

PowerShell is an awesome scripting language with many powerful features. This includes integration with SQL Server; a fantastic database engine that is both reliable and battle-tested.

If you need to automate repetitive and/or time-consuming DBA processes, connecting PowerShell to your SQL Server instance can be a massive help.

In this article, we are going to look at how PowerShell can be used to interact with different aspects of SQL Server by employing a variety of techniques.

Let’s dive right in and see what options we have for connecting to SQL Server from PowerShell.

Connection options

There are 3 main ways of connecting to SQL Server from PowerShell which I will cover in this article. These are as follows.

  1. SQL Server PowerShell Module (SQLPS/SqlServer)
  2. SQL Server Management Objects (SMO)
  3. Raw .NET SQL Client (System.Data.SqlClient)

In the following sections, we will explore each of the above options in turn.

SQL Server PowerShell Module

First up, we have the SQL Server PowerShell Module which allows us to interact with SQL Server in a very intuitive way, similar to how we navigate through the Windows filesystem from the command-line.

You should consider using the SQL Server PowerShell Module whenever you are seeking to speed up operations which you would normally carry out manually via SQL Server Management Studio.

The SQL Server PowerShell Module was first made available for SQL Server 2008 and was referred to as ‘SQLPS’. However, the module had a lot of quirks and, as a result, gained a bad reputation. More recently, in 2017, a new ‘SqlServer’ module was released which solves the majority of the annoyances from SQLPS.

In the following sub-sections, we will use the newer SqlServer module to navigate through a SQL Server instance and output information regarding tables in a database. However, note that the instructions should work for SQLPS too.

SqlServer module installation

If you don’t have the SqlServer module available on your machine already, you’ll need to install it by running the following command from an elevated PowerShell prompt.

Install-Module SqlServer

After running the above command you may be prompted that the ‘NuGet provider is required to continue’. If so, enter ‘y’ followed by the Enter/Return key to install the NuGet provider.

If you get an ‘Untrusted repository’ prompt enter ‘y’ followed by the Enter/Return key to trust modules from ‘PSGallery’.

If you get an error message about some commands already being available on your system, you may need to re-run the Install-Module command with the -AllowClobber parameter.

If all goes well the prompt should return with no error messages.

PSDrive support

In my previous PowerShell article, I introduced the Get-PSDrive cmdlet.

If you run this cmdlet from a PowerShell prompt, you’ll see a number of options such as your hard-drive letters (C, D etc.), the Registry and the Windows Certificate store; nothing related to SQL Server though.

Run the following command to import the SqlServer module into your PowerShell session.

Import-Module SqlServer

Note that you’ll need to update your script execution policy if you get an error message which states that the running of scripts is disabled on your system.

Now if you run Get-PSDrive again and check your list of drives you will see a new option called ‘SQLSERVER’.

Run the following command.

SQLSERVER:

SQL Server is now a hard-drive!

Note that you can switch back to your main hard-drive at any time e.g. to switch to the C drive just type C:

Navigating SQL Server

Now that SQL Server has been set as the current PowerShell drive, let’s go ahead and change directory to the SQL Server Database Engine.

cd sql
dir

You should now see your Machine Name displayed within the terminal.

Depending on the results of the dir command you will need to adjust the following command to match your Machine Name.

cd SPECTRE-007
dir

Providing you have SQL Server set up on your machine, you should now see a list of all of your SQL Server instances.

Again, your instance name may vary from the following command e.g. it will most likely be ‘SQLEXPRESS’ if you are running the Express Edition of SQL Server.

cd DEFAULT
dir

Now we can view the available databases contained within the chosen instance.

cd databases
dir

You should see a list of your databases along with some basic details. I have included an example of the output below.

Name                 Status          Containment Type Recovery
Model
---- ------ ---------------- -------------
AdventureWorksDW2017 Normal None Simple
SampleDatabase Normal None Simple

As the next step, we can choose a database from the list.

cd AdventureWorksDW2017
dir

Now we are in the context of the chosen database.

Database operations

There are many different areas within a database that are exposed by the SqlServer module.

Let’s keep things simple and look at the tables.

cd tables
dir

This will display a list of all tables in the current database.

You can customise the output by piping the results of the dir command to PowerShell cmdlets.

For example, you could execute the following command to get a list of the largest tables in the database and output the results to a text file.

dir | Sort-Object rowcount -descending | Format-Table name, rowcount, dataspaceused | Out-File C:\Users\Jonathan\Desktop\database-tables.txt

Note that you must update the Out-File path to a valid path on your machine.

Here’s another useful command which will output a SQL CREATE TABLE script for every table.

dir | %{$_.Script()} | Out-File C:\Users\Jonathan\Desktop\database-tables-scripts.txt

The sample commands shown above have been issued within the context of a single database.

You can imagine how much time you could save by managing multiple databases at the same time using PowerShell, rather than administering each one manually.

SSMS Integration

SQL Server Management Studio provides a convenient integration with PowerShell by allowing a PowerShell prompt which is pre-loaded with the SQL Server PowerShell Module to be launched from within the SSMS user interface.

To access PowerShell from SSMS, after logging into your SQL Server instance, right-click on the top-level instance node and select the ‘Start PowerShell’ option.

Note that you can also right-click on other nodes e.g. on a specific database node to launch PowerShell within the context of a specific database.

If you launch PowerShell from within a newer version of SSMS which doesn’t default to the SQLPS module, you’ll get a ‘SqlServer’ module not found message box if you haven’t already installed the SqlServer module.

You can click on the ‘Open PowerShell Gallery’ button within the aforementioned message box which will take you to the SqlServer PowerShell Gallery webpage. This webpage provides details regarding the SqlServer module and how to install it, as per the instructions from earlier in this article.

Providing that the SqlServer module is installed, after launching PowerShell from SSMS a ‘SQL Server PowerShell’ prompt should appear with a black background as opposed to the usual blue background.

Note that if you get a connection error, make sure that you are logged in using a proper server and instance name e.g. ‘SERVERNAME\SQLEXPRESS’ as opposed to something less common such as ‘.’

Now that your prompt is ready to go, you can go ahead and start issuing commands.

For example, we can list out all of the available databases, much like the example shown previously.

cd databases
dir

This will display details regarding all of the available databases. However, the default information which is returned is slightly different compared to when we load the SqlServer module from a standard PowerShell prompt.

Name                 Status           Size     Space  Recovery Compat. Owner                     Collation
Available Model Level
---- ------ ---- ---------- -------- ------- ----- ---------
AdventureWorksDW2017 Normal 272.00 MB 32.12 MB Simple 140 SPECTRE-007\Jonathan SQL_Latin1_General_CP1
_CI_AS
SampleDatabase Normal 426.44 MB 74.80 MB Simple 100 SPECTRE-007\Jonathan Latin1_General_CI_AS

You can now proceed to run any other command you would normally issue when using the module in a standard PowerShell prompt. The experience will be very similar to using the SqlServer module from a standard PowerShell prompt.

SQL Server Management Objects

SQL Server Management Objects, or SMO for short, is a set of .NET libraries that provide the means to manage almost any aspect of SQL Server which you can think of. This covers everything from issuing SQL commands through to backing up and restoring databases.

You should use the SMO libraries whenever you need to automate a server operation such as a backup or replication activity and run it as a script.

In the following sub-sections, we will use SMO to connect to a server and back up all of the user databases to a backup directory.

Loading the libraries

In order to make use of SMO, first of all, we need to load the libraries.

The PowerShell code below will load all of the relevant assemblies needed to work with SMO.

$assemblies = 
"Microsoft.SqlServer.ConnectionInfo",
"Microsoft.SqlServer.ConnectionInfoExtended",
"Microsoft.SqlServer.Dmf",
"Microsoft.SqlServer.Management.Collector",
"Microsoft.SqlServer.Management.CollectorEnum",
"Microsoft.SqlServer.Management.RegisteredServers",
"Microsoft.SqlServer.Management.Sdk.Sfc",
"Microsoft.SqlServer.RegSvrEnum",
"Microsoft.SqlServer.ServiceBrokerEnum",
"Microsoft.SqlServer.Smo",
"Microsoft.SqlServer.SmoExtended",
"Microsoft.SqlServer.SqlEnum",
"Microsoft.SqlServer.SqlWmiManagement",
"Microsoft.SqlServer.WmiEnum"

foreach ($assembly in $assemblies)
{
[void][Reflection.Assembly]::LoadWithPartialName($assembly)
}

The SMO libraries will now be available for the remainder of your PowerShell session or script.

Connecting to a server

After loading the SMO libraries you’ll want to connect to a server so that you can start interacting with SQL Server.

To connect to the default server instance on your local machine you can use the following code.

$machine = "$env:COMPUTERNAME"
$server = New-Object Microsoft.Sqlserver.Management.Smo.Server("$machine")
$server.ConnectionContext.LoginSecure=$true

You’ll need to update the connection details if you want to access a database on another machine e.g. use SQL Server Authentication with a username and password.

Getting a list of databases

We can use the Databases property on our Server instance to access a specific database to execute commands against.

$database  = $server.Databases["master"]
$command = "SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');"
$dataSet = $database.ExecuteWithResults($command)
$dataTable = $dataSet.Tables[0]

After getting a reference to a specific database, the above code defines a SQL command and executes it. The Data-Set which is returned contains a single Data Table with the results of the SQL query.

Backing up user databases

Now for the backup code, first, let’s create a folder to store our backups.

$datedBackupFolder = "C:\DatabaseBackups\$((Get-Date).ToString('dd-MM-yyyy'))\"
New-Item -ItemType Directory -Path $datedBackupFolder

The above code defines a dated folder name and then uses the New-Item cmdlet to create the backup directory.

Next, we’ll iterate through each database row in the Data Table which was generated earlier. We then carry out the backup operation for each database.

foreach ($row in $dataTable)
{
# Set up backup properties.
$databaseName = $row.name
$backup = New-Object Microsoft.SQLserver.Management.Smo.Backup
$backup.Database = $databaseName

# Configure the backup filename.
$dateAndTime = $((Get-Date).ToString('yyyy-MM-dd_HH-mm-ss'))
$backupFile = $datedBackupFolder + $databaseName + "_" + "$dateAndTime.bak"

# Backup the database.
$backup.Devices.AddDevice($backupFile, [Microsoft.Sqlserver.Management.Smo.DeviceType]::File)
$backup.Action = [Microsoft.Sqlserver.Management.Smo.BackupActionType]::Database
$backup.SqlBackup($server)
}

After running all of the above code, if you check the backup directory you should now find a backup file for each user database.

Raw .NET SQL Client

If you are mainly wanting to execute queries against a SQL Server database and output the results somewhere, using the .NET SQL Client is a good option.

Since the .NET SQL Client is part of the .NET Framework you can execute PowerShell scripts that connect to SQL Server without needing to install any additional modules or libraries.

The SQL Client libraries have been part of the .NET Framework for a long time. They provide a reliable way of connecting to SQL Server and offer great performance.

In the following sub-sections, we will use the .NET SQL Client to fill a Data-Set with the results of a SQL query and then output the results.

Open a connection

First of all, let’s open a connection to the database.

$connection                  = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = “Server=SPECTRE-007;Integrated Security=true;Initial Catalog=master”
$connection.Open()

In the above code, we create a new SqlConnection object, set the Connection String, then we call the Open method on the connection object to establish the connection to SQL Server.

Create a command

Next, we craft the SQL command which we want to execute.

$command             = $connection.CreateCommand()
$command.CommandText = "SELECT name, database_id, physical_database_name FROM sys.databases"

In the above code, a SqlCommand object is created from the connection object and the SQL query to execute is configured.

Fill a Data-Set

Now we can fill a Data-Set with the results of our command.

$dataSet = New-Object System.Data.DataSet
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter $command
$adapter.Fill($dataSet) | Out-Null

The code creates a Data-Set to hold the results of the SQL query and a new Data Adapter is created with the SQL command passed into it. We then call the Fill method to populate the Data-Set with the results. The Out-Null cmdlet is used to prevent the number of records from being output to the terminal.

Output results

Lastly, we can output the results of the SQL query to the terminal by accessing the Tables property on the Data-Set.

$dataSet.Tables

If needed, we could also pipe the Tables property to the Out-File cmdlet in order to write the results to a file for future reference.

Further reading

If you are seeking to further your understanding of PowerShell and are looking for a practical guide on how to accomplish a wide range of real-world tasks, I highly recommend the PowerShell Cookbook by Lee Holmes.

The PowerShell Cookbook offers a solid introduction to PowerShell fundamentals and covers a large number of problems and solutions along with the full source code for each ‘recipe’ that is covered.

The practical examples covered in the book include details on how to use the Invoke-SqlCommand cmdlet as another way of connecting to SQL Server from PowerShell.

Summary

In this article, we have explored the 3 main ways of connecting to SQL Server from PowerShell.

We’ve seen how the SQL Server PowerShell Module can be used to conveniently access SQL Server as a drive via either a standard PowerShell prompt or a SQL Server PowerShell prompt launched from SQL Server Management Studio.

SQL Server Management Objects are another powerful way of administering a SQL Server database. We’ve looked at how to use the SMO libraries to back up all user databases within a SQL Server instance.

Lastly, we’ve seen how the .NET SQL Client can be used to connect directly to SQL Server, allowing us to execute queries with fine-grained control.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments