<?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 &#187; Powershell</title>
	<atom:link href="http://www.webofwood.com/category/powershell/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, 16 Sep 2011 17:18:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<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>Woody</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>
]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2011/09/15/restore-all-sql-transaction-logs-using-powershell/feed/</wfw:commentRss>
		<slash:comments>1</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>
]]></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>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>
]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/07/30/powershell-restore-new-sql-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Powershell to Set Up SQL Server Mirroring</title>
		<link>http://www.webofwood.com/2010/07/29/powershell-sqlserver-mirroring/</link>
		<comments>http://www.webofwood.com/2010/07/29/powershell-sqlserver-mirroring/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 13:50:07 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[mirror]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=123</guid>
		<description><![CDATA[Management recently decided to use database mirroring as our DR solution. Because mirroring is done at the database level and not at the server level, I had a lot, a very lot of databases to be mirrored. To make it easier I decided to cobble together a simplistic script to do this. I typically use [...]]]></description>
			<content:encoded><![CDATA[<p>Management recently decided to use database mirroring as our DR solution. Because mirroring is done at the database level and not at the server level, I had a lot, <strong><em>a very lot</em></strong> of databases to be mirrored. To make it easier I decided to cobble together a simplistic script to do this.</p>
<p>I typically use a &#8216;management&#8217; server for most of my needs and have therefore written the script to use UNC type pathing for the primary as well as mirror server. You will also notice I defaulted several of the parameters. This is handy when working on a set of servers for multiple databases.</p>
<pre class="brush: ps">&lt;#
     .SYNOPSIS
          Set up a mirrored database
     .DESCRIPTION
          Backs up a database and tlog, copies it to the destination,
		  Restores the database on the mirror server, sets up the partner,
		  and starts the mirror.
     .PARAMETER  database
          The name of the database to be mirrored
     .PARAMETER  SourceServer
          The name of the primary server
     .PARAMETER  SourcePath
          Local Path for the backup
     .PARAMETER  DestServer
          The name of mirror server
     .PARAMETER  DestPath
          Local path for restore file
     .EXAMPLE
          PS C:\&gt; Invoke-Mirror -database 'string value' 1
		  			-SourceServer 'string\string' -SourcePath 'string' `
					-DestServer 'string\string' -DestPath 'string'
     .NOTES
          AUTHOR:    John P. Wood
          CREATED:   July, 2010
          VERSION:   1.0.5
          The SQL connections rely on Windows authentication and assumes Endpoints
          already exist. Error checking is minimal (i.e. no check is made to
          verify the recovery model is FULL).
#&gt;
Param(
	[Parameter(Mandatory=$true)]
	[string]$database,
	[string]$SourceServer='lcfsqlvs3\sqlvs3',
	[string]$SourcePath='U:\SQL Backups',
	[string]$DestServer='ldrsqlvs3\sqlvs3',
	[string]$DestPath='U:\SQL Backups'
	)
Set-StrictMode -Version 2
[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 Get-FileName {
	Param([string]$path)
	$names = $path.Split('\\')
	$names[$names.Count - 1]
}
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) for database backup of $($dbname)."
	}
	$smo = New-Object Microsoft.SqlServer.Management.Smo.Server($conn)
	$smo
}
Function Invoke-SqlBackup {
	$dbbk = new-object ('Microsoft.SqlServer.Management.Smo.Backup')
	$dbbk.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database
	$dbbk.BackupSetDescription = "Full backup of " + $database
	$dbbk.BackupSetName = $database + " Backup"
	$dbbk.Database = $database
	$dbbk.MediaDescription = "Disk"
	$device = "$SourcePath\$bkpfile"
	$dbbk.Devices.AddDevice($device, 'File')
	$smo = New-SMOconnection -server $SourceServer
	Try {
		$dbbk.SqlBackup($smo)
		$dbbk.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Log
		$dbbk.SqlBackup($smo)
		$smo.ConnectionContext.Disconnect()
	}
	Catch {
		$ex = $_.Exception
		Write-Output $ex.message
		$ex = $ex.InnerException
		while ($ex.InnerException)
		{
			Write-Output $ex.InnerException.message
			$ex = $ex.InnerException
		};
		continue
	}
	Finally {
		if ($smo.ConnectionContext.IsOpen -eq $true) {
			$smo.ConnectionContext.Disconnect()
		}
	}
}
Function Invoke-SqlRestore {
	Param(
		[string]$filename
	)
	# Get a new connection to the server
    $smo = New-SMOconnection -server $DestServer
    $backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($filename, "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
    $Restore.NoRecovery = $true
	$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)

	}
	Try {
	$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)
	}
		$smo.ConnectionContext.Disconnect()
	}
	Catch {
		$ex = $_.Exception
		Write-Output $ex.message
		$ex = $ex.InnerException
		while ($ex.InnerException)
		{
			Write-Output $ex.InnerException.message
			$ex = $ex.InnerException
		};
		continue
	}
	Finally {
		if ($smo.ConnectionContext.IsOpen -eq $true) {
			$smo.ConnectionContext.Disconnect()
		}
	}
}
Function Set-Mirror {
	Param([string]$server,[string]$database,[string]$partner)
	$conn = "Server=$server; Integrated Security=SSPI; Database=Master"
	$cn = New-Object "System.Data.SqlClient.SqlConnection" $conn
	$cn.Open()
	$cmd = New-Object "System.Data.SqlClient.SqlCommand"
	$cmd.CommandType = [System.Data.CommandType]::Text

	$cmd.CommandText = "ALTER DATABASE $database SET PARTNER = 'TCP://" + $partner + ":5022'"
	$cmd.Connection = $cn
	$cmd.ExecuteNonQuery()
	$cn.Close()
	Trap {
		$ex = $_.Exception
		Write-Output $ex.message
		$ex = $ex.InnerException
		while ($ex.InnerException)
		{
			Write-Output $ex.InnerException.message
			$ex = $ex.InnerException
		};
		continue
	}
}
$srcUNC = Join-Path "\\$($SourceServer.Split('\\')[0])" $($SourcePath.Replace(':','$'))
if (-not(Test-Path $srcUNC)) { New-Item $srcUNC -ItemType directory | Out-Null}
$destUNC = Join-Path "\\$($DestServer.Split('\\')[0])" $($DestPath.Replace(':','$'))
if (-not(Test-Path $destUNC)) { New-Item $destUNC -ItemType directory | Out-Null}
$bkpfile = $($SourceServer.Replace("\", "$")) + "_" + $database + "_FULL_" + $(get-date -format yyyyMMdd-HHmmss) + ".bak"
Invoke-SqlBackup
Copy-Item $(Join-Path $srcUNC $bkpfile) -Destination $destUNC -Verbose
Invoke-SqlRestore -filename $bkpfile
# Establish Mirroring from the mirrored database
Set-Mirror -server $DestServer -database $database -partner $($SourceServer.Split('\\')[0])
# Start the mirror
Set-Mirror -server $SourceServer -database $database -partner $($DestServer.Split('\\')[0])</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/07/29/powershell-sqlserver-mirroring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous Processing using Powershell Jobs</title>
		<link>http://www.webofwood.com/2010/03/17/asynchronous-powershell-jobs/</link>
		<comments>http://www.webofwood.com/2010/03/17/asynchronous-powershell-jobs/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 14:48:57 +0000</pubDate>
		<dc:creator>John Wood</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.webofwood.com/?p=116</guid>
		<description><![CDATA[Powershell is a fantastic tool to use for management of multiple computers. I have been slowly converting many of our administrative functions from a hodge-podge mixture of CMD, BAT, VPS, Python, and Perl scripts. One daily administrative talks is copying a variety of backups from a variety of Windows servers to our data ’warehouse’ where [...]]]></description>
			<content:encoded><![CDATA[<p>Powershell is a fantastic tool to use for management of multiple computers. I have been slowly converting many of our administrative functions from a hodge-podge mixture of CMD, BAT, VPS, Python, and Perl scripts. One daily administrative talks is copying a variety of backups from a variety of Windows servers to our data ’warehouse’ where they are then copied to tape.</p>
<p>I recently found the “Jobs” cmdlets in Powershell V2.0. With “Jobs” you can asynchronously process multiple tasks (e.g. copying backups from many remote machines to data storage on the current local machine). In my case, running the copies synchronously results in the process spanning over to the next morning. Backups are stored daily. If a backup is taken on Wednesday, I can’t have it being stored in our warehouse under Thursday.</p>
<p><span id="more-116"></span></p>
<p>Using Powershell “Jobs”, I can accommodate copying all the backups within the daily timeframe. However, I did wrestle with using “Jobs” at first. Mainly because I couldn’t see what happened with a JOB on my console! The trick is to make sure you issue a Receive-Job cmdlet after a JOB has finished.</p>
<h3>Here a a couple of examples to try:</h3>
<p><span style="font-size: xx-small;">These example assume you are running Powershell V2.0 and you have enabled remoting on the machine your running this. Remoting does not have to be enabled on the remote servers but must be enabled on your local machine.</span></p>
<h5>Begin with a simple copy you know works.</h5>
<pre class="brush: ps"># Copies a directory and all files and sub-directories, I would
# suggest using something small to quickly see results
$source = "\\RemoteServer\d$\Backups # your remote path
$target = "W:\WoodyzTest"            # your local path
Copy-Item -Path $source -Destination $target -Recurse Verbose</pre>
<h5>Next, we’ll take the Copy-Item and put it in a Start-Job</h5>
<pre class="brush: ps">$source = "\\RemoteServer\d$\Backups # your remote path
$target = "W:\WoodyzTest"            # your local path
$job Start-Job -Scriptblock {
Copy-Item -Path $source -Destination $target -Recurse -Verbose
}
Wait-Job $job  # For this test, we’ll wait for the job to complete</pre>
<p>Run the above script, look at what is returned in the console, and then check to see of the copy worked.</p>
<p>Surprise! The directory was not copied! What happened? I have no idea because I did not see anything in the console. There were no error messages!</p>
<h5>OK, let’s now add a Receive-Job</h5>
<pre class="brush: ps">$source = "\\RemoteServer\d$\Backups # your remote path
$target = "W:\WoodyzTest"            # your local path
$job Start-Job -Scriptblock {Copy-Item -Path $source -Destination $target -Recurse -Verbose }
Wait-Job $job  # For this test, we’ll wait for the job to complete
Receive-Job $job  # will now display any results from the job</pre>
<p>Now what do you see on the console? We have yet another surprise! The console shows we have an error in our Copy-Item. But why? It worked before when we ran it outside of a JOB.</p>
<p>I took a SWAG at it and decided to try enclosing the entire original script inside the JOB Scriptblock:</p>
<h5>Here is the entire, final, working script:</h5>
<pre class="brush: ps">$job = Start-Job -ScriptBlock {
    $source = "\\Lcfltr01\d$\SQL Backups\lcfltr01"
    $target = "W:\WoodyzTest"
    Copy-Item -Path $source -Destination $target -Recurse -Verbose
}
Wait-Job $job
Receive-Job $job</pre>
<p>I have not read up on it yet, but deductive reasoning implies: because the JOB creates a new background process, the local variables are not available to the newly created thread. Makes sense to me.</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.webofwood.com/2010/03/17/asynchronous-powershell-jobs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

