Powershell - Output SQL Messages to file - sql-server

I have a Powershell script that invokes a saved SQL Query file and runs it on a specific Server & Database. That part is working well, the issue is that I would like to save the SQL Messages that it generates to a log file (see picture).
SQL Output from after Query is run
This is not working with my current code, and I believe that's because since it's technically not Query output but instead reindexing and updating tables, not fetching data.
My current relevant code is:
{
Import-Module SQLPS
$Data = Invoke-Sqlcmd -InputFile $SQLQuery -ServerInstance $Server -Database $Database -QueryTimeout 0
$Data | out-file "$Output$Database$date.txt"
}
But that just generates an empty text file. I'm looking to get the info on rebuilding indexes and the updates it's doing saved off into a different file through Powershell. You can do this through SSMS by right clicking in the Messages window and clicking "Save Results As..." but looking to include this in my automation since it's running as a Scheduled Task and no one is on SSMS.
Powershell v3/Windows Server 2012/SQL SSMS 2014
Any help would be appreciated!! This is my first post so sorry for odd formatting.

It looks like the following link explains exactly this problem:
https://sqlnotesfromtheunderground.wordpress.com/2015/09/09/powershell-outputting-a-sql-server-query-result-from-the-message-tab/
Essentially, what you are seeing in the 'Messages' tab are not results from the query, but rather just PRINT statements (essentially the same as Write-Host or Console.WriteLine). If you use Invoke-SqlCommand2, its -Verbose option will capture these PRINT statements to the Verbose PowerShell stream. To then write this stream to a text file, you have to specify the specific stream (in this case, 4):
Invoke-Sqlcmd2 -ServerInstance . -Database master -Query "PRINT 'Export This result'" -Verbose 4> Out-File C:\Temp\Test.txt

I had the same issue but instead in powershell script i use it in a command and i used -verbose.
like this
Invoke-Sqlcmd -ServerInstance '.\Your_server_instance' -Database 'DATABASE_Name' -InputFile "D:\Your_script.sql" verbose 4> "C:\sql\YOUR_OUTPUT_FILE.txt"
so i think this code should work for you
{
Import-Module SQLPS
$Data = Invoke-Sqlcmd -InputFile $SQLQuery -ServerInstance $Server -Database $Database -QueryTimeout 0
$Data -verbose *> "$Output$Database$date.txt"
}
for -verbose *> it streams All output you can redirect specific streams :
1 Success output
2 Errors
3 Warning messages
4 Verbose output
5 Debug messages

Related

Powershell invoke-sqlcmd sees hash as System.Byte[]

Currently i am trying to retrieve a query hash from a database. The plan is to query slow queries from the query store and write them to a csv file. To retrieve the data fro the database I am using the following command:
$queryResult = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $SQLDatabase -InputFile $SQLQueryPath -Username $SQLUser -Password $SQLPassword -ConnectionTimeout 60 | Export-Csv $ResultPath -Delimiter "," -NoTypeInformation
The query used retrieves queries that are running slow with their query hash (stored in the query_hash field). This query is tested on the same database using SMSS and then it returns the hash field shown as a hash. This hash is stored in the sql database, it is not generated by the query or script.
But whenever I try to retrieve the query hash using Invoke-Sqlcmd it returns the query_hash field as a byte array (System.Byte[]). All other fields are shown as in SMSS. Tried printing the result in the powershell terminal but there it also shows me an array of bytes.
How can I get the script to return the hash?
Tried to use [System.Text.Encoding]::ASCII.GetString($.query_hash) and [System.Text.Encoding]::UTF8.GetString($.query_hash) but they expect a single byte where this script gives an array.

Import CSV from PowerShell to SQL Server

I was trying to import a CSV file from PowerShell over to my SQL Server database. I've already created the database and tables with columns. I got the data on a CSV file that I need to import.
I tried to research and found a bit of code I modified so it should be working, but when I run the code I get the error:
Import-CsvToSql : exeption calling "writetoserver" with "1"
argument(s): "The transaction is iether not associated with the
connection or has been completed"
But I hasn't imported the data to the table, so I don't know what's wrong.
Here is the code I've got so far:
Import-Module csvsqlimport
Import-CsvToSql -Csv C:\Users\Tim\Desktop\POWERSHELL\AutoParts.csv `
-SqlServer DHCP_SERVER -Database FeilAuto4 `
-Table dbo.Reservedele -FirstRowColumns -Delimiter ";" -Truncate
You may want to try the "SqlServer" module as it is being kept up to date by Microsoft and has multiple SQL cmdlets. The only downside is that you will have to separate the script into multiple commands based on their cmdlets.
## Install module if not installed, this is a one time install.
Install-Module SqlServer
## Input Variables
$csvPath = "C:\Users\Tim\Desktop\POWERSHELL\AutoParts.csv"
$csvDelimiter = ";"
$serverName = "DHCP_SERVER"
$databaseName = "FeilAuto4"
$tableSchema = "dbo"
$tableName = "Reservedele"
## Truncate Table
Invoke-Sqlcmd -ServerInstance $serverName -Database $databaseName -Query "TRUNCATE TABLE $tableSchema.$tableName"
## Import CSV into SQL
Import-Csv -Path $csvPath -Delimiter $csvDelimiter | Write-SqlTableData -ServerInstance $serverName -DatabaseName $databaseName -SchemaName $tableSchema -TableName $tableName -Force

Invoke-Sqlcmd ran SQL script capture verbose output

I need to do health check on various servers on daily basis. I have SQL script which includes missing indexes, duplicate indexes, CPU and memory, recovery, failed job, last backup etc in one script.
I am running this script manually on sever and changing result to text (I have made script which use print statement so I can directly copy and paste result).
Now I want to run this script with PowerShell but I am not getting result to text format with row-column format.
Code:
$RESULT = (Invoke-Sqlcmd -InputFile $sqlscript -ServerInstance $server -Database $databse -Verbose 4>&1) |
Out-File $outfile
I am getting all the print statement but not the result in text file.
A more appropriate way to do this is as follows.
[string]$SqlsSript = '..\path\'
[string]$ConnectionString = '...'
$DataSet = Invoke-SqlCmd -ConnectionString $Connectionstring -InputFile $SqlScript -As DataSet
You can then explore the $DataSet collection, i.e
$DataSet.Tables[0].Rows
Which you can then transform / output to a file if you like.
Do ensure that your SqlScript returns a table, e.g. a table variable.

Need help getting Invoke-Sqlcmd, -InputFile & -Variable working nicely together

I have File1.ps1 containing the command as follows:
$VariableArray = "PrincipleName='Jack'"
Invoke-Sqlcmd -InputFile "C:\Amit\Test.sql" -Variable $VariableArray -ServerInstance "3STOOGES"
my Test.sql contains
--Test.sql
declare #PrincipleName varchar(20)
SELECT 'PrincipleName=' + #PrincipleName
This gives me output as
Column1
-------
I tried something mentioned here
I tried the options for $(PrincipleName) inside the Test.sql but it complained the SQL server Management Studio.
Please advise as I Have SQL server 2012 with Powershell 3.0 on Windows 2012
The syntax is all wrong. SELECT #PrincipleName will just return nothing since variable is not set.
Use this syntax in a powershell ISE.
Import-Module “sqlps” -DisableNameChecking
$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
Invoke-Sqlcmd -InputFile "C:\temp\john.sql" -Variable $MyArray
Use this syntax in the sql file.
SELECT $(MyVar1) AS Var1, $(MyVar2) AS Var2;
The output is shown here and works correctly.

Invoke-Sqlcmd cmdlet throws exception when using -Variable parameter

When I try to use the Invoke-Sqlcmd cmdlet from SQL Server 2008 to execute a query that contains scripting variables, ex. $(MyVar), I receive the following exception:
Invoke-Sqlcmd : Object reference not set to an instance of an object.
Here's the code I'm trying to run (which is copy/paste from the Books Online example with only the connection parameters added).
$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
Invoke-Sqlcmd -Query "SELECT `$(MyVar1) AS Var1, `$(MyVar2) AS Var2;" -Variable $MyArray -ServerInstance "localhost" -Database "master" -UserName "who" -Password "me"
If I replace $(MyVar1) and $(MyVar2) in the -Query with 'x' and 'y' then it runs perfectly.
$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
Invoke-Sqlcmd -Query "SELECT 'x' AS Var1, 'y' AS Var2;" -Variable $MyArray -ServerInstance "localhost" -Database "master" -UserName "who" -Password "me"
Can anyone tell me why this is not working?
Indeed this is a bug in SQL Server - tracked and fixed here
https://connect.microsoft.com/sqlserver/feedback/details/358291/invoke-sqlcmd-powershell-cmdlet-fails-when-array-passed-via-variable
However, there's a posted workaround. Remove the spaces around the assignment. So instead of
$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
use
$MyArray = "MyVar1='String1'", "MyVar2='String2'"
Ok. I posted this same question on the SQL Server forums and, apparently, this is a bug in SQL Server 2008's PowerShell cmdlets... follow the thread here.
Try this alone:
PS>$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
Now:
PS>$MyArray
and
PS>MyVar1
Now:
PS>$MyArray|get-member
PowerShell thinks you've assigned 2 string objects to $MyArray, nothing more. This approach does not result in defining the variables $MyVar1 and $MyVar2 to PowerShell.
Sorry, I can't fire up my SQL2008 VM right now to comment on the other parts...

Resources