Dev Team Assemble

Evil beware!
Add to Technorati Favorites

Archive

Tag: Configuration

I was trying to install install SharePoint 2007 onto Windows 2008 r2 and was getting a strange error referencing KB article 962935. Funny enough this article is not live yet so it left me a little unhappy. Apprarently Microsoft does not support the distributed SP1 installation package of SharePoint for this version of the OS. Turns out Jei Li posting on his msdn blog detailing how to go about creating a slipstreamed installation for SP2 on this server Click here for the article. Basically the steps are (pretty much word for word from Jei Li's blog):

  • Install .Net Framework 3.5 SP1 in the features applet
  • Copy the installtion media contents to a folder on the computer (c:\install)
  • Download the WSS x64 SP package and the MOSS 2007 SP2 x64
  • Delete everything inside Updates folder in the install folder you setup.
  • Open a command prompt,  change directory to the folder you put the downloaded patches, and run the following two commands: 
    • wssv3sp2-kb953338-x64-fullfile-en-us.exe /extract:[Path to installation bits]\Updates /quiet
    • officeserver2007sp2-kb953334-x64-fullfile-en-us.exe /extract: [Path to installation bits]\Updates /quiet
  • Delete the wsssetup.dll filein the updates dir. This is a very important step so please don’t miss it.
  • If you also need the Cumulative Updates to be applied when install SharePoint, download the latest Windows SharePoint Services 3.0 and SharePoint Server 2007 Cumulative Update packages and extract them into Updates folder like step 4.
  • Your slipstream build of SharePoint Server 2007 is done!
  • Go and install it on your Windows Server 2008 R2 box, after the installation, the site version will show 12.0.0.6421 or possibly a higher version.

Please reference Jei Li's post for furthur instuctions.  I only posted all the steps here because things have a mysterious way of dissappearing or not appearing at all on Microsofts site.

After doing all of this everything seems to be fine...seems to be :)  

Links

Technorati Tags: , , , , ,

So I got this error the other day when putting together a dev site collection usign varations:

An error was encountered performing this operation. You may re-try the operation, and you may need to clean up the half-created data first before re-trying. If the problem persists, please contact your system administrator

This was actually a fairly easy fix for me.  I simply had to enable the publishing features in my site.  Which is funny...because they should have been on but I must have overlooked that.  :)

Technorati Tags: , , , ,

For the last little bit I have been working on learning how to package up all site infrastructure into a single feature.  All of this is pretty straight forward and I didn't really have any issues.....UNTIL  I tried to get lookup columns working.

Using CAML

I did some reading on the subject and apparently you can do all of this using CAML alone.  I came across a post from Josh Gaffery supporting this claim, but I simply could not get this working...so i gave up after spinning my wheels on it for longer than I wanted to.  Josh's approach is to use the list URL as opposed to the GUID that links the column to the source list and he has put up an update explaining it further.  Nonetheless....didn't work for me.

Using Feature Receiver

I knew that at this point I would have to take the feature reciever approach and modify the fields in place or create them.  I found two sources that both take different approachs to this problem.

  • Chris O'Brien has put together the a project on CodePlex that will create the lookup columns at activation time.  This actully sounds like a pretty good approach but unfortunately it didn't work for me.  I dont know if there is something wrong with my environment but I encountered a few errors doing this...things like the fields not rendering on the page layouts and getting the "The local device name is already in use. (Exception from HRESULT: 0x80070055)" error.
  • Waldek Mastykarz has a great post on creating the columns via code here.

Basically I took a hybrid approach to doing this by mixing the two approaches mentioned above.  I created a custom XML file that I deploy into the layouts directory and then use a feature reciever to read the xml content and create lookup columns based on this.  I also added a deactiving event to remove the fields when the feature is deactivated.  Heres the feature reciever code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPSite site = properties.Feature.Parent as SPSite)
            {
                string contentTypes = null;
                string listName = null;
                string fieldName = null;
                string groupName = null;
                string staticName = null;
                string lookupFieldName = "Title";
                bool mult = false;
                bool required = false;
                string filePath = properties.Feature.Properties[
                   "ColumnDefinitionPath"].Value;
 
                XmlTextReader xReader = new XmlTextReader(
                  HttpContext.Current.Server.MapPath(@"~\_layouts\" + filePath));
                while (xReader.Read())
                {
                    if (xReader.LocalName == "Field")
                    {
                        #region Get values from attributes
                        if (xReader.MoveToAttribute("List"))
                        {
                            listName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Name"))
                        {
                            fieldName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("StaticName"))
                        {
                            staticName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Group"))
                        {
                            groupName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("LookUpField"))
                        {
                            lookupFieldName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("ExistInContentTypes"))
                        {
                            contentTypes = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Mult"))
                        {
                            bool.TryParse(xReader.Value, out mult);
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Required"))
                        {
                            bool.TryParse(xReader.Value, out required);
                            xReader.MoveToElement();
                        }
 
                        #endregion
 
                        SPFieldLookup lookup = CreateLookupField(
                          fieldName, groupName, required, mult, site.RootWeb,
                          site.RootWeb.Lists[listName], lookupFieldName, staticName);
                        if (contentTypes != null)
                            foreach (string s in contentTypes.Split(','))
                            {
                                LinkFieldToContentType(s.Trim(), (SPField)lookup);
                            }
                    }
                }
 
                xReader.Close();
 
            }
        }
 
        public static SPFieldLookup CreateLookupField(
          string fieldName, string group, bool required, bool allowMultipleValues,
          SPWeb w, SPList lookupList, string lookupField, string staticName)
        {
            w.Fields.AddLookup(fieldName, lookupList.ID,
               lookupList.ParentWeb.ID, required);
            SPFieldLookup lookup = (SPFieldLookup)w.Fields[fieldName];
            lookup.AllowMultipleValues = allowMultipleValues;
            lookup.LookupField = lookupField;
            lookup.StaticName = staticName;
            lookup.Group = group;
            lookup.Update(true);
            return lookup;
        }
 
        public static void LinkFieldToContentType(string contentType, SPField field)
        {
            using (SPSite site = SPContext.Current.Web.Site as SPSite)
            {
                SPContentType ct = site.RootWeb.ContentTypes[contentType];
                ct.FieldLinks.Add(new SPFieldLink(field));
                ct.Update(true); // will update children
            }
        }

As you can read from the above code the xml file would need to have a node like below for each lookup column:

 
<Field
         Type="Lookup"
         List="Access Type"
         Name="AccessTypeColumn"
         StaticName="Access_x0020_Type"
         Group="Infrastructure"
         ExistInContentTypes="THIS IS A COMMA DELIMITED LIST OF CONTENT NAMES"
         LookUpField="Title"
         Mult="TRUE"
         Required="FALSE"
        />
 

The Final Project

So here are all the pieces of my infrastructure project. Notice the placement of the lookupfields xml file...this is because the layouts directory is setup as a virtual directory for every sharepoint site and we can read files from there without a permissions problem.

12/TEMPLATES/FEATURES/myfeature/lists.xml this contains the source lists for the lookup fields
12/TEMPLATES/FEATURES/myfeature/contenttypes.xml this contains the content type definitions MINUS the lookup fields
12/TEMPLATES/FEATURES/myfeature/sitecolumns.xml this contains all the other fields included in the content types
12/TEMPLATES/FEATURES/myfeature/feature.xml the feature def
12/TEMPLATES/LAYOUTS/myfeature/lookupfields.xml this contains all the lookup fields that need to be provisioned

Hopefully this helps anyone who's been having problems getting this going. And a big thanks to Waldek, Chris and Josh for their posts.

Technorati Tags: , , , ,

Great post here with a fix/workaround. Essentially when you go to look in the windows .net framework directory that program is not there. In order to run this utility program you will need to use the Visual Studio command prompt that is in the Programs/Visual Studio menu.

Technorati Tags: , , , ,

A little while ago I was having a problem with MS SQL Server 2005, It was ballooning my log files and not recovering space after a backup and I posted a fix for this here.  The only issue I had left at that point was rolling it into a complete solution that can be run on the server and does not require being run manually.  The following script I put together can run as a Job (or as a SQL task in a Maintenance plan) and will backup all of the databases on your server with the exception of the system db's (master, msdb, temp, model) .  There are also sections in the script to add your own exclusions in case you want to remove long running backups or databases that do not require this sort of treatment, search for DB_2EXCLUDE.

NOTE: The word press plug-in for code formatting changes my greater than and less than sign into &gt; and &lt; respectivly so you will need to change this back if copying the code....until i figure it out anyway.

DECLARE @dbExt VARCHAR(4)
DECLARE @logExt VARCHAR(4)
DECLARE @backupLocation VARCHAR(100)
DECLARE @DATE VARCHAR(50)
DECLARE @tempFile VARCHAR(4000)
DECLARE @tempPath VARCHAR(4000)
DECLARE @LOG nvarchar(MAX)
DECLARE @lasterror int
DECLARE @mailprofile VARCHAR(100)
DECLARE @mail_rec VARCHAR(1000)
-- cursor vars
DECLARE @dbname VARCHAR(100)
DECLARE @dbid int
DECLARE @recModel int
 
SELECT @dbExt = N'.bak'
SELECT @logExt = N'.trn'
SELECT @backuplocation = N'F:\SQL Backup'
SELECT @DATE = CONVERT(VARCHAR(8), GETDATE(), 112)
 
SELECT @mailprofile = 'default'
SELECT @mail_rec = 'myemailAddress@mycompany.com'
SELECT @LOG = 'SQL Server Backup' + CAST(GETDATE() AS nvarchar(100))
 
-- cycle the log
EXEC sp_cycle_errorlog
 
CREATE TABLE #dbInfo
(
database_id int NOT NULL,
dbName nvarchar(100) NOT NULL,
recoveryModel int
)
 
SELECT TOP 1 @dbid = database_id FROM sys.databases WHERE [name]
   NOT LIKE 'DB_2EXCLUDE%' AND database_id &gt; 4  ORDER BY database_id ASC;
SELECT @dbname = [name] FROM sys.databases WHERE database_id = @dbid;
SELECT @recModel = recovery_model FROM sys.databases WHERE database_id = @dbid;
 
-- begin backup process
WHILE @dbid &gt; 0
BEGIN
 
   INSERT INTO #dbInfo
      (database_id, dbName, recoveryModel)
      VALUES
      (@dbid, @dbname, @recModel);
 
   IF @recModel = 1
   BEGIN
 
      SELECT @tempFile = @backuplocation + N'\transactionlog_backup_'
      + @dbname + @DATE + @logExt
      SELECT @LOG = @LOG + '
      Backing up [' + @dbname + '] transaction log file to: '  + @tempFile
      PRINT 'Backing up [' + @dbname + '] transaction log file to: '  + @tempFile
 
      CHECKPOINT
      BACKUP LOG @dbname TO DISK = @tempFile WITH NOFORMAT, NOINIT,
        NAME = N'Transaction Log  Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
      SELECT @lasterror = @@ERROR
      IF @lasterror &lt;&gt; 0
      BEGIN
       -- log the error
       SELECT @LOG = @LOG + '-ERROR: Backing up database log for [' +
          @dbname + '] with error number ' +
          CAST(@lasterror AS nvarchar(25))
       PRINT 'ERROR: Backing up database log for [' + @dbname + '] with error number ' +
          CAST(@lasterror AS nvarchar(25))
      END
   END
 
   SELECT @tempFile = @backuplocation + N'\backup_' + @dbname + @DATE + @dbExt
   SELECT @LOG = @LOG + 'Backing up [' + @dbname + '] database file to: '  + @tempFile
   PRINT 'Backing up [' + @dbname + '] database file to: '  + @tempFile
 
   BACKUP DATABASE @dbName TO  DISK =  @tempFile WITH NOFORMAT, NOINIT,
      NAME = N'Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
 
   SELECT @lasterror = @@ERROR
   IF @lasterror &lt;&gt; 0
   BEGIN
      -- log the error
      SELECT @LOG = @LOG + '-ERROR: Backing up database: ['
         + @dbname + '] with error number ' +
         CAST(@lasterror AS nvarchar(25))
      PRINT 'ERROR: Backing up database: [' + @dbname + '] with error number ' +
         CAST(@lasterror AS nvarchar(25))
   END
 
   DECLARE @SQL nvarchar(4000)
   DECLARE @logName nvarchar(100)
   DECLARE @param nvarchar(4000)
 
   -- get the transaction log name
   SELECT @LOG = @LOG + '
   Getting Log File Name [' + @dbname + ']'
   PRINT 'Getting Log File Name [' + @dbname + ']'
 
   SELECT @SQL = 'SELECT TOP 1 @out = name FROM ' + @dbname
      + '.sys.sysfiles where FileName like ''%.ldf'' '
   SELECT @param = N'@out varchar(100) OUTPUT'
   EXEC sp_executesql @SQL, @param, @OUT = @logName OUTPUT
 
   SELECT @LOG = @LOG + 'Log File Name Is ' + @logName
   PRINT 'Log File Name Is ' + @logName
 
   -- shrink the transaction log file
   SELECT @SQL = 'USE ' + @dbname
   SELECT @SQL = @SQL + ' DBCC SHRINKFILE (@dblogname, 0, TRUNCATEONLY);'
   SELECT @SQL = @SQL + ' SELECT @lasterr = @@ERROR;'
   SELECT @param = '@dblogname nvarchar(500), @lasterr int'
   --SELECT @tempPath = @dbname+'_log'
 
   SELECT @LOG = @LOG + '
   Performing Log File Shrink [' + @dbname + ']'
   PRINT 'Performing Log File Shrink [' + @dbname + ']'
 
   EXEC sp_executesql @SQL, @param, @dblogname = @logName, @lasterr = @lasterror
   -- error obtained in the stored procedure
   IF @lasterror &lt;&gt; 0
   BEGIN
      -- log the error
      SELECT @LOG = @LOG + '-ERROR: Shrinking the database log file: ['
         + @dbname + '] with error number ' +
         CAST(@lasterror AS nvarchar(25))
      PRINT 'ERROR: Shrinking the database log file: ['
         + @dbname + '] with error number ' +
         CAST(@lasterror AS nvarchar(25))
   END
 
   SELECT @LOG = @LOG + 'Log File Shrink Completed'
 
   -- get a new record
   SELECT @dbid = 0;
   SELECT TOP 1 @dbid =  database_id FROM sys.databases
      WHERE [name] NOT LIKE 'DB_2EXCLUDE%' AND database_id &gt; 4 AND
      database_id NOT IN (SELECT DISTINCT x.database_id FROM #dbInfo x);
   SELECT @dbname = [name] FROM sys.databases WHERE database_id = @dbid;
   SELECT @recModel = recovery_model FROM sys.databases WHERE database_id = @dbid;
 
END
 
DROP TABLE #dbInfo
EXEC msdb.dbo.sp_send_dbmail @profile_name='default',
   @recipients=@mail_rec,@Body_Format = 'HTML', @BODY=@LOG;
PRINT @LOG

Technorati Tags: , , , , ,

While working on my sharepoint development machine today I was mucking about with variations and doing a proof of concept.  Now I know they worked before but for some reason when I created a new page in the source site they were not being propagated through to the variation label sites.  In Centeral Admin under the Timer Status I found that the Variations Propagate Page Job Definition and the Variations Propagate Site Job Definition were both stuck at 0% and Initialized, see below:

variations

Seeing this, I now knew that the Timer service was not creating my variation pages and sites so a quick check under the windows services control panel applet  revealed that the Windows SharePoint Services Timer Service had been shut off.  Turning this back fixed my problem.

Technorati Tags: , , ,

So I have been working on setting up a Linux box with PHP5 and mysql mostly just to fart around with but also because I like learning how to do these things. I was having a hell of a time getting PHP and mysql to install properly on my distro - ubuntu 8

I originally installed PHP using apt-get and then installed mysql doing the same but was having issues getting them to work...no big shocker considering I am still fairly new to Linux. Eventually I did the following to get everything working, well so far anyway :)

Here it is:

1. sudo tasksel install lamp-server - this installs the entire LAMP stack (Linux-Apache-MySQL-PHP) and does most of the work for you (i like this)

2. sudo apt-get install phpmyadmin - configure it for apache2 (installed above) this helped me get rid of the Fatal error: Call to undefined function: mysql_connect() I was getting...basically php was not configured to speak to mysql

3. I really cheated on this one because I was getting the following error Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111 like any good linux noob I decided to google that up and came up with an article located here that worked like a charm. Here are the steps:

* sudo gedit /etc/mysql/my.conf - comment the line corresponding to ‘bind-address’
* sudo gedit config.inc.php - in the /etc/phpmyadmin folder
* add or edit a line $cfg['Servers'][$i]['host'] = ‘localhost’;
* restart mysql using sudo /etc/init.d/mysql restart

Anyway...HTH

Technorati Tags: , , , ,

You may get the following error sometimes when trying to do something in SharePoint: Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))

This is not actually a SharePoint issue but more a SQL issue...usually a result of the transaction log being full or no drive space available to it.

To view the log information use DBCC LOGINFO('[dbName]')

To fix the issue above, use the following code to reduce the size of the transaction log (replacing the items in square brackets with your variables - [dbName]):

use [dbName]
go

BACKUP LOG [dbName] TO DISK = N'[driveLetter]:\SQL Backup\[backupName].trn'
WITH NOFORMAT, NOINIT, NAME = N'[dbName]-Transaction Log Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO

DBCC SHRINKFILE (N'[dbLogFileName]' , 0, TRUNCATEONLY)
GO

DBCC LOGINFO('[dbName]')

Technorati Tags: , , ,

Heres a simple way for you to view your GAC in its naked state, go to the following registry location:

HKLM\Software\Microsoft\Fusion, once there create a DWORD value named "DisableCacheViewer" and set it to value 1.

Easy!

Technorati Tags: , ,

http://[your sspname here]/ssp/admin/_layouts/searchsspsettings.aspx

This problem has to do with an issue that comes up after you apply a hotfix to your servers. Essentially it enforces new security rules. To resolve it add the Sharepoint service account to the Box Administrators, WSS_ADMIN_WPG and WSS_RESTRICTED_WPG. Once this is done reset your IIS and you should be good to go.

Props to Søren Nielsen for the following post:
http://soerennielsen.wordpress.com/2008/02/08/make-the-search-work-for-you/

Technorati Tags: , , ,