views:

779

answers:

2

I'm trying to use PowerShell to create some backups, and then to copy these to a web folder (or, in other words, upload them to a WebDAV share).

At first I thought I'd do the WebDAV stuff from within PowerShell, but it seems this still requires a fair amount of "manual labour", ie: constructing HTTP requests. I then settled for creating a web folder from the script and letting Windows handle the WebDAV stuff. It seems that all it takes to create a web folder is to create a standard shortcut, as described here.

What I can't figure out is how to actually copy files to the shortcut's target..? Maybe I'm going about this the wrong way.

It would be ideal if I could somehow encrypt the credentials for the WebDAV in the script, then have it create the web folder, shunt over the files, and delete the web folder again. Or even better, not use a web folder at all. Third option would be to just create the web folder manually and leave it there, though I'd rather not.

Any ideas/pointers/tips? :)

+1  A: 

Well, in the meantime I cobbled together another solution. Maybe it will be of use to someone..

[Run.cmd] --May need to change powershell path

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nologo -noninteractive -command "C:\Scripts\RunBackup.ps1"

[RunBackup.ps1] --Out-File not having the desired effect, maybe someone can figure out why?

C:\Scripts\SqlBackup.ps1 | Out-File "C:\Scripts\log.txt"
C:\Scripts\SVNBackup.ps1 | Out-File "C:\Scripts\log.txt"
C:\Scripts\Zip.ps1 | Out-File "C:\Scripts\log.txt"

[SqlBackup.ps1] --You may need to modify which SMO assemblies are loaded, depending on your version of SQL server. Don't forget to set $instance and $bkdir.

#http://www.mssqltips.com/tip.asp?tip=1862&home

$instance = ".\SQLEXPRESS"


[System.Reflection.Assembly]::LoadFrom("C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SMO.dll") | out-null

[System.Reflection.Assembly]::LoadFrom("C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SMOExtended.dll") | out-null

$s = new-object ("Microsoft.SqlServer.Management.Smo.Server") $instance

$bkdir = "c:\Backups" #We define the folder path as a variable
$dbs = $s.Databases
foreach ($db in $dbs)
{
     if($db.Name -ne "tempdb") #We don't want to backup the tempdb database
     {
     $dbname = $db.Name
     $dt = get-date -format yyyyMMddHHmm #We use this to create a file name based on the timestamp
     $dbBackup = new-object ("Microsoft.SqlServer.Management.Smo.Backup")
     $dbBackup.Action = "Database"
     $dbBackup.Database = $dbname
     $dbBackup.Devices.AddDevice($bkdir + "\" + $dbname + "_db_" + $dt + ".bak", "File")
     $dbBackup.SqlBackup($s)
     }

     if($db.RecoveryModel -ne 3) #Don't issue Log backups for DBs with RecoveryModel=3 or SIMPLE
     {
     $dbname = $db.Name
     $dt = get-date -format yyyyMMddHHmm #Create a file name based on the timestamp
     $dbBackup = new-object ("Microsoft.SqlServer.Management.Smo.Backup")
     $dbBackup.Action = "Log"
     $dbBackup.Database = $dbname
     $dbBackup.Devices.AddDevice($bkdir + "\" + $dbname + "_log_" + $dt + ".trn", "File")
     $dbBackup.SqlBackup($s)
     } 
}

[SVNBackup.ps1] --Modify repo and backup paths

#set alias to svnadmin exe
set-alias svnadmin "C:\Program Files (x86)\CollabNet Subversion Server\svnadmin.exe"

#create dump
cmd.exe /c svnadmin dump "C:\Repo" `> "C:\Backups\svn.dmp"

#remove alias
remove-item alias:svnadmin

[Zip.ps1] --Need to have 7zip installed, modify 7z.exe path if necessary

#set alias to command line version of 7zip
set-alias sevenz "c:\program files\7-zip\7z.exe"

#Backups location
cd 'C:\Backups'

#rar the contents of the directory
$dt = get-date -format yyyyMMddHHmm #We use this to create a file name based on the timestamp
$outputFileName = "SQLSVNBackup$dt.7z"
$exclude1 = "-x!*.rar"
$exclude2 = "-x!*.7z"
sevenz a -t7z "$outputFileName" *.* "$exclude1" "$exclude2"

#find all .bak files in the immediate directory 
dir '*.bak' | foreach-object{

#remove the bak file
remove-item $_.name

}


#find all .dmp files in the immediate directory 
dir '*.dmp' | foreach-object{

#remove the dmp file
remove-item $_.name

}

#find all .trn files in the immediate directory 
dir '*.trn' | foreach-object{

#remove the trn file
remove-item $_.name

}

#remove 7zip alias
remove-item alias:sevenz

I used GoodSync to backup to WebDAV and scheduled two tasks to run the .cmd file and then sync/backup offsite.

bszom
+2  A: 

If you are using powershell to backup your SVN repositories using svnadmin dump then be aware that piping to a file will silently corrupt your backups.

Powershell likes to change things to UTF-16 when piping, it also changes unix linebreaks to windows ones. This will come back to haunt you when you try and restore.

Problem well described here:

http://thoughtfulcode.wordpress.com/2010/01/29/powershells-object-pipeline-corrupts-piped-binary-data/

Solution here:

http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.windows.powershell&tid=e4cd89e9-427b-407d-a94f-c24be3f1e36f&cat=&lang=&cr=&sloc=&p=1

In summary, use cmd.exe instead of powershell:

cmd.exe /c svnadmin dump ... `> dumpfile.dump

Note that the backtick on the output redirection is required to stop powershell parsing it.

David Martin
Thanks for the info!
bszom
+1 for the backtick tip on output redirection.
Damian Powell