Sharepoint Trace for debugging
May 27
in web.config set:
<SafeMode MaxControls=”50″ CallStack=”true“/>
<customErrors mode=”Off”>
May 27
in web.config set:
<SafeMode MaxControls=”50″ CallStack=”true“/>
<customErrors mode=”Off”>
May 27
The other day, I had an issue importing User Profiles and Properties from Active Directory. In this case my MOSS server is on a child domain and it could import the child domain’s objects, but it could not import the objects from the parent domain. Checking the log, I saw an error like the following.
spsimport://domain?$$dl$$
The specified domain either does not exist or could not be contacted. (Exception from HRESULT: 0x8007054B)
I knew I had an issue with how the connections to the Active Directory was configured. On the Manage Connections page, I had one entry for the child domain and one for the parent domain as expected. After examining the parent domain’s connection carefully, I noticed that it auto discovered the domain name incorrectly. In this scenario, the NT domain name is actually something like DOMAIN.COM and the Active Directory name for the domain is domain.local. The name MOSS populated via Auto Discovery was just domain. To resolve this, I created a new connection (because you can’t modify the domain of an existing one). In this new connection, I simply added domain.local as my domain name and used default values for everything else. I deleted the original connection and did the import again. After checking the logs, I saw that everything imported correctly.
May 27
I’ve seen the question if it is possible to enable Audience Targetting on a SharePoint document library or list trough code, but I’ve never found an answer to it. But this weekend Ryan Ramcharan posted a solution in one of the SharePoint Forums posts. It looks like you can enable Audience Targeting programatically by adding the Target Audiences field as XML, here is a small code snippet:
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["Shared Documents"];
XmlElement fldElement = new XmlDocument().CreateElement(“Field”);
fldElement.SetAttribute(“ID”, “61cbb965-1e04-4273-b658-eedaa662f48d”);
fldElement.SetAttribute(“Type”, “TargetTo”);
fldElement.SetAttribute(“Name”, “TargetTo”);
fldElement.SetAttribute(“DisplayName”, “Target Audiences”);
fldElement.SetAttribute(“Required”, “FALSE”);
list.Fields.AddFieldAsXml(fldElement.OuterXml);
list.Update();
}
}
The strange thing is that this seems to only way to add the field, you can’t get a hold of the Target Audiences field through the Object Model. Thanks Ryan for posting this solution! And if you know a nicer way to accomplish this, feel free to drop a comment.
Thanks to Jan Tielens for the information
May 27
MOSS on a 2 server farm
May 27
using System;
using ASP = System.Web.UI.WebControls;
using System.Web;
using Microsoft.Office.InfoPath.Server.Controls;
namespace WMDD.WebParts
{
public class FormViewer : ASP.WebParts.WebPart
{
protected override void CreateChildControls()
{
XmlFormView formView;
formView = new XmlFormView();
formView.Width = ASP.Unit.Percentage(100);
formView.Height = ASP.Unit.Pixel(100);
formView.XsnLocation = “Path to form XSN”;
formView.ShowHeader = false;
formView.ShowFooter = false;
this.Controls.Add(formView);
base.CreateChildControls();
}
}
}
May 27
As I was playing with MOSS 2007 and ISA today, I wanted to publish a SharePoint subsite, without publishing the root site.
Since I’m not that experienced in ISA Server, I sometimes turned to Bart Bultinck (great guy, great systems engineer) on my MSN Messenger. He’s way more familiar and experienced with ISA Server.
So the situation is like this:
So how do you do it?
May 27
When you develop actions (or workflows) that should be executed when an expiration policy occurs you need to test them, and that is problem in MOSS as the Expiration Policy job only is scheduled to run once a day. Probably you can’t sit around waiting all day for the job to run so you will have to force it’s execution.
My first though was that there ought to be some operation in STSADM.EXE that would support this. But I did not find any! If there are any operation for this please let me know!
I then reverted to building an application that will find the Expiration policy job and execute it. After looking through the classes and methods available this is the code I came up with:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.SharePoint.Administration;
namespace RunExpirationPolicy
{
class Program
{
static void Main(string[] args)
{
foreach (SPService srv in SPFarm.Local.Services)
{
foreach (SPJobDefinition job in srv.JobDefinitions)
{
string jobTitle = job.Title;
if (jobTitle == “Expiration policy”)
{
Trace.WriteLine(“***************** Start of execution for expiration policy job”);
job.Execute(Guid.Empty);
Trace.WriteLine(“***************** End of execution for expiration policy job”);
}
}
}
}
}
}
I think it’s simple and quite obvious what it does. The only thing that is not obvious is why there is a Guid.Empty as parameter, it is there because it is required but only has meaning in a specific case which does not apply here (read more on MSDN).
As I use this for debugging my custom actions I have included Trace calls which log the start and end of the execution of the Expiration job. During my tests so far I have received all the traces made by my custom action within the Start and End traces, if this is always true I don’t know but it works fine for me.
May 27
Step 1: Check Service Pack Level
The first thing to verify before you do anything is to check the service pack level of your current 2.0 SharePoint installation. I found that it was still running SP1 and had never been upgraded to SP2. This presented a huge problem. At a minimum your SharePoint 2.0 installation has to be at the SP2 level. If found this out when I had the database backed up and restored to my new database server and tried to attach it to MOSS 2007. It came back saying that the database was too old and couldn’t be upgraded. So if you get a similar error message, double check the service pack level for your 2.0 installation.
Step 2: PreScan
With the installation of Services 3.0 or MOSS 2007 comes a nice little utility to help you pre scan the 2.0 install for things that might cause errors when you migrate. You can find this utility on your 2007 server under <%root%>\program files\common files\Microsoft Shared\web service extenstions\12\bin directory. Transfer the EXE to your 2.0 server and kick it off from the command line. The command line statement “Prescan /all” will start the utility and have it start enumerating all of the sites on the box.
When it is complete it will put a log file in to your Documents/Local Files/Temp directory with information as to what it found. It details any errors that it encountered, it details lists that it re-organized, and also will give you details on page customizations and the like. Verify that there are no errors, If there are, fix them before you do the migration. Rerun the prescan utility after repairing any errors to be sure that things have been rectified and are good for migration.
Step 3: Backup/Restore
I didn’t have the opportunity to do this part of the operation. I had a fellow DBA do this part for me, but it did take quite a while. The issues he encountered here was that every time he tried to transport the backup files from one server to the next it kept on corrupting. So the solution was to use a compression utility to zip up all of the data and then transport it. That seemed to do the trick.
Step 4: Create New SharePoint Web Application
Now if you have been working with and configuring SharePoint 2007 then more than likely this will be second nature to you, but there is one little step that is a bit different here. When you create a new web application usually it will default to create a new content database usually with a name like “WSS_Content_<GUID>”. If we were just going to create a new web app this would be fine, but we are looking to attach a copy of the old WSS 2.0 database to this web application. So, replace the defaulted name of the database to the name of the newly migrated and restored database from the WSS 2.0 and let it rip.
SharePoint will take over and create the web application, but instead of creating a new content database it will upgrade the 2.0 database to the correct schema that 2007 uses. Once that is done you should be able to access your content through the new url root. I did go through and verify that it did bring over all of the content as well as the security settings for the sites.
Step 4b: I don’t want a new SharePoint Web Application
Okay, so what if you don’t want a new web application? Well you can always do the same thing by attaching the migrated database to an existing web application on the 2007 box. You can do this either by the content databases interface in Central administration OR you can do it with STSADM. I would recommend the STSADM method for the only purpose that when you do the attaching and upgrade the process can take a bit of time and can possibly time out the Central Administration operation. The only issue I found with this process of attaching and upgrading is that if your 2.0 site structure had a top site (which most of all will) it will not be pulled in and overwrite the current site collection of the existing web application. At least, I found that the content at the old top site I had couldn’t be accessed. So I chose to go the path of Step 4 above.
The STSADM command line statement looks a bit like this: stsadm –o addcontentdb –url <web application url> -databasename <database name> [there other optional switches you can add on if you would like but this is the base execution].
Well, I hope that this has proved useful for anyone in the need to do this type of upgrade. Again, during this process I didn’t have to really mitigate any major errors or deal with any major customizations that might have been done to the 2.0 installation. I guess I was lucky in that respect, but with other sites that might have 3rd party web parts or other customized parts you might want to really proof out the process you will use to do the migration.
May 27
private string GetSmtpServer()
{
SPWebApplicationCollection spWebApplicationCollection = SPWebService.ContentService.WebApplications;
SPOutboundMailServiceInstance smtpServer = new SPOutboundMailServiceInstance();if (spWebApplicationCollection != null)
{
foreach (SPWebApplication spWebApplication in spWebApplicationCollection) {
smtpServer = spWebApplication.OutboundMailServiceInstance;
return smtpServer.Server.Address;
}
}
return string.Empty;
}
May 27
“The Microsoft Filter Pack for search has been released enabling critical search scenarios across a variety of Microsoft Search products including SharePoint Portal Server 2003, Microsoft Office SharePoint Server 2007, Windows SharePoint Services 3.0, Search Server 2008, Search Server 2008 Express Edition, Exchange Server 2005, SQL Server 2005/2008, and Windows Desktop Search 3.1/4.0.
The Microsoft Filter Pack provides iFilters for the following file type extensions:
May 27
You can run stsadm -o enumtemplates to verify that your template was added, and you’ll also notice that it’s been given a name like “_GLOBAL_#1″. If you’ve added a template to the Sharepoint Portal Server Template Gallery (#2 above) you’ll notice that this template is not listed when using stsadm.
Stsadm will not list the default templates either so I’ll list them here with Title and Name:
May 27
To adjust the top level navigation in all My Sites do the following.
Add new links here that will be added to the top level navigation.
For the rules.
{
ServerContext context = ServerContext.GetContext(site);
AudienceManager AudMgr = new AudienceManager(context);
Audience a = null;
bool ruleListNotEmpty = false;
{
a = AudMgr.Audiences["Eddy and Ed Connection"];
}
catch (AudienceArgumentException ex)
{
//your exception handling code here
}
if (aRules == null)
{
aRules = new ArrayList();
}
else
{
ruleListNotEmpty = true;
}
{
//if the rule is not emply, start with a group operator ‘AND’ to append
if (ruleListNotEmpty)
{
aRules.Add(new AudienceRuleComponent(null, “AND”, null));
}
aRules.Add(r0);
aRules.Add(r1);
aRules.Add(r2);
aRules.Add(r3);
aRules.Add(r4);
aRules.Add(r5);
aRules.Add(r6);
aRules.Add(r7);
aRules.Add(r8);
aRules.Add(r9);
aRules.Add(r10);
a.AudienceRules = aRules;
a.Commit();
}
catch (AudienceException e)
{
//Your exception handling code here
}
}
}
May 27
Which is the correct way to patch WSSv3 and MOSS farms.
In order to apply the patch, run PSCONFIG?
Everything needed is right here
http://technet2.microsoft.com/windowsserver/WSS/en/library/91649a7e-6b5a-4e5a-9ee5-51951f4b857f1033.mspx, Deploy software updates for Windows SharePoint Services 3.0
http://technet2.microsoft.com/Office/en-us/library/f484f5f2-35bb-4d70-bf56-dd1c4c287c721033.mspx, Deploy software updates for Office SharePoint Server 2007
May 27
By using the SPUser.Groups property you can easily enumerate the groups that a user has been assigned to. However one problem with this approach is that if the user is a member of a domain group that has been allocated to a SharePoint group, then this group does not appear in SPUser.Groups. e.g. say that a user account is assigned to SharePoint groups SP1, SP2 and SP3 and that the user is a member of an AD group, ADGroup1, which in turn is assigned to SharePoint group SP4. When enumerating SPUser.Groups only SP1, SP2, and SP3 will be listed even though the user is a member of SP4 indirectly via his membership of the ADGroup1 group.
So, how can we ascertain whether a particular user is a member of the SharePoint group or not, taking into account AD group membership ? The short answer is use the SPGroup.ContainsCurrentUser property as shown below:
string siteUrl = “http://localhost”
string userName = “DOMAIN\\username”;
string groupName = “SharePoint Test Group”;
SPSite siteCollection = new SPSite(siteUrl);
SPWeb site = siteCollection.OpenWeb();
SPGroup testGroup = site.Groups[groupName];
if (testGroup != null)
{
Console.WriteLine(
String.Format(“Is current user in group={0}”,
testGroup.ContainsCurrentUser.ToString()));
}
Obviously this only tells you whether the user account running the current context is a member of the group or not. In order to ascertain whether a different user is in the group you’ll need to create an SPSite object using the appropriate SPUserToken to give you the appropriate context to use. An example can be seen below:
string siteUrl = ” http://localhost “;
string userName = “DOMAIN\\anotheruser”;
string groupName = “SharePoint Test Group”; SPSite siteCollection = new SPSite(siteUrl);
SPWeb site = siteCollection.OpenWeb();
SPUserToken userToken = site.AllUsers[userName].UserToken;// Use an SPSite and SPWeb that have the context of the appropriate user
using (SPSite contextSiteColl = new
SPSite(siteUrl, userToken))
{
using (SPWeb contextSite = contextSiteColl.OpenWeb())
{
SPGroup testGroup = contextSite.Groups[groupName];
Console.WriteLine(String.Format(“Username = {0}, got group {1}.”,
userName, groupName));
if (testGroup != null)
{
Console.WriteLine(String.Format(“Is current user in group={0}”,
testGroup.ContainsCurrentUser.ToString()));
}
}
}by El Blanco