Windows

Shadow Copies on XP, robocopy, PowerShell v2

May 1, 2012 · 3 min read

[I forgot to post this draft back in April 2010. Needless to say I no longer utilize the technique nor can really help now that it's purged from my memory]

I've cobbled together a poor-man's backup solution using PowerShell and robocopy in what I thought was a somewhat resilient solution. Robocopy turned out to be a poor choice based upon my needs and nitpicks but I wanted to outline why to save myself and others a little pain.

Strike 1

This URL describes the bug and relative fix: https://superuser.com/questions/48303/access-denied-error-with-robocopy-as-admin. While using /ZB and /B helps it wasn't solving the problem because the relevant ACLs weren't being created even as late as Windows 7.

Strike 2

robocopy has 3 (relevant) major versions: 2003 Resource Kit (the one I was using 010), Vista/RoboCopy GUI (026), and Windows 7. To make things more complicated, installing RoboCopy GUI on a 2003/XP machine will put robocopy under %windir%system32 which happens to enumerate after the 2003 Resource Kit path. This means you have to explicitly call system32robocopy or rename the resource kit version if you hope to keep the other resource kit tools.

Strike 3

I erroneously thought by adding users to the Backup Operators group, a requirement to use the /B switch, robocopy was creating local shadow copies. I might have been confusing it with HoboCopy and figured taking a shadow copy snapshot before a robocopy operation would fix the problem. Turns out taking all that time, determining you almost always need to be administrative, and XP's limited ability to easily expose a snapshot as a drive letter/share made this become an incredible deal breaker.

Temporary solution

To combat the bug that started this investigation, I initially tried using version 026 of robocopy to no avail. I used every combination of /copyall, /copy:dats, /copy:dt or just /copy:d.

What really fixes the problem is to completely obliterate the destination folder(s) and start over. This would correctly build the relative ACL and prevent the access denied message but it would only be a matter of time until it happened again.

My permanent solution

  1. Steal Steve Murawski's great Invoke-SyncFrameworkSample code outlined Using the Sync Framework from PowerShell. (download link at the bottom)
  2. Install Sync Framework 2.0 Runtime.
  3. Modify code to use 1 or 2-way sync (default sample is 2-way).
  4. Modify code to enumerate the FileReport object and build a slightly more robocopy-like output.
  5. Modify code to create DestinationPath*. If it isn't found it doesn't make sense to do a 2-way sync either.
  6. ???
  7. Do not profit. The bulk of the code isn't mine :(

Note: Robocopy is an end-to-end solution whereas I have far more flexibility to shoot myself in the face with this PowerShell script and the Sync Framework in general.
*: This technique negates the solution completely because I'm creating these directories under the user context the script is run in.

Shadow copies aren't used so to run this in a limited user context I still need the user in the Backup Operators group. I will likely work up a solution using shadow copies on the server as I can rather painlessly manipulate them using the Create Method of the Win32_ShadowCopy Class. Sample Powershell v2 script using AlphaVSS behaves much better if you are not using Windows XP too.

ListBox, ScrollIntoView and ObservableCollection vs. ICollectionView

February 14, 2011 · 1 min read

I almost struggled with a somewhat SEO-friendly title for this but considering I've had at least one request for an explanation, I thought I'd try to post my thoughts in a blog format. The twitter shotgun of a couple of 140 character posts wasn't enough to really convey what was happening.

To set the scene a little bit, I'm making a IRC client for WP7 and one of the core requirements (to me) is "automatically scroll to bottom on output". To achieve this, the ScrollIntoView() method for certain controls like ListBox, ListView, or DataGrid is absolutely crucial. I use MVVMLight and subscribe to an approach of triggering the code-behind from the ViewModel usually through a property update. In this case I chose binding the ListBox's SelectedItem and wired up the SelectionChanged event with code that basically said "when your selection changes, scroll to that since I'm pretty sure that bit of information is what my users (and I) want to see."

The events only fire when something is on screen, which is a tell-tale sign of virtualization to me, and I needed some way around it safely while still utilizing virtualization if possible. The rescue comes in the form of binding the ItemsSource to ICollectionView instead of ObservableCollection as it gives us the MoveCurrentTo() methods as well as filter, sort, and grouping capabilities. When you call MoveCurrentTo, virtualization is turned off so that SelectionChanged can then fire and finish the job.

I will say that ICollectionView is a bit more overhead than most people need which is probably why it isn't pushed as much in samples but I pretty much never bind directly to ObservableCollection anymore.