Rename azure sql database using powershell - powershell

I've created azure database using powershell. Now i want to rename the database using powershell. My purpose to do this is creating temporary database, then deploy database release to temp DB,then rename production db to any other name, finaly rename Temp Db to production db

To achieve this, you can use the cmdlet "Set-AzureSqlDatabase", the parameter "-NewDatabaseName" permits to set a new name for a specified database name.
Set-AzureSqlDatabase -ServerName 'myservername' -DatabaseName 'mydb' -NewDatabaseName 'newNameForTheDb'
Here is the documentation : https://msdn.microsoft.com/fr-fr/library/dn546732.aspx

using Az.Sql module the command command would be:
Set-AzSqlDatabase -DatabaseName <sourceDbName> -NewName <targetDbName> -ServerName <server1> -ResourceGroupName <resgroup1>

Related

Can't read migration file using golang-migrate

After running the up command, my database doesn't seem to be recognizing the SQL contained inside relative/path/000001_init_schema.up.sql.
So far:
Verified I have a connection to the database
Successfully executed the SQL inside my database manager (TablePlus)
Relative path is correct (-path db/migration)
Full command:
migrate -path relative/path -database "postgresql://root:secret#localhost:5432/dbname?sslmode=disable" -verbose up
After running the command, I receive confirmation that "no changes have been made", but my database only has a schema_migrations table.
Any other ideas?
Thanks,
Connor
I solved the issue by replacing -path relative/path with -source file://relative/path
Alternatively, you can use -source file:///absolute/path

Set-AzureRmSqlDatabase command is failing while lowering the Azure SQL DB pricing tier due to key vault soft delete

I'm using an automated powershell script to downgrade the pricing tier of the database backup copy. While supplying the below command the tier downgrade fails. The error, if I understood correctly is referring to key-vault with a key named same as my server name, since there is no such key exists(hence the soft delete can also be not enabled), this command fails.
The command has been set-up when my application was not set-up with key-vault and seems like now it's failing.
Command used:
Set-AzureRmSqlDatabase -DatabaseName <*Back-up DB name*> -ServerName <*SQL server name*> -ResourceGroupName <*Resource Group name*> -Edition Standard -RequestedServiceObjectiveName S0
Error:
Set-AzureRmSqlDatabase : 45377: The provided Key Vault uri
'https://****.vault.azure.net/keys/<SERVERNAME>/<Subscription/some
ID> is not valid. Please ensure the key vault has been configured
with soft-delete. (https://aka.ms/sqltdebyoksoftdelete) At line:1
char:2
+ Set-AzureRmSqlDatabase -DatabaseName <Back-up DB name> -ServerName <SQL server name>...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmSqlDatabase], CloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Sql.Database.Cmdlet.SetAzureSqlDatabase
Questions :
1.Why Set-AzureRmSqlDatabase command is referring to a key-vault URI, when not mentioned explicitly ?
2.Is there a option we need to set at the server/DB level to allow this command to read the server/DB name directly rather than searching for a key with server name?
Is this anywhere related to Transparent data encryption ?
Are we suppose to make any changes to this command if the key-vault comes later than the application/DB/key-vault set-up ?
This issue was purely related to TDE(Transparent data encryption) as I thought of. Since Azure SQL databases were secured by TDE, it was expected that the key-vault should also be enabled with soft delete to recover any deleted keys.
While trying to enable soft-delete, I figured out that the Azure powershell installed on my machine doesn't support soft delete property.
I am able to resolve this issue by following steps :
Upgraded powershell :
Installation Package
Login into your azure subscription and run this command
$vault = Get-AzureRmKeyVault -VaultName myvault; $vault.EnableSoftDelete
If the above doesn't work run the below command. This will find the resourceId of the key-vault and then will enable soft-delete -
($resource = Get-AzureRmResource -ResourceId (Get-AzureRmKeyVault -VaultName "YourKeyVaultNameHere").ResourceId).Properties | Add-Member -
MemberType "NoteProperty" -Name "enableSoftDelete" -Value "true"
Set-AzureRmResource -resourceid $resource.ResourceId -Properties $resource.Properties
Verify if the key-vault soft-delete is enabled by below command
Get-AzureRmKeyVault -VaultName "YourKeyVaultNameHere"
Hope this would be helpful for someone facing the similar issue.
Here are some personal opinions for you to refer.
First, per my test, the command works fine on my side.
Note: In my test environment, it is a sql server and database without any other things, like transparent data encryption.
Set-AzureRmSqlDatabase -DatabaseName joydatabase -ServerName joydb -ResourceGroupName joywebapp -Edition Standard -RequestedServiceObjectiveName S0
Why Set-AzureRmSqlDatabase command is referring to a key-vault URI, when not mentioned explicitly ?
On my side, I catch the request via fiddler, it is not referring to a key-vault URL, refer to the screenshot.
Is there a option we need to set at the server/DB level to allow this command to read the server/DB name directly rather than searching for a key with server name?
On my side, I think we needn't to do so.
Is this anywhere related to Transparent data encryption ?
I think there is a great possibility that it is related to it. You could create a new sql server and database to have a try. Here is an article about transparent data encryption for azure sql server, you could refer to it.
Are we suppose to make any changes to this command if the key-vault comes later than the application/DB/key-vault set-up ?
I think it seems not make any change to this command.

How to get the database backup path from a server using powershell?

I have been looking for the powershell commands for getting the backup path of a database in an sql server. I would be providing sever name and database name as input. Could some one help me with the solution so that I can achieve my requirement.
Note: I just need the path of the database backup. I need not to do any back up of that database in a path.
Thanks in advance.
Sudhir
So.... couple of things.
A SQL Server instance (sounds like you're asking about SQL Server), has a default backup location, which can be overridden at the time of a backup. If you want to see an instance's default backup location, I'd use something like this:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$i = New-Object 'Microsoft.SqlServer.Management.Smo.Server' '(local)'
$i.Settings.BackupDirectory
I'm using SQL Server Management Objects (SMO) here. I've created an instance object ($i), and I've queried the BackupDirectory property in the Settings collection to get the desired path.
If you don't like SMO, you can also get this information from the registry; see this article for help there.
Adding an answer here (since I can't add comments yet), there is also the option to use the newer SQLServer module in powershell. Just run a query to get the data you need. This is for a local SQL Express instance, update the name as needed.
Import-Module SqlServer
$bkppath = Invoke-Sqlcmd -Query "SELECT SERVERPROPERTY('InstanceDefaultBackupPath')" -ServerInstance ".\SQLExpress"
$bkppath.Column1
As an added bonus, if you'd like to delete the oldest backups just run this line, updating the best number of days to keep (AddDays function) (using bits of Pinal code from https://blog.sqlauthority.com/2018/04/02/sql-server-powershell-script-delete-old-backup-files-in-sql-express/ ):
Get-ChildItem $bkppath.Column1 -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item -Recurse

Credentials using Invoke-Sqlcmd against sql azure

I'm attempting to run a powershell build script against a sql azure database but receiving Login failed for user 'X'.
I'm fairly convinced the credentials are correct as they were taken straight from the live application config.
This is the command I'm using:
Invoke-Sqlcmd -InputFile "Build.sql" -ServerInstance $server -Database $database `
-WarningAction SilentlyContinue -OutputSqlErrors $false `
-Username $username -Password $password -EncryptConnection
I had this working with sqlcmd in a batch file so I'm wondering if it's got anything to do with the way the credentials are being sent, trusted_connection=false doesn't appear to be an option I can try.
It could be the password contains a few special characters that Azure/Invoke-sqlcmd does not handle (such as dollar, single or double quote, parentheses). I tried using the Azure interface and surrounding the password with single-quotes (we had a dollar-sign in the password), but that did not work. So, we simply removed the special character and now it is OK. see: Powershell Invoke-Sqlcmd Login Failed
and
https://mohitgoyal.co/2017/08/09/vsts-azure-sql-database-deployment-task-keeps-failing-with-error-login-failed-for-user/
When connecting to SQL Azure the login name must be of the form user#server. So if you created an user 'foo' and a server 'bar', the login must be foo#bar. See Managing Databases and Logins in Azure SQL Database:
Because some tools implement tabular data stream (TDS) differently, you may need to append the Azure SQL Database server name to the login in the connection string using the <login>#<server> notation. In these cases, separate the login and Azure SQL Database server name with the # symbol. For example, if your login was named login1 and the fully qualified name of your Azure SQL Database server is servername.database.windows.net, the username parameter of your connection string should be: login1#servername.
CREATE LOGIN also explains this:
In some methods of connecting to SQL Database, such as sqlcmd, you must append the SQL Database server name to the login name in the connection string by using the <login>#<server> notation. For example, if your login is login1 and the fully qualified name of the SQL Database server is servername.database.windows.net, the username parameter of the connection string should be login1#servername.

Powershell Invoke-sqlcmd keeping connection open and trying to reuse it

I have a Powershell script that uses invoke-sqlcmd to apply scripts to a series of development databases. I loop through a list of scripts and compare it to the current release level of the database and then apply the required scripts to get the DB to the release level it needs to be at. Certain databases are reference databases and are in a READ_ONLY state. I connect to those database run an alter DB script setting them to READ_WRITE apply the script then change the back to READ_ONLY. Overall the script works well, the issue is it looks like when PowerShell first opens a connection to the database and applies the first script and then goes to alter the DB back to READ_ONLY the database has objects locked. I've traced it back to the previous connection and a Shared_Transaction_Workspace lock (sys.dm_tran_locks) for what looks to be the previous powershell connection. Why is this connection still open after the invoke-sqlcmd has completed and is there anything I can do about it? Can I force invoke-sqlcmd to use a new connection for each invocation of the cmdlet?
I have tried a messy fix killing the offending connection and then retrying the connection but I think there is something better.
I've always done this and it seems to work:
[System.Data.SqlClient.SqlConnection]::ClearAllPools()
Well, I know that this is a very old post and the people from Microsoft told that fixed this issue (as told the article mentioned by David Brabant) but maybe I'm not the luckiest guy and have to make an workaround to make it happens.
Even running Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64) I had the same issue and after make some researches I got a way to get some parameter from Invoke-Sqlcmd as output so I can get the Session ID of the current user process with the built-in ##SPID global variable from the SQL Server and make a connection with ADO.NET to execute a KILL clause to close the opened connection.
So let's to the workaround applied in my case
#Invoke the Invoke-Sqlcmd to execute an script from a file
Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -InputFile [DOT_SQL_FILE_PATH]
#Invoke the Invoke-Sqlcmd to execute a inline SQL statement to get the SessionID as a Powershell variable
$SQLSession = Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -query "select ##spid as SessionID"
# Build query to execute KILL clause
$DbQuery = "KILL " + $SQLSession.SessionID;
# Create SQL connection with ADO.NET
$DbConnection = New-Object System.Data.SqlClient.SqlConnection
$DbConnectionString = "Server = [SERVER_NAME]; Database = [DATABASE_NAME]; User ID=[USER]; Password=[PASSWORD];"
$DbConnection.ConnectionString = $DbConnectionString
$DbConnection.Open()
# Create SQL command for KILL clause
$DbCommand = New-Object System.Data.SQLClient.SQLCommand
$DbCommand.Connection = $DbConnection
$DbCommand.CommandText = $DbQuery
# Execute KILL clause
$DbCommand.ExecuteNonQuery()
# Close connection
$DbConnection.Close()
I hope that it helps
Even though I am using the newest version of SSMS (Version 16.5.3 - Build 13.0.16106.4), I still get this issue. I haven't figured out what the "right" way of forcing the connection closed is, but I have a work-around that is simple and resolves the issue for me. If you just need to get the connection off the database, you can do the following:
Run normal command(s)
Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" ...
When you are ready to eliminate the connection from the database:
Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" -Query "use [master];"
This will switch the connection to master, thus removing it from the database of interest. If you absolutely need the connection closed, I think you need to resort to SqlClient or such.