Unable to connect to SQL server via PowerShell using secure password - sql

I'm trying to connect to SQL server via PowerShell using the below (I'm new to this). I always get the error "login failed" when I use secure password (from Get-Credential or password stored in file). But if I pass the password as plaintext instead of secure string, it connects successfully. Could any one please suggest a method to pass secure password, ideally stored in an external file.
The code I ran and the error is below:
$cred = Get-Credential
$pwd = $cred.Password
$uid = $cred.UserName
$SQLServer = "."
$SQLDBName = "TestDB"
#Initialize connection string
$connString = "Data Source=$SQLServer;Database=$SQLDBName;User ID=$uid;Password=$pwd"
#Create a SQL connection object
$conn = New-Object System.Data.SqlClient.SqlConnection $connString
#Attempt to open the connection
$conn.Open()
if($conn.State -eq "Open")
{
# We have a successful connection here
# Notify of successful connection
Write-Host "Test connection successful"
$conn.Close()
}
Exception calling "Open" with "0" argument(s): "Login failed for user 'TestUser'."
At line:18 char:1
+ $conn.Open()
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
Further details of error from SQL server:
Login failed for user 'TestUser'. Reason: Password did not match that for the login provided. [CLIENT: <local machine>]

Change this
$pwd = $cred.Password
to this
$pwd = $cred.GetNetworkCredential().Password
However, I would advise against storing a plain text password in memory like this. Your method requires it to--at best--be passed as a parameter in plain text, so you need a better method.
Try using this sqlserver module which supports the -Credential parameter in the Invoke-Sqlcmd function.

I was able to pass secure string as password by adding Integrated Security = True; parameter in connection string.
Thank you.

Related

Azure automation - credentials delivered by Get-PSAutomationCredential don't work with Add-AzureAccount?

I'm modifying a gallery runbook that copies a live database to a test database on a schedule. It's failing at the first hurdle; authenticating and selecting the relevatn azure subscription
The runbook looks like this:
$Cred = Get-AutomationPSCredential -Name 'automationCredential'
Write-Output "UN: $($Cred.Username)"
Add-AzureAccount -Credential $Cred
I've used the portal credentials blade to create a credential named "automationCredential". For the username and password I supplied the username/pw that I log into the azure portal with. Note: this is NOT a school/work microsoft account, but a personal one
I can tell the call to Get-PSAutomationCredential is working out, because the Write-Ouput call shows the correct value
Add-AzureAccount however, delivers the following error:
Add-AzureAccount : unknown_user_type: Unknown User Type At
Set-DailyDatabaseRestore:22 char:22 CategoryInfo :
CloseError: (:) [Add-AzureAccount], AadAuthenticationFailedException
FullyQualifiedErrorId :
Microsoft.WindowsAzure.Commands.Profile.AddAzureAccount
Any pointers how to get a working credential?
According to your description, it seems that your account is a Microsoft account(such as *#outlook.com, *#hotmail.com). Microsoft does not support non-interactive login. It is also unsafe for you to use your account to login your subscription directly. For a runbook, you could use the following codes to logon.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
In above code, you need use connection AzureRunAsConnection, it is created by Azure default, you could use it directly, you could check this connection, it includes your subscription information.
Also, you could create a new connection, please refer to this link.
Have you tried using the resource manager version off the login cmdlet (Add-AzureRmAccount)?

powershell unable to recognize parameter

I am working on powershell script for connecting to server. If I am passing server name inside script without param it's working, but if I am using input as server name it is saying "server not found". See script below:
clear
#param([string]$servername)
$filePath = "c:\temp\result.txt"
$Servername= "cx-siscsqltest\sqlinst"
#$SqlQuery = "select SUBSTRING(CONVERT(sysname, SERVERPROPERTY('ProductVersion')),0,CHARINDEX('.',convert(sysname,SERVERPROPERTY('ProductVersion')),0)) as
#'ProductVer';"
$SqlQuery="select * from sys.sysaltfiles"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = '$Servername'; Database = master; Integrated Security = SSPI;"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$DataSet.Tables[0] | out-file "C:\temp\version.csv"
#$version=System.Data.DataSet.Tables[0].Rows[0][0]
write-host $version
Above code works well without parameters, if I take servername as parameter i get the following errors:
The term 'param' is not recognized as the name of a cmdlet, function, script fi
le, or operable program. Check the spelling of the name, or if a path was inclu
ded, verify that the path is correct and try again.
At D:\sysdba\install_sp.ps1:4 char:6
+ param <<<< ([string]$servername)
+ CategoryInfo : ObjectNotFound: (param:String) [], CommandNotFou
ndException
+ FullyQualifiedErrorId : CommandNotFoundException
Exception calling "Fill" with "1" argument(s): "A network-related or instance-s
pecific error occurred while establishing a connection to SQL Server. The serve
r 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: Name
d Pipes Provider, error: 40 - Could not open a connection to SQL Server)"
At D:\sysdba\install_sp.ps1:25 char:17
+ $SqlAdapter.Fill <<<< ($DataSet)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Can you please help me out?
Param() must be the first line in your script. Remove the clear and you will see in your ISE that the colour of param() will change

Authentication error with webclient in powershell

I'm relatively new to Powershell so really not sure where to go with this issue now. I am trying to download a file from a subversion repository and am getting the (401) Unauthorized" error. I am able to log into the site and download the file using IE using the exact Same credentials on the same machine.
$source = "http://repository/folder/File.exe"
$destination = "E:\Temp\File.exe"
$wc = New-Object System.Net.WebClient
$user="user"
$pwd=convertto-securestring -string "password" -AsPlainText -force
$creds=New-Object System.Management.Automation.PSCredential -ArgumentList $user, $pwd
$wc.Credentials = New-Object System.Net.NetworkCredential ($user, $Creds.GetNetworkCredential().Password,"DOMAIN")
$download=$wc.DownloadFile($source, "$destination")
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (401) Unauthorized."
Any ideas if this is cross platform issue? And how to get around this?
Thanks
Are you using basic auth on your iis/apache? If so try this:
$source = "http://repository/folder/File.exe"
$destination = "E:\Temp\File.exe"
$wc = new-object System.Net.WebClient
$credCache = new-object System.Net.CredentialCache
$creds = new-object System.Net.NetworkCredential($user,$pwd)
$credCache.Add($source, "Basic", $creds)
$wc.Credentials = $credCache
$wc.DownloadFile($source, $destination)

getting login to SQL Server 2005 with invalid credentials

The purpose of script is to log into a remote SQLSERVER and execute a query.
I used the below code to to ask for credentials and when the connection is open i will check using $conn.state , when its open i have to execute queries.
Even when i give invalid credentials, the control is going into Switch --> Open block and getting the statement out Logged in.The connection is Open.
clear
$servername = "Someserver";$databasename = "someDB";$c = Get-Credential
$connectionString = [string]::Format( "server={0};database={1};uid={2};pwd= {3};Integrated Security=True;", "$servername", "$databasename",$c.username,$c.GetNetworkCredential().password)
$conn = New-Object system.Data.SqlClient.SqlConnection
$conn.connectionstring = $connectionString
$conn.open()
switch ($conn.State)
{
"Open"{ write-host "Logged in.The connection is $($conn.State)"}
Default{ Write-Host "The connection is $($conn.State).Error connecting db."; }
}
$conn.close()

How do you pass a SecureString from a PSCredential to a NetworkCredential?

NOTE: I cannot use PowerShell V3.0 here otherwise I'd be using Invoke-WebRequest and living a happy life.
I have a PowerShell V2.0 script that needs to POST data to a HTTP-Basic authenticated resource. For the purposes of the script I don't want or need to know the user's password, I just want to convert from a PSCredentials object (as returned from PromptForCredential) to a NetworkCredential for use with HttpWebRequest.
$uri = "https://example.com/some/resource/"
# Get our user's credentials...
$defaultUsername = "Some Username"
$caption = "Authentication required"
$message = "A username and password is required for ${uri}"
#$target = $uri #<<--NOTE: This prepends $uri+"\" to the username.
#$target = "" #<<--NOTE: This prepends "\" to the username.
$target = $null #<<--NOTE: This still prepends "\" to the username.
$psCredential = $Host.UI.PromptForCredential($caption, $message, $defaultUsername, $target)
# Construct a CredentialCache for HttpWebRequest...
# NOTE: We need to delete the "domain part" of the username from the PSCrential.Username, otherwise we get "Something\Username"
$username = ($psCredential.Username).Split('\')[1]
$networkCredential = New-Object System.Net.NetworkCredential($username, [System.Security.SecureString]$psCredential.Password)
$credentialCache = New-Object System.Net.CredentialCache
$credentialCache.Add( (New-Object Uri($uri)), "Basic", $networkCredential)
#...
$request = New-Object System.Net.HttpWebRequest($uri)
$request.Credentials = $credentialCache
#...
[System.Net.HttpWebResponse]$response = [System.Net.HttpWebResponse]$request.GetResponse()
This of course fails with the exception:
Exception calling "GetResponse" with "0" argument(s):
"The remote server returned an error: (401) Unauthorized."
Allegedly we have a NetworkCredential(String userName, SecureString password) constructor, but the user's credentials arrive the server as username:System.Security.SecureString.
Is there some little detail I'm missing? Do I need to decrypt the SecureString and pass that to the NetworkCredential(String userName, String password) constructor instead?
I've found the problem... the NetworkCredential(String userName, SecureString password) constructor is only available starting from .NET Framework 4.0. Of course PowerShell 2.0 is running in .NET 2.0.
While there are ways and means of making PowerShell 2.0 run inside .NET 4.0 I'm not a liberty to alter the runtime environment's configuration.
Instead I've gone down the "Unsecure String" path. Based on the article "How to properly convert SecureString to String" I've created this PowerShell function:
function Convert-To-Unsecure-String {
Param(
[Parameter(HelpMessage="The SecureString object to make a very unsecure String")]
[ValidateNotNull()]
[System.Security.SecureString]
$securePassword
)
$unmanagedString = [System.IntPtr]::Zero
try {
$unmanagedString = [Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($securePassword);
return [Runtime.InteropServices.Marshal]::PtrToStringUni($unmanagedString);
}
finally {
[Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($unmanagedString);
}
}
And replace the original example's NetworkCredential constructor with:
$networkCredential = New-Object System.Net.NetworkCredential($username, (Convert-To-Unsecure-String($psCredential.Password)) )
Now I'm getting the correct base64 encoded "username:password" string at the server.
I ran into the same issue. The fix for mine was very simple. Do not include the Domain name in the user name. I was trying to connect to JIRA to run a JQL.
Don't do this
$userName = Me#Mydomain; Or $userName=MyDomain/Me
But do that
$userName = Me