http://www.mssqltips.com/category.asp?catid=81
|
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/category.asp?catid=81
|
Yazı kategorisi: PowerShell, Sql Server | » yorum bırak;
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/tip.asp?tip=1849
Problem
In my last set of tips, I discussed SMO at a basic level. In this tip I am going to provide examples to SQL Server Database Administrators on how to backup and restore SQL Server databases with SMO. I will start with how you can issue different types (Full, Differential and Log) of backups with SMO and how to restore them when required programmatically using SMO.
Solution
As I discussed in my last tip, SMO provides utility classes for specific tasks. For backup and restore, it provides two main utility classes (Backup and Restore) which are available in Microsoft.SqlServer.Management.Smo namespace.
Before you start writing SMO code, you need to reference several assemblies which contain the SMO namespaces. For more details on these assemblies and how properly to reference them in your code, refer to my tip Getting started with SQL Server Management Objects (SMO).
Examples
C# Code Block 1 – Full Backups – This example shows how to issue full database backups with SMO. First, create an instance of the Backup class and set the associated properties. With the Action property you can specify the type of backup such as full, files or log backup. With the Database property specify the name of the database being backed up. The device is the backup media type such as disk or tape, so you need to add a device (one or more) to the Devices collection of backup instance. With the BackupSetName and BackupSetDescription properties you can specify the name and description for the backup set. The Backup class also has a property called ExpirationDate which indicates how long backup data is considered valid and to expire the backup after that date. The backup object instance generates several events during the backup operation, we can write event-handlers for these events and wire them up with events. This is what I am doing for progress monitoring. I am wiring up CompletionStatusInPercent and Backup_Completed methods (event-handlers) with PercentComplete and Complete events of backup object instance. Finally, I am calling the SqlBackup method for starting up the backup operation, SMO provides a variant of this method called SqlBackupAsync if you want to start the backup operation asynchronously.
| C# Code Block 1 – Full Database Backup |
| Backup bkpDBFull = new Backup(); /* Specify whether you want to back up database or files or log */ bkpDBFull.Action = BackupActionType.Database; /* Specify the name of the database to back up */ bkpDBFull.Database = myDatabase.Name; /* You can take backup on several media type (disk or tape), here I am * using File type and storing backup on the file system */ bkpDBFull.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File); bkpDBFull.BackupSetName = “Adventureworks database Backup”; bkpDBFull.BackupSetDescription = “Adventureworks database – Full Backup”; /* You can specify the expiration date for your backup data * after that date backup data would not be relevant */ bkpDBFull.ExpirationDate = DateTime.Today.AddDays(10); /* You can specify Initialize = false (default) to create a new * backup set which will be appended as last backup set on the media. You * can specify Initialize = true to make the backup as first set on the * medium and to overwrite any other existing backup sets if the all the * backup sets have expired and specified backup set name matches with * the name on the medium */ bkpDBFull.Initialize = false; /* Wiring up events for progress monitoring */ bkpDBFull.PercentComplete += CompletionStatusInPercent; bkpDBFull.Complete += Backup_Completed; /* SqlBackup method starts to take back up * You can also use SqlBackupAsync method to perform the backup * operation asynchronously */ bkpDBFull.SqlBackup(myServer); |
| private static void CompletionStatusInPercent(object sender, PercentCompleteEventArgs args) { Console.Clear(); Console.WriteLine(“Percent completed: {0}%.”, args.Percent); } private static void Backup_Completed(object sender, ServerMessageEventArgs args) { Console.WriteLine(“Hurray…Backup completed.” ); Console.WriteLine(args.Error.Message); } private static void Restore_Completed(object sender, ServerMessageEventArgs args) { Console.WriteLine(“Hurray…Restore completed.”); Console.WriteLine(args.Error.Message); } |
| Result: |
C# Code Block 2 Differential Backups - The process of issuing differential backups is not much different from issuing full backups. To issue a differential backup, set the property Incremental = true. If you set this property the incremental/differential backup will be taken since last full backup.
| C# Code Block 2 – Differential Database Backup |
| Backup bkpDBDifferential = new Backup(); /* Specify whether you want to backup database, files or log */ bkpDBDifferential.Action = BackupActionType.Database; /* Specify the name of the database to backup */ bkpDBDifferential.Database = myDatabase.Name; /* You can issue backups on several media types (disk or tape), here I am * using the File type and storing the backup on the file system */ bkpDBDifferential.Devices.AddDevice(@”D:\AdventureWorksDifferential.bak”, DeviceType.File); bkpDBDifferential.BackupSetName = “Adventureworks database Backup”; bkpDBDifferential.BackupSetDescription = “Adventureworks database – Differential Backup”; /* You can specify the expiration date for your backup data * after that date backup data would not be relevant */ bkpDBDifferential.ExpirationDate = DateTime.Today.AddDays(10); /* You can specify Initialize = false (default) to create a new * backup set which will be appended as last backup set on the media. * You can specify Initialize = true to make the backup as the first set * on the medium and to overwrite any other existing backup sets if the * backup sets have expired and specified backup set name matches * with the name on the medium */ bkpDBDifferential.Initialize = false; /* You can specify Incremental = false (default) to perform full backup * or Incremental = true to perform differential backup since most recent * full backup */ bkpDBDifferential.Incremental = true; /* Wiring up events for progress monitoring */ bkpDBDifferential.PercentComplete += CompletionStatusInPercent; bkpDBDifferential.Complete += Backup_Completed; /* SqlBackup method starts to take back up * You cab also use SqlBackupAsync method to perform backup * operation asynchronously */ bkpDBDifferential.SqlBackup(myServer); |
| Result: |
C# Code Block 3 Transaction Log Backups - Again the process of issuing transactional log backup is not much different from issuing full backups. To issue transactional log backups, set the property Action = BackupActionType.Log instead of BackupActionType.Database as in the case of a full backup.
| C# Code Block 3 – Transaction Log Backup |
| Backup bkpDBLog = new Backup(); /* Specify whether you want to back up database or files or log */ bkpDBLog.Action = BackupActionType.Log; /* Specify the name of the database to back up */ bkpDBLog.Database = myDatabase.Name; /* You can take backup on several media type (disk or tape), here I am * using File type and storing backup on the file system */ bkpDBLog.Devices.AddDevice(@”D:\AdventureWorksLog.bak”, DeviceType.File); bkpDBLog.BackupSetName = “Adventureworks database Backup”; bkpDBLog.BackupSetDescription = “Adventureworks database – Log Backup”; /* You can specify the expiration date for your backup data * after that date backup data would not be relevant */ bkpDBLog.ExpirationDate = DateTime.Today.AddDays(10); /* You can specify Initialize = false (default) to create a new * backup set which will be appended as last backup set on the media. You * can specify Initialize = true to make the backup as first set on the * medium and to overwrite any other existing backup sets if the all the * backup sets have expired and specified backup set name matches with * the name on the medium */ bkpDBLog.Initialize = false; /* Wiring up events for progress monitoring */ bkpDBLog.PercentComplete += CompletionStatusInPercent; bkpDBLog.Complete += Backup_Completed; /* SqlBackup method starts to take back up * You cab also use SqlBackupAsync method to perform backup * operation asynchronously */ bkpDBLog.SqlBackup(myServer); |
| Result: |
C# Code Block 4 Backup with Compression - SQL Server 2008 introduces a new feature to issues backups in a compressed form. As such, SMO for SQL Server 2008 has been enhanced to support this feature. If you look at the image below you will notice the compressed backup size is almost 25% of full backup, though the level of compression depends on the several factors.
| C# Code Block 4 – Backup with Compression (SQL Server 2008) |
| Backup bkpDBFullWithCompression = new Backup(); /* Specify whether you want to back up database or files or log */ bkpDBFullWithCompression.Action = BackupActionType.Database; /* Specify the name of the database to back up */ bkpDBFullWithCompression.Database = myDatabase.Name; /* You can use back up compression technique of SQL Server 2008, * specify CompressionOption property to On for compressed backup */ bkpDBFullWithCompression.CompressionOption = BackupCompressionOptions.On; bkpDBFullWithCompression.Devices.AddDevice(@”D:\AdventureWorksFullWithCompression.bak”, DeviceType.File); bkpDBFullWithCompression.BackupSetName = “Adventureworks database Backup – Compressed”; bkpDBFullWithCompression.BackupSetDescription = “Adventureworks database – Full Backup with Compressin – only in SQL Server 2008″; bkpDBFullWithCompression.SqlBackup(myServer); |
| Result: |
C# Code Block 5 Full or Differential Restores – Thus far we have worked through SMO backup examples. Now let’s change gears to restore with SMO. SMO provides a Restore class to restore a database, similar to the Backup class. With these classes it is necessary to specify the Action property to indicate the type of restore i.e. database, files or log. In a scenario where if you have additional differential or log backups to be restored after it is necessary to specify the NoRecovery = true except for the final restore. In this example, I am wiring up events of the Restore object instance to event-handlers for progress monitoring. Finally the SqlRestore method is called to start the restoration. If you want to start the restore operation asynchronously you would need to call SqlRestoreAsync method instead.
| C# Code Block 5 – Database Restore – Full or Differential |
| Restore restoreDB = new Restore(); restoreDB.Database = myDatabase.Name; /* Specify whether you want to restore database, files or log */ restoreDB.Action = RestoreActionType.Database; restoreDB.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File); /* You can specify ReplaceDatabase = false (default) to not create a new * database, the specified database must exist on SQL Server * instance. If you can specify ReplaceDatabase = true to create new * database image regardless of the existence of specified database with * the same name */ restoreDB.ReplaceDatabase = true; /* If you have a differential or log restore after the current restore, * you would need to specify NoRecovery = true, this will ensure no * recovery performed and subsequent restores are allowed. It means it * the database will be in a restoring state. */ restoreDB.NoRecovery = true; /* Wiring up events for progress monitoring */ restoreDB.PercentComplete += CompletionStatusInPercent; restoreDB.Complete += Restore_Completed; /* SqlRestore method starts to restore the database * You can also use SqlRestoreAsync method to perform restore * operation asynchronously */ restoreDB.SqlRestore(myServer); |
| Result: |
To restore a database SQL Server needs to acquire exclusive lock on the database being restored. If you try to restore a database which is in use, SQL Server will throw the following exception:
C# Code Block 6 Transaction Log Restore – The process of restoring a transactional log is similar to restoring a full or differential backup. While restoring a transactional log, it is necessary to set the property Action = RestoreActionType.Log instead of RestoreActionType.Database as in case of full/differential restore. Here is an example:
| C# Code Block 6 – Database Restore – Log |
| Restore restoreDBLog = new Restore(); restoreDBLog.Database = myDatabase.Name; restoreDBLog.Action = RestoreActionType.Log; restoreDBLog.Devices.AddDevice(@”D:\AdventureWorksLog.bak”, DeviceType.File); /* You can specify NoRecovery = false (default) so that transactions are * rolled forward and recovered. */ restoreDBLog.NoRecovery = false; /* Wiring up events for progress monitoring */ restoreDBLog.PercentComplete += CompletionStatusInPercent; restoreDBLog.Complete += Restore_Completed; /* SqlRestore method starts to restore database * You cab also use SqlRestoreAsync method to perform restore * operation asynchronously */ restoreDBLog.SqlRestore(myServer); |
| Result: |
C# Code Block 7 Database Restore to a new location – At times you need to create a new database and restore to a new physical location which differs from the original database. For that purpose, the Restore class has the RelocateFiles collection which can be completed for each file with the new location as shown in the code below.
| C# Code Block 7 Database Restore – Different location |
| Restore restoreDB = new Restore(); restoreDB.Database = myDatabase.Name + “New”; /* Specify whether you want to restore database or files or log etc */ restoreDB.Action = RestoreActionType.Database; restoreDB.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File); /* You can specify ReplaceDatabase = false (default) to not create a new * database, the specified database must exist on SQL Server instance. * You can specify ReplaceDatabase = true to create new database * regardless of the existence of specified database */ restoreDB.ReplaceDatabase = true; /* If you have a differential or log restore to be followed, you would * specify NoRecovery = true, this will ensure no recovery is done * after the restore and subsequent restores are completed. The database * would be in a recovered state. */ restoreDB.NoRecovery = false; /* RelocateFiles collection allows you to specify the logical file names * and physical file names (new locations) if you want to restore to a * different location.*/ restoreDB.RelocateFiles.Add(new RelocateFile(“AdventureWorks_Data”, @”D:\AdventureWorksNew_Data.mdf”)); restoreDB.RelocateFiles.Add(new RelocateFile(“AdventureWorks_Log”, @”D:\AdventureWorksNew_Log.ldf”)); /* Wiring up events for progress monitoring */ restoreDB.PercentComplete += CompletionStatusInPercent; restoreDB.Complete += Restore_Completed; /* SqlRestore method starts to restore database * You can also use SqlRestoreAsync method to perform restore * operation asynchronously */ restoreDB.SqlRestore(myServer); |
| Result: |
Complete code listing (created on SQL Server 2008 and Visual Studio 2008, though there is not much difference if you are using it on SQL Server 2005 and Visual Studio 2005) can be found in the below text box.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
namespace BackupAndRestoreWithSMO2008
{
class Program
{
static void Main(string[] args)
{
Server myServer = new Server(@”ARSHADALI-LAP\ARSHADALI”);
try
{
//Using windows authentication
myServer.ConnectionContext.LoginSecure = true;
myServer.ConnectionContext.Connect();
Database myDatabase = myServer.Databases["AdventureWorks"];
BackupDatabaseFull(myServer, myDatabase);
//BackupDatabaseDifferential(myServer, myDatabase);
//BackupDatabaseLog(myServer, myDatabase);
//BackupDatabaseFullWithCompression(myServer, myDatabase);
RestoreDatabase(myServer, myDatabase);
//RestoreDatabaseLog(myServer, myDatabase);
//RestoreDatabaseWithDifferentNameAndLocation(myServer, myDatabase);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.InnerException.Message);
}
finally
{
if (myServer.ConnectionContext.IsOpen)
myServer.ConnectionContext.Disconnect();
Console.WriteLine(“Press any key to terminate…”);
Console.ReadKey();
}
}
private static void BackupDatabaseFull(Server myServer, Database myDatabase)
{
Backup bkpDBFull = new Backup();
/* Specify whether you want to back up database or files or log */
bkpDBFull.Action = BackupActionType.Database;
/* Specify the name of the database to back up */
bkpDBFull.Database = myDatabase.Name;
/* You can take backup on several media type (disk or tape), here I am using
* File type and storing backup on the file system */
bkpDBFull.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File);
bkpDBFull.BackupSetName = “Adventureworks database Backup”;
bkpDBFull.BackupSetDescription = “Adventureworks database – Full Backup”;
/* You can specify the expiration date for your backup data
* after that date backup data would not be relevant */
bkpDBFull.ExpirationDate = DateTime.Today.AddDays(10);
/* You can specify Initialize = false (default) to create a new
* backup set which will be appended as last backup set on the media. You can
* specify Initialize = true to make the backup as first set on the mediuam and
* to overwrite any other existing backup sets if the all the backup sets have
* expired and specified backup set name matches with the name on the medium */
bkpDBFull.Initialize = false;
/* Wiring up events for progress monitoring */
bkpDBFull.PercentComplete += CompletionStatusInPercent;
bkpDBFull.Complete += Backup_Completed;
/* SqlBackup method starts to take back up
* You cab also use SqlBackupAsync method to perform backup
* operation asynchronously */
bkpDBFull.SqlBackup(myServer);
}
private static void BackupDatabaseDifferential(Server myServer, Database myDatabase)
{
Backup bkpDBDifferential = new Backup();
/* Specify whether you want to back up database or files or log */
bkpDBDifferential.Action = BackupActionType.Database;
/* Specify the name of the database to back up */
bkpDBDifferential.Database = myDatabase.Name;
/* You can take backup on several media type (disk or tape), here I am using
* File type and storing backup on the file system */
bkpDBDifferential.Devices.AddDevice(@”D:\AdventureWorksDifferential.bak”, DeviceType.File);
bkpDBDifferential.BackupSetName = “Adventureworks database Backup”;
bkpDBDifferential.BackupSetDescription = “Adventureworks database – Differential Backup”;
/* You can specify the expiration date for your backup data
* after that date backup data would not be relevant */
bkpDBDifferential.ExpirationDate = DateTime.Today.AddDays(10);
/* You can specify Initialize = false (default) to create a new
* backup set which will be appended as last backup set on the media. You can
* specify Initialize = true to make the backup as first set on the mediuam and
* to overwrite any other existing backup sets if the all the backup sets have
* expired and specified backup set name matches with the name on the medium */
bkpDBDifferential.Initialize = false;
/* You can specify Incremental = false (default) to perform full backup
* or Incremental = true to perform differential backup since most recent
* full backup */
bkpDBDifferential.Incremental = true;
/* Wiring up events for progress monitoring */
bkpDBDifferential.PercentComplete += CompletionStatusInPercent;
bkpDBDifferential.Complete += Backup_Completed;
/* SqlBackup method starts to take back up
* You cab also use SqlBackupAsync method to perform backup
* operation asynchronously */
bkpDBDifferential.SqlBackup(myServer);
}
private static void BackupDatabaseLog(Server myServer, Database myDatabase)
{
Backup bkpDBLog = new Backup();
/* Specify whether you want to back up database or files or log */
bkpDBLog.Action = BackupActionType.Log;
/* Specify the name of the database to back up */
bkpDBLog.Database = myDatabase.Name;
/* You can take backup on several media type (disk or tape), here I am using
* File type and storing backup on the file system */
bkpDBLog.Devices.AddDevice(@”D:\AdventureWorksLog.bak”, DeviceType.File);
bkpDBLog.BackupSetName = “Adventureworks database Backup”;
bkpDBLog.BackupSetDescription = “Adventureworks database – Log Backup”;
/* You can specify the expiration date for your backup data
* after that date backup data would not be relevant */
bkpDBLog.ExpirationDate = DateTime.Today.AddDays(10);
/* You can specify Initialize = false (default) to create a new
* backup set which will be appended as last backup set on the media. You can
* specify Initialize = true to make the backup as first set on the mediuam and
* to overwrite any other existing backup sets if the all the backup sets have
* expired and specified backup set name matches with the name on the medium */
bkpDBLog.Initialize = false;
/* Wiring up events for progress monitoring */
bkpDBLog.PercentComplete += CompletionStatusInPercent;
bkpDBLog.Complete += Backup_Completed;
/* SqlBackup method starts to take back up
* You cab also use SqlBackupAsync method to perform backup
* operation asynchronously */
bkpDBLog.SqlBackup(myServer);
}
private static void BackupDatabaseFullWithCompression(Server myServer, Database myDatabase)
{
Backup bkpDBFullWithCompression = new Backup();
/* Specify whether you want to back up database or files or log */
bkpDBFullWithCompression.Action = BackupActionType.Database;
/* Specify the name of the database to back up */
bkpDBFullWithCompression.Database = myDatabase.Name;
/* You can use back up compression technique of SQL Server 2008,
* specify CompressionOption property to On for compressed backup */
bkpDBFullWithCompression.CompressionOption = BackupCompressionOptions.On;
bkpDBFullWithCompression.Devices.AddDevice(@”D:\AdventureWorksFullWithCompression.bak”, DeviceType.File);
bkpDBFullWithCompression.BackupSetName = “Adventureworks database Backup – Compressed”;
bkpDBFullWithCompression.BackupSetDescription = “Adventureworks database – Full Backup with Compressin – only in SQL Server 2008″;
bkpDBFullWithCompression.SqlBackup(myServer);
}
private static void CompletionStatusInPercent(object sender, PercentCompleteEventArgs args)
{
Console.Clear();
Console.WriteLine(“Percent completed: {0}%.”, args.Percent);
}
private static void Backup_Completed(object sender, ServerMessageEventArgs args)
{
Console.WriteLine(“Hurray…Backup completed.” );
Console.WriteLine(args.Error.Message);
}
private static void Restore_Completed(object sender, ServerMessageEventArgs args)
{
Console.WriteLine(“Hurray…Restore completed.”);
Console.WriteLine(args.Error.Message);
}
private static void RestoreDatabase(Server myServer, Database myDatabase)
{
Restore restoreDB = new Restore();
restoreDB.Database = myDatabase.Name;
/* Specify whether you want to restore database or files or log etc */
restoreDB.Action = RestoreActionType.Database;
restoreDB.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File);
/* You can specify ReplaceDatabase = false (default) to not create a new image
* of the database, the specified database must exist on SQL Server instance.
* If you can specify ReplaceDatabase = true to create new database image
* regardless of the existence of specified database with same name */
restoreDB.ReplaceDatabase = true;
/* If you have differential or log restore to be followed, you would need
* to specify NoRecovery = true, this will ensure no recovery is done after the
* restore and subsequent restores are allowed. It means it will database
* in the Restoring state. */
restoreDB.NoRecovery = true;
/* Wiring up events for progress monitoring */
restoreDB.PercentComplete += CompletionStatusInPercent;
restoreDB.Complete += Restore_Completed;
/* SqlRestore method starts to restore database
* You cab also use SqlRestoreAsync method to perform restore
* operation asynchronously */
restoreDB.SqlRestore(myServer);
}
private static void RestoreDatabaseLog(Server myServer, Database myDatabase)
{
Restore restoreDBLog = new Restore();
restoreDBLog.Database = myDatabase.Name;
restoreDBLog.Action = RestoreActionType.Log;
restoreDBLog.Devices.AddDevice(@”D:\AdventureWorksLog.bak”, DeviceType.File);
/* You can specify NoRecovery = false (default) so that transactions are
* rolled forward and recovered. */
restoreDBLog.NoRecovery = false;
/* Wiring up events for progress monitoring */
restoreDBLog.PercentComplete += CompletionStatusInPercent;
restoreDBLog.Complete += Restore_Completed;
/* SqlRestore method starts to restore database
* You cab also use SqlRestoreAsync method to perform restore
* operation asynchronously */
restoreDBLog.SqlRestore(myServer);
}
private static void RestoreDatabaseWithDifferentNameAndLocation(Server myServer, Database myDatabase)
{
Restore restoreDB = new Restore();
restoreDB.Database = myDatabase.Name + “New”;
/* Specify whether you want to restore database or files or log etc */
restoreDB.Action = RestoreActionType.Database;
restoreDB.Devices.AddDevice(@”D:\AdventureWorksFull.bak”, DeviceType.File);
/* You can specify ReplaceDatabase = false (default) to not create a new image
* of the database, the specified database must exist on SQL Server instance.
* You can specify ReplaceDatabase = true to create new database image
* regardless of the existence of specified database with same name */
restoreDB.ReplaceDatabase = true;
/* If you have differential or log restore to be followed, you would need
* to specify NoRecovery = true, this will ensure no recovery is done after the
* restore and subsequent restores are allowed. It means it will database
* in the Restoring state. */
restoreDB.NoRecovery = false;
/* RelocateFiles collection allows you to specify the logical file names and
* physical file names (new locations) if you want to restore to a different location.*/
restoreDB.RelocateFiles.Add(new RelocateFile(“AdventureWorks_Data”, @”D:\AdventureWorksNew_Data.mdf”));
restoreDB.RelocateFiles.Add(new RelocateFile(“AdventureWorks_Log”, @”D:\AdventureWorksNew_Log.ldf”));
/* Wiring up events for progress monitoring */
restoreDB.PercentComplete += CompletionStatusInPercent;
restoreDB.Complete += Restore_Completed;
/* SqlRestore method starts to restore database
* You cab also use SqlRestoreAsync method to perform restore
* operation asynchronously */
restoreDB.SqlRestore(myServer);
}
}
}
Notes:
Next Steps
Readers Who Read This Tip Also Read
Yazı kategorisi: C#, SQL Server Backup, Sql Server Management Objects, Sql Server Restore | » yorum bırak;
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/tip.asp?tip=1745
|
Yazı kategorisi: PowerShell, Sql Server, Sql Server Management Objects | » yorum bırak;
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/tip.asp?tip=1759
Problem
In a previous tip on using Using PowerShell with SQL Server Management Objects (SMO), you’ve seen how you can use Windows PowerShell and SMO to administer SQL Server databases. I would like to translate some of the Transact-SQL scripts that I use every day, starting with the simple ones like retrieving a list of databases and their properties for auditing purposes.
Solution
One of the things that we do as DBAs is to retrieve a list of databases and their properties for auditing and reporting purposes. We check for properties such as recovery model, available free space, autoshrink, etc., and generate action items based on them. We’ve already seen how to access the Server object – its properties and methods – using SMO. We will dig into the object hierarchy and look at the different members of the Server object. A SQL Server instance can be described using different properties like instance name, logins, settings, all of which are members of the Server object.
What would be of main interest for this tip is the Databases property. This property represents a collection of database objects defined on a SQL Server instance, regardless whether they are system or user databases. Let’s start by retrieving all the members of the Databases property. The script below is the same as the one in the previous scripts with the addition of a Get-Member cmdlet to retrieve the list of members for the Databases property, specifying Property as the MemberType which just means to retrieve all the database properties. Be sure not to get confused with the terms – the Databases property of the Server object is a collection of database objects and the database objects themselves have their own properties.
| [System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null $s = New-Object (‘Microsoft.SqlServer.Management.Smo.Server’) “LOCALHOST\SQL2000″ $dbs=$s.Databases $dbs | Get-Member -MemberType Property |

From the list of properties from the Database object, let’s select the most common ones – Name, Collation, CompatibilityLevel, AutoShrink, RecoveryModel, Size and SpaceAvailable
| $dbs | SELECT Name, Collation, CompatibilityLevel, AutoShrink, RecoveryModel, Size, SpaceAvailable |

Notice that it is pretty simple and straight-forward. Since the $dbs variable contains a collection of database objects, you can now pipe the results so a Select-Object cmdlet, which we just refer to as SELECT. You can then make this script dynamic by introducing variables and saving it as a PowerShell script which we have done in previous tips.
Reading from a Text File
There are a couple of ways to list the servers that you manage, but for simplicity’s sake, we’ll use a simple text file. What we will do is store the names of the SQL Server instances that you administer in a text file named SQL_Servers.txt and pass the contents in a variable named $instance. We will use the Get-Content cmdlet to read thru the contents of the text file and the ForEach-Object cmdlet to iterate thru the collection. The script would look something like the one below. You can either write it in a script file or type it directly in the PowerShell console
| ForEach ($instance in Get-Content “D:\SQL_Servers.txt”) { [System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null $s = New-Object (‘Microsoft.SqlServer.Management.Smo.Server’) $instance $dbs=$s.Databases $dbs | SELECT Name, Collation, CompatibilityLevel, AutoShrink, RecoveryModel, Size, SpaceAvailable } |

Generate Fancy Reports – Enter Microsoft Excel
Let’s admit it, Microsoft Excel happens to be the most popular application to generate spreadsheets and reports so it does make sense to make the most out of it with any reports that we need to generate. IT Managers and key stakeholders would like to see either graphs with colors instead of just numerical values within reports. What we will do is to use PowerShell to automate report creation for our database audit report with Excel. There are a few key things that we need to understand about the process. First, we will be calling Excel thru COM automation and not as a .NET application. We used the New-Object cmdlet to create an instance of the Excel object, the -ComObject parameter to create a new COM object of type Excel.Application which is the ProgID of the object we want to create and assign it the variable $Excel.
| $Excel = New-Object -ComObject Excel.Application |
You might be interested to find out what other COM components are available on a Windows machine for you to use. To retrieve their ProgID values, you can query the registry with a one-liner like the one below (this was derived from the PowerShell team blog)
| dir ”REGISTRY::HKEY_CLASSES_ROOT\CLSID” -include PROGID -recurse | foreach {$_.GetValue(“”)} |
So much for COM objects as we only need the Excel.Application at this point. Next, we set the Visible property of the Excel object to True so we can see what is happening
| $Excel.visible = $True |
Next, we use the Add() method to add a new workbook to the instance of the Excel object and use the Item property to create an object reference to the first worksheet in the workbook. The variable $Sheet will hold that pointer to the worksheet and will be referred to in most of the code
| $Excel = $Excel.Workbooks.Add() $Sheet = $Excel.Worksheets.Item(1) |
You can add as many workbooks as you want, but one would be enough for our purpose. Now, to actually work with Excel we need to reference row and column numbers. To do that, we call the Cells property of the Excel object to return the cell or cells in the active sheet. We can then modify the cells like providing a value, changing the Font properties, etc. An example to assign a value to a cell in row 1, column 1 and change the Font property to Bold is shown below.
| $Sheet.Cells.Item(1,1) = “SQL SERVER INSTANCE NAME:” $Sheet.Cells.Item(1,1).Font.Bold = $True |
Saving the code and running it in PowerShell will open up an Excel spreadsheet that will look something like the one below

You can either call the SaveAs() method of the Worksheet object $Sheet to save the Excel spreadsheet or just leave it as it is.
Imagine dealing with row and column values that are dynamic since there would be a fair amount of databases on each of your SQL Server instances. Below is a PowerShell script that takes into account what we have just covered with SMO and Excel to create a fancy report
| #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 $intRow = 1 #Read thru the contents of the SQL_Servers.txt file #Create column headers $intRow++ $Sheet.Cells.Item($intRow,1) = “DATABASE NAME” #Format the column headers $intRow++ [System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null # Create an SMO connection to the instance $dbs = $s.Databases #$dbs | SELECT Name, Collation, CompatibilityLevel, AutoShrink, RecoveryModel, Size, SpaceAvailable #Formatting using Excel ForEach ($db in $dbs) #Divide the value of SpaceAvailable by 1KB #Format the results to a number with three decimal places $Sheet.Cells.Item($intRow, 1) = $db.Name #Change the background color of the Cell depending on the AutoShrink property value $Sheet.Cells.Item($intRow, 4) = $db.AutoShrink $Sheet.Cells.Item($intRow, 5) = $db.RecoveryModel #Change the background color of the Cell depending on the SpaceAvailable property value $Sheet.Cells.Item($intRow, 7) = $dbSpaceAvailable $intRow ++ } $intRow ++ } $Sheet.UsedRange.EntireColumn.AutoFit() |
Running the script in PowerShell will generate an Excel spreadsheet similar to the one below, highlighting those properties that need immediate attention using some fancy colors from the definitions available here.

Next Steps
Readers Who Read This Tip Also Read
Yazı kategorisi: PowerShell, Sql Server | » yorum bırak;
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/tip.asp?tip=1798
Problem
Checking for SQL Server Agent jobs and their status is part of your daily task as a DBA. How do we use Windows PowerShell to check for SQL Server Agent jobs?
Solution
Similar to the task described in the tip Check the Last SQL Server Backup Date using Windows PowerShell, it would require reading the tables in the msdb database and joining them appropriately to find out which jobs failed. Two tables in particular are of interest to us to check for job execution information like job name, execution status, run date, run time, etc. – the sysjobs and sysjobhistory tables.
The script below displays a list of jobs on your SQL Server instance with there status.
| USE msdb GO SELECT j.[name] AS [JobName], run_status = CASE h.run_status WHEN 0 THEN ’Failed’ WHEN 1 THEN ’Succeeded’ WHEN 2 THEN ’Retry’ WHEN 3 THEN ’Canceled’ WHEN 4 THEN ’In progress’ END, h.run_date AS LastRunDate, h.run_time AS LastRunTime FROM sysjobhistory h INNER JOIN sysjobs j ON h.job_id = j.job_id WHERE j.enabled = 1 AND h.instance_id IN (SELECT MAX(h.instance_id) FROM sysjobhistory h GROUP BY (h.job_id)) GO
|
Notice that the run_date and run_time columns of the sysjobhistory table are of type int and would be a bit challenging to convert the columns to their appropriate data types. Server Management Objects (SMO) exposes these properties when using Windows PowerShell. The JobServer property of the Server object represents the SQL Server Agent associated with an instance of SQL Server. This includes the SQL Server jobs, operators and alerts.When translating the T-SQL query above to Windows PowerShell, we would be interested in the Name, LastRunDate and LastRunOutcome properties of the Jobs object. What’s really good to note is that the LastRunDate property is in a datetime format that no longer requires conversion to the appropriate data type, similar to what we get from the sysjobhistory table in the msdb database. I keep trying to highlight this for every tip I’ve written that uses PowerShell with SMO. The only aspect of the code that we have changed from the scripts in the previous tips is the last line, i.e. adding new properties for the new objects we are working with. This highlights the power and simplicity of Windows PowerShell from the script.
| [System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null $rvs = New-Object (‘Microsoft.SqlServer.Management.Smo.Server’) “LOCALHOST\SQL2000″
#Create an instance of the Jobs object collection from the JobServer property
|
Notice that the LastRunDate property is in the correct data type. The LastRunOutcome property is returned as they are without the need for further translations as in the T-SQL script above. Let’s call to the Excel object as we did in the previous tips to format the results. Again, the script above is more than enough for what we need.
| #Create a new Excel object using COM $Excel = New-Object -ComObject Excel.Application $Excel.visible = $True
$Excel = $Excel.Workbooks.Add() #Counter variable for rows
#Read thru the contents of the SQL_Servers.txt file
#Create column headers
$intRow++
$Sheet.Cells.Item($intRow,1) = “JOB NAME”
#Format the column headers
$intRow++
[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null
# Create an SMO connection to the instance
$jobs=$srv.JobServer.Jobs
#Formatting using Excel
# Formatting for the failed jobs
$Sheet.Cells.Item($intRow, 1) = $job.Name }
$Sheet.UsedRange.EntireColumn.AutoFit()
|
Next Steps
Readers Who Read This Tip Also Read
Yazı kategorisi: PowerShell, SQL Server Backup, Sql Server | » yorum bırak;
Yazan: esersahin 29/10/2009
http://www.mssqltips.com/tip.asp?tip=1862&home
Problem
In a previous tip on Backup and Restore SQL Server databases programmatically with SMO, you’ve seen how you can use Windows PowerShell to backup and restore SQL Server databases. In this tip, I will cover how to use Windows PowerShell to generate SQL Server backups.
Solution
Generating and maintaining backups are the most important tasks that any DBA has to fulfill. And, as mentioned in the previous tip, SMO can be used to backup and restore a database. There are different ways to backup a database, depending on company policies on disaster recovery. We will be introducing a new SMO namespace that will allow us to create the Backup object. This is an added line in our previous PowerShell scripts to create a new instance of the Backup object.
| $dbBackup = new-object (“Microsoft.SqlServer.Management.Smo.Backup”)
|
The first property of the Backup object that we need to assign is the name of the database that we need to do a backup on. This is defined by the Database property of the Backup object. The code snippet below defines a Database property for the Backup object to perform a backup on the Northwind database.
| $dbBackup.Database = “Northwind”
|
Whenever you generate or create backups, SMO considers this as a Device. This requires us to add the Backup file to the Devices collection of the Backup object, specifying the DeviceType as File. The first parameter in the AddDevice method of the Devices collection is the file name of the backup file with the full path as stored in the file system whereas the second parameter is the DeviceType. While SQL Server supports the use of devices, I normally recommend using the file system to easily identify the backup sets based on the file name using the proper naming convention (one thing you would not want to be worried about during disaster recovery is scrambling to find the valid backup sets).
| $dbBackup.Devices.AddDevice(“yourDBbackupFile.bak”, “File”)
|
The next important property of the Backup object that we are interested in is the Action property. The Action property sets the type of backup to be performed – Database, Log or File. The default value of the Action property is set to Database. This property is of importance based on the definition of our service level agreement as you don’t just generate backups without understanding the defined SLAs for a specific database or application. For our example, we will define a FULL database backup
| $dbBackup.Action = “Database”
|
Once we have defined the properties of our Backup object, it’s just a matter of calling the SqlBackup method of the Backup object. The SqlBackup method performs the backup operation as defined by the properties you have set in the Backup object. It accepts a parameter of type Server which represents the SQL Server instance that you have defined as the source of the backup operation.
| $dbBackup.SqlBackup($s)
|
Combining the code snippets above, here is a working Windows PowerShell script to perform a FULL database backup against the Northwind database, storing the backup file in your file system.
| [System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null $s = New-Object (‘Microsoft.SqlServer.Management.Smo.Server’) “LOCALHOST\SQL2005_1″
#Create a Backup object instance with the Microsoft.SqlServer.Management.Smo.Backup namespace
#Set the Database property to Northwind
#Add the backup file to the Devices collection and specify File as the backup type
#Specify the Action property to generate a FULL backup
#Call the SqlBackup method to generate the backup
|
Now, since you won’t be performing backups of just a single database, it would be better if we loop the entire script in a For-Each cmdlet iterating thru the Databases collection of the Server object.
| [System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SqlServer.SMO”) | out-null $s = new-object (“Microsoft.SqlServer.Management.Smo.Server”) $instance
$bkdir = “D:\PSScripts\backups” #We define the folder path as a variable
|
While my only condition for generating backups is to exclude the tempdb database, you can include other conditions such as querying the database property if it is used for database mirroring (IsMirroringEnabled property) or specifying database names if you are sure enough that you won’t be needing backups for them. While not really necessary, you also might want to include other Backup object properties such as BackupSetName, BackupSetDescription, and MediaDescription as they can be of help in case you wanted to find out the contents of your backup sets.
NOTE: If you have SQL Server 2008 Client Tools installed on your workstation where you intend to run this PowerShell script, it is important that you add a reference to the Microsoft.SqlServer.SmoExtended namespace. The Backup object and a few other objects were moved from the Microsoft.SqlServer.Smo to the Microsoft.SqlServer.SmoExtended. In the example I provided, I have SQL Server 2005 and SQL Server 2008 running on my machine, thus, requiring that I add a reference to the Microsoft.SqlServer.SmoExtended namespace. SQL Server MVP Allen White has blogged about Loading SMO Assemblies in PowerShell and explains using a custom script to load appropriate SMO assemblies depending on the SQL Server version.
| [System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SqlServer.SMO”)| out-null [System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SqlServer.SmoExtended”)| out-null
|
Depending on your service level agreement, you would also need to define either Differential or Log backups to complement your Full backups. This can be done by changing the Action property of the Backup object to either Log for Log backups or setting the Incremental property of the Backup object to a value of 1. Below is a code snippet for generating Log backups, simply by changing the Action property.
| $dbBackup.Action = “Log”
|
Note that you can only do Log backups on databases that are not configured to use the SIMPLE recovery model. This means that your condition for generating Log backups would include a check on the RecoveryModel property
| if($db.RecoveryModel -ne 3) #Don’t issue Log backups for DBs with RecoveryModel=3 or SIMPLE { $dbname = $db.Name $dt = get-date -format yyyyMMddHHmm #Create a file name based on the timestamp $dbBackup = new-object (“Microsoft.SqlServer.Management.Smo.Backup”) $dbBackup.Action = “Log” $dbBackup.Database = $dbname $dbBackup.Devices.AddDevice($bkdir + “\” + $dbname + “_log_” + $dt + “.trn”, “File”) $dbBackup.SqlBackup($s) }
|
For Differential backups, you would need to replace the Action property with the Incremental property and set the value to 1
| if($db.Name -ne “tempdb”) { $dbname = $db.Name $dt = get-date -format yyyyMMddHHmm #Create a file name based on the timestamp $dbBackup = new-object (“Microsoft.SqlServer.Management.Smo.Backup”) $dbBackup.Incremental = 1 $dbBackup.Database = $dbname $dbBackup.Devices.AddDevice($bkdir + “\” + $dbname + “_diff_” + $dt + “.bak”, “File”) $dbBackup.SqlBackup($s) }
|
Your backup strategies, depending on your service level agreement, will definitely include a combination of either Full and Differential and/or Log backups.
Next Steps
Readers Who Read This Tip Also Read
Yazı kategorisi: PowerShell, SQL Server Backup, Sql Server | » yorum bırak;
Yazan: esersahin 21/10/2009
http://gchandra.wordpress.com/2007/12/04/sql-server-2005-verify-table-already-exists/
Verifying that an object exists
If the table exists, it is deleted. If the table does not exist, the DROP TABLE statement is not executed.
IF OBJECT_ID (N’dbo.AWBuildVersion’, N’U’) IS NOT NULL
DROP TABLE dbo.AWBuildVersion;
GO
Syntax :
OBJECT_ID (’object_name’, ['object_type'])
Object Type is optional, and possible values it can hold are.. (Items in bold are frequently used)
Object type:
AF = Aggregate function (CLR)
C = CHECK constraint
D = DEFAULT (constraint or stand-alone)
F = FOREIGN KEY constraint
PK = PRIMARY KEY constraint
P = SQL stored procedure
PC = Assembly (CLR) stored procedure
FN = SQL scalar function
FS = Assembly (CLR) scalar function
FT = Assembly (CLR) table-valued function
R = Rule (old-style, stand-alone)
RF = Replication-filter-procedure
SN = Synonym
SQ = Service queue
TA = Assembly (CLR) DML trigger
TR = SQL DML trigger
IF = SQL inlined table-valued function
TF = SQL table-valued-function
U = Table (user-defined)
UQ = UNIQUE constraint
V = View
X = Extended stored procedure
IT = Internal table
Yazı kategorisi: Sql Server, Table, Transact-SQL | » yorum bırak;
Yazan: esersahin 06/10/2009
http://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.isstatic(VS.80).aspx
// Make two fields.
public class Myfielda
{
private string field = “A private field”;
public string Field
{
get{return field;}
set{if(field!=value){field=value;}}
}
}
public class Myfieldb
{
static string field = “B private static field”;
public string Field
{
get{return field;}
set{if(field!=value){field=value;}}
}
}
public class Myfieldinfo
{
public static int Main()
{
Console.WriteLine(“\nReflection.FieldInfo”);
Myfielda Myfielda = new Myfielda();
Myfieldb Myfieldb = new Myfieldb();
// Get the Type and FieldInfo.
Type MyTypea = typeof(Myfielda);
FieldInfo Myfieldinfoa = MyTypea.GetField(“field”, BindingFlags.NonPublic|BindingFlags.Instance);
Type MyTypeb = typeof(Myfieldb);
FieldInfo Myfieldinfob = MyTypeb.GetField(“field”, BindingFlags.NonPublic|BindingFlags.Static);
// For the first field, get and display the name, field, and IsStatic property value.
Console.Write(“\n{0} – “, MyTypea.FullName);
Console.Write(“{0}; “, Myfieldinfoa.GetValue(Myfielda));
Console.Write(“IsStatic – {0}”, Myfieldinfoa.IsStatic);
// For the second field get and display the name, field, and IsStatic property value.
Console.Write(“\n{0} – “, MyTypeb.FullName);
Console.Write(“{0}; “, Myfieldinfob.GetValue(Myfieldb));
Console.Write(“IsStatic – {0}”, Myfieldinfob.IsStatic);
return 0;
}
}
Yazı kategorisi: Enum, FieldInfo | » yorum bırak;
Yazan: esersahin 06/10/2009
http://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo(VS.80).aspx
using System; using System.Reflection; public class FieldInfoClass { public int myField1 = 0; protected string myField2 = null; public static void Main() { FieldInfo[] myFieldInfo; Type myType = typeof(FieldInfoClass); // Get the type and fields of FieldInfoClass. myFieldInfo = myType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); Console.WriteLine("\nThe fields of " + "FieldInfoClass are \n"); // Display the field information of FieldInfoClass. for(int i = 0; i < myFieldInfo.Length; i++) { Console.WriteLine("\nName : {0}", myFieldInfo[i].Name); Console.WriteLine("Declaring Type : {0}", myFieldInfo[i].DeclaringType); Console.WriteLine("IsPublic : {0}", myFieldInfo[i].IsPublic); Console.WriteLine("MemberType : {0}", myFieldInfo[i].MemberType); Console.WriteLine("FieldType : {0}", myFieldInfo[i].FieldType); Console.WriteLine("IsFamily : {0}", myFieldInfo[i].IsFamily); } } }
Yazı kategorisi: Enum, FieldInfo | » yorum bırak;
Yazan: esersahin 06/10/2009
Here’s a small function I’ve found to be quite useful recently. It takes an enum type and returns a generic list populated with each enum item.
// Can’t use type constraints on value types, so have to do check like this
if (enumType.BaseType != typeof(Enum))
throw new ArgumentException(“T must be of type System.Enum”);
Array enumValArray = Enum.GetValues(enumType);
List<T> enumValList = new List<T>(enumValArray.Length);
foreach (int val in enumValArray) {
enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
}
return enumValList;
}
Here’s one of the ways that I’ve used it:
Yazı kategorisi: Enum, List | » yorum bırak;