Invoke-SqlQuery.ps1
#requires -version 5.0 <# .SYNOPSIS Invoke any T-SQL query against any SQL supported database. .DESCRIPTION This command uses the .NET SqlClient classes to connect to a SQL database and execute any type of query. The default behavior is to use integrated Windows authentication, but you can pass a credential object for a username and password. This works well when run on Linux. When you run a SELECT query the command will write a custom object for each row to the pipeline. .PARAMETER Query Any T-SQL query string .PARAMETER Database The database name. It is assumed the account you are using has the necessary permissions. .PARAMETER ServerInstance The name of the SQL server instance. .PARAMETER Credential If you need to specify a username and password, use a PSCredential object. .EXAMPLE PS C:\Scripts> .\Invoke-SqlQuery "Select * from diskinfo" -Database scripting ComputerName : YPJH10 DiskSize : 206266429440 DriveType : 3 FreeSpace : 27722903552 DriveID : C: DateAdded : 6/23/2017 5:24:01 PM ComputerName : YPJH10 DiskSize : 26843541504 DriveType : 3 FreeSpace : 16025034752 DriveID : D: DateAdded : 6/23/2017 5:24:01 PM This queries the Scripting database in the localhost\SQLExpress instance. .EXAMPLE PS C:\Scripts> .\Invoke-SqlQuery "Insert Into diskinfo (ComputerName,DiskSize,DriveType,FreeSpace,DriveID,DateAdded) Values ('SERVER01',53687091200,3,41875931136,'C:','7/20/2017 4:12PM')" -Database scripting -credential jane Running an INSERT query with alternate credentials. In this situation the user would be prompted for the password. .EXAMPLE PS C:\Scripts> .\Invoke-SqlQuery "Select * from diskinfo where computername='server01'" -database scripting | format-table ComputerName DiskSize DriveType FreeSpace DriveID DateAdded ------------ -------- --------- --------- ------- --------- SERVER01 53687091200 3 46707769344 C: 7/14/2017 4:02:00 PM SERVER01 53687091200 3 41875931136 C: 7/20/2017 4:12:00 PM SERVER01 53687091200 3 41811131136 C: 6/2 0/2017 5:12:00 PM .INPUTS None .OUTPUTS [PSCustomObject] .NOTES Version 1.0 This function does not rely on any SQL modules. Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/ **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** #> [cmdletbinding(SupportsShouldProcess,DefaultParameterSetName="Default")] Param( [Parameter(Position = 0, Mandatory, HelpMessage = "The T-SQL query to execute")] [ValidateNotNullorEmpty()] [string]$Query, [Parameter(Mandatory, HelpMessage = "The name of the database")] [ValidateNotNullorEmpty()] [string]$Database, [Parameter(Mandatory,ParameterSetName='credential')] [pscredential]$Credential, #The server instance name [ValidateNotNullorEmpty()] [string]$ServerInstance = "$env:computername\SqlExpress" ) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" if ($PSCmdlet.ParameterSetName -eq 'credential') { $username = $Credential.UserName $password = $Credential.GetNetworkCredential().Password } Write-Verbose "[BEGIN ] Creating the SQL Connection object" $connection = New-Object system.data.sqlclient.sqlconnection Write-Verbose "[BEGIN ] Creating the SQL Command object" $cmd = New-Object system.Data.SqlClient.SqlCommand } #begin Process { Write-Verbose "[PROCESS] Opening the connection to $ServerInstance" Write-Verbose "[PROCESS] Using database $Database" if ($Username -AND $password) { Write-Verbose "[PROCESS] Using credential" $connection.connectionstring = "Data Source=$ServerInstance;Initial Catalog=$Database;User ID=$Username;Password=$Password;" } else { Write-Verbose "[PROCESS] Using Windows authentication" $connection.connectionstring = "Data Source=$ServerInstance;Initial Catalog=$Database;Integrated Security=SSPI;" } $connection.open() #join the connection to the command object $cmd.connection = $connection $cmd.CommandText = $query Write-Verbose "[PROCESS] Invoking $query" if ($PSCmdlet.ShouldProcess($Query)) { #determine what method to invoke based on the query Switch -regex ($query) { "^Select (\w+|\*)|(@@\w+ AS)" { $reader = $cmd.executereader() $out=@() #convert datarows to a custom object while ($reader.read()) { $h = [ordered]@{} for ($i=0;$i -lt $reader.FieldCount;$i++) { $col = $reader.getname($i) $h.add($col,$reader.getvalue($i)) } #for $out+=new-object -TypeName psobject -Property $h } #while $out $reader.close() Break } "@@" { $cmd.ExecuteScalar() Break } Default { $cmd.ExecuteNonQuery() | Out-Null } } } #should process } End { Write-Verbose "[END ] Closing the connection" $connection.close() Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end <#PSScriptInfo .VERSION 1.0.0 .GUID d152442f-6e97-4b92-803b-dc91bf9f9b3a .AUTHOR Jeff Hicks .COMPANYNAME JDH Information Technology Solutions, Inc. .COPYRIGHT (c) 2017 JDH Information Technology Solutions, Inc. .TAGS SQL .LICENSEURI https://gist.github.com/jdhitsolutions/d97a81b86ca7a8f419f75acd33368ece .PROJECTURI https://gist.github.com/jdhitsolutions/4851ae5e3f85d80792f64809caf22fdc .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES This script is still being developed for cross-platform support in Linux. #> <# .DESCRIPTION This command uses the .NET SqlClient classes to connect to a SQL database and execute any type of query. The default behavior is to use integrated Windows authentication, but you can pass a credential object for a username and password. This works well when run on Linux. It does not require any of the SQL modules. #> |