Thursday, 23 February 2012

Tag a SharePoint 2010 Site with PowerShell (PropertyBags)

Here's an easy one. My current project requires quite alot of automation. It's a migration but prior to migration I am rolling out over 100 sites of varied type, each type of site has it's own roll-out requirements such as web parts, lists, content types and so forth all being built, configured and deployed from powershell.

It's all publishing sites, so saving as a template is out of the question and building the custom site definitions in Visual Studio 2010 (although would be best practice) - was also ruled out during the planning phases. I'll explain why in some other post.

A common question, and perhaps limitation of SharePoint 2010 is the lack of site directories - you can't associate meta-data with a site or subsite like you can an item and so forth.

For this reason, we're using site property bags, on deployment we set the metadata for each site, then as my later scripts go round to make changes they can reference the site properties to add a little logic.

First, get the site properties.

$siteUrl = http://sharepointSite/subsite/targetSite
$web = Get-SpWeb $siteUrl
$web.properties

you will see some standard out of box properties like default language, a property for the custom upload page.

To add properties to the site property bag:

$siteUrl = http://sharepointSite/subsite/targetSite
$web = Get-SpWeb $siteUrl
$web.properties["customProperty1"]="propertyValue"
$web.properties["customProperty2"]="Another propperty value"

calling another $web.properties will show you your new properties,
you can reference them directly using $web.properties["customProperty1"].


Have Fun!

Ryan

Thursday, 26 January 2012

Update a Content Query Web Part using Powershell

Here is a quick little script you can use to change the properties of a content query web part using powershell. I have a whole load of them to do post-deployment and i'm dynamically building the query to do so.

I am using SharePoint 2010 Publishing with a subsite called "news" being deployed with every site. On the home page of each site we have a styled content qeury web part which is being populated from the "news" subsite. I did an export of the content query web part (along with several others) and because i'm doing everything in powershell to automate the deployment, i figured i'd dynamically update the web parts after they have been deployed. That allows me a litttle more control later.


#Set the Site Url and find our publishing page.
$SiteUrl = http://sharepointsite.sharepoint/subsite

$WpWeb = Get-SPWeb $SiteUrl
$PageFolder = $WpWeb.GetFolder("pages")
$Page = $PageFolder.Files Where-Object { $_.Name -eq "default.aspx" }

#Check the page out
$Page.CheckOut()

#Find our web part - the one i'm looking for is "Latest News" and it's visible to all.
$AllWebParts = $WpWeb.GetWebPartCollection($page,"Shared")
$MyWebPart = $AllWebParts Where-Object { $_.Title -eq "Latest News” }

In my case, want to update the WebUrl property to point at my $SiteUrl+"/news" -
just type $MyWebPart if you want to see all of the available properties.

#Update the property. I want to ALWAYS point to the subsite of my current site
$MyWebPart.WebUrl = $siteurl+"/news"
$MyWebPart.ItemLimit = "5"

#Save changes to the web part it's self & Check in and publish -
$AllWebParts.SaveChanges($MyWebPart.StorageKey)
$Page.Update()
$Page.CheckIn("")
$Page.Publish("")

#Because its a publishing page - we'll approve it.
$pweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($WpWeb)
$publishingPage = $pweb.GetPublishingPages() Where { $_.Name -eq "default.aspx"}
$publishingPage.ListItem.File.Approve("Page approved by ps")

#job done
$pweb.dispose()
$WpWeb.Dispose()




Right, thats all for today.
Have Fun!

Thursday, 19 January 2012

Add a Publishing Page and Set it to Default Welcome Page with custom Page Layout (PowerShell)

As part of a rather extensive process, i am currently writing a site structure deployment script that gets around the problem of being unable to deploy Publishing Sites from a template.

Instead, I've built my publishing site templates in a dev environment, exported the pages to XML, and using that xml, I am deploying brand new sites from the out of box Publishing template, and carefully reconstructing each site to match my template. I am doing this via powershell (of course) and using an excel sheet with all of the site types pre-defined.

A big issue I had was applying a custom page layout to the default.aspx page produced by the out of box template - I decided that this wasn't best practice and instead - I create a "Home.aspx" file, set it as default welcome page and apply my custom page layout.

As a taster, here's how I am creating the new pages, applying the custom page layout and setting them as default, welcome page BEFORE importing all of the default site content, and most importantly, the page content.

function CreatePages([string]$SiteUrl, [string]$PageLayoutName)
{

$site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
$psite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($site)
$web = Get-SPWeb $SiteUrl
$pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)

#Create new Page(s)
$pl = $pubWeb.GetAvailablePageLayouts() Where { $_.Name -eq $PageLayoutName }
$newHomePage = $pubWeb.AddPublishingPage("home.aspx", $pl)
$newHomePage.Update()

# Check-in and publish page
$newHomePage.CheckIn("")
$newHomePage.ListItem.File.Publish("")

$newAboutPage = $pubWeb.AddPublishingPage("about-us.aspx", $pl)
$newAboutPage.Update()

# Check-in and publish page
$newAboutPage.CheckIn("")
$newAboutPage.ListItem.File.Publish("")


write-host "Published new page "

#Set new page to be the welcome (home page)
$assignment = Start-SPAssignment
$rootFolder = $web.RootFolder
$rootFolder.WelcomePage = "Pages/home.aspx"
$rootFolder.Update()
Stop-SPAssignment $assignment

write-host "Set as new default "

$site.Dispose()
$web.Dispose()

}

As you can see, I'm passing in just the "NAME" of the page layout, using [Microsoft.SharePoint.Publishing.PublishingWeb.GetAvailablePageLayouts() and a filter to bring back JUST that page layout.

Here we create the new page and apply the page layout.

$newHomePage = $pubWeb.AddPublishingPage("home.aspx", $pl)
$newHomePage.Update()


At some point, I will do a break down of the entire script. It does quite alot and is a pretty good alternative to a custom site defination. Although - given more time and resource, a custom site definition is the best way to solve this problem.


Have fun!
Ryan

Tuesday, 10 January 2012

3 Ways to Save SharePoint 2010 Publishing Sites as a Template

Well first post of 2012 - last year was a fantastic year filled with all sorts of juicy SharePoint solutions. I have a few blog posts in Draft that I am looking forward to publishing about powershell, DPM and Property Bags, but for now heres a wee easy one that might save you some time!

I'm currently tasked with packaging a series of 2010 publishing sites, the challenge in doing so is not only that it's "not supported by Microsoft" but publishing makes it exceedingly difficult.

All of our sites for this particular part of the project are publishing sites and have all been pre-created on a lab. The requirement is that following the standard new-site creation practice, a fully customised publishing site (with subsites!) is deployed from site template.

To do this, I saved the top level Publishing Site as a template, imported it into Visual Studio 2010 and added the subsites etc. More about this later.

I discovered that you can't save a site as a template once publishing features are enabled. I found 3 ways of getting round this but be warned, it's not supported by MS. Infact, it's claimed that publishing sites saved as templates and redeployed won't upgrade later.

Anyways, first thing you can do is go to your site http://sharepoint.net/MyPublishingSite

you'll notice that "Save Site as Template" is missing from site actions. Here is 3 ways in which you can do this.

1. Go straight to the save template page

just add "/_layouts/savetmpl.aspx" to your url.
http://sharepoint.net/MyPublishingSite/_layouts/savetmpl.aspx
This will let you save "MyPublishingSite" as a template.

If you really want to knock SharePoint out of support (it's ok for labs or dev machines) –

2. Edit the PublishingSiteSettings.xml file in the hive.

C:\PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\WEB SERVER EXTENSIONS\12\TEMPLATE\FEATURES\PUBLISHING

Open PublishingSiteSettings.xml in notepad.

At the bottom there’s a tag for HIDECUSTOMACTION.

Comment it out like so:

<!--<HideCustomAction Id="HideSaveAsTemplate" HideActionId=”SaveAsTemplate" GroupId="Customization" Location="Microsoft.SharePoint.SiteSettings" /> -->

Then add the custom action for saving as template:

<CustomAction Id="SaveAsTemplate" GroupId="Customization" Location="Microsoft.SharePoint.SiteSettings" Rights="AddAndCustomizePages,BrowseDirectories,ManagePermissions,ManageSubwebs,ManageWeb,UseRemoteAPIs,ViewFormPages" Sequence="60" Title="$Resources:SiteSettings_SaveAsTemplate_Title;"> <UrlAction Url="_layouts/savetmpl.aspx" /> </CustomAction>

3. Use PowerShell

$Web=Get-SPWeb http://sharepoint.net/MyPublishingSite
$Web.SaveAsTemplate(“Template Name”,”Template Title”,”Template Description”,1)

That’s it, have fun!

Friday, 4 November 2011

SharePoint and DPM Protection

Been tasked with setting up and configuring DPM (Microsoft Data Protection Manager 2010) to provide disaster recovery and granular backups to a domain of development servers.

The domain its self has everything, domain controllers, exchange, sql cluser(s), sharepoint 2007 multi server farms, sharepoint 2010 multi server farms and plenty of single server instances to worry about. The domain is a virtualised domain with some impressive tin and plenty of resources so its used globably by the company i work for.

I've been using my increasing powershell kung fu to automate and batch most of the process but before I write some posts about what i'm doing and how - on a farm this big I needed to make sure I knew the basics of DPM and specifically doing it for Sharepoint.

I found a fantastic post that helps me do just that and wanted to share.

http://scug.be/blogs/scdpm/archive/2010/03/11/sharepoint-2010-protection-in-dpm-2010-part-1.aspx


Have fun!

Wednesday, 26 October 2011

Update SharePoint User Profile for all users in a Active Directory Distribution List

Putting my 2010 project work aside, I was asked to programmatically update each users "User Profile" that was a member of a group (Distribution List) in active directory. In my case, I had to create a custom user profile property called "location". I then had to map each person from their DL in AD to a location in their user profile.


So if I am based in "Glasgow" and I am in the Active Directory Group "Scotland_All" - they wanted some code to update my user profile property, on a mass scale (12,000 users)..


I did some googling before i set about the task but didn't find very much so figured i'd post a quick how-to.


First I went through active directory to get all users that were a member of X group.





const string ADaddress = "domain.com";

const string ADuserName = @"domain\admin";

const string ADPassword = "DomainAdminPassword";

const string ad_group = "Xgroup";

const string domain_name = "Domain"; //not entirely needed

const string sp_site = "http://yourSharePointSite.domain.com";

const string location_value = "Value";




I had to use an account and password with access to AD.






try

{

//Create connection to AD and get all users in specified group

PrincipalContext ctx = new PrincipalContext

(ContextType.Domain,

ADaddress,

ADuserName,

ADPassword);



//Search for members in group

GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, ad_group); //CL_France being the DL we need

PrincipalSearchResult members = group.GetMembers(); //getting them all



//Get the user names and add the domain (we are assuming that all these users will be "s7")

foreach (Principal member in members)

{

string domainUserName = domain_name + @"\" + member.SamAccountName;



//Update in Sharepoint

UpdatespProfile(domainUserName);

}

}

catch (Exception ex)

{

Console.WriteLine(ex); //show me the error

Console.Read(); //pause



}

}




Once have the users details, I start updating their user profile. This is done using the object model so the console app was run locally. It can be done via web services but with so many users and transactions I found that simelar tasks would time out..





//take user names, check they have a user profile - if they do, update "localtion" field

static void UpdatespProfile(string uName)

{

//show user in console

Console.WriteLine(uName);//member.SamAccountName);



try

{



using (SPSite site = new SPSite(sp_site))

{

//Connect to user manager and pass in user name

UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(site));

UserProfile userProfile = profileManager.GetUserProfile(uName);



//check if we have a valid user profile

if (userProfile != null)

{



//Update location field

userProfile["Location"].Value = location_value;


//update the user profile

userProfile.Commit();



//show it worked in console

Console.WriteLine("Updated Location to" +" " + location_value);



}

else

{

//show we didn't have a valid user profile in console

Console.WriteLine("No user profile");

}

}

}

catch (Exception ex)

{

//show the error

Console.WriteLine(ex);

//pause

Console.Read();

}

}



Works very nicely. Hope someone out there finds it useful.

Thursday, 25 August 2011

Upcoming Posts

Having started a new contract last month working predominately on the infrastructure, administration and consultancy side of SharePoint I am missing development a little but in the meantime getting my hands very dirty with some work i'll be blogging in the near future.

I have been particularly working with Powershell, Hyper-V and SharePoint.

Recently I designed and implemented a full new Development lab infrastructure which allows new stand-alone SharePoint 2010 servers to be deployed in Hyper-V with almost 0 configuration from the deployment agent.

In otherwords, I have scripted and automated the entire process using Poweshell with the following processes automated:

  • New Virtual Machine created from clone of base server
  • New virtual machine configured
  • Powershell scripted configuration of the operating system installation
  • powershell scripted configuration of networking, renaming the machine, joining the domain
  • Powershell scripted configuration of a Sql server 2008 pre-deployment image
  • Powershell scripted installation of SharePoint 2010
  • Powershell scripted configuration of SharePoint 2010 configuration database and new farm
  • powershell scripted deployment of new SharePoint 2010 farm
  • powershell scripted deployment of web applications and site collections
  • powershell scripted configuration of SSP
  • Powershell scripted configuration of search services
  • powershell scripted server security configs, terminal services and so forth
  • powershell scripted assignment of Alternate access mappings to allow remote access

Basically a fully functioning development lab, fully scripted and deployed in less than 1 hour with no manual overhead for the user other than initiation the process.

I hope to blog most of the process, in particular the scripts them selves and while many other people have deployed similar scripts, the dynamic nature of this type of deployment means they can be re-used in many scenarios.




Friday, 28 January 2011

New laptop



It's come time to get a new work laptop - I've always been a DELL man, having worked there twice in my career - first as a tech support guy for their laptops and onwards into software.

I was looking at the DELL XPS laptops and reviews. My old one was an XPS M1730 - At the time I got it one of the best laptops on the market. Was fantastic for gaming, Virtual machines, had a huge screen but it was also exceptionally large and heavy. It was also quite flashy with glowing vents and XPS logos etc. The screen was amazing and had a really high resolution for a laptop. This allowed me to work without feeling constricted.

Having reviewed all the newer "slicker" XPS laptops I am torn between the new XPS 17 laptop. It looks really sleek, has a great spec and doesn't require weightlifting training to carry it around!


Nice hi res screen, good graphics card and sound engine along with a fairly good spec.

however.. At the same time, I am a huge fan of Alienware. I own the Area51 ALX Desktop - easily the most powerful, coolest looking home gaming computer on the market and I am tempted to go for the new Alienware M17x Laptop




Everything about this laptop is "cool" - its extremely powerful with a standard build of 6gb of ram, a TB of hard disk space on a raid array. I7 processor with. its also very durable and the screen is not only 1200p but has 3d capability.

I'll decide at the weekend which one I am going to buy - I like new toys and from a work perspective; either of these laptops will handle pretty much anything I throw at them. The only drawback is the price. The alienware is almost £1000.00 more expensive!


*edit:

Went with the XPS :)

2.93 ghz CPU i7 Quad Core
16 GIG DDR
500 GB Hard Drive
Windows 7 Ultimate 64BIT
3GB Graphic Card
Built in Wireless
DVDRW / BluRay
UK Spec
USB 3.0 Technology
9 Cell Battery
JBL 2.1 Designed & Certified Speakers +Waves MaxxAudio®
2.1 Audio: 2 X 5W + 12W sub-woofer 22W Total
Integrated Camera
15 Months McAfee Anti Virus
Computrace LoJack so it can't get pinched :)





Tuesday, 24 August 2010

Rational Guide to implementing SharePoint Server 2010 User Profile Synchronization (Link)

Just thought i'd share an absolutely fantastic post on setting up User Profile Sync in SharePoint Server 2010

As the guy says, there are tones of "guides" and tuition on this available on the net but hopefully landing here, or following here (all 2 of you) will save you the hassle. -All credit to the author, of course.

life saving!

http://www.harbar.net/articles/sp2010ups.aspx

Just remember to do the damn IIS Reset at the end lol

Ryan ;)

Wednesday, 26 May 2010

Track Any Download in SharePoint using Google Analytics

,,,,,,,,

Ryan Mathieson wrote:

SharePoint and Google Analytics: Track external downloads and who’s downloading them

Loads of posts available explaining how to track downloads from document libraries and lists but not external links or content links written into HTML Content fields in publishing pages. After some time fiddling around with different ideas this very basic little script can be adapted to most requirements.

My requirement was simply to track forms based authenticated users downloading PDFs using Google analytics and build a report on it. The challenge was that the downloads being tracked could be document libraries, lists, external links or files sitting in IIS (don’t ask..)

 

<%@ Import Namespace="Microsoft.SharePoint" %>

<script type="text/javascript">

    var loginName = "<%= SPContext.Current.Web.CurrentUser.LoginName %>";   

</script>

<a href="#" onClick="javascript: pageTracker._trackPageview('/downloads/PDF/' + loginName); ">

 

In my case i put the <script> into my page layout and in the html fields on the page, I would add the link with the onClick event. This worked perfectly.

 

 

 

Wednesday, 24 February 2010

Define Site-Level Search scopes using master pages

Introduction

My client has a custom public facing Web Content Management SharePoint solution on the web. Their requirement is that within certain areas of this public site searches submitted by users only search the current area they are in.

To achieve this; a Search Scope was created specific to each site using Microsoft Office SharePoint Server, Shared Services provider. A search scope defines a subset of information in the search index. Normally used in the context of allowing a user to select a search scope when performing a search in order to restrict search results to within that search scope. Typically, search scopes encompass specific topics and content sources that are important and common to users in the organization and selection of the desired search scope is done using the standard SearchBox web part for MOSS providing a drop down to the user.

In our scenario; searches are taking place from one central input control on the Master Page of the site collection and our search scope selection is based definitively on the current area of the site in which the user performs the search.

Use Example: If a user navigates to: http://sharepointsite.com/subsite/contentsite/. Our user is in the current site “contentsite” which in this case is a site collection defaulting to the “/pages” with no document libraries, lists or additional content as it is a public facing SharePoint site. When a user submits a search from this site his returned results should be all pages and documents within the Trustees site and its subsites without returning unnecessary SharePoint content.

Defining Search Scopes for Public Facing SharePoint Site

our site is a public facing WCM (Web Content Management) version of SharePoint and configuring search on this site is more advanced than on an out-of-box Intranet or publishing solution. Standard SharePoints search results include all content of the site, its subsites and all of the resource content such ass CSS, JavaScript, XSL, Images, Administration list, User Profiles and more. For public facing site the search experience must only return relevant results based on the content and context of the web site.

Search Scope Configuration

Searches using these scopes will return anything that is in the content source “Site” AND (the content is a publishing page OR the content is a document). If you need to know more about defining content sites, click here

The logic of these rules are as follows:

  • Include = OR
  • Require = AND
  • Exclude = AND NOT

The ‘contentclass’ property specifies what type the indexed item is and will be automatically available for any content item in SharePoint. The two types that we are specifically targeting are:

  • STS_ListItem_850 (Publishing Pages)
  • STS_ListItem_DocumentLibrary (Documents)

SubsiteA

Title:

SubsiteA

Description:

Search scope specific to SubsiteA site & subsites

Rules

Behavior

Folder = http://SharePointSite.com/SubsiteA

Require

contentclass = STS_ListItem_850

Include

contentclass = STS_ListItem_DocumentLibrary

Include

ContentSource = Site

Require

Search Field Customisation

Determining which search scope is to be used is done programmatically. Search queries are inputted using a field on the master pages of the site rather than an independent control on the page or web part. This means that on the event where a user submits a search it will execute a search query against the Enterprise Search in Microsoft Office SharePoint Server 2007 service by encoding the query in a URL and posting it to the custom search page.

When doing this we are passing two parameters: http://SharepointSite.com/Utils/Pages/SearchSite.aspx?k=Keyword&s=SubsiteA

  • K=”Keywords” – The keywords submitted by our user
  • S=”Scope” – The scope which will be used to run our query against

Posting from master page

Before implementation of this solution, the search button event posted just the keyword to the search centre producing a site collection level search:

protected void ImageButtonSearch_Click(Object sender, ImageClickEventArgs e)

{
Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text);
}

http://SharePointSite.com/Utils/Pages/SearchSite.aspx?k=Keyword

This has been extended to:

protected void ImageButtonSearch_Click(Object sender, ImageClickEventArgs e)

{

SPSite site = new SPSite(Page.Request.Url.AbsoluteUri);
SPWeb web = site.OpenWeb();
string strSiteTitle = web.Title;
string strParentSite = web.ParentWeb.Title;

if (strSiteTitle == "SubsiteA" || strParentSite == "SubsiteA")
{
Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text + "&s=SubsiteA");
}

else

{

Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text);

}

}

This code utilises the Microsoft SharePoint 2007 development API first of all opening a connection to the current site. Once the connection is open the Site Title and the Parent Site Title are stored.

The code then checks if the Site Title or Parent Site Title matches the conditions that it is one of our site level search enabled sites. At which point it passes the extended url string to the search centre including which scope to use. In our case any searches within the upper level subsite area and all of its subsites are included. A more specific rule can be created by removing the parentsite condition.

NOTE: The name of the scope being used must be identical to the Title of the search scope and case sensitive. An invalid scope title passed into the query will return zero search results with no error.

Deployment

Presently the above code is deployed by being produced on each master page used by selected pages in the scope of this implementation. For future implementations it may be more appropriate to develop and install a custom SharePoint Feature which processes all search queries across the entire site. This would be viable on a larger scale implementation where by each site (every site) had predefined processes and search scope requirements.

The scope of this implementation is focused on the above pages and does not justify the design, development, deployment and testing requirements of implementing a site wide custom search handler feature although that would probably be the best way to do it.

Monday, 16 February 2009

SharePoint application templates installer

Automating the process of installing SharePoint 2007 Application Templates

The application templates supplied by Microsoft are almost considered to be a standard feature of SharePoint. Anyone looking up SharePoint will come across them and inevitably want to try them out, if not deploy them to a large scale environment!

If you have not installed these templates before, its worth a go doing it manually.
The installation typically involves copying or downloading the files onto the SharePoint server, running stsadm -o addsolution -filename -title -immediate/local -allowgacdeployment. which doesnt sound like alot but when you have 20 of these, and 20 uploadable templates it gets a tad tedious.

see here for more information


There are several bat files you can download which do a mass install, but they don't do individual installs, they don't do mass removals and a couple of them are quite poorly designed..

This system:

  • optionally installs the application template core
  • presents a menu to install all & individual templates or deleting them
  • writes to a log so you can check why something might have failed
  • is commented through out for easy editing


Automation
I do these templates alot, there is usually a day put aside to configure all of the templates and test them but from now on, installing these templates where needed will be an addition to my SharePoint install routine. Automation of this task comes int he fashion of a .BAT file, its light - took 10minutes to develop, can be edited on a whim and does exactly what it supposed to so i saw no reason to get VS out and start writing an installer as such.

The purpose of this post is to tell you about how the bat file installs the application templates and how to edit the file if you wish, if your just looking to download the file - click here.


GOTO :CORE

The first thing this bat file asks when you run it is "Has APPLICATION TEMPLATE CORE been installed already?" - This is because i don't like the idea of running checks from a bat file and further more, i don't like the idea of re-installing the core every time we install a template, this will lengthen how long each install takes etc so its asked immediately and should be the first thing the user does. If a user isnt sure, i've suggested installing it anyway. once the user has selected Y, they won't see this question again until next time they run the bat file.

If the user selects "N" for No, then the application template is installed by the bat file


set fname="ApplicationTemplateCore.wsp"
set ttle="Application Template Core"
SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
echo.
echo Adding Solution: %fname%
%STS% -o addsolution -filename %fname%
echo.
echo deploying solution: %ttle%
%STS% -o deploysolution -name %ttle% -allowgacdeployment -immediate
ECHO.
ECHO.
ECHO Copying app bin content.
ECHO.

%STS% -o copyappbincontent

ECHO.
ECHO App bin content complete.
ECHO.
ECHO.
ECHO Executing jobs.
ECHO.

%STS% -o execadmsvcjobs
ECHO.
ECHO Ready to reset IIS.
iisreset -noforce
ECHO.
ECHO CORE HAS BEEN INSTALLED
ECHO.
pause

The application template has to be installed for the templates to work, its the first thing an admin should do before installing the templates. The line marked red indicates a field which should be edited, in some instances you will need to select -local instead of -immediate.

Now our menu
:




GOTO: INSTALLALL

As it says on the tin, you can now install ALL application templates, install individual application templates or start removing them from the system. NOTE: Application template core is not removed

this is done like so:


:installall

CLS

SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"

FOR %%G IN (\templates\*.wsp) DO (
ECHO %%G start
%STS% -o addsolution -filename %%G
%STS% -o deploysolution -name %%G -allowgacdeployment -immediate
ECHO %%G end
ECHO.
ECHO.
)

ECHO Copying app bin content.
ECHO.

%STS% -o copyappbincontent

ECHO.
ECHO App bin content complete.
ECHO.
ECHO.
ECHO Executing jobs.
ECHO.

SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"

FOR %%G IN (\templates\*.stp) DO (
ECHO %%G start
%STS% -o addtemplate -filename %%G -title %%G
ECHO %%G end
ECHO.
ECHO.
)

%STS% -o execadmsvcjobs

ECHO.
ECHO Ready to reset IIS.
PAUSE

iisreset -noforce

ECHO.
ECHO Jobs complete.
ECHO.
ECHO.
ECHO Back go menu
ECHO.

PAUSE
GOTO :Start

This installs all of the application templates from within the TEMPLATES folder, it does both the .wsp files and the .stp files using a separate command. %STS% -o execadmsvcjobs is used to then run any jobs that are backed up by SharePoint (happens alot) and then its all finished off with an IIS Reset.

You'll have to monitor the bat file as it installs these templates to check that no errors occur, if an error does occur it continues on with its tasks and won't alert you. If you don't have 5 minutes to watch this process then check the log.txt file which is output and make sure everything installed successfully.

GOTO :INSTALLINDV

Another cool feature of this tool is the ability to quickly install one or more of the application templates required at a time, when you select this in the menu you'll be presented of a numbered list of all the templates and you can decide which ones to install.



Each template has its own command line call, and its own properties, which are passed into one of two method type installation processes called either :installindv or :installwsp. An example of an stp file install would be:

:add20
set fname="\templates\TimecardManagement.stp"
set ttle="Timecard Management"
GOTO :InstallIndv

:InstallIndv
ECHO.
ECHO Adding Template
SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
%STS% -o addtemplate -filename %fname% -title %ttle%
ECHO.
ECHO Template %ttle% Added
ECHO.
ECHO.
ECHO.
ECHO Copying app bin content.
ECHO.
%STS% -o copyappbincontent
ECHO.
ECHO App bin content complete.
ECHO.
ECHO.
ECHO Executing jobs.
ECHO.
%STS% -o execadmsvcjobs
ECHO.
ECHO Job complete.
ECHO.
ECHO.
ECHO Ready to reset IIS.
iisreset -noforce
ECHO.
ECHO Back to selections
ECHO.
pause

GOTO :addselect

once this is complete, the user is presented with the menu and that template is installed. If a user attempts to install the same template again, they will get an error saying that it already exists.
adding -force to %STS% -o addtemplate -filename %fname% -title %ttle% would resolve this issue and do a clean re-installation of that template. Alternatively remove it and re-add it.

an example of a wsp (SERVER ADMIN TEMPLATE) is:


:add21
set fname="\templates\AbsenceVacationSchedule.wsp"
set ttle="Absence Request and Vacation Schedule Management "
GOTO :Installwsp

:Installwsp
CLS

SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
echo.
echo Adding Solution: %fname%
%STS% -o addsolution -filename %fname%
echo.
echo deploying solution: %ttle%
%STS% -o deploysolution -name %ttle% -allowgacdeployment -immediate
ECHO.
ECHO.
ECHO Copying app bin content.
ECHO.

%STS% -o copyappbincontent

ECHO.
ECHO App bin content complete.
ECHO.
ECHO.
ECHO Executing jobs.
ECHO.

%STS% -o execadmsvcjobs
ECHO.
ECHO Ready to reset IIS.
iisreset -noforce
ECHO.
ECHO Back to selections
ECHO.
pause
GOTO :addselect



The main difference between the installation of a server admin template and a site admin template is simply that a site admin template just has to be added to the site template store while a server admin template has to be installed and added to the global assembly cache before it will be run and "trusted" by SharePoint.

GOTO :REMALL
The application templates can now be removed in full, again - this won't remove the application template core and DOES NOT REMOVE ALL TEMPLATES. the remove all option only removes SERVER ADMIN TEMPLATES as it uninstalls them. to remove the site admin templates:

  1. Log into your SharePoint site as the site Administrator.
  2. From the Site Actions drop-down menu in the top right,
  3. select Site Settings.
  4. Under the Galleries section, select Site templates.
  5. In the list of site templates, find the application template you wish to remove and click the Edit link.
  6. Confirm that this is the application template you wish to remove. If so, select Delete Item.
  7. Click Ok to confirm the deletion.
  8. The application template is now unavailable to SharePoint sites and has been removed from your SharePoint site template gallery.

Our bat file removes all server admin templates individually like so:

:Remallwsp
SET STS="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
echo.

set fname="AbsenceVacationSchedule.wsp"
set ttle="Absence Request and Vacation Schedule Management "
echo retracting solution %fname%
%STS% -o retractsolution -filename %fname% -force
echo Deleting solution: %ttle%
%STS% -o deletesolution -name %ttle% -force


Now that they have all been removed. they have to be re-added and won't appear in the site templates gallery. Further to that, if the application templates are removed in full, then any sites created from these templates will no longer work.

GOTO :END

Now that you can see how the bat file works and how to edit the very basic properties of it, you can go ahead and write your own solution to performing these tasks.

Of course, you can download mines here, but i take no responsibility for it. Feel free to contact me for advice with it but please use at your own risk.

Thats all for now,

Ryan

Tuesday, 10 February 2009

MOSS 2007 PDF ICON

Adding the .PDF Icon to MOSS 2007


How many SharePoint projects have you done where a week after the implementation, you get an email from the customer about the .PDF icon not existing in document libraries.

By now you probably no doubt know how to resolve the problem,

  1. Download This is the icon from Adobe.

  2. Save to TEMPLATE\IMAGES directory. (DEFAULT: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\template\images)

  3. Open the file docicon.xml. (DEFAULT: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\template\xml\docicon.xml)

  4. Add a new Mapping element to the ByExtension element.


    NOTE: Be sure to change pdficon_small.gif to whatever image you downloaded to represent pdf documents.

  5. Save the edited docicon.xml file.
  6. Restart IIS (iisreset /noforce).

Thats a fine fix and not too manual compared to some other fixes that are repeatedly done but recently ive been working on minimizing the amount of time i need to spend doing these tasks and writing some batch files to simplify manual fixes like this.

I have zipped up this fix so you can download it.

Download it here

the zip file contains
  • DOCICON.XML (with ammendments)
  • PDF16.Gif
  • PDFICON.BAT
the bat file does 4 things:

copy pdf16.gif "c:\program files\common files\microsoft shared\web server extensions\60\template\images\pdf16.gif" /y

this line copies the file into the images folder on the SharePoint server

rename "c:\program files\common files\microsoft shared\web server extensions\60\template\xml\docicon.xml" docicon.old

this line renames DOCICON.XML so that it can be restored if required

copy docicon.xml "c:\program files\common files\microsoft shared\web server extensions\60\template\xml\docicon.xml" /y

this line copies across the new DOCICON.XML file

iisreset /noforce

Resets IIS committing the changes

How to use

Extract the zip file to anywhere on your front end server(s) and run "pdficon.bat."


Ryan!