Using a Powershell. I'm calling stored procedure containing batch of insert statements. Now I would like to capture the event log of the insert statements (both success message and error) into file like.
(1 row(s) affected).
Msg 8146, Level 16, State 1, Procedure test, Line 0 [Batch Start Line 0]
Procedure test has no parameters and arguments were supplied.
I'm trying this, but it not work. The execution happens, but file loads empty.
$conn = New-Object System.Data.SqlClient.SqlConnection SqlConnection
$conn.ConnectionString = "Server=$server;Database=$databaseName;User=$userName;password=$password;trusted_connection=true;" # set the connection string
$conn.Open();
$cmd = $conn.CreateCommand();
Invoke-Sqlcmd -ServerInstance $server -Database $databaseName -Query "exec batch_insert_statements" -Verbose
out-file -filepath C:\Logs\Test.txt
I found the answer here: https://www.sqlservercentral.com/Forums/Topic914307-391-1.aspx
$sql = "sqlcmd.exe -S ServerName -E -d DatabaseName -Q ""EXEC YourProc"""
Invoke-Expression $sql | Out-File C:\temp\outfile.txt
I just tried it (ps version 5.1.16299.98) and it wrote (1 rows affected) to outfile.txt
This would of course require SQLCMD.EXE to be installed, but I think that's a given if you are already using Invoke-Sqlcmd
You shouldn't need the first few lines, you also haven't piped the command to Out-File, try this:
$server = "."
$databaseName = "dbName"
Invoke-Sqlcmd -ServerInstance $server -Database $databaseName -Query "exec batch_insert_statements" -Verbose -OutputSqlErrors 1 -IncludeSqlUserErrors | out-file -filepath C:\Logs\Test.txt
I found much similar way, but it is totally powershell.
$Query = 'EXEC tes'
$log = "c:\logs\Lead_Scoring_Log_$(get-date -f dd-MM-yyyy-HH-mm-ss).txt"
$SqlcmdOptions = #"
-S"$ServerInstance" -d "$Database" -v User=$userName Password=$password -Q
"$Query"
"#
Start-Process -FilePath "sqlcmd.exe" -ArgumentList #"
$SqlcmdOptions
"# -Wait -NoNewWindow -RedirectStandardOutput $log -PassThru
Related
I have a Powershell script that calls a stored procedure in SQL server and outputs the resulting XML directly to a file. It works for a smaller test file but falls down with the full size (~1.5gb file).
The stored procedure works fine. I can call it within SQL server - the problem is that I have to open it in the SQL server then manually save it to a file, then edit that file to remove newlines. When I run the script it falls down when it tries to delete the intermediary files at the end. However, when I run it line by line it falls down at the invoke-sql line.
#net use S: "\\processStore\projects"
# Create variables
$SQLquery = "DECLARE #return_value int; EXEC #return_value = [XML].[XMLdata];"
$outpath = "D:\MyDocuments\XML\XML files"
$outfile = "TestOutput"
# Run the SQL command and store the object to a variable. Need to extend the timeout from the default.
$sql = invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 100000
cd C:
# Store the SQL output as an interim text file
$sql.{XML_F52E2B61-18A1-11d1-B105-00805F49916B} | out-file -Filepath "$outpath\$outfile.txt"
# Remove Linebreaks
(Get-Content "$outpath\$outfile.txt" -Raw).Replace("`r`n","") | Set-Content "$outpath\${outfile}_del.xml" -Force
format-xml "$outpath\${outfile}_del.xml" | Set-Content "$outpath\$outfile.xml" -Force
# Delete interim text files
del "$outpath\$outfile.txt"
del "$outpath\${outfile}_del.xml"
When running lines one by one the code falls down at the invoke-sqlcmd line with the error:
invoke-sqlcmd : A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote
host.)
At line:1 char:8
+ $sql = invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinst ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
+ FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Change from
invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 100000
to
invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 0
Setting QueryTimeout = 0 will prevent the query from timing out
I have below PS script which creates a table. I would like to capture messages output (Command(s) completed successfully.) from sql server. Is there a way to achieve that?
I tried -Verbose switch but that didn't helped.
PS File:
$CreateTableFile = "C:\DBScripts\CreateTable.sql"
Invoke-Sqlcmd -ServerInstance xyz -InputFile $CreateTableFile -Database "PSLearning" -Verbose
CreateTable.sql:
CREATE TABLE abc (
column_1 int,
)
You don't say what you want to capture. Everything or just errors.
Errors, you can use try/catch, everything you can use Start-Transcript, or write your own log code, or stuff like print script.
Example:
Invoke-Sqlcmd -Query "update your database set column_name ={expression} where <search_condition>; PRINT 'update successfully';" –Verbose
As documented in the Bulit-In Help files …
# get function / cmdlet details
(Get-Command -Name Invoke-SqlCmd).Parameters
Get-help -Name Invoke-SqlCmd -Full
Get-help -Name Invoke-SqlCmd -Online
Get-help -Name Invoke-SqlCmd -Examples
Get-help -Name Invoke-SqlCmd -Examples
# -------------------------- EXAMPLE 5 --------------------------
C:\PS>Invoke-Sqlcmd -Query "PRINT N'abc'" -Verbose
VERBOSE: abc
# Description
# -----------
# This example uses the PowerShell -Verbose parameter to return the message output of the PRINT command.
... or the online ones.
Invoke-Sqlcmd
You can display SQL Server message output, such as those that result
from the SQL PRINT statement, by specifying the Verbose parameter
Example 5: Run a query and display verbose output
PSet-Location "SQLSERVER:\SQL\MyComputer\MainInstance"
Invoke-SqlCmd -Query "PRINT N'abc'" -Verbose
VERBOSE: abc
My goal is to have a PowerShell script run several Sqlquery.sql files against a specific SQL server and then log the output to a log file.
I can't get the logging to work and I don't know what I'm missing. My log file is always empty and I'm at a loss for that I am missing.
Contents of C:\Temp:
Build1.SQL
Build2.SQL
Build3.sql
Build4.sql
Build5.SQL
Build6.SQL
$PatchPostConvSQLScripts = Get-ChildItem -Path C::\Temp -Filter *.sql -Name
$Queries = $PatchPostConvSQLScripts
foreach ($query in $Queries){
Write-Host "Starting: $query"
Invoke-Sqlcmd -ServerInstance $DBServer -InputFile $query |
Out-File "C:\TEMP\scriptResults.log"
Write-Host "Completed: $query"
}
Once I get it logging to a file, I'll need to get a newline each time with a `n`r, but baby steps right now.
Is there a better way to do this that I just don't know?
The main reason you got nothing in log file is that Output-File rewrite whole data in it on each run. Try to use -Verbose as mentioned in answer by TechSpud to collect print/server statements, or write output to temp file and Add-Content to main log file:
$DBServer = "MYPC\SQLEXPRESS"
$sqlPath = "C:\TEMP\"
$log = "scriptResults.log"
$tempOut = "temp.log"
$files = Get-ChildItem -Path $sqlPath -Filter *.sql -Name
foreach ($file in $files){
Write-Host "Starting: $file"
Invoke-SQLcmd -ServerInstance $DBServer -InputFile $sqlPath$file | Out-File $sqlPath$tempOut
Get-Content $sqlPath$tempOut | Add-Content $sqlPath$log
Write-Host "Completed: $file"
}
Firstly, as #Ben Thul has mentioned in his comment, check that your SQL files actually output something (a resultset, or messages), by running them in Management Studio.
Then, you'll need to use the -Verbose flag, as this command will tell you.
Get-Help Invoke-Sqlcmd -Full
Invoke-Sqlcmd does not return SQL Server message output, such as the
output of PRINT statements, unless you use the PowerShell -Verbose parameter.
$Queries = Get-ChildItem -Path C::\Temp -Filter *.sql -Name
Clear-Content -Path "C:\TEMP\scriptResults.log" -Force
foreach ($query in $Queries){
Write-Host "Starting: $query"
Invoke-Sqlcmd -ServerInstance $DBServer -InputFile $query -Verbose |
Add-Content -Path "C:\TEMP\scriptResults.log"
Write-Host "Completed: $query"
}
I’m trying to run the sql script .sql file from powershell and save the result into .sql file. Overview : SQL database restore requires a user and permission backup pre-restore and once the restore is complete we need to execute the output( users permissions backup which we did pre-restore ) on the database.
here’s my script and when i execute i see an empty file.
Add-PSSnapin SqlServerProviderSnapin100;
$server = 'DBA_Test';
$database = 'Test';
$mydata = invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize
$mydata | out-file C:\users\output.sql;
Remove-PSSnapin SqlServerCmdletSnapin100;
Can someone help me on this ?
Thanks in advance
invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize >> C:\users\output.sql
or
Invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize | Out-File –FilePath C:\users\output.sql –Append
should do the trick.
Your problem is that you're only capturing one output stream. Your code would work as expected if your query was running "Select 'Hello World!'".
In order to get all output streams (verbose, error, and output), into a single file, you can do the following:
invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database -verbose *>&1 | out-file C:\users\output.sql
The -verbose flag turns on a lot of the messages you'd expect to see. The * indicates you want all output streams (you can look up the definitions if you'd like. The verbose stream itself is 4, so 4>&1 would just redirect that one stream). Then you are just redirecting the output to out-file.
Here's what I have:
Add-PSSnapin sqlservercmdletsnapin100
Add-PSSnapin sqlserverprovidersnapin100
Invoke-Sqlcmd -inputfile "somefile0.sql" -Server "server0" -Username user0 -Password password0
Invoke-Sqlcmd -inputfile "somefile1.sql" -Server "server1" -Username user1 -Password password1
Each Invoke-Sqlcmd run by itself runs fine. When placed in a script that reads like above, the last Invoke-Sqlcmd returns no results to the screen.
I figured this out. Turns out that it works well when I return the results of each Invoke-Sqlcmd to a variable and then output the variable. Like this:
Add-PSSnapin sqlservercmdletsnapin100
Add-PSSnapin sqlserverprovidersnapin100
$result0 = Invoke-Sqlcmd -inputfile "somefile0.sql" -Server "server0" -Username user0 -Password password0
$result1 = Invoke-Sqlcmd -inputfile "somefile1.sql" -Server "server1" -Username user1 -Password password1
Write-Host $result0.ItemArray
Write-Host $result1.ItemArray
The output to the screen is now visible, but poorly formatted. That'll get straightened out next.