SharePoint - Recursive delete SPWeb PowerShell script

Or, what happens when you stuffed up and need to clean up a lot of sites created by accident.

 

Story

  • I have a feature receiver stapled to my site template, it checks a few conditions, does a few things, then creates 1 subsite and stops
  • The new subsite is created, and runs the same receiver, it checks a few more conditions, does a few things.  It shouldn't create any subsites.
  • This afternoon, it did.  The process did not stop.
  • Ouch

 

Problem

  • You can't delete the higher level web object when it has subsites.  You can't follow the subsites because the path has gone way deep.
  • Sounds like time for a good PowerShell script

 

Script

$web = get-spweb http://dev/ourprojects/nsw/1000

function CleanSite( $w )
{
    $ws = $w.Webs;
    foreach( $w1 in $ws)
    {
        CleanSite($w1)
    }
    echo $w.Title
    $w.Delete()

}

CleanSite $web

 

Closing thoughts

My initial fears were that the feature receivers has gone berserk and I'd have hundreds of subsites to clean up.  This turned out to be not the case - I only had about 12 subsites.  I'm wondering if there was a SharePoint error that prevented deeper subsites from being created.  So the disaster really wasn't that bad.  12 subsites I can manage. 

image

InfoPath, custom WCF Service, Word and Open XML SDK (outline)

This upcoming series of articles promise to be far more exciting than the title.

Scenario

How do you use an InfoPath form document to populate a word document with content controls. 

 

Steps:

  1. Building a Word document template with Content Control place holders
  2. Use Content Control toolkit to bind values to place holders in the template to an embedded custom XML (hey, isn't an InfoPath document an XML file?)
  3. Creating a WCF service to take a Word template document, and replace the custom XML, by the power of Open XML SDK (2.0, of course).
  4. Invoking the WCF service from within an InfoPath document to generate a word template version of itself!
  5. Finally, a bit of discussion on where Word Automation services fits in the bigger picture, as well as thoughts on best practices.


Drop a comment below if you have any specific questions relating to these steps.  Specifically, if you can think of a far better title for this series.

Otherwise, stay tuned!  :-)

InfoPath - disabling backspace key in browser form

How to disable the backspace key using Javascript/jQuery for an InfoPath browser form in SharePoint 2010.

 

The problem

One really troubling problem with almost all web solutions is how the Backspace key works.  By default, it tells your browser to go back to the previous page in history.

If you are just browsing around on your Intranet, this is probably not a big deal - firstly, you wouldn't be pressing backspace unless you actually wanted to go back.  Secondly, if you did indeed made a mistake and pressed the backspace key, you'd just undo that action by clicking the forward button, or navigate to another link.  No problem.

 

When you are filling in a form on the browser though, such as through InfoPath, suddenly the backspace key is a big deal.  You users may be using the backspace key to delete text that they are in the middle of entering.  And if they didn't have a textbox focused, the backspace key is sent to the browser form, and suddenly you have a problem.  The form disappeared, and you have lost information.

 

InfoPath is quite smart - it remembers which view you are supposed to be on, and when you navigate to an outdated browser historical view of the form - Form Server will automatically redirect you forward to show you the correct form you are supposed to be viewing.  This is good, at least in the navigation sense.  So the only remaining problem is the lost data - your user may have had a whole page filled out and this mistake has just cleared their form.  Not good.

 

Enter Javascript

So, the plan is simple:

  1. Inject javascript to the existing browser form
  2. Listen to keydown event for a backspace key (keycode 8)
  3. Eat the event and stop it from propagation, so the browser don't see it

Using jQuery, you'll need this simple function.

 

function document_keydown(e) {
    if (e.keyCode == 8 && e.target.tagName != "INPUT") {

        // letting us know we've ate a backspace key
        SP.UI.Notify.addNotification('Ate a backspace key, hew!', false);

        // cancel backspace navigation
        e.preventDefault();
        e.stopImmediatePropagation();
        return false;
    }
};

$(document).keydown(document_keydown);

 

Injecting Javascript in modal dialog

 

If you are using SharePoint 2010's modal dialog to show InfoPath in a modal popup, it's slightly trickier.

 

// grab a reference to the modal window object in SharePoint
var w = SP.UI.ModalDialog.showModalDialog(options);

if (w) {
    // get the modal window's iFrame element
    var f = w.get_frameElement();

    // watch frame's readyState change - when page load is complete, re-attach keydown event
    // on the new document       
    f.onreadystatechange = function(e) {
        if (f.readyState == 'complete') {
            var fwin = f.contentWindow || f.contentDocument;
            $(fwin.document).keydown(document_keydown);
        }
    };
}

Result

 

nom-nom-nom backspace keys.

image

 

Note, because the Javascript catches the keypress event at the document level.  If your user still has focus on the input (textbox) level, the event will not be stopped - so your user still will be able to backspace when they are using a textbox.

AUSPC 2012 summary

I had an awesome time presenting Building your own custom REST Services and consuming them with jQuery AJAX in the Australian SharePoint Conference 2012.  A big thank you to the developers that came and geeked out with me for an hour on a Wednesday afternoon.

Notes

When you build a custom WCF Service using the CKS template, it is deployed to a subfolder the web front end's ISAPI folder, which, in turn, is mapped to the site's /_vti_bin/ folder.

image

 

It appears that in my earlier attempt to create an incomplete version of the REST service template item, I interfered with how CKS's templates worked - and correct features for deploying the WCF service is no longer being included in the package.  While existing items were updated and deployed, the new WCF service that I was creating wasn't being deployed to the ISAPI folder.

I've removed the REST template item from my Visual Studio .NET environment, and voila - the WCF services deployed nicely once again.

So that's one mystery resolved.  Now I scratch my head about how to fix my VS.NET REST template item.

 

Downloads

AUSPC 2012 quick update

I'm in the strange and calm interlude between day 1 and day 2 of awesomeness in the annual Australian SharePoint Conference (AUSPC) 2012.

Day 1 has been a lot of fun.  Manned the user group booth in the morning with Dan Brown.  Met many of the SharePoint guys in the community that I haven't seen for the last 6 month to a year.  Talked to a number of vendors, and attended a number of awesome sessions on the developer track.

I also got to sit on the panel answering developer questions amongst the legends like Nick Hadlee, Ishai Sagi, Brian Farnhill and Jeremy Thake

The oddest part is probably with MCA SharePoint Wayne Ewington sitting in the audience.  Every time we said something silly he'd start shaking his head and we'd all stop.  Hilarious.

 

Tomorrow morning, my session on Building your own custom REST Service and consuming them with jQuery AJAX is running in the developer track at 10:30am.  Hope to see everyone there.

All my related resources and presentations on this topic are summarized on /rest