Exploring SQL Databases Using SQL Server Management Objects (SMO) and PowerShell

Continuing with my little SQL and PowerShell series, I am going to talk about how you can use PowerShell to explore SQL databases using SMO.

As shown in the previous articles, I will make my initial connection to a SQL server.

## Add Assemblies
add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, 
PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SMOExtended, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SqlEnum, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

## Connect to SQL Server
$sqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server('Boe-PC\SHIRE')

Viewing all of the databases and their properties is as simple as doing this:

$sqlServer.Databases

image

Of course, you get EVERYTHING with this. It may be better to filter out only the properties I need.

##Databases
$sqlServer.Databases | 
Format-Table Name,Owner,Status,LastBackupDate,
LastDifferentialBackupDate,LastLogBackupDate,
RecoveryModel,DataSpaceUsage -AutoSize

image

Much better. Here we can see some relevant information such as when backups have last taken place as well as the recovery model for each database among other things. Of course, you can choose what you feel like are the most important things to view.

Typically when working with objects and you want to only get a specific item from the collection, you would need to do a Where-Object and filter for a specific property (Name in this case). Luckily, you don’t have to do this at all. You can just run the following command to grab a lone database.

$db = $sqlServer.Databases['AdventureWorks']
$db.name

image

Now I have access to a single database to work with and view other interesting things on it.

Something that I think is really cool is that you can generate the TSQL code to create the database just by using the Script() method.

#Show Database TSQL Script
$db.Script()

image

Pretty cool stuff if you wanted to create another database somewhere else.

Finding all of the users that have logins added to a specific database can be found on the Users property. Within that object is a method called EnumRoles()  which will also show you what roles each user is in.

#Show Users with their roles
$db.Users | ForEach {
    [pscustomobject] @{
        Name = $_.Name
        Login = $_.Login
        LoginType = $_.LoginType
        UserType = $_.UserType
        HasDBAccess = $_.HasDBAcces
        CreateDate = $_.CreateDate
        Database = $_.Parent
        Roles = $_.EnumRoles()
    }
} | Format-Table -AutoSize

image

This provides a nice way to track who has access to what databases on your SQL Server.

In the flip side, you can also look at the available roles on the database.

#Roles
$db.Roles | ForEach {
    [pscustomobject] @{
        Name = $_.name
        Database = $_.Parent
        CreateDate = $_.CreateDate
        LastModified = $_.DateLastModified
        Owner = $_.Owner
        Users = $_.EnumMembers()
    }
} | Format-Table -AutoSize

image

If you want to check out the schemas on the database, you can run this.

#Look at schemas
$db.Schemas | FT Name,Parent,Owner -AutoSize

image

Let’s take a look at the permissions on the database.

#Database Permissions
$db.EnumDatabasePermissions() | 
Format-Table Grantee,GranteeType,PermissionType,
PermissionState,Grantor -AutoSize

image

We can also look at any locks that are on the database using the EnumLocks() method.

#Database Locks
$db.EnumLocks() | Format-Table -AutoSize

image

Depending on the database, you may have some database logon mappings.

$sqlServer.Databases.EnumLoginMappings()

image

You can check to see if any transactions are running and then view those transactions on the database.

If ($db.GetTransactionCount() -gt 0) {
    $db.EnumTransactions()
}

Depending on what is happening, you may or may not get anything. In my case, I ran the following command to ‘monitor’ transactions to show what is happening when I run a simple TSQL command to inserta row.

while ($True) {$db.EnumTransactions()}

image

You can view all of the objects on a database using the EnumObjects() method.

$db.EnumObjects()

image

Yes, there will be a lot of objects returned when you run this command.

If you want to know the size of your data files (both .mdf and .ldf) as well as what their growth rate might be, then the following lines of code will be pretty useful for you.

First off is the database file/s. First we can check out the FileGroups property to see how many file groups we have associated with this database.

$db.FileGroups

 

image

Only one file group to work with here. We can dig deeper by looking at the Files property to see more information about the database file.

$db.FileGroups.Files

 

image

Here you can see the actual size of the file (Size) and the size actually being used by the database (UsedSpace). Also, you are able to see more information like its growth rate. Lets do some formatting to make this a little easier to read.

$db.FileGroups.Files | Select FileName,Name,
@{L='FileSizeMB';E={[math]::Round(($_.Size * 1024)/1MB,2)}},
@{L='DatabaseSizeMB';E={[math]::Round(($_.UsedSpace * 1024)/1MB,2)}},
MaxSize,@{L='PhysicalDiskFreeSpaceMB';E={[math]::Round(($_.VolumeFreeSpace * 1024)/1MB,2)}},
Growth,GrowthType  | Format-Table -AutoSize

 

image

Here you can see where the file is located at, the size of the file (4MB) as well as how much of that size is actually being used by the database (2.88MB). The max size is –1, basically meaning that this thing is a goldfish and will grow to the size of the bowl (or drive in this case) if allowed. We can also see that this will grow by 10% each time its DatabaseSizeMB out-grows the FileSizeMB. So it may be a good idea to not only give it a maxsize but to also change the growth rate on this database to prevent a potential disaster.

Not to be left out, we can also check out the transaction log size in a similar way by looking at the LogFiless property of the database.

$db.LogFiles

image

Much like the database files, lets format it a little.

$db.LogFiles | Select FileName,Name,
@{L='FileSizeMB';E={[math]::Round(($_.Size * 1024)/1MB,2)}},
@{L='TLogSizeMB';E={[math]::Round(($_.UsedSpace * 1024)/1MB,2)}},
MaxSize,@{L='PhysicalDiskFreeSpaceMB';E={[math]::Round(($_.VolumeFreeSpace * 1024)/1MB,2)}},
Growth,GrowthType  | Format-Table -AutoSize

image

 

You can even run TSQL using the ExecuteWithResults() method. In this case I want to see all of the tables on this database.

$db.ExecuteWithResults('SELECT * FROM INFORMATION_SCHEMA.TABLES').Tables.Rows

image

I will be finishing up this article by showing you how you can create a database, make some configuration changes, verify it exists and then removing the database from the SQL server.

First, lets create a database on the SQL server..

#Create a database quickly
([Microsoft.SqlServer.Management.Smo.Database]@{
    Name ='ProxTest'
    Parent = $sqlServer
}).Create()

image

Now we can make some configuration changes to this database. But first we need to show the settings prior to making the change.

$newDb | Format-Table Name,Owner,Auto*Statistics* -AutoSize 

image

Now we can make some changes.

$newDB.SetOwner("boe-pc\Administrator")
$newDB.AutoCreateStatisticsEnabled = $True
$newDB.AutoUpdateStatisticsAsync = $True
$newDB.AutoUpdateStatisticsEnabled = $True
$newDB.Alter()

The Alter() is important because if I don’t call it, no changes will be made to the database. With that, lets check out those properties again.

$newDb | Format-Table Name,Owner,Auto*Statistics* -AutoSize

image

As you can see, the properties have been updated with a new owner as well as some statistics options.

Now, I really don’t need this database, so lets use the Drop() method to remove the database.

$newDB.Drop()
$sqlServer.Databases.name

image

No more database!

That is all for this article on exploring the database using SMO. The next article will talk about backing up and restoring a database using SMO.

Posted in powershell, SQL | Tagged , , , | 5 Comments

Exploring SQL Server Using SQL Server Management Objects (SMO) and PowerShell

Continuing on from my previous article where I showed you how to make an initial connection to a SQL server using SMO, this article aims to dive deeper into the Microsoft.SqlServer.Management.Smo.Server object to view the configuration and available methods of the server.

First thing is to load the assemblies and make the initial connection to the SQL server.

## Add Assemblies
add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, 
PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SMOExtended, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SqlEnum, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

## Connect to SQL Server
$sqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server('Boe-PC\SHIRE')

Just by itself, the SQL server object has a lot of properties.

image

Just a few of the properties available are shown below.

image

You can even enumerate through all of the databases via the database property. This will display the Microsoft.SqlServer.Management.Smo.Database objects. I won’t dive too deep into the database objects for this article, but will for a future article.

$sqlServer.Databases | Select Name

image

SQL Server roles can also be looked at as well.

$sqlServer.Roles | Select Name

image

Same goes for SQL logins on the server.

$sqlServer.Logins | Select Name

image

All of these will be looked at in greater detail in future articles. The main point of this is to show you what is available at the root of the SQL server object.

Digging deeper into the configuration using the Configuration property, we can really take a look at some useful properties that can even be configured.

$sqlServer.Configuration

image

image

As you can tell, there are quite a few things available here look at and possibly configure. Let’s take a look at the currently configured MaxServerMemory to see what it is set at compared to what we are using and how much physical memory is on this system.

MaxServerMemory

$sqlServer.Configuration.MaxServerMemory

image

The ConfigValue is the actual value of the configuration while the Minimum and Maximum are just that, the limits both upper and lower for this particular setting. On a default installation of SQL, this value is set to the Maximum value (not really the best thing).

Before I get into how I changed this, lets also take a look at the physical memory of the server which can be found in the SQL server object.

PhysicalMemory

$sqlServer.PhysicalMemory

image

This value is in MB, so this is basically 4GB of memory on this system. So this begs the question as to how much memory is being consumed by the SQL server? Well, one way to find this out is by using performance counters. What counter should we use to find the information needed? The quickest way is to use Get-Counter –ListSet with a little filtering to find the correct counter.

(get-counter -ListSet "*SQL*" -ErrorAction Stop).Counter -like "*Memory Manager*Total*"

image

In this case, the counter required is \MSSQL$SHIRE:Memory Manager\Total Server Memory (KB). Note that this returns a value in KB. Running Get-Counter with the counter will show just how much memory is being used.

Get-Counter -Counter '\MSSQL$SHIRE:Memory Manager\Total Server Memory (KB)'

image

Looks like this server is using 92200KB (or 90MB) of memory.

image

Keep in mind that this is the current amount of memory being used and would be subject to change.  But going back to the MaxServerMemory and changing it, lets say to 1GB of memory. Doing so is fairly simple:

#Remember that this is in MB
$sqlServer.Configuration.MaxServerMemory.ConfigValue = 1024
#Apply the change to the server
$sqlServer.Alter()
#Verify
$sqlServer.Configuration.MaxServerMemory 

image

There you have it! The MaxServerMemory is now set to 1024 MB. If I didn’t call the Alter() method after making the change, the memory config would not have been updated.

You can also check for any locks on the server.

$sqlServer.EnumLocks()

image

A fun method to use is EnumProcesses()

$sqlServer.EnumProcesses() | Format-Table -Auto

image

Now you can see the current snapshot of activity that is occurring on the SQL Server; similar to viewing the Processes on Activity Monitor.

You are also able to look at the server permissions.

$sqlServer.EnumServerPermissions() | Format-Table -AutoSize

image

These are just some of the things you can look at and explore in your SQL server. Next time we will look at databases using PowerShell and SMO!

Posted in powershell, SQL | Tagged , , | 2 Comments

Video From Mississippi PowerShell User Group Presentation on WSUS and PowerShell Available

The video recording from my presentation on WSUS Administration with PowerShell has been posted and is now available to be viewed. The presentation materials from this are available at the link below.

WSUS Administration Using PowerShell

 

PowerShell and WSUS Demos and Slides

Posted in News, WSUS | Tagged , , , | Leave a comment

Connecting to a SQL Server Using SQL Server Management Objects (SMO) and PowerShell

In a previous article, I showed you how to find all of the SQL servers and instances using a function that queries the registry. Moving on from this, I will now show how you can connect to a SQL server (and instance) using SQL Server Management Objects (SMO).

In case you are wondering why I am talking about SQL, it is because I enjoy working with SQL when I get the chance and while I may not be an expert at it, you can be sure that I will learn as much as I can and even more so how I can leverage PowerShell to work with it.

SMO can be used with PowerShell to make a connection to a SQL server by name (or name\instance) and allow you to utilize the objects to traverse the SQL server to look at the databases, jobs and just about anything else you need to do. Did I also mention that you can use T-SQL as well through this? If you are looking to only run T-SQL statements without anything else, then there is another method that might suit you without the need for SMO that I will try to discuss in a future article.

To use these, you need to have the SQL Server Management Studio installed (or you can find the assemblies on another installation, but I cannot promise that everything will work correctly for you OR you can download the SQL Feature Pack to get access to the assemblies). Once you have that installed, you can run the following command to load up the assemblies (SQL 2008 as an example).

#SQL 2008
add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, 
PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SMOExtended, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.SqlEnum, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

add-type -AssemblyName "Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, 
Culture=neutral, PublicKeyToken=89845dcd8080cc91" -ErrorAction Stop

Using Add-Type and specifying the exact version will  make sure that you are using the latest version of the assemblies if you happen to have multiple versions of SQL installed such as 2005 and 2008.

Once the assemblies have been loaded up, you can then attempt to make your first SQL server connection.

$sqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server('DC1')
#View the connection
$sqlServer

image

image

Ok, that is a ton of information to look at! But as you can see, there are a lot of things to look at and traverse through to view what is on the SQL Server. So what happens if I connect to a server that doesn’t have SQL installed? Will it just error out?

$sqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server('DoesNotExist')
$sqlServer

image

No error message, but it still has a somewhat empty shell of an object that is available. Keep this in mind when you are working with SMO and PowerShell. Just because the connection appears to have worked, it doesn’t mean it actually did work.

One last thing, if you want to check out all of the databases on this particular server, run this (make sure you re-connect to a known good server first):

$sqlServer.Databases

image

To make this more useful, I will only show a few properties so you can get the idea of what is available.

$sqlServer.Databases | 
Select Name,Owner,RecoveryModel,DataSpaceUsage

image

Hmm… my SUSDB is not using a Full RecoverModel. Better get that changed sometime soon, but as you can see, you can see the name, owner recoverymodel and dataspaceusage to name a few things which are available.

There is much more to explore with using SMO and PowerShell and I will do just that in some upcoming articles including showing how you can perform Transact-SQL (T-SQL) queries as well as checking the status of SQL Jobs and events.

Posted in powershell, SQL | Tagged , , | 1 Comment

Find All SQL Instances Using PowerShell Plus A Little More

A while back I saw this the following post on the PowerShell Magazine that showed how to get all of the instances of a SQL server. This was pretty cool, but only listed the instances and nothing else (well it can return a boolean value if you choose to search for a specific instance). I wanted more out of this ability to locate instances and decided to dive deeper into the registry rabbit hole and came back up with a wealth of information that will turn this into a super-charged function capable of being used in your domain to find out some great information about your SQL server environment!

As specified in the PowerShell Magazine article, you can find the available instance names (SQL 2005 and above) at the following key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL.

image

The next trick is to look at the data value that lies within the instance name, in this case MSSQL10.SHIRE and use that to locate its key under the SQL key. I am mostly concerned with what is in the Setup key and what the edition is. I know that there is a Version key,but this is not as accurate as what you can get with the actual file for the sqlservr.exe file. More on that in a minute.

image

Now we can take a look at the SQL version that is running for this particular instance. Using the instance name, you can locate the service under SYSTEM\CurrentControlSet\Services and find the SQL service running the instance and locate the path to the file (imagepath).

image

Those are pretty much the basics of what I will doing in my version of Get-SQLInstance. I have also added a couple of other things such as the ability to determine if this particular SQL server is part of  a cluster (I don’t have a cluster to show the examples, but you will see in the code how it works), find its cluster name and the other nodes in the cluster. What I decided not to do is to allow an option to filter out the nodes and only show the actual cluster itself. It is pretty simple to do this in a script that I will show later on.

$Computer = $computer -replace '(.*?)\..+','$1'
Write-Verbose ("Checking {0}" -f $Computer)
Try { 
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer) 
    $regKey= $reg.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server")

I start out by only using the hostnames of the systems by making sure there are no fully qualified domain names here (my own cosmetic choice) and then attempting the remote registry connection to the system and connecting to the registry path hosting the SQL server information.

If ($regKey.GetSubKeyNames() -contains "Instance Names") {
    $regKey= $reg.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL" ) 
    $instances = @($regkey.GetValueNames())
} ElseIf ($regKey.GetValueNames() -contains 'InstalledInstances') {
    $isCluster = $False
    $instances = $regKey.GetValue('InstalledInstances')
} Else {
    Continue
}

Here I am looking for the Instance Names key to determine if this is actually a SQL Server (note that I am also looking for InstalledInstances which is a SQL 2000 key), otherwise this is assumed to not be a SQL Server.

If ($instances.count -gt 0) { 
    ForEach ($instance in $instances) {
        $nodes = New-Object System.Collections.Arraylist
        $clusterName = $Null
        $isCluster = $False
        $instanceValue = $regKey.GetValue($instance)
        $instanceReg = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server\\$instanceValue")
        If ($instanceReg.GetSubKeyNames() -contains "Cluster") {
            $isCluster = $True
            $instanceRegCluster = $instanceReg.OpenSubKey('Cluster')
            $clusterName = $instanceRegCluster.GetValue('ClusterName')
            $clusterReg = $reg.OpenSubKey("Cluster\\Nodes")                            
            $clusterReg.GetSubKeyNames() | ForEach {
                $null = $nodes.Add($clusterReg.OpenSubKey($_).GetValue('NodeName'))
            }
        }
        $instanceRegSetup = $instanceReg.OpenSubKey("Setup")
        Try {
            $edition = $instanceRegSetup.GetValue('Edition')
        } Catch {
            $edition = $Null
        }

A lot of things happening here. If I find at least one instance, the function will continue to gather more information about the SQL server. One of the next checks is to make the determination about whether this is a SQL cluster or not. If it is a cluster, then it will check the Cluster key under the root of Software and get the cluster name and all of the cluster nodes. The edition of the SQL server is also located as well in this code snippet.

Try {
    $ErrorActionPreference = 'Stop'
    #Get from filename to determine version
    $servicesReg = $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Services")
    $serviceKey = $servicesReg.GetSubKeyNames() | Where {
        $_ -match "$instance"
    } | Select -First 1
    $service = $servicesReg.OpenSubKey($serviceKey).GetValue('ImagePath')
    $file = $service -replace '^.*(\w:\\.*\\sqlservr.exe).*','$1'
    $version = (Get-Item ("\\$Computer\$($file -replace ":","$")")).VersionInfo.ProductVersion
} Catch {
    #Use potentially less accurate version from registry
    $Version = $instanceRegSetup.GetValue('Version')
} Finally {
    $ErrorActionPreference = 'Continue'
}

Up next is the file version gathering (more accurate than looking in the registry) by locating the proper service for the instance and then performing a little cleanup on the image path courtesy of some regex. Once we have the path, it is just a matter of getting the file version information from the file and moving forward.

                        New-Object PSObject -Property @{
                            Computername = $Computer
                            SQLInstance = $instance
                            Edition = $edition
                            Version = $version
                            Caption = {Switch -Regex ($version) {
                                "^11" {'SQL Server 2012';Break}
                                "^10\.5" {'SQL Server 2008 R2';Break}
                                "^10" {'SQL Server 2008';Break}
                                "^9"  {'SQL Server 2005';Break}
                                "^8"  {'SQL Server 2000';Break}
                                Default {'Unknown'}
                            }}.InvokeReturnAsIs()
                            isCluster = $isCluster
                            isClusterNode = ($nodes -contains $Computer)
                            ClusterName = $clusterName
                            ClusterNodes = ($nodes -ne $Computer)
                            FullName = {
                                If ($Instance -eq 'MSSQLSERVER') {
                                    $Computer
                                } Else {
                                    "$($Computer)\$($instance)"
                                }
                            }.InvokeReturnAsIs()
                        }
                    }
                }
            } Catch { 
                Write-Warning ("{0}: {1}" -f $Computer,$_.Exception.Message)
            }  
        }   
    }
}

The rest of the code finishes up by outputting the object that lists all of the information gathered previously. The only other things is that it adds a boolean value if the cluster is in a node and also gets the type of SQL server being used (SQL 2008, etc…). An additional thing is the FullName property which gives a ‘fullname’ of the SQL instance that can be used in a script for a SQL connection using something like SMO.

So with that, it is time to take a little look at this function in action. First lets just look at my own local system. Remember that this is a function so the script needs to be dot sourced first!

Get-SQLInstance

image

Here you can tell that what version I am running as well as the type of SQL server that is being used. Now we can take this a step further by checking out what exists on my remote server.

Get-SQLInstance -Computername DC1

image

Here you can tell that I actually have 2 instances installed on DC1. Both are the same version and type of SQL server.

If you remember , I mentioned something about filtering out the cluster nodes and only showing the cluster server itself. Here is what I have been using when I attempt to locate those systems.

Get-SQLInstance -ComputerName $Computername -Verbose | ForEach {
    If ($_.isClusterNode) {
        If (($list -notcontains $_.Clustername)) {
            Get-SQLInstance -ComputerName $_.ClusterName
            $list += ,$_.ClusterName
        }
    } Else {
        $_
    }
}

If I had a clustered server, then it would only show the cluster name and would not show the nodes in the cluster.

Personally, I use this to scan the active directory domain for reporting purposes using the following code that provides a simple CSV with the SQL information:

$Computername = Get-ADComputer -Filter {operatingSystem -Like '*server*'} | Select -Expand DNSHostName
Get-SQLInstance -ComputerName $Computername -Verbose | ForEach {
    If ($_.isClusterNode) {
        If (($list -notcontains $_.Clustername)) {
            Get-SQLInstance -ComputerName $_.ClusterName
            $list += ,$_.ClusterName
        }
    } Else {
        $_
    }
} | Export-Csv -NoTypeInformation 'SQLServers.csv'

 

The download for this function is below. Please let me know what you think of it! I am sure improvements can be made to this and will definitely do so if needed.

Download Get-SQLInstance

Get-SQLInstance.ps1

Posted in powershell, scripts | Tagged , , , | 19 Comments