How to get SQL Server Management Studio tab messages in PowerShell? - sql-server

With Powershell, I execute a SQL script which returns a generated script in the tab "Messages" of SQL Server Management Studio. But I can't get it in PowerShell.
When I do this :
$ps = [PowerShell]::Create()
[ref]$e = New-Object System.Management.Automation.Runspaces.PSSnapInException
$ps.Runspace.RunspaceConfiguration.AddPSSnapIn( "SqlServerCmdletSnapin100", $e ) | Out-Null
$ps.AddCommand( "Invoke-Sqlcmd" ).AddParameter( "ServerInstance", "localhost").AddParameter( "Database", "MyDatabase").AddParameter("InputFile", "D:\MyScript.sql").AddParameter("Verbose")
$ps.Invoke()
$ps.Streams
$ps.Streams.Verbose | % { $_.Message | Out-File -Append D:\SqlLog.txt }
I get this error :
PS D:\NEMO\Scripts\Database> $ps.Invoke()
Exception calling "Invoke" with "0" argument(s): "Object reference not set to an instance of an object."
At line:1 char:11
+ $ps.Invoke <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : DotNetMethodException
Thank you for your help.

So make Powershell to output messages is not that simple and it works only in command-line i think. Try this
write-host $line
Start-Transcript $outputfilepath
$ScriptParams = "DatabaseName=$line" "
Invoke-Sqlcmd -ServerInstance $SQLInstance -Username $SQLAdminUser -Password $SQLAdminPwd -InputFile "D:\File.sql" -verbose -Variable $ScriptParams
Stop-Transcript

Related

Invoke-Sqlcmd error in Loop, No error once?

If I run this .ps1 script-
$secID = Invoke-Sqlcmd -ServerInstance "MyDBServer" -Database "MyDataBase"-Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';"
Write-Host "MyDataBase"
Write-Host $secID.SysID
I get the following on the console with no error -
MyDataBase
18
However if I try this same query in a for loop in a larger script -
$dbservers = #('DataBaseServer1', 'DataBaseServer2')
foreach ($dbserver in $dbservers)
{
$databases = Get-SqlDatabase -ServerInstance $dbserver | Where-Object { $_.Name -Match '\d{3,4}' -and $_.Name -notlike '*test*'}
foreach ($database in $databases)
{
$secID = Invoke-Sqlcmd -ServerInstance $dbserver.Name -Database $database.Name -Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';"
Write-Host $database.Name
Write-Host $secID.SysID
}
}
I get the correct query result but errors preceding it on the console -
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 \SQL.ps1:28 char:13
+ ... $secID = Invoke-Sqlcmd -ConnectionString $ConnectionString -Query ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlException
+ FullyQualifiedErrorId : SqlExceptionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Invoke-Sqlcmd :
At \SQL.ps1:28 char:13
+ ... $secID = Invoke-Sqlcmd -ConnectionString $ConnectionString -Query ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Invoke-Sqlcmd], ParserException
+ FullyQualifiedErrorId : ExecutionFailureException,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand*
MyDataBase
18
Why do I get errors when running it in the loop versus running it one time? Also why does the query work even though I get an error? I think I am missing something any help would be greatly appreciated!
I think its because you are calling property Name on a String, effectively returning nothing. try this (I just deleted the calling of the property $dbserver.Nameto $dbserver):
$dbservers = #('DataBaseServer1', 'DataBaseServer2')
foreach ($dbserver in $dbservers)
{
$databases = Get-SqlDatabase -ServerInstance $dbserver | Where-Object { $_.Name -Match '\d{3,4}' -and $_.Name -notlike '*test*'}
foreach ($database in $databases)
{
$secID = Invoke-Sqlcmd -ServerInstance $dbserver -Database $database.Name -Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';"
Write-Host $database.Name
Write-Host $secID.SysID
}
}
The error must be because its looking for a DB instance "" and it doesn't find it, and the query might still go though because the the first server might not have an instance, or because those values were already loaded into the properties from before. But I'm just speculating, haven't really used this cmdlets.
PS: if you want to avoid calling empty properties add Set-StrictMode -Version 2 to your script, example:
PS > $text = "This is just a string"
PS > $text.AnyProperty
PS > Set-StrictMode -Version 2
PS > $text.AnyProperty
The property 'AnyProperty' cannot be found on this object. Verify that the property exists.
At line:1 char:1
+ $text.AnyProperty
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict
Hope it helps.

Database Back Up using Powershell

I am trtying to take back up using poweshell
Below is the command which we are trying to execute,
Backup-SqlDatabase -ServerInstance "SERVER\DEFAULT" -Database "AFC" -BackupFile "\\REMOTESERVER\temp123\$dbName.bak"
However when we are trying to execute the same we are getting below error
Backup-SqlDatabase : Failed to connect to server 10.254.5.37\DEFAULT.
At line:1 char:1
+ Backup-SqlDatabase -ServerInstance "10.254.5.37\DEFAULT" -Database "A ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Backup-SqlDatabase], ConnectionFailureException
+ FullyQualifiedErrorId : Microsoft.SqlServer.Management.Common.ConnectionFailureException,Microsoft.SqlServer.Man
agement.PowerShell.BackupSqlDatabaseCommand
However when we are trying to execute Get-ChildItem command we are gettting names of all databases.
Please help us.
Regards,
Pradeep

Exception calling ".ctor" with "2" argument(s): "SetParent failed for Database 'XXX' ."

I have a problem with running SQLPS commands to create a DB on Windows Server 2012R2 and Powershell v4
#Import SQL Server Module called SQLPS
Import-Module SQLPS -DisableNameChecking
#Your SQL Server Instance Name
$Inst = "sql03"
$Srvr = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $Inst
#database PSDB with default settings
#by assuming that this database does not yet exist in current instance
$DBName = "PSDB"
$db = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database($Srvr, $DBName)
$db.Create()
#Confirm, list databases in your current instance
$Srvr.Databases |
Select Name, Status, Owner, CreateDate
I receive the below error:
New-Object : Exception calling ".ctor" with "2" argument(s): "SetParent failed for Database 'PSDB'. "
At C:\test.ps1:11 char:7
+ $db = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database($Srvr, $D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
You cannot call a method on a null-valued expression.
At C:\test.ps1:12 char:1
+ $db.Create()
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
The following exception occurred while trying to enumerate the collection: "Failed to connect to server sql03.".
At C:\test.ps1:15 char:1
+ $Srvr.Databases |
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : ExceptionInGetEnumerator
Any suggestions how to fix this?
If you are working locally try replacing:
$Srvr = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $Inst
With:
$Srvr = new-object ('Microsoft.SqlServer.Management.Smo.Server') localhost

Error thrown while taking backup of SQL Server content database using PowerShell

I am trying to take a backup of SQL Server content database using PowerShell.
Here is my code:
$dt = Get-Date -Format yyyyMMddHHmmss
$null =
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo");
$srvrvinstancename= "srvr-04\mssqlserver1"
$svr = New-Object
Microsoft.SqlServer.Management.Smo.Server($srvrvinstancename);
#Write-Output $svr WSS_Content_2d426b353ded49aa8ace920d4178c298
$bdir = "C:"
$svnm = $svr.Name
$db =
$svr.Databases['WSS_Content_2d426b353ded49aa8ace920d4178c298']
$dbname = $db.Name
$dt = get-date -format yyyyMMddHHmmss
$bfil = "$bdir\$($dbname)_db_$($dt).bak"
Backup-SqlDatabase -ServerInstance $svnm -Database $dbname -
BackupFile $bfil
but when I run the code I get the error:
Backup-SqlDatabase : The 'Backup-SqlDatabase' command was found in the module 'SQLPS', but the module could not be loaded. For more information, run 'Import-Module SQLPS'.
At line:19 char:1
+ Backup-SqlDatabase -ServerInstance $svnm -Database $dbname -BackupFile $bfil
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Backup-SqlDatabase:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CouldNotAutoloadMatchingModule
After that, I ran
import-module sqlps
But this also ran into error state:
Import-Module : File C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS\Sqlps.ps1 cannot be loaded because running scripts is disabled on this system.
For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ Import-Module SQLPS
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [Import-Module], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess,Microsoft.PowerShell.Commands.ImportModuleCommand
What am I doing wrong?
I think you need to load a couple off Assembly:
# Load SQL server assemblies
#
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
# SmoExtended
#
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
UPDATE.
For scripts which can't be executed you need to do (as administrator in Powershell)
Set-ExecutionPolicy remotesigned

Error "You cannot call a method on a null-valued expression." while taking backup of SQL Files

I want to take backup of a few user databases on SQL Server 2008 R2.
I am running the following script on Powershell v2.0.
#load SQL snap-in
Add-pssnapin SqlServerCmdletSnapin100
Add-pssnapin SqlServerProviderSnapin100
#pull the current date
$date = Get-Date -Format yyyyddMM
#set location of backup files
$directory = "F:\sql\backup"
#Grab the database names
$dbname = dir 'SQLSERVER:\SQL\MyServer\DEFAULT\Databases\MyDataBase' | Select Name
#Backup each user database found.
$dbname | foreach { $_.Name.ToString() } | foreach {$bakfile = "$directory" + $_ + "_" + $date + ".bak";
"Backing up Database: $_"; Invoke-Sqlcmd -SuppressProviderContextWarning -Query
"BACKUP DATABASE $_ TO DISK=N'$bakfile' WITH INIT";
}
But this script shows me the following error in succession:
You cannot call a method on a null-valued expression.
At F:\sql\backup.ps1:40 char:21
+ $dbname | foreach { $_.Name.ToString() } | foreach {$bakfile = "$directory" + $_ ...
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
What exactly is this error?
Where is it occurring?
How to correct this?
what changes should I make if I want to save the backup
file in '.sql' form?
Is there any other simpler way?

Resources