I'm trying to write a PowerShell script which will execute tsql query to only one remote server using invoke-sqlcmd. Those tsql queries are simple one like backup/restore database, create a user, etc.
Below is an extract of it :
# 5 # Create clientdb database on secondary server by restoring the full backup for primary
Try {
Invoke-sqlcmd -ServerInstance 'REMOTESQLSRV'`
-Username 'ts_sql' -Password 'somepassword'`
-InputFile "$LScltid\__01_On_Secondary_CreateDB2_srv2.sql"`
-ErrorAction Stop
Write-Host " clt_$id is now restored to secondary server "`
-ForegroundColor White -BackgroundColor Green
} Catch {
Write-Host " Restore operation for clt_$id did not succeed. Check the error logs " -ForegroundColor Black -BackgroundColor Red
}
My scripts always break here. For some reasons that i could not put my head on, invoke-sqlcmd does not use the variable "$LScltid" to resolve the path where it will find the .sql script.
Everytime i had to run it, it change the current directory to either the SQLERVER:\ provider or some other causing the script to failed at this step.
Am I doing this the right way? If so, how should i adapt the command to perform as I expect it to.?
UPDATE
Forgot to mention, if i run the script with the variables values hard-coded I'm able to get the result i need (in this case restoring a database from device).
Thanks for your feedbacks.
Odd thing, the command is now working. I don't really know what i've done wrong previously, but the exact same command is now working.
Just a heads up for those facing the same issue:
If you have to use Invoke-Sqlcmd in your scripts, beware of the provider change especially if the commands coming after Invoque-Sqlcmd are regulars one (get, set, copy, new, etc....)
In my case, somewhere in my script between two Invoke-sqlcmd commands i had to copy files from local to remote server. Everytime the command failed because the provider changed. As a workaround I set-location before copy-item command execution and that maneuver seemed to do the trick (don't know if its re-commanded tough.
Thanks Stackoverflow Team
Related
The process: an Azure agent that runs on a Windows 10 32bit pro machine with SQL Server 2014 Express installed.
The pipeline is built and runs successfully with PowerShell scripts as follows:
Create blank database
Create tables needed
C# application runs and populates the tables executed via a PowerShell script
Cross reference tables to update data needed.
Build a SSIS package
After result from SSIS package is success perform a backup
Command:
Backup-SqlDatabase -ServerInstance "$env.ComputerName" -Database "RealDB"
-BackupAction Database -BackupFile $Path -Blocksize 4096
This all works with one exception the actual backup I get is missing the data from the SSIS package run. BUT if I log into the machine and restore the backup used from $Path it is missing the data.
When I query the database after this process the data is there in the database.
There is only one database so its not backing up a different one.
I can run this command in powershell on the machine and my backup has the missing data that the powershell command from the agent does not.
Also interesting enough if I remove the -Blocksize 4096, it works as I expect and the backup has the data in it. I am considering abandoning the powershell due to this but thought I would ask to see if anyone experienced this or no.
Any help or thoughts are appreciated.
Thank you
Thank you #user19702 I was so consumed looking at the backup command with the added -BlockSize that I completely ignored the fact that my data has increased (thanks random process I never heard of before today) and even though the powershell is written to start the backup AFTER the SSIS package the process was not done. To find it I started task manager on the machine while the build was running and watched the process stay in memory for a few seconds when the backup started. I added a powershell command to make it wait a few seconds before processing the backup and its working.
In case anyone is wondering this is the command
$result = $package.Execute("false", $null)
Write-Host "Package ID Result: " $result
Start-Sleep -Seconds 10
Backup-SqlDatabase -ServerInstance "$env:ComputerName" -Database "RealDB" -BackupAction Database -BlockSize 4096 -BackupFile $Path
Thank You!!
I'm trying to automate executing SQL scripts using Invoke-SQLCmd powershell command. As a source I have a one script generated by SSDT Schema Compare (4000 lines, all inside transaction). I'm triggering this script in the following way:
Invoke-SQLCmd -InputFile "$Path" -ServerInstance "$Server" -Database "$DbName" -ErrorAction "Stop"
As an output I'm receiving the following error:
Invoke-SQLCmd : Could not allocate a new page for database 'TEMPDB' because of insufficient disk space in filegroup 'DEFAULT'. [...]
I know that this problem is probably related to lack of free space on testdb disk, but what is interesting the script has been completed successfully when it was executed from SQL Server Management Studio on the same database.
The question is how is it possible and how can I make this script working correctly from PowerShell.
This error is due to insufficient Transaction log space...
You can use below command to find out offending transaction and take care of it
Dbcc opentran
This may be also due to your script generating a lot of transaction log and you dont have enough Transaction log space left...if this is the case, you might need to break up your command into multiple commands or increase your tlog space
I have a PowerShell script:
Invoke-Sqlcmd -ServerInstance "PRODUCTION" -Database "DATABASE" -InputFile "E:\DW_Exports\cdd.sql" | Export-Csv "E:\DW_Exports\Pearsonvue\CDD.csv" -NoTypeInformation
When I run this manually in ISE, works fine, no problems.
However, when I set it up as a SQL Agent job it just returns a blank file. No errors reported, it says it was successful, but all I end up with is a blank file.
I've tried the process with very simple queries (just changing the input file the PowerShell points to), and it works fine. So we can rule out SQL Server Agent access issues to the file location or running PowerShell. It just doesn't work for this specific query.
Whats also odd is that sometimes after I run the job, if I try to run the PowerShell script manually it says I don't have access to the file location unless I delete the blank file, then it works fine again.
Any ideas?
I am trying to create a PowerShell script to automate a very simple process, however, I cannot get much (if anything) to work. The documentation is either not what I need, outdated or conflicting.
I've had a few variations of this:
$SQLConnection = New-Object System.Data.SQLClient.SQLConnection
$SQLConnection.ConnectionString = "Data Source=.\SQL2016;Initial Catalog=TEST;Trusted_Connection=true;"
$SQLConnection.Open()
$Cmd = new-object system.Data.SqlClient.SqlCommand($SQLConnection)
Invoke-Sqlcmd -InputFile "C:\dev\test\script.sql" | Out-File -filePath "C:\dev\test\output.sql"
$SQLConnection.Close()
I've not managed to connect to the database.
The idea being, script.sql spits out a bunch of SQL (this works fine) which we will put into source control. Once in source control, a Jenkins job will do something with it.
Trying to keep this as basic as possible, no flexibility is needed other than different connection strings. I want to avoid using PSSQL if possible, a user throws in their connecting string (database will be the name) and runs the script, job done.
Can anyone point me in the right direction?
System.Data.SQLClient is only necessary if you don't have the SqlServer module installed or are doing something unusual. It's a much more verbose method.
You just need:
Import-Module SqlServer;
Invoke-Sqlcmd -ServerInstance '.\SQL2016' -Database 'TEST' -InputFile 'C:\dev\test\script.sql' |
Out-File -FilePath "C:\dev\test\output.sql"
However... your output file isn't really an .sql file unless the queries in script.sql are actually returning strings that should be executed as SQL. It should probably be a .txt file.
And depending on what exactly you're generating, you might want to consider Export-Csv -Path "C:\dev\test\output.csv" -NoTypeInformation instead of Out-File. I can't tell if you're trying to export data or just logging information.
Additionally, you'll need to make sure that you're not using the batch separator (GO) in script.sql, or relying on any "SQLCMD Mode" (as it's called in SQL Server Management Studio) or other sqlcmd.exe specific syntax. The Invoke-Sqlcmd doc outlines the differences between the two. If you don't know what that is, you're probably safe.
I have a (pretty much clean) Windows Server 2008 R2 Build with SQL Server 2012 installed. I'm having a problem with PowerShell (Version 3).
I am trying to use the Invoke-Sqlcmd cmdlet. However, when I call get it i get a message saying that 'Invoke-Sqlcmd' is not recognized as the name of a cmdlet, function, script file, or operable program.
It works if if I run Import-Module SqlPs -Verbose -Force (bypassing the security policy). However it this lasts only as long as the tab is open. If i open a new tab, try to run another script or re-open Powershell ISE I have to import the module all over again.
Any ideas why this is happening?
This is more of a work around, but you can add it to your profile.
"'Import-Module SqlPs -Verbose -Force'" > $profile
Obviously if you have a profile file from before, you dont want to do it like that, but instead open it and add it through notepad or similar.
Also note that Powershell and PowershellISE has different profiles, so you would need to add it in both if you mix.
From my understanding, module loading is done on a per session basis. So the behavior you're seeing is what is expect.