For those out there that are a little curious as to whether SAF is any use to your organisation, please read this FAQ.
What is SAF ?
-
SAF is free to use.
-
SAF is the "SharePoint Action Framework", it was built by myself and Hugo (plus a few others along the way).
-
-
SAF is a way to automate SharePoint configuration changes.
-
An Action is a command/class/task/script written in C# that performs a unit of execution against SharePoint such as "CreateWeb" or "AddLookupColumn".
-
A SAF Macro is collection of one or more Actions.
-
A SAF Macro can be run from Msbuild, a Feature, StsAdm or plain old .Net code.
-
Parameters can be passed to a Macro at run-time from a variety of sources such as "Environment Variable", "*.config", "Msbuild Properties", Feature Properties, command line args, .net code.
-
SAF emits lots of trace statements at run-time, these can be viewed using "DebugView".
-
One Action can pass parameters to another Action.
-
Parameters can be set using Spring expression syntax such as "DateTime.Now - 10".
You should consider SAF if you suffer from one of the following symptoms...
-
"Our developers write lots of code to deploy changes at release time - it's always rushed"
-
"I don't want my developers shelling out to Powershell or Stsadm from a Feature".
-
"We have loads of Console applications now, I have lost track of where they are, or what they do"
-
"We seem to be writing similar scripts against SharePoint in lots of ways, testing is hard".
-
"My scripts often have lots of errors - they are done at the last minute".
-
"When something goes wrong - I have no idea what went wrong or how to solve it".
-
"Our Features get stuck and bomb out half way through - there no way to roll them back".
-
"We have tons of Features now - I can't keep track".
-
"We deploy Features to run one-off tasks"
-
"We have a library of reusable scripts, but, we can only run them in one way, sometimes we want to run them from MSbuild and a Feature".
-
"I want to automate the deployment of changes to our development environment".
-
"I would like to run a housekeeping task on a scheduled basis"
So I like the sound of SAF - what's the problems ?
Realistically (and honestly), there are few things that need to be considered:
-
Someone on your team will need to spend a day or 2 learning + understanding SAF and deciding exactly how you want to use it. I would suggest a Tech Lead, System Admin or SP Architect will need to download it, try out the examples, look through the unit tests. Ask us questions. Although SAF can be downloaded and set to go in a few minutes, you will still need to address issues such as - "Do you want to execute your Macros in MsBuild or from a Feature ?" and "How can I integrate SAF into my current build and deployment process?"
-
You will need to decide who is going to do your deployments - is it each developer to themself, or do you require a dedicated Build Manager ?
-
As most environments (Dev, QA, Live etc) require different settings (e.g. Urls, Database names, accounts etc), you will more than likely want to define these and set a properties file up for each environment. (These can then be injected into Saf at run-time).
-
There may be no Actions to solve your particular problem. If this is the case, suggest it to us - we can try and write it, or write it yourself. It's very easy to write a new Action - we have an approach to easily unit test it, document it and author it. For example, I wrote one to deploy a WSP in 2 hours the other day. Alternatively, Saf can also call Stsadm commands and Powershell scripts. Once the Action is written you can register it with SAF then all your devs can run it using the most appropriate client.
Anyway, I do hope this helps! If you still need help, or a quick start, we can also offer consultancy around SAF. If you want to know more give us a call or drop an email to support@collaboris.co.uk
One of the major areas developed for v2 of the SharePoint Action Framework (SAF) is its ability to integrate tightly with Msbuild. In order to get SAF working, you simply need to reference the Msbuild Saf task - which can be referenced like this :
<UsingTask AssemblyName="Collaboris.Saf, Version=2.0.0.0, Culture=neutral, PublicKeyToken=182db3eac6a9e195" TaskName="Collaboris.Saf.Adapters.MSBuild.SAF" />
You may also choose to create a couple of targets (one for the Undo and one for the Do) - like this - but this is optional.
<Target Name="Do">
<SAF MacroPaths="@(Macros)" ProcessMode="Do" ContinueOnError="false" />
</Target>
<Target Name="Undo">
<SAF MacroPaths="@(Macros)" ProcessMode="Undo" ContinueOnError="false" />
<Target>
Now this is setup, you then need to create a few item groups where all the properties can be passed to.
<ItemGroup>
<Macros Include="Collaboris.Saf.Actions.Wss.Web.CreateWeb.macroTemplate">
<disabledo>false</disabledo>
<disableundo>false</disableundo>
<description>New Web created by SAF</description>
<lcid>1033</lcid>
<overwrite>true</overwrite>
<template>STS#0</template>
<title>New Web title</title>
<url>NewWeb</url>
<useuniqueperms>false</useuniqueperms>
<webname>New Web name</webname>
<id>{47B640DD-64A9-493b-8445-789FC0D05FF1}</id>
<stopondoexception>true</stopondoexception>
<stoponundoexception>true</stoponundoexception>
<Url>http://localhost:4422</Url>
<InstanceId>{156E17A5-A7BA-4e1f-8A48-1BC341A7C658}</InstanceId>
</Macros>
</ItemGroup>
For a more detailed walkthrough, please take a look at 'How to run a Macro from MSBuild '. You will find an example of how to call every SAF action in the documentation which can be accessed at here.
MOSS Actions available in SAF :
Standard Actions available in SAF
Major points worth noting in this release :
- Loads more actions to help you automatically configure SharePoint.
- Downloadable examples and documentation explaining how to run every Action.
- Run actions from an MSBuild project and pass properties.
- Run actions from a SharePoint Feature and pass properties.
- Run actions from StsAdm and pass properties.
- Support for Dynamic Properties - allowing you to pass values from one action to another.
- Support for Placeholders (tokens) allowing runtime replacement from these sources :
- Web|app.config files,
- Environment Variables,
- Registry values,
- MSBuild Properties
- Feature Properties.
- Support for Expressions when setting properties on the actions.
- Improvements to logging using .Net tracing statements - easily viewable in DebugViewer
As always we love to hear your feedback, so drop us an email to
support@collaboris.co.uk or leave a comment on our Wiki or on Codeplex.
Happy automating!
The SAF Team
It’s 6am and I am bored, so I thought I would give you a quick heads up on what’s coming in the next version of SAF (due by the end August). Here’s the Feature list :
DSL with Diagram capabilities inside Visual Studio 20008.
This is probably been the most exciting one for the release. We have been spending a few months working on a way to create SAF Macros visually via a VS 2008 designer window. This will give you the following advantages :
- You don’t need to know the Schema for a SAF Macro (which happens to be a Spring IOC Container)
- It’s much easier to see what a Macro will do. (a “picture paints a thousand words (or Xml Elements in our case)
- It’s nice to demo – much nicer than showing you how to create a Macro in Xml anyway.
Usage will be very simple and will happen like this :
- Load a new VS2008 Project –(more than likely a WSP Builder project).
- From the menu, choose “Add new SAF Macro”
- …Designer loads…
- Select one or more actions and drag onto the design surface
- Configure the parameters for each of the Actions
- Connect the actions to set up a processing order.
- Save and deploy.
Underneath, the SAF Diagram will be converted to a Macro Xml message, which can then be chucked into SAF for processing.
MSBuild Adapter
The Adapter has been knocking around in our codebase for a few releases now, but, hasn’t really been road tested in a working scenario yet. Luckily, I have a wonderful opportunity to do this on a large SharePoint Project I am working with. The main idea is to integrate SAF into MSBuild (and hence, Visual Studio too). If you team this up with the DSL above (and WSP Builder), then the possibilities for tight integration are awesome.
Unit / Integration (“Uni-gration”) Testing for all Actions
We already have excellent test coverage for the SAF Engine and its Adapters. The last tests we need to author are for about 5 (or so) Actions. All of the existing Action tests have been done as SharePoint “integration” tests, which means that we start with a virgin WSS / MOSS site on the same machine as VS and then run Action for real in SharePoint. We tried various mocking approaches, but, in our experience SharePoint has so many quirks that “Uni-gration” is the only way to gain real confidence that it will work!
Documentation and Screencasts
Yeah I know – we have sucked on this so far! There are only so many hours (blah, blah), but, I do understand that the easiest way to gain mass adoption is to document and demo. All I can say is – it’s coming!!! I need to get used to Camtasia first though!
Useful Links :
SAF on Codeplex : http://saf.codeplex.com
SAF related Blogs : http://www.collaboris.co.uk/blogs.aspx?CntCatID=dc5a1df9-790f-43ee-b3e8-c0124927b7af
My Twitter : MarkQJones
Join the SharePoint 2007 – 2010 Linked in group (nearly 5000 members) : http://www.linkedin.com/groupRegistration?gid=43166
Introduction
Well it's now Saturday afternoon and the family have been out shopping all day, so I have taken the opportunity to conduct some tests that I had been meaning to do for a long time now (geek I hear you say). I wanted to find specifically what happens if you want to make changes to Content Types, Columns and Lists that have previously been deployed using Features and CAML. I am going to split my findings up into several posts.
I will detail each set of tests then summarise at the end what I think should be best practice if you want to update these.
Test Cases – Removing Content Types
Can we remove a content type by deactivating the Feature that deployed it? Yes
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Deactivate the Feature
Outcome:
1. Content type will be removed
2. Feature is deactivated
Can a Content Type can be removed that’s in use by a List? Yes (and No)
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Deactivate the Feature
Outcome:
1. Content Type is removed
2. Feature is deactivated
3. List Content Type is still associated with the list
4. The Lists Content Type “Parent” is now amended to be the “Grand Father” Content Type (e.g. the List Content Type gets granddad as its new dad!)
Can an “orphaned” List Content Type be re-parented by reactivating the feature containing the CAML for the real dad? Yes it can.
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Deactivate the Feature (list CType gets grandad as the new parent)
4. Reactivate Feature (list CType gets it the real dad back)
Outcome:
1. Content Type is re-installed
2. Features is Activated
3. List Content Type is associated with the list
4. List Content Types “Parent” is the Content Type (not the GrandFather).
Can we remove a Content Type that’s been customised in the GUI by deactivating a Feature ? No
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Change the “name” of the Content Type using the GUI
4. Deactivate the Feature
Outcome:
1. Content Type is not removed
2. Feature is deactivated
3. List Content Type is still associated with the list
4. List Content Types parent is still the real parent
What if we customise a Content Type and then deactivate its Feature? Can we remove the Content Type via the GUI? No, as it's in referenced in a List.
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Change the “name” of the Content Type in the GUI
4. Deactivate the Feature
5. Attempt to Delete the Content Type via the GUI
Outcome:
1. Feature is deactivated
2. List Content Type is still associated with the list
3. List Content Types parent is still the real parent
4. Exception thrown on Delete : “The content type "TestCType123" is part of an application feature”
5. Content Type is NOT removed
Ok, so we have customised the content type in the GUI, deactivated and reactivated the feature and it still won’t go? Remove all References then it will go!
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Change the “name” of the Content Type in the GUI
4. Delete the Reference From the List
5. Deactivate and Uninstall the Feature
Outcome:
1. Feature is deactivated
2. Content Type is removed
Test Cases – Updating Content Types
A series of tests were conducted to see if updating the underlying CAML (in the 12 Hive) causes changes to the (already) installed content type...
What can we change by simply editing the CAML XML (within the 12 Hive)? A Lot more than you would expect!
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Amend the “Group”, “Description”, “Sealed”, “ReadOnly”, “Name” in the CAML (residing in the 12 Hive)
3. Recycle App Pools
Outcome:
1. The Content Type reflects all the changes appropriately
Is there anything we cannot change in the CAML XML (within the 12 Hive)? Yes, as you would expect its "ID"
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Change the “ID” to something Unique
3. Recycle App Pools
Outcome:
1. The Content Type is no longer available.
2. (Note changing this back to its original ID restores all functionality)
If we corrupt the content type as above (by changing the ID), then what happens if we have list content type depending upon it? The List Content Type gets grandad as his new dad.
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Reference it in a list
3. Change the “ID” to something Unique
4. Recycle App Pools
Outcome:
1. The Content Type is no longer available
2. The List Content Type is still installed
3. The List Content Type gets parented to the grand parent
4. (Note changing this back to its original ID restores all functionality)
If we customise the content type (in the GUI) then what happens if we change the underlying CAML? Nothing at all, which will be a pain for most people!
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Amend the “Group” in the GUI to “GUI Group”
3. Change the “Group” in the CAML to “CAML Group”
4. Recycle App Pools
Outcome:
1. The Content Type is installed
2. The Content Types Group reads “GUI Group”
If we customise the content type (in the GUI) then what happens if we change the underlying CAML and the FORCE Activate the Feature? Nothing at all!
Test Steps:
1. Deploy a Content Type (via Feature and CAML)
2. Amend the “Group” in the GUI to “GUI Group”
3. Change the “Group” in the CAML to “CAML Group”
4. Use “%STSADM% -o activatefeature” (using FORCE)
5. Recycle App Pools
Outcome:
1. The Content Type is installed
2. The Content Types Group reads “GUI Group”
Summary
Here's a summary of my findings:
-
If a Content Type is not referenced then it can easily be removed by deactivating the Feature that deployed it.
-
If a Content Type is referenced by a child List Content Type, then you can still remove the Content Type but this will not delete the List Content Type. In this scenario, you effectively change the parent of the List Content Type to the Parent of the Content Type you just deleted.
-
If a Content Type is updated by the GUI, or Object Model then the CAML (defining the content type) will be moved into the Database and the relationship with the CAML on the File System is over (with regards to updates). (I am going to do some research into how you can reverse this situation).
-
If you do want to perform updates to Content Types and you can prevent customisations, then CAML and Upgrade Solutions is a pretty nice way to keep your schema changes owned by your development team.
So, having found all that, if you are running a SharePoint application that requires multiple updates (via Features and WSP's), it is recommended that you don't update the Content Type in anyway via the GUI. To prevent GUI updates then perhaps you could make the Content Type read-only and hidden!
As you can understand, this situation isn't ideal as once you have gone live and updated a content type you are on your own (if you customise via the GUI). Hence, Hugo has been working on an Action to add to SAF (to be released next week), that will allow you to create a Content Type, update it and also push the changes to any children. This will act as a direct replacement for the standard CAML we all currently use. This does mean that from birth your Content Type will always be in the database, but maintainable by XML that lives inside your feature. As soon as they are ready, I will update this post with links to the documentation.
Note. To find out where a Content Type is referenced, we have written an Action in the SharePoint Action Framework (SAF) to do this. The Action is called : "SynchroniseContentTypes". This action was designed push down Content Type changes to child Content Types, but, it can also run in Report only mode. When run in this mode it wont do any updating, but will give you an XML report showing the differences.
To solve these problems (and to give you the best of both worlds), why not try the "Ensure Content Type" Action in SAF. This action takes the same CAML (as you would use in a feature), but SAF processes it, instead of the standard Feature provisioning in SharePoint.
Try it out here : http://www.collaboris.co.uk/saf/doc/Collaboris.Saf.Actions.Wss.ContentType.EnsureContentType.html
To download SAF - please read here : http://saf.codeplex.com/
To see a list of all Actions in SAF, go here : http://www.collaboris.co.uk/saf/doc/
Introduction
In a previous post, I explained my findings with "Upgrading Content Types", but now I want to test out a few scenarios with upgrading Site Columns. On the whole, the test results for Site Columns were pretty similar to that of Content Types. Although, I wanted to test what we can do when it comes to updating site columns that contain data. If you don't want to read each test case, please check out the "Summary" at the end of this post.
Test Cases – Removing a Site Column
Can we remove a site column by deactivating the Feature that deployed it? Yes
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Deactivate the Feature
Outcome:
1. Site Column will be removed
2. Feature is deactivated
Can we remove a site column (thats referenced by a List Column) by deactivating the Feature that deployed it? Yes
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Add the Site Column to a List (as a List Column)
3. Deactivate the Feature
4. Recycle Application Pools
Outcome:
1. Site Column will be removed
2. Feature is deactivated
3. List Column still exists
Can we remove a site column (that has been customised) by deactivating the Feature that deployed it? No
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Change the “Column Name” via the GUI
3. Deactivate the Feature
4. Recycle Application Pools
Outcome:
1. Site Column will not be removed
2. Feature is deactivated
3. (Note. Although Deactivating via a Feature doesn’t remove the site column, it can still be deleted via the GUI).
Can we re-parent a Site Column that’s been deleted? Yes
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Add the Site Column to a List (as a List Column)
3. Deactivate the Feature
4. Recycle Application Pools
5. Activate the Feature (put the site column back)
6. Change the “Column Name” (via the GUI)
7. Select “Update all list columns based on this site column”
8. Click Ok
Outcome:
1. List Column is updated with the new name (hence re-parenting a Site Column that’s previously gone AWOL actually works).
Test Cases – Updating Site Columns
Can we update a site column by editing the CAML XML (within the 12 Hive)? Yes
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Change the “Column Name”, “Group” in the CAML
3. Recycle Application Pools
Outcome:
1. Site Column is amended as expected
Can we update a site column by editing the CAML XML, when it has child List Columns? Yes, but changes are NOT pushed down to children.
Test Steps:
1. Deploy a Site Column (via Feature and CAML)
2. Change the “Column Name”, “Group”, in the CAML
3. Recycle Application Pools
Outcome:
1. Site Column is amended as expected
2. List Column (Child) doesn’t change
Can we change a columns type from Text to Choice (when it’s not in use)? Yes
Test Steps:
1. Deploy a “Text” Site Column (via Feature and CAML)
2. Change the Type, from “Text” to “Choice” in the CAML (add some sample the Choices into the CAML)
3. Recycle Application Pools
Outcome:
1. Site Column changes type to "Choice"
Can we change a columns type from “Text” to “Choice”, when it’s in use? Yes, although this worries me!
Test Steps:
1. Deploy a “Text” Site Column (via Feature and CAML)
2. Add the Site Column to a List (as a List Column)
3. Add some test data into the column (from the list)
4. Change the Type, from “Text” to “Choice” in the CAML (add some sample the Choices into the CAML)
5. Recycle Application Pools
6. From the GUI “Push” the changes to the list column
Outcome:
1. The Site Column changes type to Choice
2. The List Column changes to Choice, although the edit form hides it, but no data is lost!
Summary
When changing the type of a column always recycle application pools immediately after. If the CAML for the Site Column is updated, then this will not cascade the changes to any child List Columns. This must be done via the GUI (using “Update all list columns based on this site column?”).
I suspect, though haven't had time to prove it that SharePoint will always allow the type of the column to change. If this change is then propagated to Lists that use it then this “may” result in loss of data, or some weird casting error. E.g. Text > Number.
Once again, this has short comings as once the Site Column is customised, it can no longer be changed by updating the CAML on the file system. (This is because its definition will reside in the database).
To solve these problems (and to give you the best of both worlds), why not try the "Ensure Site Column" Action in SAF. This action takes the same CAML (as you would use in a feature), but SAF processes it, instead of the standard Feature provisioning in SharePoint.
Try it out here : http://www.collaboris.co.uk/saf/doc/Collaboris.Saf.Actions.Wss.Column.EnsureSiteColumn.html
To download SAF - please read here : http://saf.codeplex.com/
To see a list of all Actions in SAF, go here : http://www.collaboris.co.uk/saf/doc/
A couple of you emailed and asked how to install SAF, so here's some instructions.
Installing...
If you have never insalled SAF on your SharePoint Farm then you need to install. To do this, you need to use STSAdm commands which I have popped into a batch file. Hence follow the steps below :
- Logon to a SharePoint Server in your Farm as a Farm Administrator.
- Download "Install.bat" to that server in your SharePoint Farm (right click "Save Target as...")
- Remove the '.txt' extension.
- Download the latest version of SAF from "http://saf.codeplex.com/".
- Extract "SAF.wsp" to the same folder as the batchfile in step 2.
- Ensure the path in STSAdm in "install.bat" is correct.
- Run "install.bat"
Upgrading...
If you already have a version of SAF on your Farm and want to upgrade to a newer version, please complete the steps below :
- Logon to a SharePoint Server in your Farm as a Farm Administrator.
- Download "Upgrade.bat" to that server in your SharePoint Farm (right click "Save Target as...").
- Remove the '.txt' extension.
- Download the latest version of SAF from "http://saf.codeplex.com/".
- Extract "SAF.wsp" to the same folder as the batchf ile in step 2.
- Ensure the path in STSAdm in "install.bat" is correct.
- Run "upgrade.bat"
Well, the hayfever has got me again! Here I am at 6am with a bunged up nose and itchy eyes wide awake. So I thought I would do the sensible thing and give you a heads up on what’s due in the next release of SAF.
Here’s the Feature list :
New Actions
STSAdm Action. This allows us to call STSAdm commands and pass arguments from a SAF Macro.
Powershell Action. Allows us to to call Powershell “Function” and pass arguments from a SAF Macro.
Adapters
In SAF, we think of “Adapters” as being components that allow a SAF Macro to be run from a particular technology. In the current release we have :
STSAdm Adapter. Allows you to run SAF from an STSAdm extension.
Feature Adapter. Allows you to SAF run from a SharePoint Feature. This is simple as creating a Feature.Xml and a Macro.xml file. Check out the Quick Start for more info.
In the next release here’s what’s coming :
MSBuild Adapter. This will let you hook SAF directly into your MSBuild process. This is going to pretty useful for companies that already have a MSBuild process, but want to hook SharePoint automation in too.
WCF Adapter. This could be one of the most powerful adapters out there. It’s effectively going to allow you to run SAF remotely. eg. if you are working locally on a SharePoint DEV farm and want to push some SharePoint changes to a different farm then (say QA), then this will let you do that. If you mix this concept with the use of Gary LaPoint’s awesome STSAdm extensions, then wow – we have just given you a way to run tons of STSAdm commands (or Powershell scripts) remotely!
Visual Studio DSL
Not sure this will make the next release, but, we are intending to write a GUI in Visual Studio that will allow you to create a Macro using Graphical canvas to do so.
Changes to the SAF Context
If you don’t know – the SAF Context is pretty much a Prop Bag that gets passed between one Action to the next. We have made some changes to make this Serializable. There are good reasons for this which I will cover in a later post.
When’s the next release?
Hugo has booked a few weeks into the diary to work on SAF (and Macro Centre using SL3), so we should see a release late next week once he’s finished it. (But we are close!)
I am pleased to announce that it’s now possible (with release 1.2.3463.00) , to run STSADM commands from the SharePoint Action Framework (SAF). Hence, if you add the standard STSAdm commands (that ship with SharePoint) to the truly awesome collection that Gary Lapointe has developed, (available on his STSADM Blog), you are looking at over 250 useful SharePoint Actions.
This functionality has been made available by a new Action called “StsAdm”. The Action should be called via an Alias like this “Action.StsAdmin”. (Aliasing is for convenience so that you don’t have to put the full 4 part assembly reference into the Macro).
An example :
This example illustrates how to create a Macro that calls the new Action and executes 2 STSAdm commands to delete a group and also create the group.
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<!-- Defines the main macro to process -->
<object id="MacroToProcess" type="Macro" >
<constructor-arg name="id" value="{8BB25F02-5E41-4e86-BCA2-E253747354A3}" /> <constructor-arg name="actions">
<list element-type="IAction">
<!-- Runs the STSAdm Command-->
<object name="RunStsAdminCommands" type="Action.StsAdmin">
<property name="EntityList" ref="StsAdminCommandList"/>
<property name="StopOnDoException" value="false"/>
</object>
</list>
</constructor-arg>
</object>
<!-- Holds a list of individual list Items to export -->
<object id="StsAdminCommandList" type="Entities">
<constructor-arg>
<list>
<!-- Delete the Group using STSADM -->
<object type="Entity.StsAdminCommand">
<property name="Operation" value="deletegroup" />
<property name="Arguments">
<dictionary key-type="string" value-type="string">
<entry key="url" value="${CurrentWeb.Url}"/> <entry key="name" value="SAF Demo Group"/>
</dictionary>
</property>
</object>
<!-- Create the Group using STSADM -->
<object type="Entity.StsAdminCommand">
<property name="Operation" value="creategroup" />
<property name="Arguments">
<dictionary key-type="string" value-type="string">
<entry key="url" value="${CurrentWeb.Url}"/> <entry key="name" value="SAF Demo Group"/>
<entry key="description" value="This is a group create by SAF"/>
<entry key="ownerlogin" value="${CurrentUser}"/> <entry key="type" value="owner"/>
</dictionary>
</property>
</object>
</list>
</constructor-arg>
</object>
</objects>
The StsAdmin Action
As can be seen from the example above, it’s pretty straight forward to use the StsAdmin command. You use the Action by adding this line :
<object name="RunStsAdminCommands" type="Action.StsAdmin">
<property name="EntityList" ref="StsAdminCommandList"/>
<property name="StopOnDoException" value="false"/>
</object>
The StsAdminCommand Entity
As with every Action, all of the parameter information is passed into the Action via a simple Entity. The Entity in this case is called “Entity.StsAdminCommand”. This entity has 2 properties that need to be passed, the Operation and the Arguments. Please Note! It’s possible to supply as many entities as you like. These will all get executed as separate STSAdm commands.
<object type="Entity.StsAdminCommand">
<property name="Operation" value="deletegroup" />
<property name="Arguments">
<dictionary key-type="string" value-type="string">
<entry key="url" value="${CurrentWeb.Url}"/>
<entry key="name" value="SAF Demo Group"/>
</dictionary>
</property>
</object>
By supplying the Action (with its entity) this is equivalent to writing :
STSADM -o deletegroup -url http://localhost -name -“SAF Demo Group".
Note! The “${CurrentWeb.Url}” line, shown in the example, is called a Placeholder and will substitute the value with real “url” at runtime.
That’s pretty much it. You can now call any STSAdm command available by supplying a correct “Operation” and dictionary matching the parameters that the command takes.
Download SAF from http://SAF.Codeplex.com.