Getting SQL Server Version using dbatools

Time to read: ~ 4 minutes

Words: 730



I will discuss different ways to get the SQL Server version using PowerShell.

I’ll explore a function you can use, and how a dictionary/hash table could also work.

Finally, I’ll discuss how neither of these are needed since dbatools/SMO has a better way.

The Initial Issue

I’m sure you’ve needed the version of a SQL Server instance for a report a few times.
And, surprisingly, not many people are up for parsing the output of @@VERSION.

I can’t see why not, it’s perfectly fine. It is not the easiest thing in the world, but it is also not the hardest. But, you do you.

Invoke-DbaQuery -SqlInstance localhost\SQL2019 -Query "SELECT version = @@VERSION;" | FL
No, I haven’t updated this instance in a while. Thank you for asking

My team lead has a function that he uses to get these versions, but it encountered an issue. We recently updated to a later version of SQL Server, and the function stopped working.

$instance = Connect-DbaInstance -SqlInstance localhost\SQL2019

$instance.Version.Major

Get-WhatVersionAmI -Version $instance.Version.Major
15? Never heard of it.

It seems to work fine if I pass in an older version of SQL Server.

Get-WhatVersionAmI -Version 14
Oh! 14! Yeah, I know 14!

So, what’s the issue?
I’m going to take a look under the hood of that function, and see if I can spot what’s wrong.

Checking under the function’s hood

If you don’t have the code, or are screen-sharing, you can query the function provider to get the definition of most PowerShell functions.

Get-ChildItem function:\Get-WhatVersionAmI | Select-Object *
There’s more, but it boils down to “this is a simple function”.

Taking a look at the function, here’s the gist of the function block:

param([string] $Version)

    switch ($Version) {
        14 { "SQL Server 2017" }
        13 { "SQL Server 2016" }
        12 { "SQL Server 2014" }
        default { "Unknown" }
    }

This seems simple enough. Hell, it’s just a switch statement that takes the input and spits out the matching output.

Seeing something this simple I’d almost suggest using a dictionary

Using a dictionary instead

This is the equivalent code of the function, but using a hash-table.

$dict = @{
    14 = "SQL Server 2017" 
    13 = "SQL Server 2016" 
    12 = "SQL Server 2014" 
}

$version = $dict[15]
if (!$version) {
    $version = "Unknown"
} 

"Version: $version"
Still unknown, but visibly unknown.

The benefit of this approach is:

  • it’s easier to modify. I don’t need to update the function and either dot-source it, e.g. . <path_to_function_file.ps1>, or re-run it in memory to use it. I only need to add an entry to the hash table.
$dict = @{
    15 = "SQL Server 2019" 
    14 = "SQL Server 2017" 
    13 = "SQL Server 2016" 
    12 = "SQL Server 2014" 
}

$version = $dict[15]
if (!$version) {
    $version = "Unknown"
} 

"Version: $version"
Updated to know about the number 15.

The problem with this approach is:

  • I have to keep it updated, and I’ll find it difficult if I have to add it to multiple scripts.

Shift left?

The above approaches have common issues. They have to be ported to every script I have, run into memory, be in sync, etc., etc.

Can I do something about that? Can this be shifted left somehow? Can I remove some of the work that I’ve to do? In the words of Homer Simpson “can’t someone else do it?”.

Someone else is normally “me” though.

Why yes, yes they can.

Using dbatools

When dbatools connects to a SQL Instance, the usually returned object is a Microsoft.SqlServer.Management.Smo.Server, and that object has a few methods. The one I’m interested in is GetSqlServerVersionName.

Connect-DbaInstance -SqlInstance localhost\SQL2019 | Get-Member -MemberType Method -Name GetSql*
Many methods have been returned, but I only care about one now.

Now, I can connect to an instance, and query what version it is without any external functions or scripts:

Connect-DbaInstance

$instance = Connect-DbaInstance -SqlInstance localhost\SQL2019
$Instance.GetSqlServerVersionName()
Oh, look! The “somebody else”.

Hey, the function is even there on Microsoft.SqlServer.Management.Smo.Database from Get-DbaDatabase, in case I get the strange notion that the version changes from database to database.

Get-DbaDatabase

$databases = Get-DbaDatabase -SqlInstance localhost\SQL2019
$databases.GetSqlServerVersionName()
So many versions, all the same kind.

I don’t think they change, by the way.

End

I’m a dbatools fan. I’m also slightly lazy, which is why I like automation so much.

Now that I know that there’s a built-in way to get a proper human readable version of an instance. You better believe I’m using that!

Author: Shane O'Neill

DBA, T-SQL and PowerShell admirer, Food, Coffee, Whiskey (not necessarily in that order)...

One thought on “Getting SQL Server Version using dbatools”

Leave a Reply

Discover more from No Column Name

Subscribe now to keep reading and get access to the full archive.

Continue reading