Blog » Powershell Backup to S3 Script

Powershell Backup to S3 Script

Have you ever used Powershell? Well, neither have I. Until recently I’d been happily scripting my server maintenance routines in batch files (I know, I know) but figured when one of our dev servers turned out to need to be a Windows Server 2012, I found that my tried and true batch files would need to be massively rewritten so I figured, time to dive into PowerShell.

There were three aspects of what the routine that I needed to address

  • Learn Powershell: Thank God for Google! Not sure how long this would have taken if I hadn’t had Google’s great search results
  • Figure out how to create and add files to a zip file. Well, it turns out the easiest way is to create a new file by adding the necessary “header” information to the file and then just start copying files to this file as if you were copying files to a folder
  • Figure out a good way to interact with S3. In the batch file I had been using S3 Browser’s s3browser-put utility but thanks to Google I found out about the Cloudberry Explorer which is freeware from Cloudberry Lab. And best of all, it includes Powershell extensions!

Well, without much more ado, here is the code:

 

<#
	Backup script for a particular purpose
	Written by: Michael J. Gibbs, Exhibit A Communications
			    4/24/2013
	Requires: CloudBerry Explorer for Amazon S3 Freeware (PowerSHell Snap-ins) found at 
http://www.cloudberrylab.com/free-amazon-s3-explorer-cloudfront-IAM.aspx with tips at
http://www.cloudberrylab.com/default.aspx?page=amazon-s3-powershell
#> # Set up initial variables $key = "__AMAZON KEY GOES HERE__" $secret = "__AMAZON SECRET KEY GOES HERE__" $bucket = "__S3 BUCKET NAME AND PATH GOES HERE__" $dow = (Get-Date).DayOfWeek.ToString().Substring(0,3) # Returns shortened day of the week $archiveToSend = $dow + ".zip" $fullPathFilename = "__FULL PATH TO THIS FILE__" + $archiveToSend $extensionToFind = "*.*" # You would use *.xls for Excel files, *.doc for Word docs, etc
$relativeFolder = "__FOLDER TO LOOK FOR FILES IN RELATIVE TO CURRENT FOLDER__" 
$archiveFolder = "__FOLDER WHERE THE ARCHIVE CAN BE FOUND__" 

# Let's zip up the required files echo "Backing up to $fullPathFilename..." if (Test-Path $fullPathFilename) { echo "Deleting old backup file..." # Just to be safe, let's remove any ReadOnly attributes from this file # We need to cast the filename string into a file object so we can modify the ReadOnly attrib (dir $fullPathFilename).IsReadOnly = $false # Now we remove the file Remove-Item $fullPathFilename } # Let's make our zipfile if (-not (test-path $fullPathFilename)) { echo "Creating new backup file..." # Add the Zip header to this file set-content $fullPathFilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) # Again, just to be safe, we'll remove ReadOnly attrib (dir $fullPathFilename).IsReadOnly = $false } $shellApplication = new-object -com shell.application $ZipFile = $shellApplication.NameSpace($fullPathFilename) # Create a list of all the files ending in $extensionToFind from the folder called $relativeFolder below current directory. We could recurse using -recurse flag if we wanted to $files = Get-ChildItem $relativeFolder -filter $extensionToFind foreach($file in $files) { echo "Adding $file to $archiveToSend..." $ZipFile.CopyHere($file.FullName) Start-Sleep -milliseconds 500 } echo "Adding Rank Tracker system settings to $archiveToSend..." $ZipFile.CopyHere("c:\users\ottreports\.ranktracker.properties"); echo "Sending $archiveToSend to our $bucket S3 bucket..." # Add snap-in add-pssnapin CloudBerryLab.Explorer.PSSnapIn # Now, let's move that zip file up to the S3 bucket called $bucket $s3 = Get-CloudS3Connection -Key $key -Secret $secret $destination = $s3 | Select-CloudFolder -path $bucket $src = Get-CloudFilesystemConnection | Select-CloudFolder $archiveFolder $src | Copy-CloudItem $destination -filter $archiveToSend echo "All Done!"

Phew, that was a whole lot of work to replace a 7 line batchfile but I guess this is progress. Biggest “aha” moment from this exercise? I sure which Microsoft had strongly-typed the base language for Powershell. I guess I’m just too used to C# (and I like it that way).

Anyone else have some really handy Powershell scripts to share?

Of course, the final step is to get this scheduled to run on the server but that shouldn’t be too hard, should it?

Michael Gibbs
Stalk Me...
Latest posts by Michael Gibbs (see all)