Enable SQL Server Authentication - DSN Configuration - sql-server

I'm using Powershell to update DSN configuration. Example code:
$properties = #('server=databaseServer1', 'description=Test description')
Set-OdbcDsn -Name 'TestDSN' -SetPropertyValue $properties -DsnType System
This works. I want to enable SQL Server Authentication, following this page I tried:
$properties = #('SqlPassword=SQL_AU_PASSWORD')
Does not work. Also tried:
$properties = #('Authentication=SqlPassword')
Does not work. Both show the error Invalid keyword-value pairs.
What am I doing wrong?

you have to set Trusted_Connection (No = SQL Server Authentication, Yes = Windows Authentication)
$properties = #('server=databaseServer1', 'description=Test description','Trusted_Connection=No')
Set-OdbcDsn -Name 'TestDSN' -SetPropertyValue $properties -DsnType System

Related

How to use ApplicationIntent=ReadOnly inside my powershell code in SQL command

I need to use ApplicationIntent=ReadOnly with my SQL command in powershell which is connecting to a replica database. Can anyone help ?
Since replicas servers could not be accessed directly. So I need to use this command. I know how to manually do it but need help on code.
$SQLQuery = "SELECT x.SCode, x.DatabaseName FROM dbo.Logins x ORDER BY x.SCode"
$auth = #{Username = $SQLUserName; Password = $SQLAdminPassword}
try
{
$allTenants = Invoke-Sqlcmd -Query $SQLQuery -ServerInstance $SQLServerName -Database 'SShared'-QueryTimeout -0 #Auth -ErrorAction Stop
Write-Log -LogFileName $logfile -LogEntry ("Found {0} tenants" -f $allTenants.Count)
}
I am geeting the below error using this -
Exception Message 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)
There's a few ways that you can do this.
Easy way
dbatools
There is a PowerShell module for interacting with SQL Server created by the SQL Server community called dbatools.
In the module, there is a function called Invoke-DbaQuery which is essentially a wrapper for Invoke-Sqlcmd.
This function has a parameter, -ReadOnly, that you can use that was created exactly for this scenario.
# Changing your $auth to a PSCredential object.
$cred = [System.Management.Automation.PSCredential]::New(
$SqlUserName,
(ConvertTo-SecureString -String $SqlAdminPassword -AsPlainText -Force))
# Splatting the parameters for read-ability.
$QueryParams = #{
Query = $SQLQuery
SqlInstance = $SQLServerName
Database = 'SShared'
QueryTimeout = 0
SqlCredential = $cred
ReadOnly = $true # <-- Specifying read-only intent.
ErrorAction = 'Stop'
}
$allTenants = Invoke-DbaQuery #QueryParams
Other way
Invoke-Sqlcmd
If you can't, won't, don't want to use dbatools, you can still use Invoke-Sqlcmd. The latest release at the time of writing, has the option to specify the parameter -ConnectionString.
You can state that it's read-only there.
# Splatting again for read-ability.
$SqlcmdParams = #{
Query = $SQLQuery
QueryTimeout = 0
ConnectionString = "Data Source=$SQLServerName;Initial Catalog=SShared;User ID=$SqlUserName;Password=$SqlAdminPassword;Integrated Security=false;ApplicationIntent=ReadOnly" # <-- Specifying read-only intent.
ErrorAction = 'Stop'
}
Invoke-Sqlcmd #SqlcmdParams

Connecting to SQL Server with SQL Server account and encrypted password and executing invoke-sqlcmd

Would really appreciate some help. I have a PowerShell script which I use to update columns in a SQL Server table. When this uses a domain account it works fine.
However, I want to run during user login, and use a SQL Server account, not Windows account, but I can't figure out why it isn't working.
When the key/txt file uses the domain account, no problems. But when replace with SQL Server account details, no go.
$SQLUser = "Username"
$SQLPasswordFile = "\\pathto\UserPW.txt"
$SQLKeyFile = "\\pathto\UserPW.key"
$SQLkey = Get-Content $SQLKeyFile
$SQLMyCredential = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $SQLUser, (Get-Content $SQLPasswordFile | ConvertTo-SecureString -Key $SQLkey)
$SQLCredentials = Get-Credential -Credential $SQLMyCredential
$SQLSession = New-PSSession -ComputerName "uhpkpdb01" -Credential $SQLCredentials
Invoke-Command -Session $SQLSession -ScriptBlock {
$exist = Invoke-Sqlcmd "select count(1) from [table] where USER_NAME = '$($args[0])'" -ServerInstance "SERVERNAME"
if ($exist.column1 -eq "1") {
Invoke-Sqlcmd "UPDATE [table] SET PASSWORD = '$($args[1])' WHERE USER_NAME = '$($args[0])'"
Write-Host "Account Updated" }
else {
Write-Host "User Does Not Exists"}} -ArgumentList $env:USERNAME, "PASSWORD"
Remove-PSSession $SQLSession
I am getting
New-PSSesion : Connecting to remote server failed with : The user name or password is incorrect.
I can connect using the SQL Server account to SSMS and open and update table.
I must be passing the user name incorrectly, but can't figure out how to do it properly.
Any assistance would be greatly appreciated.
You cannot pass a PSCredential object that contains your SQL Login to Invoke-Command. The only thing that command understands is Windows Credentials.
You can pass and call the Invoke-SqlCmd command directly from your own machine if you have the module installed.
If you need to use the SQL Login on a remote session you will have to pass that credential object into the remote session so it can be utilized within your script block.

Automating Database Counts for All SQL Servers

I need database counts for every SQL server instance (PROD/Non PROD) in an environment.
If I logged into each and every SQL Server then it is very tedious task for me, so I need to automate it.
Is there any t-sql or powershell script from which I can get consolidated report for database counts for all servers at one place.
You can use Azure Functions with Timer schedule to automate what you want.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer
And you can use stored procedures with azure functions.
Take a look at the SqlServer module documentation, specifically the Get-SqlDatabase cmdlet. You can import your server names from a file or define them in an array and then iterate through them.
#get your credential
$credentials = get-credential
#read server names from a file
$servers = get-content "C:\Some\Path\servers.txt"
#use calculated properties
$servers | select-object `
#{Name='ServerName';Expression={$_}},
#{Name='DatabaseCount';Expression={
#force to array to ensure .count exists
#(Get-SqlInstance -MachineName $_ -Credential $credential | Get-SqlDatabase).Count
}}
If you are unable to install the SqlServer module you can do it with the SMO
#load the assembly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
#read server names from a file
$servers = get-content "C:\Some\Path\servers.txt"
#use calculated properties
$servers | select-object `
#{Name='ServerName';Expression={$_}},
#{Name='DatabaseCount';Expression={
(New-Object Microsoft.SqlServer.Management.SMO.Server $_).Databases.Count
}}
Output:
ServerName DatabaseCount
---------- -------------
ServerOne 12
ServerTwo 22
ServerThree 6
Note that there is no error checking and I am assuming that you are running in a context that has rights to the server and DB engine.

Powershell: Find all SQL Server instances per ser server?

Strictly speaking, the question is, I use this solution and it works, but is there a better way?
With the following caveats.
1) I don't want to do a network wide search for SQL instances, I am interrogating known SQL servers, but I want to grab the instance names on each.
2) The code assumes Microsoft will never change the display name for the SQL Server Service.
function getSQLInstance ([string]$SERVER) {
$services = Get-Service -Computer $SERVER
# Filter for SQL services
$services = $services | ? DisplayName -like "SQL Server (*)"
# Remove MSSQL$ qualifier to get instance name
try {
$instances = $services.Name | ForEach-Object {($_).Replace("MSSQL`$","")}
}catch{
# Error if none found
return -1
}
return $instances
}
getSQLInstance "YOUR_SERVER"
Rather than re-invent the wheel, take a look at how SQL Power Doc discovers instances on a server. Which, from looking at NetworkScan.psm1, appears to be very similar to your approach:
$ManagedComputer.Services | ForEach-Object {
if (($_.Name).IndexOf('$') -gt 0) {
$InstanceName = ($_.Name).Substring(($_.Name).IndexOf('$') + 1)
$IsNamedInstance = $true
$ManagedComputerServerInstanceName = $InstanceName
} else {
$InstanceName = $null
$IsNamedInstance = $false
$ManagedComputerServerInstanceName = $_.Name
}
Or, just use SQL Power Doc and point it at specific server names to collect this and more data about the instances.

Not able to connect to a remote SQL Server instance

I am trying to find a solution to my problem online but no luck yet. Hence posting the question:
I am running a powershell script which will fetch backup details from all SQL Servers mentioned in a notepad. The script is working fine for SQL Servers till 2008R2. But I am getting error while connecting to SQL Server 2012/2014. The script is running on Windows Server 2008 having SQL Server 2008R2 installed on it. So I will request you to help me to troubleshoot it.
Input File:E:\Sachin\SQL_Servers2.txt
SERVERNAME,SERVERNAME,1433
$servers = Get-Content 'E:\Sachin\SQL_Servers2.txt'
#Create a new Excel object using COM
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()
$Sheet = $Excel.Worksheets.Item(1)
#Counter variable for rows
$global:intRow = 1
foreach ($sv in $servers) {
# Separate the server and instance names
$srvr = $sv.Split(",")
$server = $srvr[0]
$instance = $srvr[1]
$port = $srvr[2]
getsqlinfo $server $instance $port
function getsqlinfo {
param (
[string]$svr,
[string]$inst,
[string]$port
)
foreach ($instancename in $inst)
{
#Create column headers
$Sheet.Cells.Item($intRow,1) = "INSTANCE NAME:"
$Sheet.Cells.Item($intRow,2) = $instancename
$Sheet.Cells.Item($intRow,1).Font.Bold = $True
$Sheet.Cells.Item($intRow,2).Font.Bold = $True
$global:intRow++
$Sheet.Cells.Item($intRow,1) = "DATABASE NAME"
$Sheet.Cells.Item($intRow,2) = "LAST FULL BACKUP"
$Sheet.Cells.Item($intRow,3) = "LAST DIFFERENTIAL BACKUP"
$Sheet.Cells.Item($intRow,4) = "FULL BACKUP AGE(DAYS)"
#Format the column headers
for ($col = 1; $col -le 4; $col++)
{
$Sheet.Cells.Item($intRow,$col).Font.Bold = $True
$Sheet.Cells.Item($intRow,$col).Interior.ColorIndex = 48
$Sheet.Cells.Item($intRow,$col).Font.ColorIndex = 34
}
$global:intRow++
#######################################################
#This script gets SQL Server database information using PowerShell
$ConnectionString = "data source = $inst,$port; initial catalog = master; trusted_connection = true;"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
# Create an SMO connection to the instance
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server')
$s.ConnectionContext.ConnectionString = $ConnectionString
$dbs = $s.Databases
#Formatting using Excel
ForEach ($db in $dbs)
Error Msg:
The following exception was thrown when trying to enumerate the collection: "Failed to connect to server .".
At E:\sachin\BackupDetailsVersion7.ps1:51 char:8
+ ForEach <<<< ($db in $dbs)
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : ExceptionInGetEnumerator
Pre-Checks Done:
I am able to telnet the target SQL Server from the Server where I am running the script.
I am having access to the target SQL Server as well.
Microsoft® Windows PowerShell Extensions for Microsoft® SQL Server® 2012 SP2,Microsoft® SQL Server® 2012 SP2 Shared Management Objects and Microsoft® System CLR Types for Microsoft® SQL Server® 2012 SP2 are already installed on the target Server.
Execution policy is set to unrestricted on the target Server.
I am able to get the SQL Server details on the target machine when checking locally, but not able to get details from other machine.
I am suspecting whether is there any restriction/limitation to connect between different SQL Server versions through powershell (any kind of compatibility issue).
Any help/suggestions will be highly appreciated. Thanks in advance. :)

Resources