I'd like to have a PowerShell script that uses as input;
-username
-password
-remote servername
And then lists the remote SQL databases. Thing is, it should work from any PC with powershell, even if there are no SQL client/tools used/installed/plugins loaded. Standard .NET framework call are accepted ofcourse.
I know it's possible, because I've seen 'sql-clientless' machines list databases remotely.
The following should work with an installed .NET Framework:
function Get-SqlDatabases
{
[CmdletBinding()]
Param
(
$Server,
$User,
$Password
)
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection "Data Source=$Server;User ID=$User;Password=$Password"
$sqlConnection.Open();
$sqlConnection.GetSchema("Databases") | select -expand database_name
$sqlConnection.Close();
}
Usage:
Get-SqlDatabases -Server 'myServer' -User 'myUser' -Password 'mySecret'
Related
I have SQL script which I want to execute using azure DevOps pipeline
I found multiple tasks for SQL but can not find any required task where I can pass sql server , database name and login details. Is there any task available for this ?
If there is not any task available and only way to execute is powershell script any sample available script for this ?
You can use PowerShell to execute sql scripts. Example:
Invoke-Sqlcmd -InputFile "$(scriptfilepath)" -ServerInstance $(sqlserver) -Database $(dbname) -Username "$(username)" -Password "$(pwd)" -QueryTimeout 36000 -Verbose
Add custom variables (scriptfilepath, sqlserver, ...) and set values to them.
PowerShell task
Define variables
Invoke-Sqlcmd
You can use Invoke-Sql command like this
$SQLServer = "TestServerOne"
$db3 = "TestDB3"
$qcd = "PRINT 'This is output'"
Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db3 -Query $qcd -Username "User" -Password "Password" -Verbose
Make sure SqlServer module is installed. It works also with Powershell Core
You can also try to use Run SQL Server Scripts Task extension
If you want to do this in Azure Release Pipeline (classic), you can use the '
Azure SQL Database deployment
' block which uses Invoke-Sqlcmd under the hood.
With that, you can configure it to execute an SQL script on a given database under one or your subscriptions or service connections.
I am writing a Powershell script that should connect and query the database (that is hosted in Azure). I am able to connect without a problem to SSMS using my AzureAD ID. However, I am unable to do the same in Powershell. I am using this pattern for my connection string:
"Server=tcp:myserver.database.windows.net,1433;Authentication=Active Directory Password;Database=myDataBase;UID=myUser#myDomain;PWD=myPassword;"
Just to be clear, the connection string works perfectly fine and the DB admin told me that I have all the needed permissions. What is the possible cause for this? I tried both Invoke-SqlCMD and ADO.net. Please help!!
Here is a piece of code I ran as a test and it worked fine.
$server = "tcp:thesqlservername.database.windows.net,1433"
$database = "testdb"
$adminName = "testuser01#mytenantname.onmicrosoft.com"
$adminPassword = "TestPassword"
$connectionString = "Server=$server;Database=$database;User ID=$adminName;Password=$adminPassword;authentication=Active Directory Password;"
$connection = New-Object -TypeName System.Data.SqlClient.SqlConnection($connectionString)
$ds = new-object "System.Data.DataSet" "dsPersonData"
$q = #"
SELECT * FROM [SalesLT].[Customer]
"#
$da = new-object "System.Data.SqlClient.SqlDataAdapter" ($q, $connection)
$da.Fill($ds)
$dtPerson = $ds.Tables[0]
I created a demo azure sql db, set the test user as "active directory admin" on the sql server in azure, and installed smss (management studio) on my desktop to test.
what error are you getting?
I am putting together some powershell scripts to execute SQL commands against SQL Server and need to specify the windows account to use in the connectionstring. I have tried the following which does not work.
$SQLServer = ".\sqlexpress"
$SQLDBName = "dbname"
$uid ="domain\user
$pwd = "password"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = false; User ID = $uid; Password = $pwd;"
$SqlCmd.Connection = $SqlConnection
$SqlConnection.Open();
.... Execute query...
I get the following error.
Exception calling "Open" with "0" argument(s): "Login failed for user
'Domain\user'.
I was lead to understand that if you specify false on integrated security then is would take the username and password and connect using the corresponding windows account.
For me this is failing to connect. Am I missing something here ?
Many thanks
Darren
Another way to tackle this would be to use the SQL PowerShell Module (SQLPS) which can be obtained by installing "Management Tools" from the SQL Management Studio Installer. By default, when using Invoke-Sqlcmd it will connect as the windows account that initiated the PowerShell instance. If you wish to run as another windows account other than the one you are signed in with, you would shift + right click PowerShell and choose option to "run as different user".
Once Module has been installed, you can import module by executing:
Import-Module SQLPS
Next you would execute your query like the following:
Invoke-Sqlcmd -ServerInstance "ServerName\Instance" -Database "DatabaseName" -Query "Some Query Here"
While entirely optional, I would recommend adding -Verbose as this will show you output just as you would see in Sql Management Studio.
Hope this helps.
I need to provide a powershell script that runs a bunch of steps to install a custom solution. One of these steps is create a SQL Server database and execute a .sql file to generate the schema.
The thing is that I need a way of doing it in any machine, whether is has SQL server locally installed or not (it usually is on another network machine).
Also I need to avoid using 3rd party modules since I cannot force clients to install them.
Is there a way of doing this?
UPDATE: The server running the script will have .NET 4.5 installed since SharePoint 2013 will be installed.
Something like this:
#Variables
$sqlServer = "."
$sqlDBName = "master"
$sqlQuery = "CREATE DATABASE test"
# Create the connection string
$sqlConnectionString ="Server = $sqlServer; Database = $sqlDBName; Integrated Security = True"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $sqlConnectionString
#Create the SQL Command object
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
#Open SQL connection
$SqlCmd.Connection.Open()
#Execute the Query
$ReturnValue = $SqlCmd.ExecuteNonQuery()
--Edit
Technically GO is not a T-SQL command. It's the end-of-batch marker recognised by Microsoft SQL tools (Management Studio, isql, osql). So that is why when you execute the statement directly, it isn't recognized. The 'real' solution is to either eliminate the GO statements, or split up the statements into separate batch processes (either physically or string.split("GO"))
Or the alternate using SQL Management Object which theoretically can handle "Go" statements (SqlCommand() ExecuteNonQuery() truncates command text):
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
$SMOServer = New-Object ('Microsoft.SqlServer.Management.Smo.Server')
$SMOServer.ConnectionContext.ConnectionString = $sqlConnectionString
$SMOServer.ConnectionContext.ExecuteNonQuery($sqlQuery)
--Edit 2
Or, if you can't use SQL Management Object, and you have "GO" Statements, something quick and dirty is that you can split the string and use code like this:
#Variables
$sqlServer = "."
$sqlDBName = "master"
$sqlQuery = "CREATE DATABASE test; GO; CREATE DATABASE test2; GO;"
# Create the connection string
$sqlConnectionString ="Server = $sqlServer; Database = $sqlDBName; Integrated Security = True"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $sqlConnectionString
$sqlQuery -split "GO;" | ForEach-Object{
if($_ -ne "")
{
#Create the SQL Command object
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $_
$SqlCmd.Connection = $SqlConnection
#Open SQL connection
$SqlCmd.Connection.Open()
#Execute the Query
$ReturnValue = $SqlCmd.ExecuteNonQuery()
#Close the connection
$SqlCmd.Connection.Close()
}
}
You can use the ordinary .NET classes SqlConnection and SqlCommand from PowerShell. To do that you don't need SQL Server, nor any specific PowerShell modules, installed. Just create the objects using the New-Object cmdlet.
Update:
Here's a sample of how you could do (no error handling added) to call execute SQL code without using SQL specific cmdlets:
$connectionString = "" #Set your connection string here
$connection = New-Object -TypeName System.Data.SqlClient.SqlConnection($connectionString)
$query = "" #Set your sql query here
$command = New-Object -TypeName System.Data.SqlClient.SqlCommand($query, $connection)
$connection.Open()
$command.ExecuteNonQuery() #Other methods are available if you want to get the return value of your query.
$connection.Close()
You are trying to do something that perhaps cannot be done, depends on your definition of "sql not installed". If the client does not have the sql client tools installed, you will not be able to talk directly to sql server at all.
If you need to install sql server on a remote computer, you will not in general be able to do so without admin permissions, and doing so remotely with admin permissions is still complicated as SQL server 2012 is not designed for a remote install -- though you could perform a remote install using the CMD processor via remote connection (if you have some way to do that as this is not built in to the standard windows installation.
If the sql client tools are installed on your local machine (where you are running powershell) and sql server is running on the remote machine -- and you have a database login with suitable permissions, you can instantiate SqlCommand objects to do everything you might need.
I have a problem where I cannot connect to a SQL Server using domain credentials. Using the SA credentials it works and the query runs as expected. But when I use domain credentials, I get an error.
Here is the script:
$SQLServer = 'server.domain.com'
$SQLDBName = 'DBname'
$username = "DOMAIN\user"
$password = "password"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
#--> With SA, it works, with DOMAIN creds, it does not
#$SqlConnection.ConnectionString = "Server=$SQLServer; Database=$SQLDBName; User ID=sa; Password=SApassword;"
$SqlConnection.ConnectionString = "Server=$SQLServer; Database=$SQLDBName; User ID=$username; Password=$password;"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = 'select count (*) from my.table'
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]
And here is the error I get when I run the script:
Exception calling "Fill" with "1" argument(s): "A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
At C:\scripts\PowerShell\myscript.ps1:28 char:1
+ $SqlAdapter.Fill($DataSet)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
I should point out the fact that I am connecting to a SQL Server from a computer which is NOT in the domain (therefore I cannot use any sort of authentication passthrough).
Any ideas as to why I cannot connect with my domain credentials? I've followed other posts which offer advice on checking connections, firewalls etc. That's all in working order and the script runs perfectly as the sa (local) user. Just not on the domain..
If you have SQL Credentials use something like this:
$ConnectionString = server=*serverName*;database=*databaseName*;user id=*userName*;password=*passWord*;
If you have Domain Credentials use something like this:
$ConnectionString = "server=*serverName*;database=*databaseName*;user id=*domain\username*;password=*passWord*;trusted_connection=true;"
This works in my environment. Of course after that you do:
$Connection = New-Object System.Data.SQLClient.SQLConnection($ConnectionString)
You cannot connect with domain credentials THAT WAY.
Domain credentials are present in the process making the connection. The account using in the process (or if using the NETWORK ONLY option in RUNAS) will be used to make the connection to SQL Server using integrated security.
Of course, because your process CANNOT actually run as a user on that domain because your computer is not in a trust relationship with that domain, I recommend you look at using RUNAS /NETONLY.
This will prompt for a password, and so you may have to write your own replacement for it which uses the CreateProcessWithLogonW API instead.
https://stackoverflow.com/a/758805/18255
This will allow your process to use domain credentials from the other domain which are only used on network connections and verified at that time, while still using the local account for other things. This MAY cause problems getting to other network resources which might rely on your local (or other domain?) account, I haven't fully tested how RUNAS /NETONLY works if you make DIFFERENT network connections from the same process.
Function SQL_CONN1 ($Query) {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=myPC;Database=myDB;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.Connection = $SqlConnection
$SqlCmd.CommandText = $Query
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$a=$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0] }
SQL_CONN1 "Select * from [MyTable]"
Try
$SqlConnection.ConnectionString = "Server=myPC;Database=myDB;Integrated Security=True"
If you are not worried about security you can do it like this (not secure, though):
#Set variables here
$connectionString="server=$s;database=$sqlDbName;user id=$userName;password=$passWord";
$sqlConnection=New-Object System.Data.SqlClient.SqlConnection($connectionString);
It works in SQL Server 2012. But, again, not secure. Hope that helps someone...
You cannot pass username and password as string.
Try something like this -
#$cred = Get-Credential
# this will prompt for username and password, fill them in
# use this in your connection string
$secpwd = ConvertTo-SecureString $password -AsPlainText -Force
$SqlConnection.ConnectionString = 'Server=$SQLServer; Database=$SQLDBName; User ID=$username; Password=$secpwd;'