<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Personal Weblog of John Wood</title>
	<atom:link href="http://www.webofwood.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.webofwood.com</link>
	<description>Wordpress weblog of John Wood, a Database Administrator</description>
	<lastBuildDate>Fri, 11 May 2012 20:11:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Powershell Function to Get Last SQL Server Backup File</title>
		<link>http://www.webofwood.com/2012/05/11/powershell-function-to-get-last-sql-server-backup-file/</link>
		<comments>http://www.webofwood.com/2012/05/11/powershell-function-to-get-last-sql-server-backup-file/#comments</comments>
		<pubDate>Fri, 11 May 2012 18:57:28 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[smo]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[VEEAM]]></category>
		<category><![CDATA[VMWare]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=174</guid>
		<description><![CDATA[Powershell is a great tool to use for a multitude of SQL Server administrative functions. I frequently need to know or get the file name of the last backup of a database. Sometimes I just need it for a report or to pass it off to another function. I created a Powershell function to obtain [...]]]></description>
			<content:encoded><![CDATA[<p>Powershell is a great tool to use for a multitude of SQL Server administrative functions. I frequently need to know or get the file name of the last backup of a database. Sometimes I just need it for a report or to pass it off to another function. I created a Powershell function to obtain the data for me and had been using it for some time. Unfortunately, it recently broke down.</p>
<p>After some debugging, I was able to find the cause of my problem and I thought it would be a good idea to post my new and improved function. The function had to be changed because of snapshots being taken by VEEAM backups. We recently built a new SQL Server on VMWare and I implemented my normal backup methodology. However, when I recently wanted a report of the latest backups, my Powershell function failed! VEEAM snapshots are reported as backups but there is no file name associated with it. The new function excludes all backups which are snapshots.</p>
<p>I’ll first post the T-SQL to obtain the latest backup for a database and then I’ll show you how to use it in a Powershell function.</p>
<pre class="brush: plain">DECLARE @dbname sysname
SET		@dbname = 'YOURDB'
SELECT	f.physical_device_name as [backup]
FROM	msdb.dbo.backupset AS s WITH (nolock) INNER JOIN
			msdb.dbo.backupmediafamily AS f WITH (nolock) ON s.media_set_id = f.media_set_id
WHERE	(s.database_name = @dbname) AND (s.type = 'D') AND (f.device_type &lt;&gt; 7)
			AND (s.backup_finish_date = (SELECT     MAX(backup_finish_date)
FROM        msdb.dbo.backupset WITH (nolock)
WHERE	(database_name = @dbname) AND (type = 'D') AND (is_snapshot = 0)))</pre>
<p>And now the Powershell use of it.</p>
<pre class="brush: ps">Param(
	[Parameter(Mandatory=$true,Position=0)]
	[string]$server,
	[Parameter(Mandatory=$true,Position=1)]
	[string]$database
)
Function New-SMOconnection {
    Param (
		[Parameter(Mandatory=$true)]
		[string]$server,
		[int]$StatementTimeout=0
	)
	If(!(Test-Connection -ComputerName ($server.Split('\')[0]) -Quiet -Count 1)) {
		Throw "Could not connect to SQL Server $server."
	}
	$conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($server)
	$conn.applicationName = "PowerShell SMO"
	$conn.StatementTimeout = $StatementTimeout
	Try {$conn.Connect()}
	Catch {Throw $Error}
	if ($conn.IsOpen -eq $false) {
		Throw "Could not connect to SQL Instance $server."
	}
	$smo = New-Object Microsoft.SqlServer.Management.Smo.Server($conn)
	$smo
}
Function Get-LastBackupFile {
	Param(
		[string]$server,
		[string]$database
	)
	<# 	Use a hereto to construct the T-SQL
		You will notice the query eliminates any snapshots. This is because we
		sometimes have VEEAM backups on some servers.
	#>
	$qry = @"
DECLARE @dbname sysname
SET @dbname = '$database'
SELECT	f.physical_device_name as [backup]
FROM	msdb.dbo.backupset AS s WITH (nolock) INNER JOIN
			msdb.dbo.backupmediafamily AS f WITH (nolock) ON s.media_set_id = f.media_set_id
WHERE	(s.database_name = @dbname) AND (s.type = 'D') AND (f.device_type <> 7)
		AND (s.backup_finish_date = (SELECT MAX(backup_finish_date)
FROM         msdb.dbo.backupset WITH (nolock)
WHERE     (database_name = @dbname) AND (type = 'D') AND (is_snapshot = 0)))
"@

	# Get an SMO Connection
	$smo = New-SMOconnection -server $server
	# most appropriate to use MSDB
	$db = $smo.Databases["msdb"]
	# Execute query with results
	$rs = $db.ExecuteWithResults($qry)
	# SMO connection is no longer needed
	$smo.ConnectionContext.Disconnect()
	# Return the result
	$rs.Tables[0].Rows[0].Item('backup')
}
# Load SMO Assemblies
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")

# Call the function and trap any error
Try {$backup = Get-LastBackupFile -server $server -database $database}
Catch {
	$ex = $Error[0].Exception
	Write-Host $ex.Message
	While($ex.InnerException) {
		$ex = $ex.InnerException
		Write-Host $ex.Message
	}
}
<# Verify the file
	NOTE: most developent and run-time is performed on remote servers
	so there may be a need to convert to UNC format
#>
$backup = Join-Path "\\$($server.split('\')[0])" $backup.replace(':','$')

if(!(Test-Path $backup)) {
	Throw "Database backup $backup not found"
}
Write-Host $backup</pre>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.webofwood.com%2F2012%2F05%2F11%2Fpowershell-function-to-get-last-sql-server-backup-file%2F&amp;title=Powershell%20Function%20to%20Get%20Last%20SQL%20Server%20Backup%20File" id="wpa2a_2"><img src="http://www.webofwood.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2012/05/11/powershell-function-to-get-last-sql-server-backup-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restore All SQL Transaction Logs using Powershell</title>
		<link>http://www.webofwood.com/2011/09/15/restore-all-sql-transaction-logs-using-powershell/</link>
		<comments>http://www.webofwood.com/2011/09/15/restore-all-sql-transaction-logs-using-powershell/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 20:49:16 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=167</guid>
		<description><![CDATA[I came across another opportunity for using Powershell when setting up mirroring for a large database at our DR site. The database was over 73Gig. The problem arose when it took a very long time to copy the backup and transaction logs and run the database restore. By the time the copy had finished another [...]]]></description>
			<content:encoded><![CDATA[<p>I came across another opportunity for using Powershell when setting up mirroring for a large database at our DR site. The database was over 73Gig. The problem arose when it took a very long time to copy the backup and transaction logs and run the database restore. By the time the copy had finished another several transaction logs had been produced. While applying the *.bak  restore, yet another several transaction logs had been produced.<span id="more-167"></span></p>
<p>I don’t know about you, but using the SSMS GUI tool to restore a bunch of transaction logs is very tedious. I’ve got another number of large databases which will require mirroring also. With this in mind, I decided it would be beneficial to have a script to automate the process. What was of interest to me was being able to iterate through the process several times while copying new transaction logs. The script will process all the transaction logs in a directory at one time. If you happen to generate more transaction logs to the directory and run the script again, you will get error messages for the logs already restored but the new logs will still be restored.</p>
<p>The script also takes into account using UNC paths. So, you can run the script from any machine against an SQL Server on a remote machine.</p>
<pre class="brush: ps"> Restore-TransLogs.ps1 -server "MYSERVER\MYSQL" -database "MY_Database"
	.NOTES
		AUTHOR:    John P. Wood
		CREATED:   September, 2011
		VERSION:   1.0.0
#&gt;
Param(
	[Parameter(Mandatory=$true)]
	[string]$Server,
	[Parameter(Mandatory=$true)]
	[string]$database,
	[Parameter(Mandatory=$true)]
	[string]$FilePath
	)
Set-StrictMode -Version Latest
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")

## SQL Server Backup\Restore uses local file paths.
Function Get-LocalPath($File) {
	$dir = $File.DirectoryName
	$rp = $dir.Remove(0,($dir.IndexOf('$')+2))
	$root = (((Get-Item $dir).Root).Name).Replace('$',':')
	$local = $root + '\' + $rp + '\' + $File
	$local
}
Function New-SMOconnection {
    Param (
		[string]$server
	)
	$conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($server)
	$conn.applicationName = "PowerShell SMO"
	$conn.StatementTimeout = 0
	$conn.Connect()
	if ($conn.IsOpen -eq $false) {
		Throw "Could not connect to server $($server)"
	}
	$smo = New-Object Microsoft.SqlServer.Management.Smo.Server($conn)
	$smo
}
Function Invoke-SqlRestore {
	Param(
		[string]$filename
	)
	# Get a new connection to the server
    $backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($filename, "File")

	# Load up the Restore object settings
	$Restore = new-object Microsoft.SqlServer.Management.Smo.Restore
	$Restore.Action = [Microsoft.SqlServer.Management.Smo.RestoreActionType]::Log
	$Restore.Database = $database
    $Restore.NoRecovery = $true
	$Restore.Devices.Add($backupDevice)

	$Restore.SqlRestore($smo)
}
Clear-Host
$smo = New-SMOconnection -server $Server
If(!(Test-Path -LiteralPath $FilePath)){Throw "FilePath not found: $FilePath"}
Get-ChildItem $FilePath -Filter "*.trn" | Sort-Object -Property LastWriteTime |
	ForEach-Object {
		If(($_.Fullname).StartsWith('\\')) {$file = Get-LocalPath $_ }
		Else {$file = $_.FullName}
		Try {Invoke-SqlRestore -filename $file}
		Catch {
			$ex = $Error[0].Exception
			Write-Output $ex.message
			while ($ex.InnerException)
			{
				$ex = $ex.InnerException
				Write-Output $ex.message
			}
		}
}
If ($smo.ConnectionContext.IsOpen -eq $true) {$smo.ConnectionContext.Disconnect()}</pre>
<p>&nbsp;</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.webofwood.com%2F2011%2F09%2F15%2Frestore-all-sql-transaction-logs-using-powershell%2F&amp;title=Restore%20All%20SQL%20Transaction%20Logs%20using%20Powershell" id="wpa2a_4"><img src="http://www.webofwood.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2011/09/15/restore-all-sql-transaction-logs-using-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get a Midnight DateTime Value in Powershell</title>
		<link>http://www.webofwood.com/2010/08/13/get-a-midnight-datetime-value-in-powershell/</link>
		<comments>http://www.webofwood.com/2010/08/13/get-a-midnight-datetime-value-in-powershell/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 18:40:16 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[midnight]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/2010/08/13/get-a-midnight-datetime-value-in-powershell/</guid>
		<description><![CDATA[&#1080;&#1082;&#1086;&#1085;&#1086;&#1075;&#1088;&#1072;&#1092;&#1080;&#1103;&#1080;&#1082;&#1086;&#1085;&#1080;&#1082;&#1091;&#1093;&#1085;&#1077;&#1085;&#1089;&#1082;&#1080; &#1084;&#1072;&#1089;&#1080; Some quick methods of obtaining a midnight DateTime value for almost any date. Clear-Host # Get Midnight for current date Get-Date -Hour 0 -Minute 00 -Second 00 # Another way [datetime]::Today # Get Midnight for date a week ago (Get-Date -Hour 0 -Minute 00 -Second 00).AddDays(-7) # Or use this ([datetime]::Today).AddDays(-7) # Get [...]]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://xn--h1aafme.net/">&#1080;&#1082;&#1086;&#1085;&#1086;&#1075;&#1088;&#1072;&#1092;&#1080;&#1103;</a></font><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/ikoni">&#1080;&#1082;&#1086;&#1085;&#1080;</a></font><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://www.videnov.com/">&#1082;&#1091;&#1093;&#1085;&#1077;&#1085;&#1089;&#1082;&#1080; &#1084;&#1072;&#1089;&#1080;</a></font>
<p>Some quick methods of obtaining a midnight DateTime value for almost any date.</p>
<pre class="brush: ps">Clear-Host
# Get Midnight for current date
Get-Date -Hour 0 -Minute 00 -Second 00
# Another way
[datetime]::Today

# Get Midnight for date a week ago
(Get-Date -Hour 0 -Minute 00 -Second 00).AddDays(-7)
# Or use this
([datetime]::Today).AddDays(-7)

# Get Midnight for date a month ago
Get-Date -Month $((Get-Date -Format &quot;MM&quot;) - 1) -Hour 0 -Minute 0 -Second 0

# Get Midnight for a date one year ago
Get-Date -Year $((Get-Date -Format &quot;yyyy&quot;) - 1) -Hour 0 -Minute 0 -Second 0</pre>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.webofwood.com%2F2010%2F08%2F13%2Fget-a-midnight-datetime-value-in-powershell%2F&amp;title=Get%20a%20Midnight%20DateTime%20Value%20in%20Powershell" id="wpa2a_6"><img src="http://www.webofwood.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/08/13/get-a-midnight-datetime-value-in-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle 11g Installation Default Bites</title>
		<link>http://www.webofwood.com/2010/08/04/oracle-11g-installation-default-bites/</link>
		<comments>http://www.webofwood.com/2010/08/04/oracle-11g-installation-default-bites/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 17:58:48 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[alter]]></category>
		<category><![CDATA[default]]></category>
		<category><![CDATA[expire]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[profile]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=141</guid>
		<description><![CDATA[Beware of a new default when installing Oracle 11g! This default can raise its ugly head and bite you in the ass! It just happened to me. The default has to do with enforcing a password expiration when creating a user. I don’t know about you but we generally have applications (Oracle based as well [...]]]></description>
			<content:encoded><![CDATA[<p>Beware of a new default when installing Oracle 11g! This default can raise its ugly head and bite you in the ass! It just happened to me.</p>
<p>The default has to do with enforcing a password expiration when creating a user. I don’t know about you but we generally have applications (Oracle based as well as SQL Server) which rely on user logins specific for that application. These applications also have configurations in which you specify the user login, sometimes in several locations. Users and application managers come and go and along with them the knowledge of application configurations and where they are. Consequently, we do not change application passwords! As soon as you do, applications break and it could take hours or even days to get them working again.</p>
<p>With this in mind, you might seriously think about changing the Oracle 11g default policy as one of your steps immediately after installation. I did not change the policy as I was unaware of it. I had several user logins become disabled duet to expiring passwords. These also included SYSTEM and DBSNMP! Talk about a real PITA!</p>
<p>Here’s how you can change the password policy:</p>
<pre class="brush: sql">ALTER PROFILE DEFAULT LIMIT
    FAILED_LOGIN_ATTEMPTS 10
    PASSWORD_LIFE_TIME UNLIMITED;</pre>
<p>Oh!  And by-the-way, if the password does expire, you cannot unexpire it. You are forced to supply a new password even if it is the same as the old one. Unfortunately in my case, the application was installed by a third party and they were not sure of the password.</p>
<div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3280cbfb-6fb4-402a-93f5-8f7abfd7c71e" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">del.icio.us Tags: <a rel="tag" href="http://del.icio.us/popular/Oracle+11g+installation+user+login+default+policy+passord+expire">Oracle 11g installation user login default policy passord expire</a></div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.webofwood.com%2F2010%2F08%2F04%2Foracle-11g-installation-default-bites%2F&amp;title=Oracle%2011g%20Installation%20Default%20Bites" id="wpa2a_8"><img src="http://www.webofwood.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/08/04/oracle-11g-installation-default-bites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell Restore to New SQL Server Database</title>
		<link>http://www.webofwood.com/2010/07/30/powershell-restore-new-sql-database/</link>
		<comments>http://www.webofwood.com/2010/07/30/powershell-restore-new-sql-database/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 18:44:36 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[multiple]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[smo]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=128</guid>
		<description><![CDATA[I don’t often have to restore a database. However, while having to restore a few dozen to set up database mirroring, I came across a few with multiple database files. My first ‘mirroring’ script did not account for this. I quickly wrote a new restore script to accommodate the possibility of multiple files. &#60;# .SYNOPSIS [...]]]></description>
			<content:encoded><![CDATA[<p>I don’t often have to restore a database. However, while having to restore a few dozen to set up database mirroring, I came across a few with multiple database files. My first ‘<a title="mirror_link" href="http://www.webofwood.com/2010/07/29/powershell-sqlserver-mirroring/" target="_blank">mirroring</a>’ script did not account for this. I quickly wrote a new restore script to accommodate the possibility of multiple files.</p>
<pre class="brush: ps">&lt;#
     .SYNOPSIS
          Restore to a NEW Database
     .DESCRIPTION
          Restores an SQL Server backup file to a new database.
	   1) Uses existing Logical and physical file names and restores to the
	      SQL server default file locations.
	   2) Restores multiple files.
	   3) Can specify NoRecover (necessary for mirrored database)
     .PARAMETER  file
          Full path and file name for the backup file. Must be local
     .PARAMETER  Server
          The name\instance of the SQL Server.
     .PARAMETER  database
          The name of the database to be restored
     .EXAMPLE
          PS C:\&gt; Invoke-SqlRestore -file 'D:\Backups\mydb.bak' `
		  	-server 'MyServr\SQLinstance' -database NEWDB
     .NOTES
         AUTHOR:    John P. Wood
         CREATED:   July, 2010
         VERSION:   1.0.3
     .LINK

http://www.webofwood.com

#&gt;
Param(
	[string]$file,
	[string]$server,
	[string]$database,
	[switch]$norecovery=$true
	)
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")
Function New-SMOconnection {
    Param ([string]$server)
	$conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($server)
	$conn.applicationName = "PowerShell SMO"
	$conn.StatementTimeout = 0
	$conn.Connect()
	if ($conn.IsOpen -eq $false) {
		Throw "Could not connect to server $($server)."
	}
	$smo = New-Object Microsoft.SqlServer.Management.Smo.Server($conn)
	$smo
}
Function Get-FileName {
	Param([string]$path)
	$names = $path.Split('\\')
	$names[$names.Count - 1]
}
Function Invoke-SqlRestore {
	Param(
		[string]$backupFile,
		[Microsoft.SqlServer.Management.Smo.Server]$smo
	)
	$backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") `
		($backupFile, "File")
	# Get local paths to the Database and Log file locations
	If ($smo.Settings.DefaultFile.Length -eq 0) {$DBPath = $smo.Information.MasterDBPath }
	Else { $DBPath = $smo.Settings.DefaultFile}
	If ($smo.Settings.DefaultLog.Length -eq 0 ) {$DBLogPath = $smo.Information.MasterDBLogPath }
	Else { $DBLogPath = $smo.Settings.DefaultLog}

	# Load up the Restore object settings
	$Restore = new-object Microsoft.SqlServer.Management.Smo.Restore
	$Restore.Action = 'Database'
	$Restore.Database = $database
    $Restore.ReplaceDatabase = $true
	if ($norecovery.IsPresent) { $Restore.NoRecovery = $true }
	Else { $Restore.Norecovery = $false }
	$Restore.Devices.Add($backupDevice)

	# Get information from the backup file
	$RestoreDetails = $Restore.ReadBackupHeader($smo)
	$DataFiles = $Restore.ReadFileList($smo)

	# Restore all backup files
	ForEach ($DataRow in $DataFiles) {
        $LogicalName = $DataRow.LogicalName
        $PhysicalName = Get-FileName -path $DataRow.PhysicalName
		$RestoreData = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
		$RestoreData.LogicalFileName = $LogicalName
		if ($DataRow.Type -eq "D") {
			# Restore Data file
			$RestoreData.PhysicalFileName = $DBPath + "\" + $PhysicalName
		}
		Else {
			# Restore Log file
			$RestoreData.PhysicalFileName = $DBLogPath + "\" + $PhysicalName
		}
		[Void]$Restore.RelocateFiles.Add($RestoreData)

	}
	$Restore.SqlRestore($smo)
	# If there are two files, assume the next is a Log
	if ($RestoreDetails.Rows.Count -gt 1) {
		$Restore.Action = [Microsoft.SqlServer.Management.Smo.RestoreActionType]::Log
		$Restore.FileNumber = 2
		$Restore.SqlRestore($smo)
	}
}
Clear-Host
# Get a new connection to the server
$smo = New-SMOconnection -server $server
Write-Host "Starting restore to New Database $database on $server."
Try {
	Invoke-SqlRestore -backupFile $file -smo $smo
	}
Catch {
	$ex = $_.Exception
	Write-Output $ex.message
	$ex = $ex.InnerException
	while ($ex.InnerException) {
		Write-Output $ex.InnerException.message
		$ex = $ex.InnerException
	}
	Throw $ex
}
Finally {
	$smo.ConnectionContext.Disconnect()
}
Write-Host "Restore ended without any errors."</pre>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 159px; width: 1px; height: 1px; overflow: hidden;">
<pre class="brush: ps">	 1) Uses existing Logical and physical file names and restores to the
	    SQL server default file locations.
	 2) Restores multiple files.
	 3) Can specify NoRecover (necessary for mirrored database)
</pre>
</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.webofwood.com%2F2010%2F07%2F30%2Fpowershell-restore-new-sql-database%2F&amp;title=Powershell%20Restore%20to%20New%20SQL%20Server%20Database" id="wpa2a_10"><img src="http://www.webofwood.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/07/30/powershell-restore-new-sql-database/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

