Author: way0utwest

  • Powershell – Copy the Latest Backup

    I got an email recently where someone asked me how they can refresh a dev environment with Powershell. I guess I’d written something about this in 2009, though that would have been for testing as Red Gate had already banned me from development on SQLServerCentral by that time.

    I dug around and came up with a few partial scripts and cleaned them up for these posts. This post will look at getting the backup and a later one will examine the restore.

    Finding the Latest Backup

    I’ll assume that you make backups on a known path somewhere. My philosophy is that I want the machines to stand alone as much as possible. That means that I don’t want the source machine (the one making the backup) to be working on refreshing the backup elsewhere. I want a pull system.

    For a high level overview, this process looks like this:

    • Search the backup path for files matching a pattern.
    • Find the most recent one, based on date.
    • Copy that most recent file to another location.

    For the sake of consistency and easy, I want to copy the file with the same destination name every time. That will simplify my restore process, which I could easily then do in T-SQL.

    Let’s examine how to do this. I’ve got a folder with a few backups in it.

    backuplatest

    For my PoSh, I’ll start by setting a variable to the path.

    $backuppath = "D:\SQLServer\MSSQL11.MSSQLSERVER\MSSQL\Backup" 

    Once I have this, I can now look for the files in this path. To do that, I’ll use Get-Children.

    get-childitem -path $backuppath

    This will return to me a list of the files. That’s what I want, but I want to limit the files to a pattern. In this case, I’m looking for .bak files, from the EncryptionPrimer database. All of these

    There’s nothing special about what I do that’s not contained in plenty of places. I don’t have this running on an environment currently as someone else manages that process, but here’s the process I’ve followed in the past:

    • Find the latest backup (whatever the date) in the source folder.
    • Copy this with a set name to the destination folder, overwriting previous backups with the same name.
    • Restore the known name to the development database, moving files as needed.

    I’ll go through each of these steps in my PoSh script.

    Find the Latest Backup

    This is fairly easy. I’ll use the Get-ChildItem method, which I found in a StackOverflow post. I’ll use a variable for the path I need, and then check the path.

    $backuppath = "D:\SQLServer\MSSQL11.MSSQLSERVER\MSSQL\Backup"

    get-childitem -path $backuppath

    That works well, but since I’m building a process for a specific backup type, I’ll add a filter.

    $backuppath = "D:\SQLServer\MSSQL11.MSSQLSERVER\MSSQL\Backup"

    get-childitem -path $backuppath -Filter "EncryptionPrimer*.bak"

     

    To find the latest backup, we’ll pipe the output through the Where-object filter, removing folders. Then we use sort-object to order things by creation date and select-object to get just the one file.

    $backuppath = "D:\SQLServer\MSSQL11.MSSQLSERVER\MSSQL\Backup"

    get-childitem -path $backuppath -Filter "EncryptionPrimer*.bak" |

        where-object { -not $_.PSIsContainer } |

        sort-object -Property $_.CreationTime |

        select-object -last 1

     

    The last part of the script is the copy-item command, which is again the recipient of piped output. We give a standard name, and path (another variable).

    $backuppath = "D:\SQLServer\MSSQL11.MSSQLSERVER\MSSQL\Backup"

    $destpath = "d:\SQLServer\Backup"

    get-childitem -path $backuppath -Filter "EncryptionPrimer*.bak" |

        where-object { -not $_.PSIsContainer } |

        sort-object -Property $_.CreationTime |

        select-object -last 1 | copy-item -Destination (join-path $destpath "EncryptionPrimer.BAK")

    Once this is done we can restore things. I learned how to do this from PoSh using this post: http://stuart-moore.com/day-11-31-days-sql-server-backup-restore-using-powershell-basic-restore/

    However, since I have a standard backup file name, I’d probably do this in T-SQL and set a job that I can just run anytime. It’s simpler and easier, and since most of the time I’d want to do this from SSMS, a job works well.

    Here’s the PoSh script.

    Import-Module "SQLPS" -DisableNameChecking

    $sqlsvr = New-Object -TypeName  Microsoft.SQLServer.Management.Smo.Server("JollyGreenGiant\SQL2012")

    $BackupFile = "D:\SQLServer\Backup\EncryptionPrimer.BAK"

    #

    #echo ""

    #echo "Databases"

    #echo "———"

    #foreach ( $db in $sqlsvr.Databases) { write-host $db.name }

    echo " "

    echo "Begin Restore"

    echo "============="

    $Restore = New-Object "Microsoft.SqlServer.Management.Smo.Restore"

    $Restore.NoRecovery = $false

    $Restore.ReplaceDatabase = $true

    $Restore.Action = "Database"

    $Restore.PercentCompleteNotification = 10

    $BackupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($BackupFile, "File")

    $Restore.Devices.Add($BackupDevice)

    $RestoreDetails = $Restore.ReadBackupHeader($sqlsvr)

    $logicalFileNameList = $Restore.ReadFileList($sqlsvr)

    $Restore.Database = $RestoreDetails.Rows[0]["DatabaseName"]

    foreach($row in $logicalFileNameList) {

        $RestoreDBFile = new-object("Microsoft.SqlServer.Management.Smo.RelocateFile")

        $RestoreDBFile.LogicalFileName = $row["LogicalName"]

        $RestoreDBFile.PhysicalFileName = $row["PhysicalName"]

        $Restore.RelocateFiles.Add($RestoreDBFile)

            }

    $Restore.SqlRestore($sqlsvr)

    write-host ("Completed the Database Restore operation on server for Database " +  $RestoreDetails.Rows[0]["DatabaseName"] + " on server $server")

     

    That’s it. I ran this a few times, and it worked well. A handy script to get the last backup and have it ready in a dev/test environment.

  • Moving On

    I’m not leaving; I have the best job in the world, and I could easily see this being my last job. However, we’ve had a few people leave Red Gate recently, a few of which I have known for some time. It’s inevitable as a company grows that there will always be some people that find better opportunities or need a change of jobs. Perhaps it’s a sign of the times, but I doubt that many of us in technology will keep the same job for decades.

    Leaving a job isn’t a bad thing, and it certainly doesn’t have to be antagonistic. I’ve left quite a few jobs on good terms, with both myself and my employer wishing each other well in new endeavors. I have found most people will behave as adults and professionals, even when one side is not happy with the way in which the employment relationship ended. Being open and honest certainly helps, as people usually respect a position if they understand it, even if they don’t like the circumstances.

    One of the things that typically happens at Red Gate is that the person leaving sends a note around to the department(s) affected, and sometimes the company. Recently we had an interesting one come out that was broken into different sections. Each section looked back at this person’s time at Red Gate, and the note got me thinking. How would I look back at my time in various companies?

    The sections talked about good times, things learned, mistakes made, memorable events and more. It’s the type of perspective I like, and what I’d like to write if I ever leave. Then I thought maybe it’s the type of thing I should write every year, looking back at the good and bad times I’ve had at the company.

    Taking stock of your situation, the good, bad, challenging, growing, and other events, is a healthy way to examine your employment. I might encourage each of you to write a “leaving letter” as we close out the year. Write down the things you’ve had fun doing, the achievements you’re proud of, the mistakes you’ve made and more. Don’t limit it to 2014, but look at your entire time with this employer. Use the letter to evaluate your position and career. Maybe you’ll think about how you’d like next year to proceed, or even if you want to change companies. Either way, stepping back and reviewing your career is something that is valuable to ensuring you continue to move in a direction you want.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 2.7MB) podcast or subscribe to the feed at iTunes and LibSyn. 

  • A Week Away

    Almost. I’m off this week in Steamboat Springs, enjoying a vacation with the family, but I’ve got one commitment: Database Weekly.

    We rotate the workload, and most everyone else has something this month, so I got stuck with it. I didn’t want to try and mess up anyone else’s schedule, as we’re all on holiday, so I’m going to fit it in.

    It will be short, so don’t be disappointed next weekend.

  • Quick Audio Switching

    I’ve got a semi complicated desktop setup, with multiple monitors, lots of USB stuff, and a few ways to record and listen to sound. I hadn’t thought of things as complex, especially with regards to audio, but between recording podcasts, having regular video conferences, and the speakers I added to my machine, I found the need to control where my audio goes in and out of.

    The other day I was waiting for a conference call to start on Skype and was listening to an interview through my computer. I’d plugged in a USB headset for the call, but the interview (Flash-based web page), came through the speakers. I’ve gotten used to redirecting audio easily from the speakers to headphones to Bluetooth devices, but I wasn’t sure how to do this in Windows. I messed with the audio mixer a bit, but didn’t see anything.

    I did a bit of searching and ran across this post on Superuser. I decided to blog briefly in the hopes that I’ll remember this process for next time.

    The long and short of it was that I needed to right click the audio speaker icon.

    recorduadio1

    I could then select Playback devices. This allows me to see the setup, not just the volume. I got the Control Panel app, with all my devices listed. I can also see the recording devices.

    recorduadio2

    From here, if I right click a device, in this case, the USB headset, I can select "Set as Default".

    recorduadio3

    Once I did this, the audio for the interview came through on the headset. I could listen and when my Skype call came in, it cut out and I could continue on with work.

    This is especially handy for recording, as I’ve had the wrong device setup for recording at times because I’ve expected the default to be used.