DBPedias

Your Database Knowledge Community

Kendal Van Dyke

  1. SQL Power Doc Update - Version 1.0.1.0

    A quick note to let you know that SQL Power Doc version 1.0.1.0 is now live. This release fixes issues reported since version 1.0, adds 11 new assessment checks, and improves error handling in multiple places. The nitty-gritty details of what's changed are available in the changelog.

    You can grab the latest version from the CodePlex project page. If you find it useful please do consider giving it a rating and\or review. And of course if you run into any problems post a description on the discussions page and I'll be happy to help troubleshoot.

  2. Discover, Diagnose, and Document ALL Your SQL Servers On Your Coffee Break

    We all know that we should document our SQL Servers, right? RIGHT?

    So let's say you had some time on your hands and decided that today's the day you're going to get it done. You might open SSMS, connect to a server in Object explorer, start clicking around, and copying properties into an Excel spreadsheet. That gets old quick, so you write TSQL to grab information...until you realize that you're going deep down the rabbit hole accounting for all the nuances and new features between versions of SQL Server. If you're adventurous you might crack open your IDE of choice and dig into SMO, but that's another rabbit hole of a different kind, too. Frustrated, you give in and download a trial version of a commercial documentation tool. It works pretty well, except it's taking forever to manually go through every database on every server. A couple hours later you've got a handful of databases documented...but what about server configurations or  details about the Windows OS they're installed on? How do you compare server configurations against each other? Or spot potential configuration problems? And what about those servers you just inherited - or don't even know are out there yet?

    Wow, you think to yourself as you head home, this could be someone's full time job just keeping track of all this stuff!

    There Is a Better Way: Introducing SQL Power Doc

    Starting today, there is a better way. I'm proud to officially announce the release of SQL Power Doc.

    Imagine combining the functionality of what Quest's Discovery Wizard for SQL Server, your favorite commercial SQL documentation tool, msinfo32.exe, and Brent Ozar Unlimited's sp_Blitz™ script does into a single standalone tool that you can run against all of your SQL servers at once. That's SQL Power Doc.

    Here's a look at what SQL Power Doc does:

    Discover

    Find SQL Server Services on your network by:

    • Active Directory DNS
    • Subnet Scan
    • Computer Name
    Document

    Collect comprehensive details about all your SQL Server instances and their underlying Windows OS, including:

    • Service Details For All Installed SQL Sever Services
    • Database Engine
      • Configuration
      • Security
      • Server Objects
      • Databases
        • Configuration
        • Database Objects
        • Service Broker
        • Storage
        • Security
    • SQL Agent
      • Configuration
      • Jobs
      • Alerts
      • Operators
    • Windows OS
      • Machine Information
      • OS Information
      • Software 
    Diagnose

    SQL Power Doc performs over 100 checks to find hidden problems and performance bottlenecks on your SQL Servers before they turn into major headaches.

    SQL Power Doc does all of this using Windows PowerShell and Microsoft Excel. Never touched PowerShell before? Don't worry, I've written a How To Guide for PowerShell Beginners to walk you through every step of the way.

    While you're on your coffee break you can put SQL Power Doc to work for you to generate comprehensive, top to bottom documentation of your entire SQL Server environment. This documentation is useful for:

    • Baselines - know what your SQL Server environment looked like last week, last month, etc.
    • Security Audits
    • Licensing Audits
    • Provide a complete look at how your servers are configured without having to grant access
    • Troubleshooting
    • Comparing servers and databases
    • Creating a runbook that you can give to your operations team
    • Planning upgrades - see what hidden features are in use on an instance

    One More Thing...

    SQL Power Doc isn't limited to just SQL Server - you can also use it to collect an inventory of all the Windows machines on your network. If your IT department is looking for a way to document their Windows machines do them a favor and tell them about SQL Power Doc.

    Ready To Get Started?

    Now that you know there's a tool that can do the work for you there's no excuse not to document your servers. Head on over to the SQL Power Doc CodePlex site, check out the Requirements and How To Guide, then grab the code to discover, document, and diagnose your SQL Servers today!

  3. T-SQL Tuesday #41 - Presenting Opens Doors

    This blog post is part of T-SQL Tuesday, a monthly SQL blog party with a rotating host and common topic. This month marks #41, hosted by Bob Pusateri (@SQLBob), and the theme is how I came to love presenting.

    Presenting Changed My Life

    My story starts in early 2006; I had moved to Orlando to work for a small E-commerce company as a Sr. Production DBA, but I was the DBA's equivalent of the ghost who codes. While I had a nice resume there really wasn't much associated with my name and SQL server that I could show off to people. When I had a problem I searched for the answer on Google. I didn't follow anyone's blog or know any of the big names in the SQL Server world. I had no idea was PASS was all about or that the concept of a user group even existed. As I write this I laugh because I'm reminded that I even searched for logins to SQLServerCentral on BugMeNot because I wanted to remain anonymous.

    A coworker of mine at the time told me that a friend of his was looking for people to present to a local group of database people. It sounded like an interesting way to meet other people around town who worked with SQL Server so I accepted and agreed to talk about the new XML features in SQL 2005. A month later I made the one hour trek across town to present to 15 people and as much as I'd like to remember that it was an overwhelming success it was anything but. I rambled. I had 3 slides and spent the rest of the time showing code in SSMS. I went at least 20 minutes over time. I know I lost a few people along the way and probably gave a few wrong answers to questions. By all accounts it was a terrible presentation.

    But I survived.

    The next day I received an email from the user group leader - one Andy Warren (@sqlandy) - with constructive suggestions on how to improve and an invitation to give the presentation again at this newfangled concept he called SQLSaturday. I accepted, took the suggestions to heart, and felt like a million bucks after I gave a much improved presentation to a full room at SQLSaturday #1. It was a great feeling, so I did it again...and again...and started to find new things to present about. I began attending OPASS and reading blogs (and started this blog, too). I kept at it, and in 2009 I was selected to present a session at the PASS Summit, an honor I had every year until 2012 when I attended the Summit in a different capacity - as a PASS Board member and Director of the SQLSaturday portfolio.

    It's been quite a journey, to say the least! Along the way I've learned a metric ton (that's the technical term) about SQL Server and I've met incredible people, many of whom I have become good friends with. What a difference between the 2006 me and who I've become now - in large part because of presenting.

    You Never Know Who You Will Influence

    It wasn't obvious to me at first but I've come to the realize that one of the most rewarding things about presenting is that you have the opportunity to open doors for people, if ever so slightly. I doubt Kevin Kline had any idea who I was when I sat in a session he gave in Tampa many years ago, or who that guy named Jonathan Kehayias (@SQLPoolBoy) a few seats over from me was. I certainly had no idea who Jonathan was when I gave my XML presentation at SQLSaturday, and it's fun to think now that I was the one who first introduced him to XML-DML in SQL Server.

    My point is that you never know if the next great blogger, user group leader, or eventual PASS President is someone you encouraged to give their presentation or someone who attended your session and walked away motivated to do more because of it. It doesn't matter if you're just getting started or you're a veteran speaker - by presenting you're helping yourself and others at the same time. I'll call that a win any day!

    Your Turn

    If you've ever considered giving a presentation but something's holding you back, consider this a challenge to get over it and submit. There are plenty of PASS chapters who will be happy to put you on their schedule and there's no shortage of SQLSaturdays these days either. Both are great places to start and there are plenty of people in the SQL community who can help you prepare in advance.

    I promise, it won't be too painful - but be careful, because you might just walk away wanting to do it again!

  4. T-SQL Tuesday #39 - Use PowerShell To Copy A Database To Another Instance

    This blog post is part of T-SQL Tuesday, a monthly SQL blog party with a rotating host and common topic. This month marks #39, hosted by Wayne Sheffield (@DBAWayne), and the theme is "Can You Shell What The PoSh Is Cooking?"

    For many years I made learning PowerShell a goal and for many years the best I could do was use the PowerShell console as a replacement for the command prompt. Like most DBAs I figured out how get by with T-SQL and multi-server queries...and then I started a side project using PowerShell that didn't involve SQL Server (yet) and it was time to sink or swim. I'm happy to say a year and a half later I swam, and now PowerShell has become such an essential core skill for me that I'm kicking myself for not having learned it sooner!

    On that note, Wayne has started an excellent month-long series on PowerShell that even seasoned script writers should check out. Open a console, start at the series landing page, and get scripting!

    For today's post I'm going to share a script I wrote which uses Server Management Objects (SMO) to copy a database from one instance to another via backup and restore. This works against all versions and editions of SQL Server starting with SQL 2000.

    If you've got Management Studio installed then you've already got SMO. If you want to run this script on a machine that doesn't have SMO you can download it as part of the SQL 2012 Feature Pack.

    The script is below. Copy and paste the contents into your favorite editor and save the file as Copy-SqlServerDatabase.ps1. If copy and paste isn't your thing you can download the script - but make sure to unblock the file in Windows Explorer before extracting or you'll run into problems when you try to run it.

    Finally, make sure your Execution Policy is set to RemoteSigned before trying to run this script (and I'm hoping Wayne blogs about that in his series!).

     

    <#
    .SYNOPSIS
    Copies a SQL Server DB from a source instance to a target instance via backup & restore, optionally renaming the DB at the target
    
    .DESCRIPTION
    This script uses SQL Server Management Objects (SMO) to copy a SQL Server database from one instance to another, optionally renaming the database at the target instance.
    
    SQL Server Native backup & restore operations are used to write a backup to a file and restore it to the target instance.
    
    Once restored to the target instance, the database owner is changed to SA and the compatibility level adjusted to match the target instance's model database.
    
    NOTE: This script does NOT delete the backup file that it creates. If you no longer need the file you must delete it manually.
    
    .PARAMETER SourceInstance
    The source instance containing the database you want to copy
    
    .PARAMETER SourceDatabase
    The name of the database that you want to copy
    
    .PARAMETER TargetInstance
    The target instance that you want to copy the database to
    
    .PARAMETER TargetDatabase
    The new name for the database at the target SQL Server instance. If omitted, the database will retain the same name as on the source instance
    
    .PARAMETER BackupDirectoryPath
    The intermediate location where the backup file will be written. This should be accessible by both the source and target instances
    
    .PARAMETER Username
    Username to use when connecting to the source and target instances with a SQL login. If omitted, Windows Authentication is used.
    
    .PARAMETER Password
    Password to use when connecting to the source and target instances with a SQL login. If omitted, Windows Authentication is used.
    
    .PARAMETER Force
    Force overwriting the database at the target server if a database with the same name already exists
    
    .EXAMPLE
       .\Copy-SqlServerDatabase.ps1 -SourceInstance Server1 -SourceDatabase AdventureWorks -TargetInstance Server2 -BackupDirectoryPath \\Server3\Backups
    
    .EXAMPLE
       .\Copy-SqlServerDatabase.ps1 -SourceInstance Server1 -SourceDatabase AdventureWorks -TargetInstance Server2 -TargetDatabase AdventureWerkz -BackupDirectoryPath \\Server3\Backups -Force
    
    .EXAMPLE
       .\Copy-SqlServerDatabase.ps1 -SourceInstance Server1 -SourceDatabase AdventureWorks -TargetInstance Server2 -TargetDatabase AdventureWerkz -BackupDirectoryPath \\Server3\Backups -Username sa -Password N0tBl@nk!
    
    .EXAMPLE
       .\Copy-SqlServerDatabase.ps1 -SourceInstance Server1,3143 -SourceDatabase AdventureWorks -TargetInstance Server2,4133 -TargetDatabase AdventureWerkz -BackupDirectoryPath \\Server3\Backups
    #>
    [cmdletBinding(DefaultParametersetName='WindowsAuthentication')]
    param(
        [Parameter(Mandatory=$true, ParameterSetName = 'WindowsAuthentication')]
        [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]
        [ValidateNotNullOrEmpty()]
        [alias('Source', 'Src')]
        [System.String]
    $SourceInstance
    ,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [alias('SourceDb', 'SrcDb', 'Database')]
        [System.String]
    $SourceDatabase
    ,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [alias('Target', 'Tgt')]
        [System.String]
    $TargetInstance
    ,
        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [alias('TargetDb', 'TgtDb', 'RenameAs')]
        [System.String]
    $TargetDatabase = $SourceDatabase
    ,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [alias('Path')]
        [System.String]
    $BackupDirectoryPath
    ,
        [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]
        [ValidateNotNull()]
        [System.String]
    $Username
    ,
        [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]
        [ValidateNotNull()]
        [System.String]
    $Password
    ,
        [Parameter(Mandatory=$false)]
        [Switch]
    $Force = $false
    )
    
    # Load SMO assembly, and if we're running SQL 2008 DLLs or higher load the SMOExtended and SQLWMIManagement libraries
    # SMO Major Versions
    # 9    :    SQL 2005
    # 10:    SQL 2008 & 2008 R2 
    # 11:    SQL 2012
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | ForEach-Object {
    $SmoMajorVersion = $_.GetName().Version.Major
    if ($SmoMajorVersion -ge 10) {
            [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMOExtended') | Out-Null
            [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SQLWMIManagement') | Out-Null
        }
    }
    
    
    ######################
    # CONSTANTS
    ######################
    
    # SQL Versions
    # See http://social.technet.microsoft.com/wiki/contents/articles/783.sql-server-versions.aspx for version timeline
    # Also see http://support.microsoft.com/kb/321185
    # Also see http://sqlserverbuilds.blogspot.com/
    
    New-Object -TypeName System.Version -ArgumentList '8.0.0.0' | New-Variable -Name SQLServer2000 -Scope Script -Option Constant
    New-Object -TypeName System.Version -ArgumentList '9.0.0.0' | New-Variable -Name SQLServer2005 -Scope Script -Option Constant
    New-Object -TypeName System.Version -ArgumentList '10.0.0.0' | New-Variable -Name SQLServer2008 -Scope Script -Option Constant
    New-Object -TypeName System.Version -ArgumentList '10.50.0.0' | New-Variable -Name SQLServer2008R2 -Scope Script -Option Constant
    New-Object -TypeName System.Version -ArgumentList '11.0.0.0' | New-Variable -Name SQLServer2012 -Scope Script -Option Constant
    
    
    ######################
    # FUNCTIONS
    ######################
    
    function Get-SqlConnection {
        [CmdletBinding()]
        [OutputType([System.Data.SqlClient.SqlConnection])]
    param(
            [Parameter(Mandatory=$false)]
            [ValidateNotNullOrEmpty()]
            [System.String]
    $Instance = '(local)'
    ,
            [Parameter(Mandatory=$false)]
            [ValidateNotNullOrEmpty()]
            [System.String]
    $Database = 'master'
    ,
            [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]
            [ValidateNotNull()]
            [System.String]
    $Username
    ,
            [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]
            [ValidateNotNull()]
            [System.String]
    $Password
    ,
            [Parameter(Mandatory=$true, ParameterSetName = 'WindowsAuthentication')]
            [ValidateNotNull()]
            [alias('WindowsAuth','IntegratedAuth')]
            [switch]
    $WindowsAuthentication
    ,
            [Parameter(Mandatory=$false)]
            [System.String]
    $FailoverPartner = $null
    ,
            [Parameter(Mandatory=$false)]
            [System.String]
    $ApplicationName = 'Windows PowerShell' # $MyInvocation.ScriptName    
        )
    try {
    
    # ConnectionStringBuilder docs: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.aspx
            # http://www.connectionstrings.com/Articles/Show/all-sql-server-connection-string-keywords
    
    $SQLConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection
    $SQLConnectionBuilder = New-Object -TypeName system.Data.SqlClient.SqlConnectionStringBuilder
    
    $SQLConnectionBuilder.psBase.DataSource = $Instance
    $SQLConnectionBuilder.psBase.InitialCatalog = $Database
    
    if ($PSCmdlet.ParameterSetName -eq 'SQLAuthentication') {
    $SQLConnectionBuilder.psBase.IntegratedSecurity = $false
    $SQLConnectionBuilder.psBase.UserID = $Username
    $SQLConnectionBuilder.psBase.Password = $Password
            } else {
    $SQLConnectionBuilder.psBase.IntegratedSecurity = $true
            }
    
    $SQLConnectionBuilder.psBase.FailoverPartner = $FailoverPartner
    $SQLConnectionBuilder.psBase.ApplicationName = $ApplicationName
    
    $SQLConnection.ConnectionString = $SQLConnectionBuilder.ConnectionString
    
    Write-Output $SQLConnection
    
        }
    catch {
    Throw
        }
    }
    
    ######################
    # VARIABLES
    ######################
    $SourceConnection = $null
    $SourceServer = $null
    $TargetConnection = $null
    $TargetServer = $null
    $TargetDbExists = $false
    $SaLogin = 'sa'
    
    $FileDeviceType = [Microsoft.SqlServer.Management.Smo.DeviceType]::File
    
    $TargetDataPath = [String]::Empty
    $TargetLogPath = [String]::Empty
    $PhysicalName = [String]::Empty
    
    $Backup = $null
    $Restore = $null
    $RelocateFile = $null
    
    
    ######################
    # BEGIN SCRIPT
    ######################
    
    try {
    
    # Open a connection to the target server and check if the target database already exists
        if ($PSCmdlet.ParameterSetName -eq 'SQLAuthentication') {
    $TargetConnection = Get-SqlConnection -Instance $TargetInstance -Username $Username -Password $Password
        } else {
    $TargetConnection = Get-SqlConnection -Instance $TargetInstance -WindowsAuthentication
        }
    $TargetServer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $TargetConnection
    $TargetServer.ConnectionContext.Connect()
    
    $TargetServer.Databases | Where-Object { $_.Name -ieq $TargetDatabase } | ForEach-Object {
    $TargetDbExists = $true
        }
    
    # If the target database already exists and -Force was not specified throw an error
        if ($TargetDbExists -and -not $Force) {
    throw "Database '$TargetDatabase' exists on target instance $TargetInstance; Rerun script and specify -Force to overwrite the existing database"
        }
    
    
    # Open a connection to the source server and kick off a full, copy-only backup to the backup path
        if ($PSCmdlet.ParameterSetName -eq 'SQLAuthentication') {
    $SourceConnection = Get-SqlConnection -Instance $SourceInstance -Username $Username -Password $Password
        } else {
    $SourceConnection = Get-SqlConnection -Instance $SourceInstance -WindowsAuthentication
        }
    $SourceServer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $SourceConnection
    $SourceServer.ConnectionContext.Connect()
    
    # Setup the backup
        $Backup = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Backup
    $Backup.Action = 'Database'
    $Backup.BackupSetName = "$SourceDatabase FULL Backup"
    $Backup.BackupSetDescription = 'FULL backup of $SourceDatabase for RemitPlus upgrade'
    $Backup.Database = $SourceDatabase
    $Backup.Incremental = $false
    
    # COPYONLY supported by SQL 2005+ and SMO 2008
        if ((($SourceServer.Information.Version).CompareTo($SQLServer2005) -ge 0) -and ($SmoMajorVersion -ge 10)) {
    $Backup.CopyOnly = $true
        }
    
    # Compression supported by:
        #    - SQL 2008 enterprise edition
        #     - SQL 2008 R2 standard edition and higher
        if (
    $( $SourceServer.Information.Version).CompareTo($SQLServer2008R2) -ge 0 -or
            (
    $( $SourceServer.Information.Version).CompareTo($SQLServer2008) -ge 0 -and
    $SourceServer.Information.Edition -ilike '*enterprise*'
            )
        )
        {
    $Backup.CompressionOption = 'on' 
        }
    
    # Build backup filename
        # Note: I'm not accounting for invalid characters here. I'm assuming this won't be an issue for this iteration!
        $BackupFileName = [String]::Join('_', @($SourceServer.Name.Replace('\','_'), $SourceDatabase, 'FULL', [System.DateTime]::Now.ToString('yyyy_MM_dd_HH_mm')))
    $BackupFileName = [System.IO.Path]::ChangeExtension($BackupFileName, 'bak')
    $BackupPath = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($BackupDirectoryPath, $BackupFileName))
    
    $BackupDevice = New-Object -TypeName Microsoft.SqlServer.Management.Smo.BackupDeviceItem -ArgumentList $BackupPath, $FileDeviceType
    $Backup.Devices.Add($BackupDevice)
    
    # Do the backup
        $Backup.SqlBackup($SourceServer)
    
    # Cleanup
        $Backup.Devices.Remove($BackupDevice) | Out-Null
    $Backup = $null
    $SourceServer.ConnectionContext.Disconnect()
    
    
    
    # Get the path to the data and log file directories on the target server
    
    # Get the default data and log file path on the target server
        $TargetDataPath = if (($TargetServer.Settings.DefaultFile).Length -gt 0) { $TargetServer.Settings.DefaultFile } else { $TargetServer.Information.MasterDBPath }
    $TargetLogPath = if (($TargetServer.Settings.DefaultLog).Length -gt 0) { $TargetServer.Settings.DefaultLog } else { $TargetServer.Information.MasterDBPath }
    
    
    # Setup the restore
        $Restore = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Restore
    $Restore.Action = 'Database'
    $Restore.Database = $TargetDatabase
    $Restore.NoRecovery = $false
    $Restore.Devices.Add($BackupDevice)
    
    # Iterate through files in backup and set up a new physical path for each
        $Restore.ReadFileList($TargetServer).Rows | ForEach-Object {
    $RelocateFile = New-Object -TypeName Microsoft.SqlServer.Management.Smo.RelocateFile
    $RelocateFile.LogicalFileName = $_.LogicalName
    
    $PhysicalName = [System.IO.Path]::GetFileName($_.PhysicalName)
    #$PhysicalName = [System.IO.Path]::GetFileNameWithoutExtension($_.PhysicalName) + '_TEST' + [System.IO.Path]::GetExtension($_.PhysicalName)
    
    # Set new physical path depending on file type
            if ($_.Type -ieq 'L') {
    $RelocateFile.PhysicalFileName = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($TargetLogPath, $PhysicalName))
            } else {
    $RelocateFile.PhysicalFileName = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($TargetDataPath, $PhysicalName))
            }
    
    $Restore.RelocateFiles.Add($RelocateFile) | Out-Null
        }
    
    # Do the restore
        $Restore.SqlRestore($TargetServer)
    
    # Cleanup
        $Restore.Devices.Remove($BackupDevice) | Out-Null
    $Restore = $null
    
    
    # Get the SA login for the target instance (fallback is 'sa')
        $TargetServer.Logins | Where-Object { [System.BitConverter]::ToString($_.Sid) -eq [System.BitConverter]::ToString(0x01) } | ForEach-Object { $SaLogin = $_.Name }
    
    # Have SMO update the list of databases
        $TargetServer.Databases.Refresh()
    
    # Change DB Owner to SA and compatibility level to match target server's model DB compatibility level
        $TargetServer.Databases.Item($TargetDatabase) | ForEach-Object {
    $_.SetOwner($SaLogin)
    $_.CompatibilityLevel = $TargetServer.Databases['model'].CompatibilityLevel
    $_.Alter()
        }
    
    $TargetServer.ConnectionContext.Disconnect()
    }
    catch {
    # Get the lowest level error and throw it
        $ThisException = $_.Exception
    while ($ThisException.InnerException) {
    $ThisException = $ThisException.InnerException
        }
    throw $ThisException
    }
    finally {
    # Close any open connections
        If ($TargetServer.ConnectionContext.IsOpen) { $TargetServer.ConnectionContext.Disconnect() } 
    If ($SourceServer.ConnectionContext.IsOpen) { $SourceServer.ConnectionContext.Disconnect() } 
    }
    
    Remove-Variable -Name SourceConnection, SourceServer, TargetConnection, TargetServer, FileDeviceType, BackupFileName, `
    BackupPath, TargetDataPath, TargetLogPath, Backup, Restore, RelocateFile, PhysicalName, SmoMajorVersion, TargetDbExists, SaLogin
    
  5. Transactional Replication Toolbox Scripts: Show Articles And Columns For All Publications

    During the last few years I've worked extensively with transactional replication and have written a handful of scripts that have found a permanent home in my "useful scripts" toolbox. I've provided these scripts as downloads whenever I've presented about replication...but not everyone who has worked with replication has been to one of my presentations (or had access to the downloads afterwards) so I'm posting them here.

    The first script in my toolbox shows all of the articles and columns in each article for all transactional publications in a published database. It's pretty straightforward - just execute the script in the published database on the publisher. Note that because it uses the FOR XML PATH directive it must be run on SQL 2005 or higher.

    Here's the script:

    /*********************************************************************************************
    Transactional Replication Toolbox: Show Articles and Columns for All Publications

    Description:
       Shows articles and columns for each article for all transactional publications

       (C) 2013, Kendal Van Dyke (mailto:kendal.vandyke@gmail.com)

    Version History:
       v1.00 (2013-01-29)

    License:
       This query is free to download and use for personal, educational, and internal
       corporate purposes, provided that this header is preserved. Redistribution or sale
       of this query, in whole or in part, is prohibited without the author's express
       written consent.

    Note:
       Execute this query in the published database on the PUBLISHER

       Because this query uses FOR XML PATH('') it requires SQL 2005 or higher
      
    *********************************************************************************************/

    SELECT
      
    syspublications.name AS "Publication",
       sysarticles.name
    AS "Article",
      
    STUFF(
           (
              
    SELECT ', ' + syscolumns.name AS [text()]
              
    FROM sysarticlecolumns WITH (NOLOCK)
                  
    INNER JOIN syscolumns WITH (NOLOCK) ON sysarticlecolumns.colid = syscolumns.colorder
              
    WHERE sysarticlecolumns.artid = sysarticles.artid
                  
    AND sysarticles.objid = syscolumns.id
              
    ORDER BY syscolumns.colorder
              
    FOR XML PATH('')
           ),
    1, 2, ''
      
    ) AS "Columns" FROM syspublications WITH (NOLOCK)
      
    INNER JOIN sysarticles WITH (NOLOCK) ON syspublications.pubid = sysarticles.pubid
    ORDER BY syspublications.name, sysarticles.name

  6. T-SQL Tuesday #36 - SQL Community (Guest Post)

    tsql2sdayThis blog post is part of T-SQL Tuesday, a monthly SQL blog party with a rotating host and common topic. This month marks #36, hosted by Chris Yates (@YatesSQL), and the theme is "SQL Community". This post is not mine, but the handiwork of Andy Levy (@ALevyInROC), a first timer at the 2012 PASS Summit. Andy doesn't have a blog yet, but was compelled by the topic so I offered to let him post on my blog as a guest. Hopefully this won't be his only post and we'll see his own blog up and running soon!

    I'm very new to the SQL Community and still finding my way around. I had been exposed to it a little through SQL Saturday #129 and several MVPs I've spoken with over the past 18 months or so, but my first real exposure to the community was last week at PASS Summit 2012. I was completely blown away.
    I arrived not knowing anyone, and feeling a bit overwhelmed by the sheer enormity of the event. 3900+ people. Sessions & events (official & unofficial) stacked from pre-dawn until midnight or later. Tweets flying by at a ridiculous pace. But after a couple hours, I finally came to a realization: These are my people. We're all here for similar reasons, but we don't have to have serious technical discussions all the time. In fact, in a lot of cases it's better that we don't. We can talk about topics at a high level, then redirect for more detail - "go read so-and-so's blog, he had a real good post last month about that" or even skip technical discussion entirely - "I had that particular experience, but now I need something different, and really want to move more toward doing this other thing." We don't have to get into details if we don't want to.

    I met one woman near the Community Zone on Wednesday who told me that I should come speak at her user group - not 10 minutes after we  met for the first time. But I don't have anything to present. No worries, she says - surely I can come up with something. The following day, a discussion about SQLite came up, and Brian Davis pointed me at a blog post he wrote last year about working with SQLite from within SSMS. This got me started on about a half-dozen ideas for ways I could use data that I already had, ideas that were relevant to another hobby I engage in, which eventually I could turn into a presentation for a user group. Wow! I stumbled into a topic for a presentation - and the very notion of speaking at a user group - thanks to two brief conversations with members of the SQL Community. I had previously tried blogging and failed due to a lack of material. Now I see that I have my own ideas & insights into topics discussed by others that I can contribute back to the community, so I'm thinking about starting up again.

    There's a recurring theme of "everyone in this room can learn at least one valuable thing from someone else in the room" that I've heard for quite a while, both in conversations and presentations, and now that I've experienced it firsthand (both as a learner and a teacher), I see just how true and valuable it is. It's very karmic - today I may get help from someone via twitter, and tomorrow I may be able to help someone else out the same way. There's no competition, it's incredibly collaborative & supportive. There's a tremendous feedback cycle - someone writes a blog post, someone takes the idea & make some adjustments to it or takes it to the next logical step, and then the original author integrates that feedback - or someone else can pick it up and run with it.

    SQL Server & our general job roles may be the reason why we congregate at Summit, SQL Saturdays & user groups, but it's not what brings us together. What brings us together is the conversations we have on the side, sharing not just technical expertise but life and career knowledge & insights. The passion for the community is infectious - I've already asked my local chapter president how I can get involved with planning the local SQL Saturday in 2013, because I want other people to experience what I've experienced from this community in a very short time already.

    Note from Kendal: Did you like Andy's post? Follow him on Twitter and encourage him to keep it up!

  7. 2012 PASS Elections Letter Of Recommendation From Ed Watson

    I'm a candidate in the 2012 PASS Board of Directors elections and believe that an important part of what makes a good candidate is support from the community that they wish to represent. During the last 5 years I have connected with people in PASS community from chapter members to speakers and from SQLSaturday volunteers to Directors. I've been fortunate this year to receive several letters of recommendation in support of my desire to continue serving on the Board. In this post I'm sharing the letter I received from Ed Watson (Blog | Twitter).

    I met Ed for the first time at SQLSaturday  #110 in Tampa earlier this year and again at the Tampa Bay SQL User Group in March. Ed is the perfect embodiment of someone who jumped straight into the deep end of the PASS community - he regularly attends chapter meetings, is active on Twitter, started blogging, presented at his first SQLSaturday a few weeks ago, and in November will be joining us for the first time at the Summit. It's been fun to watch Ed's upward trajectory in the SQL community and I have no doubt that we'll be seeing more of him around PASS for a few years. Here's what Ed had to say about me:

    To Whom It May Concern:

    I have only had the privilege of knowing Kendal Van Dyke for a little over a year which is about the same amount of time that I have been involved with PASS. In that time frame and beyond, Kendal has been an ever present force in the Central Florida area for PASS. I live closer to the Tampa user group; however Kendal has continually invited me to the MagicPASS meetings. He has presented for our Tampa group as well as presenting at all of the local SQL Saturdays that I have attended.

    Kendal has never ceased being an ambassador for PASS, in my opinion. I have never seen dialog on twitter or blogs where he has been nothing but the consummate professional always raising the flag for PASS and always looking to help users in the SQL Server community.

    He has also encouraged me to do more in the PASS community and I have now presented a session to my user group as well as at a SQL Saturday. He has continued the cycle of mentoring new presenters. After several conversations, I feel that he has a great passion for the SQL Server community as well as some great ideas for the PASS community globally.

    I fully recommend Kendal for the PASS Board of Directors without any hesitation.

    Sincerely,

    Ed Watson

    For those of your who have already cast your vote - thank you for helping to decide who you want to lead PASS forward. And for everyone else yet to fill out their ballot, please take the time to visit the elections website, read about each candidate, and exercise your right to vote. (And of course I hope that you'll consider voting for me!)

  8. 2012 PASS Elections Letter Of Recommendation From Stacia Misner

    I'm a candidate in the 2012 PASS Board of Directors elections and believe that an important part of what makes a good candidate is support from the community that they wish to represent. During the last 5 years I have connected with people in PASS community from chapter members to speakers and from SQLSaturday volunteers to Directors. I've been fortunate this year to receive several letters of recommendation in support of my desire to continue serving on the Board. In this post I'm sharing the letter I received from Stacia Misner (Blog | Twitter).

    I met Stacia for the first time in person in 2011 at SQLRally in Orlando - which is slightly humorous given that we had both been to the PASS Summit since 2009 but never crossed paths. Stacia has become a trusted friend as we've gotten to know each other better. I value her experience and always look forward to conversing with her about SQL Server and her adventures living in Alaska. Here's what Stacia had to say about me:

    I don't remember exactly when I first became aware of Kendal Van Dyke's presence in the SQL Server community, but I do recall that it was on Twitter. His sense of humor and his active involvement with community were the first things that I noticed about him. Those are two qualities that I think are important for anyone seeking a board position at PASS.

    Over time, I got to know Kendal in other ways. As a speaker at SQLRally in Orlando, I benefited from his hospitality during a time when he was pulled in multiple directions at once. I observed his graciousness under pressure throughout the event, and appreciated his willingness to participate in after-hours activities when I'm sure he was very tired. I also have been a panel speaker with Kendal, participating in a session at PASS that he moderated. The purpose of that session was to help people learn to blog. It was evident to me from that interaction that Kendal feels strongly, as do I, that we all benefit through shared knowledge. He is encouraging to everyone, even if they feel they have very little to contribute. Again, Kendal's concern for community and passion for helping others stretch their skills was a stand-out quality and his willingness to invest personal time in these efforts is commendable.

    Kendal has hands-on experience with many of the activities associated with PASS, which has given him a wealth of insight into the needs of the membership. His roles as a chapter leader, event organizer both small and large, and as a speaker, demonstrate his commitment to serving the community in whatever way he can. Furthermore, he's had the opportunity to serve on the PASS Board in an appointed seat, and has had the opportunity to be involved in initiatives to make things even better. Therefore, he can hit the ground running as an elected Board member. I think our SQL Server community will benefit greatly from Kendal's passion, commitment, and service, and heartily recommend him.

    Stacia Misner
    DataInspirations.com
    Inspiring Intelligence from Information

    For those of your who have already cast your vote - thank you for helping to decide who you want to lead PASS forward. And for everyone else yet to fill out their ballot, please take the time to visit the elections website, read about each candidate, and exercise your right to vote. (And of course I hope that you'll consider voting for me!)

  9. 2012 PASS Elections Letter Of Recommendation From Jes Borland

    I'm a candidate in the 2012 PASS Board of Directors elections and believe that an important part of what makes a good candidate is support from the community that they wish to represent. During the last 5 years I have connected with people in PASS community from chapter members to speakers and from SQLSaturday volunteers to Directors. I've been fortunate this year to receive several letters of recommendation in support of my desire to continue serving on the Board. In this post I'm sharing the letter I received from Jes Borland (Blog | Twitter).

    Like many people in the PASS Community I first "met" Jes on Twitter about two years ago. Over time we tweeted and emailed back and forth, and at the 2011 PASS Summit we met in person for the first time. Jes is even more energetic in person than she is online!  Throughout the last year she and I have had some great conversations about volunteering, careers, and life in general, and I'm fortunate to be able to include her in my network of SQL peers. Here's what Jes had to say about me:

    I finally met Kendal Van Dyke in person at PASS Summit 2011, after “meeting” him through Twitter and talking to him virtually for a couple years. Kendal has given me guidance on consulting, and answered questions about SQL Server, user groups and SQL Saturdays. Anytime I’ve had a question, he’s been willing to take time out of his day to answer me. He’s reached out to me when he’s wanted an opinion or needed a volunteer for PASS tasks.

    Kendal is passionate about growing the PASS community in a truly grassroots way. He wants to focus on growing members, but not just in numbers. He wants community members to connect with each other, and wants individuals to grow through opportunities such as speaking and volunteering. He has ideas on how to do this, and the drive to accomplish them.

    I fully support Kendal running for the PASS Board of Directors, and think he will guide and grow the PASS community with passion and integrity.

    Jes Borland

    For those of your who have already cast your vote - thank you for helping to decide who you want to lead PASS forward. And for everyone else yet to fill out their ballot, please take the time to visit the elections website, read about each candidate, and exercise your right to vote. (And of course I hope that you'll consider voting for me!)

  10. 2012 PASS Elections Letter Of Recommendation From Karen Lopez

    I'm a candidate in the 2012 PASS Board of Directors elections and believe that an important part of what makes a good candidate is support from the community that they wish to represent. I've worked hard to connect with people in PASS community from chapter members to speakers and from SQLSaturday volunteers to Directors. I've been fortunate to receive several letters of recommendation in support of my desire to continue serving on the Board. In this post I'm sharing the letter I received from Karen Lopez (Blog | Twitter).

    I met Karen several years ago through Twitter and then in person at SQLSaturday. We've crossed paths at PASS events many times since then, and more recently I've had the chance to work with Karen on PASS's Global Growth initiatives where she's served as an advisor to the Board. Over the years as I've gotten to know her I have come to respect Karen for her professional opinions, advice as a consultant, and insight from her time as a member of other Boards. Here's what Karen had to say about me:

    Dear PASS Nomination Committee:

    I’m recommending Kendal Van Dyke for a continued PASS Board position. My primary reason for supporting him is his willingness to listen to feedback and take actions that he believes are in the best interest of PASS members and the community as a whole.

    In my discussions with Kendal about SQL Saturdays, PASS events and PASS communications, Kendal has always been willing to hear what I had to say and shown that he is genuinely interested in the feedback I have. Even at times where he didn’t agree with my recommendations, he treated my ideas with respect and attention. He carried my feedback to the Board and followed up with me about the outcomes.

    My interactions with Kendal have always been engaging, fun, and professional, something I think are key to balancing the needs of managing an association and meeting the needs of individual members. I’ve also had the benefit of seeing the outcomes of his efforts as programs are improved. He sets a high standard for leadership and professionalism when interacting with other volunteers and the community. I couldn’t ask for more from a Board member.

     

    Sincerely,

    Karen Lopez
    Senior Project Manager and Architect
    InfoAdvisors

    For those of your who have already cast your vote - thank you for helping to decide who you want to lead PASS forward. And for everyone else yet to fill out their ballot, I hope that you'll consider voting for me.

  1. 1
  2. Next ›
  3. Last »