Here is a handy custom class I created for PowerShell 5+ that can query an SQL database. The class creates a SQL connection using the System.Data.SqlClient.SqlConnection class in .Net, and gives you full access to this object for information or to manipulate parameters. The class can also query the list of tables and views available in the database to help you prepare your SQL query.
Here’s a quick how-to:
Instantiate the Class
Create an instance of the object. You can create an empty instance like this:
$SQLQuery = [SQLQuery]::new()
You can then specify the SQL Server name and Database name:
$SQLQuery.SQLServer = "SQL-01\Inst_SCCM" $SQLQuery.Database = "CM_ABC"
And then add a query:
$SQLQuery.Query = "Select top 5 * from v_R_System"
Or you can pass these parameters when you create the object, like:
$SQLQuery = [SQLQuery]::new("SQL-01\Inst_SCCM","CM_ABC")
Or..
$SQLQuery = [SQLQuery]::new("SQL-01\Inst_SCCM","CM_ABC","Select top 5 * from v_R_System")
Execute the Query
Now execute the query to return the results:
$SQLQuery.Execute()
The result will be displayed in the console window, or you can pipe to GridView for easier viewing:
$SQLQuery.Execute() | Out-GridView
The query results will be stored to the object in the Result parameter so you can retrieve them later.
$SQLQuery.Result
The results are stored in a DataTable format with rows and columns which is an ideal format for SQL query results.
Load a Query from a File
You can load in a SQL query from a “.sql” file like so, passing the location of the file to the method:
$SQLQuery.LoadQueryFromFile("C:\Scripts\SQLScripts\OSD_info.sql")
Then execute the query as before.
Change the Connection String
By default, the connection string will be created for you, but you can add your own custom connection string using the ConnectionString parameter:
$SQLQuery.ConnectionString = "Server=SQL-01\inst_sccm;Database=CM_ABC;Integrated Security=SSPI;Connection Timeout=5"
Timeout Values
There are two timeout parameters which can be set:
$SQLQuery.ConnectionTimeout $SQLQuery.CommandTimeout
The ConnectionTimeout parameter is the maximum time in seconds PowerShell will try to open a connection to the SQL server.
The CommandTimeout parameter is the maximum time in seconds PowerShell will wait for the SQL query to execute.
Get a List of Views or Tables in the Database
The following two methods can be used to retrieve a list of views or tables in the database:
$SQLQuery.ListViews() $SQLQuery.ListTables()
The views or tables will be stored to the parameter of the same name in the object, so you can retrieve them again later.
You can filter the list to search for a particular view or table, or group of. On the command line you could do:
$SQLQuery.ListViews() $SQLQuery.Views.Rows | where {$_.Name -match "v_Client"}
Or as a one-liner:
$SQLQuery.ListViews().Where({$_.Name -match "v_Client"})
You could also output to GridView for filtering:
$SQLQuery.ListViews() | Out-GridView
Hide the Results
By default, the Execute(), ListViews() and ListTables() methods will return the results to the console after execution. You can turn this off by setting the DisplayResults parameter to $False. This scenario may be useful for scripting where you may not wish to display the results right away but simply have them available in a variable.
$SQLQuery.DisplayResults = $False
Access the SQL Objects
You can access the SQLConnection object, or the SQLCommand object to view or set parameters, or execute any of the methods contained in those objects. These objects are only available once the SQL query has been executed.
You can re-use the same SQLQuery object to run other queries; only the results for the most recent query will be stored in the object itself.
SQLQuery Custom Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SQLQuery | |
{ | |
# Properties | |
[string]$SQLServer | |
[string]$Database | |
[string]$Query | |
[string]$QueryFile | |
[string]$Path | |
[int]$ConnectionTimeout = 5 | |
[int]$CommandTimeout = 600 | |
# Connection string keywords: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx | |
[string]$ConnectionString | |
[object]$SQLConnection | |
[object]$SQLCommand | |
hidden $SQLReader | |
[System.Data.DataTable]$Result | |
[System.Data.DataTable]$Tables | |
[System.Data.DataTable]$Views | |
[bool]$DisplayResults = $True | |
# Constructor -empty object | |
SQLQuery () | |
{ | |
Return | |
} | |
# Constructor – sql server and database | |
SQLQuery ([String]$SQLServer,[String]$Database) | |
{ | |
$This.SQLServer = $SQLServer | |
$This.Database = $Database | |
} | |
# Constructor – sql server, database and query | |
SQLQuery ([String]$SQLServer,[String]$Database,[string]$Query) | |
{ | |
$This.SQLServer = $SQLServer | |
$This.Database = $Database | |
$This.Query = $Query | |
} | |
# Method | |
LoadQueryFromFile([String]$Path) | |
{ | |
If (Test-Path $Path) | |
{ | |
If ([IO.Path]::GetExtension($Path) -ne ".sql") | |
{ | |
throw [System.IO.FileFormatException] "'$Path' does not have an '.sql' extension'" | |
} | |
Else | |
{ | |
Try | |
{ | |
[String]$This.Query = Get-Content –Path $Path –Raw –ErrorAction Stop | |
[String]$This.QueryFile = $Path | |
} | |
Catch | |
{ | |
$_ | |
} | |
} | |
} | |
Else | |
{ | |
throw [System.IO.FileNotFoundException] "'$Path' not found" | |
} | |
} | |
# Method | |
[Object] Execute() | |
{ | |
If ($This.SQLConnection) | |
{ | |
$This.SQLConnection.Dispose() | |
} | |
If ($This.ConnectionString) | |
{ | |
} | |
Else | |
{ | |
$This.ConnectionString = "Server=$($This.SQLServer);Database=$($This.Database);Integrated Security=SSPI;Connection Timeout=$($This.ConnectionTimeout)" | |
} | |
$This.SQLConnection = [System.Data.SqlClient.SqlConnection]::new() | |
$This.SQLConnection.ConnectionString = $This.ConnectionString | |
Try | |
{ | |
$This.SQLConnection.Open() | |
} | |
Catch | |
{ | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
Try | |
{ | |
$This.SQLCommand = $This.SQLConnection.CreateCommand() | |
$This.SQLCommand.CommandText = $This.Query | |
$This.SQLCommand.CommandTimeout = $This.CommandTimeout | |
$This.SQLReader = $This.SQLCommand.ExecuteReader() | |
} | |
Catch | |
{ | |
$This.SQLConnection.Close() | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
If ($This.SQLReader) | |
{ | |
$This.Result = [System.Data.DataTable]::new() | |
$This.Result.Load($This.SQLReader) | |
$This.SQLConnection.Close() | |
} | |
If ($This.DisplayResults) | |
{ | |
Return $This.Result | |
} | |
Else | |
{ | |
Return $null | |
} | |
} | |
# Method | |
[Object] ListTables() | |
{ | |
If ($This.ConnectionString) | |
{ | |
$TableConnectionString = $This.ConnectionString | |
} | |
Else | |
{ | |
$TableConnectionString = "Server=$($This.SQLServer);Database=$($This.Database);Integrated Security=SSPI;Connection Timeout=$($This.ConnectionTimeout)" | |
} | |
$TableSQLConnection = [System.Data.SqlClient.SqlConnection]::new() | |
$TableSQLConnection.ConnectionString = $TableConnectionString | |
Try | |
{ | |
$TableSQLConnection.Open() | |
} | |
Catch | |
{ | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
Try | |
{ | |
$TableQuery = "Select Name from Sys.Tables Order by Name" | |
$TableSQLCommand = $TableSQLConnection.CreateCommand() | |
$TableSQLCommand.CommandText = $TableQuery | |
$TableSQLCommand.CommandTimeout = $This.CommandTimeout | |
$TableSQLReader = $TableSQLCommand.ExecuteReader() | |
} | |
Catch | |
{ | |
$TableSQLConnection.Close() | |
$TableSQLConnection.Dispose() | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
If ($TableSQLReader) | |
{ | |
$This.Tables = [System.Data.DataTable]::new() | |
$This.Tables.Load($TableSQLReader) | |
$TableSQLConnection.Close() | |
$TableSQLConnection.Dispose() | |
} | |
If ($This.DisplayResults) | |
{ | |
Return $This.Tables | |
} | |
Else | |
{ | |
Return $null | |
} | |
} | |
# Method | |
[Object] ListViews() | |
{ | |
If ($This.ConnectionString) | |
{ | |
$ViewConnectionString = $This.ConnectionString | |
} | |
Else | |
{ | |
$ViewConnectionString = "Server=$($This.SQLServer);Database=$($This.Database);Integrated Security=SSPI;Connection Timeout=$($This.ConnectionTimeout)" | |
} | |
$ViewSQLConnection = [System.Data.SqlClient.SqlConnection]::new() | |
$ViewSQLConnection.ConnectionString = $ViewConnectionString | |
Try | |
{ | |
$ViewSQLConnection.Open() | |
} | |
Catch | |
{ | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
Try | |
{ | |
$ViewQuery = "Select Name from Sys.Views Order by Name" | |
$ViewSQLCommand = $ViewSQLConnection.CreateCommand() | |
$ViewSQLCommand.CommandText = $ViewQuery | |
$ViewSQLCommand.CommandTimeout = $This.CommandTimeout | |
$ViewSQLReader = $ViewSQLCommand.ExecuteReader() | |
} | |
Catch | |
{ | |
$ViewSQLConnection.Close() | |
$ViewSQLConnection.Dispose() | |
return $(Write-host $_ –ForegroundColor Red) | |
} | |
If ($ViewSQLReader) | |
{ | |
$This.Views = [System.Data.DataTable]::new() | |
$This.Views.Load($ViewSQLReader) | |
$ViewSQLConnection.Close() | |
$ViewSQLConnection.Dispose() | |
} | |
If ($This.DisplayResults) | |
{ | |
Return $This.Views | |
} | |
Else | |
{ | |
Return $null | |
} | |
} | |
} |