Robocopy backup to dynamically-lettered removable drive

I use a Seagate FreeAgent GoFlex USB drive to carry large install files to customer sites. I wanted an easy, portable way to keep my Flex drive in sync with the working files on my laptop’s D: drive. I use Robocopy for big backup jobs on the server application products we support so I put it to use here, too, and it worked fine. The only annoying part was editing the Robocopy statement whenever the drive letter of the Flex changed.

To get around this I named the Flex volume “flex” (original) and added a statement to find the driver letter on-the-fly.

This should work for any removable drive for which you know the volume name. Just change the text of the find "flex" statement in line 10.

  • You’ll need a copy of Robocopy. I grabbed it from the Windows Server 2003 Resource Kit and it runs fine on the XP & Win7 workstations I’m using. I think the new version might be delivered standard with Server 2008.
  • This example mirrors the entire D: drive, excluding two directories I don’t care about, to the Flex drive. If you haven’t used Robocopy, do some reading before using /MIR. It will delete anything on the destination that doesn’t exist on the source.

backup_flex.bat


@echo off

echo. > "%cd%\backup_flex.log"
echo %time% *** backup starting *** >> "%cd%\backup_flex.log"
echo. >> "%cd%\backup_flex.log"

rem Find the drive letter corresponding to the removable drive named "flex"
setLocal Enabledelayedexpansion
for %%i in (d e f g h i j k l m n o p q r s t u v w x y z) do (
	for /f "tokens=1,* delims=:" %%x in ('fsutil fsinfo volumeinfo %%i: ^|find /i "flex"') do set drive=%%i
)

REM Mirror the D: drive to the Flex drive, excluding some directories.
Robocopy D:\ %drive%:\ /MIR /XJ /R:0 /W:1 /NP /NDL /xd "D:\Tools\Outlook offline files" "D:\Tools\Windows Search Index" /LOG+:"%cd%\backup_flex.log" 2>>errors.txt

echo. >> "%cd%\backup_flex.log"
echo %time% *** flex backup done *** >> "%cd%\backup_flex.log"
echo. >> "%cd%\backup_flex.log"

p.s. If anyone comes up with a cool way to limit the drive letters the FOR statement needs to iterate through, I’d be happy to hear about it. I spent more than a few minutes trying to work the output from fsutil fsinfo drives into the loop but I’m missing something.

for /f "tokens=1,*" %%i in ('fsutil fsinfo drives') do (
  rem iterate through the ...volumeinfo command with %%j
)

ssh logins without a password

Setup

To set this up you first need to create an ssh identity on your local machine.

$ ssh-keygen -t dsa

Your user’s home will now have a .ssh subdirectory with the identity file (id_dsa) and the public key file (id_dsa.pub). Copy the contents of id_dsa.pub to <target server>/<username>/.ssh/authorized_hosts

You can automate this with the ssh-copy-id script.

$ ssh-copy-id -i ~/.ssh/id_dsa.pub user@host

Note: If you use a non-standard ssh port on the target–doesn’t everyone?–edit the script (/usr/bin/ssh-copy-id) at line 41:

{ eval "$GET_ID" ; } | ssh -p 12345 $1 "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" || exit 1

You’re not quite there yet, but close.
If you try to ssh to your target now, you’ll be prompted for the local identity’s passphrase first. That’s a good sign; it means the target machine is accepting your public key authentication. You need to start a local ssh agent and add your identity to it.
(replace bash with your favorite shell)

$ ssh-agent bash
$ ssh-add

You’ll be prompted for the passphrase and the identity will be added to the ssh agent. The agent will use this identity’s authentication until you exit the shell where it’s running. (To avoid even this step, setup keychain.)
You can now ssh to your target machine without being pestered for a password or phrase of any kind.

$ ssh test@remoteMachine

When you can connect without being prompted for a password, you’re ready to go crazy with pssh.

Enjoy!

pssh to manage multiple systems

pssh (Parallel SSH) is a powerful tool if you need to manage multiple boxes. Originally developed by Brent Chun, it’s now maintained by Andrew McNabb.

Installation

Depending on your distro, you probably have pssh available in a repository of some sort. I know there’s a new version in the Fedora 12 yum repository and lots of binaries in RPM format. Since I was playing with a CentOS 5.4 installation, and pssh isn’t in the default repositories, I chose to grab the source from the new project home.

pssh is written in Python. Now, I don’t know the first thing about Python, but using ez_setup.py made the build and install exceedingly painless. (Follow the INSTALL notes in the tar file.)

Install setuptools, extract the source, and then build it:

$ wget 'http://peak.telecommunity.com/dist/ez_setup.py'
$ python ez_setup.py
$ tar -xvf pssh-2.0.tar.gz
$ cd pssh-2.0
$ python setup.py install

This will install the utilities to /usr/bin

Usage

$ pssh --help

usage: pssh [OPTIONS] -h hosts.txt command [...]
options:
--help show this help message and exit
-h HOST_FILES, --hosts=HOST_FILES
hosts file (each line "host[:port] [user]")
-l USER, --user=USER username (OPTIONAL)
-p PAR, --par=PAR max number of parallel threads (OPTIONAL)
-o OUTDIR, --outdir=OUTDIR
output directory for stdout files (OPTIONAL)
-e ERRDIR, --errdir=ERRDIR
output directory for stderr files (OPTIONAL)
-t TIMEOUT, --timeout=TIMEOUT
timeout (secs) (-1 = no timeout) per host (OPTIONAL)
-O OPTIONS, --options=OPTIONS
SSH options (OPTIONAL)
-v, --verbose turn on warning and diagnostic messages (OPTIONAL)
-A, --askpass Ask for a password (OPTIONAL)
-P, --print print output as we get it (OPTIONAL)
-i, --inline inline aggregated output for each server (OPTIONAL)

Configuration

Create a hosts file for pssh to act on.

$ more pssh_hosts.txt
# host[:port] [user]
192.168.5.10:12345 glen
192.168.5.11:12345 glen

Run

$ pssh -h /home/pssh_hosts.txt -P date

192.168.5.10: Wed Dec 30 03:44:40 GMT 2009
[1] 22:44:24 [SUCCESS] 192.168.5.10:12345
192.168.5.11: Wed Dec 30 03:42:22 GMT 2009
[2] 22:44:24 [SUCCESS] 192.168.5.11:12345

I’m not sure if I like the output from -P or -i better. I’ll have to play with both for a while.

To redirect the output to a file, use the -o switch and give it a directory name. In the output directory will be files, named after each of your targets, containing the command results.

There is some old documentation still available at Brent Chun’s original site, but it could be out-dated. I know the binary install location has changed and the --help switch has the newer options.

While playing with the 2.0 version from the Fedora 12 repo, I noticed the pscp command is now pscp.pssh. I couldn’t find any reference to why the change was made. The source I built from has the original pscp command. (Update: I came across this comment referring to a name-clash with PuTTY’s scp utility.)

Note:

pssh assumes you have publickey–no password entry–access to all the machines you’re managing. To set that up, take a look at this.

Enjoy!