I'm trying to set a database name in powershell using Microsoft.SqlServer.SMO. When I execute my script it runs in error with the following error text:
format-default : Index was outside the bounds of the array.
+ CategoryInfo : NotSpecified: (:) [format-default], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException,Microsoft.PowerShell.Commands.FormatDefaultCommand
The server is set as follows
$srv = New-Object "Microsoft.SqlServer.Management.SMO.Server" $server
$srv.ConnectionContext.LoginSecure=$false;
$srv.ConnectionContext.set_Login("login");
$srv.ConnectionContext.set_Password("password")
$srv.Databases | Select name,
shows me the proper databases, but when setting the database,
$db = $srv.Databases[$database]
the error is thrown.
This scrip does work in other sqlservers.
Any solutions for this issue?
It looks like the database "CRD_DEV" does not exist on the server where the script throws the error.
That or the user does not have access to that database.
The IndexOutOfRangeException is thrown because there is no item in $srv.Databases that matches "CRD_DEV"
Related
I'm having an odd issue using the System.Data.SqlClient in PowerShell. The following works, using MSSMS:
INSERT INTO [dbo].[secDb_AADDevices]
([objectGuid]
,[displayName]
,[deviceGuid])
VALUES
('test','here','now')
But when doing this in PowerShell:
$sqlQuery = "INSERT INTO secDb_AADDevices ('objectGuid','displayName','deviceGuid') VALUES('test','here','now')"
$sqlCmd=new-object system.Data.SqlClient.SqlCommand($sqlQuery, $sqlConn)
$sqlCmd.ExecuteNonQuery()
It fails;
Exception calling "ExecuteNonQuery" with "0" argument(s): "Invalid column name 'objectGuid'.
Invalid column name 'displayName'.
Invalid column name 'deviceGuid'."
At line:4 char:1
+ $sqlCmd.ExecuteNonQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
The column types in MSSQL are nvarchar(50) not null.
I've simplified it as much as possible to reduce complexity while debugging, will parameterize when this part works.
I've triple-verified that MSSQL and PowerShell ($sqlConn object) are connected to the same server and database instance, using the exact same user.
I'm trying to change the "schemas owned by this user" on a database using the following powershell script:
$dbname = "mydb"
$sql_server = "mysqlserver"
$username = "myuser"
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server")($sql_server)
$db = $server.Databases["$dbname"]
$login = $server.Logins[$username]
$roleName = "db_owner"
if(-not $db.Users.Contains($login.Name)){
$user = New-Object('Microsoft.SqlServer.Management.Smo.User') $db, $login.Name
$user.Login = $login.Name
$user.create();
}
$user = $db.Users[$login.Name]
$role = $db.Roles[$roleName]
$role.AddMember($user.Name);
$schema = $db.Schemas["dbo"]
$schema.Owner = "myuser"
$schema.Alter()
When I get to the step $schema.Alter() I get the following error:
Exception calling "Alter" with "0" argument(s): "Alter failed for Schema 'dbo'. "
At line:1 char:1
+ $schema.Alter()
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FailedOperationException
I get the impression the Alter Method is looking for more parameters but I'm not sure what parameters it wants. Anyone have any suggestions what I'm doing wrong?
Thanks
Brad
In my experience, the top level exception is not helpful. My typical method for dealing with this is something like $e = $error[0]; and then calling $e.Exception, $e.Exception.InnerException, $e.Exception.InnerException.InnerException, … until I get to the actual error. This doesn't solve your problem, but at least can give you a better idea of what the problem is.
I use a T-SQL command which I found here to get the fragmentation of my database tables. When I execute the T-SQL in the Management Studio, everything works. If I use it inside PowerShell, I get the following error (translated from German):
Exception when calling "ExecuteReader" with 0 Argument(s):
"Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'."
In Zeile:17 Zeichen:6
+ $Result = $cmd.ExecuteReader()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
This is the part of my script which throws the error
foreach ($table in $tables)
{
$Data = New-Object System.Data.DataTable
$cmd = New-Object System.Data.SqlClient.SqlCommand
$getFragRate = "
-- SQL Command von Microsoft um die Index Fragmentation zu überprüfen
USE Logik;
GO
SELECT a.index_id, name, avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats (DB_ID(N'Logik'), OBJECT_ID(N'$($table)'), NULL, NULL, NULL) AS a
JOIN sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id;
GO
"
$cmd.CommandText = $getFragRate
$cmd.Connection = $con
$Result = $cmd.ExecuteReader()
$Data.Load($Result)
$Data
}
Why does this error occur?
The User I use to do this has sysadmin, db_ddladmin and db_owner permission.
Edit: Another T-SQL Command to get all tables of my database worked without a problem from PowerShell.
GO is NOT a T-SQL command - therefore you cannot have it in T-SQL statements being executed from PowerShell.
GO is a batch separator used by SQL Server Management Studio.
You need to break up that statement into several individual statements yourself and execute them one by one.
I am trying to test the following script in powershell which gets the status of the mirrored databases.
#SQL Variables
$sqlservers = "APNSQL01"
#SQL database mirroring status
$body +=echo "------------Originating Server-----------"`r`n""`r`n""
Import-Module "sqlps" -DisableNameChecking
$body +=echo "--------Status of mirrored databases---------"`r`n""`r`n""
foreach ($server in $sqlservers){
$body +=echo "Database mirroring state on $server
"
$body += Invoke-Sqlcmd -Query "USE master
SELECT sys.database_mirroring.mirroring_state_desc
,sys.databases.name
FROM sys.database_mirroring INNER JOIN sys.databases ON sys.database_mirroring.database_id=sys.databases.database_id
WHERE mirroring_state_desc IS NOT NULL" -ServerInstance "$server" | out-string
}
When I run this code, I get the following error :
Invoke-Sqlcmd : 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:\Users\ctxadmin\Desktop\SQL.ps1:20 char:11
+ $body += Invoke-Sqlcmd -Query "USE master
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlException
+ FullyQualifiedErrorId : SqlExectionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Invoke-Sqlcmd :
At C:\Users\ctxadmin\Desktop\SQL.ps1:20 char:11
+ $body += Invoke-Sqlcmd -Query "USE master
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Invoke-Sqlcmd], ParserException
+ FullyQualifiedErrorId : ExecutionFailureException,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
My SQL server is a STANDARD database. It has no mirror. Is that the issue?
What might the error be?
I’m trying to take back-up of a large database using “Backup-SQLDatabase” cmdlet using following statement, but I’m getting time-out error after 10 minutes.
{Backup-SqlDatabase -ServerInstance $Server -Database $DatabaseName -BackupFile $BackUpFile -CompressionOption On -ConnectionTimeout 0 -Initialize -Verbose -ea Stop}
Here’s the error exactly after 600 seconds of execution :
VERBOSE: 60 percent processed.
VERBOSE: The backup or restore was aborted.
The wait operation timed out
+ CategoryInfo : InvalidOperation: (:) [Backup-SqlDatabase], Win3
2Exception
+ FullyQualifiedErrorId : ExecutionFailed,Microsoft.SqlServer.Management.P
owerShell.BackupSqlDatabaseCommand
+ PSComputerName : localhost
I looked up at internet and found a bug filled here.
However, the issue still exists in SQL Server 2012 (11.0.339).
I’ve also tried reconfiguring “remote query timeout” to 0 as given here, but the issue persists.
This is actually very weird issue. PowerShell is for automation and scripts do take more than 10 minutes to run. “Backup-SQLDatabase” should have considered this.
Please suggest a workaround by which I can fix this while using this cmdlet.
Else , I’ve to re-write the code using SMO classes or basic T-SQL.
I did some research on this and came around the following workaround :
$serverConn = new-object ("Microsoft.SqlServer.Management.Smo.Server") $server
$serverConn.ConnectionContext.StatementTimeout = 0
Backup-SqlDatabase -InputObject $serverConn -Database abc -BackupFile "L:\123\abc.bak"
When we pass Server name as a string, it tries to create it's own connection and we don't have the option to change QueryTimeout from 600 to 0.
However, we can create a SMO.Server object and use it after setting desired properties.
Hope it helps!