Dev Team Assemble

Evil beware!
Add to Technorati Favorites

Archive

Category: 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 a little while ago I was playing around with building a virtual environment using Windows 2008 Hyper-V and while this was an interesting experience I found Microsoft's lack of any Linux distro support beyond the SUSE to be a bit of a pain.  That being said I wanted to increase the resources available on my Dell PowerEdge server and thought I would take this opportunity to rebuld it before I get started on building out a SharePoint 2010 beta 2 testing farm....whew, try saying that 10 times fast :)

I downloaded and installed the new VMWare ESXi 4.  It looks like they are really streamlining this technology with the vSphere platform...blah blah blah means they are the same product with license key feature unlocks (from what I understand of it anyways).  Not surprisingly this was a lightning fast install.  I did have a couple of hiccups trying to figure out a) where to put my free license key in and b) getting SSH enabled.

License Key - like most normal people I thought that after installing the vsphere client onto my desktop that there would be a little section in the help menu for adding license keys (like most software).  Turns out you need to click on the host, then the configuration tab and then the Licensed Features option under Software. (OK ... umm forgot to mention...click the edit button on the right hand side!!)

esxfeatures

SSH - enabling this took some digging.  Not much mind you because there are actual quite a few people out there writing about the same thing...  here are a couple that I found:

I don't want to rehash it but here are the steps (in case they take down their postings!)

  1. At the ESXi console ALT+F1 for new session at the console screen
  2. enter the command "unsupported" and type your password
  3. use vi to edit the inetd.conf file so type...vi /etc/inetd.conf
  4. scroll to the areas where ssh is listed and remove the # sign (delete key works!)
  5. type :wq to exit vi and save your changes
  6. restart the server OR do the killing of the process number for inetd and using the correct switches (i just rebooted because I dont care that much :)

And after the machine comes back up you should be able to connect via Putty or whatever tool you are using no problem.

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: , , , ,

Recently I acquired some server class hardware (Dell PowerEdge 2950)  and I thought, hey this is a great opportunity for me to setup a virtual environment at home so I can test out some beta products and do some tinkering with Linux. I have VMWare Workstation installed inside of Windows Vista machine at home and I have ubuntu 8.10 running in it and this seems to work ok but I have come across some issues with it that annoy me.

I was undecided on whether to install VMWare ESXi or Windows 2008 Hyper-V server. Based on the title of this article you can probably guess which route I took. I didn't decide to do this simply because I think Microsoft's virtualization platform is superior...I chose it simply because I use VMWare ESXi and ESX at work and was interested in seeing the capabilities of this free product in comparison.

After configuring the server with RAID 0 (faster and this is test) I popped the disk in and started installing. Truth be told the installation was a breeze...so much so in fact that I started the install, watched a soccer game and when I came back it was ready for me to login. I was a little confiused at first because at no point did I provide a username and password for the admin account but it prompted me at the login screen. Didn't take long to figure out it was Administrator/-blank- to login.

This all seemed a little too good to be true and I quickly found out that it was...after downloading and installing the Hyper-V Manager MMC into my vista machine I found I could not connect to the server. found this odd as the very purpose of this server is too allow connections. Turns out there were a few steps I had to do:

  1. I had to add my user account (the vista one) to the server in order to pass my creds through.  I believe that once you have connected to it you can turn this off via the Hyper-V settings panel.
  2. I had to turn off the server's firewall (I know, I know this is a bad thing but its a test box that will never see the outside world so...).  You can use the following command netsh firewall set opmode disable
  3. I was able to connect to the server...BUT when I tried to create a machine I would get an error about Access Denied.  So I added myself to the Administrators group on the server.  At this point I can now use MMC to do most admin work on the server from my Vista client
  4. I then started getting the following when trying to connect: Hyper-V Access Denied. Unable to establish communication between ‘SERVER’ and ‘CLIENT’ .  Funny thing is it would let me create a virtual machine but I could never seem to connect to it.  This one was quite confusing so I turned to my trusty friend Google to help me resolve this...I came across a blog post of one Adrian Dimcev here and it had the solution I was looking for.   Word for word heres the instructions from his site:
    • Click Start, Run, type DCOMCNFG. Click OK.
    • Expand Component Services, expand Computers. Right-click on My Computer and click on Properties.
    • Click on COM Security.
    • In the Access Permission area, click Edit Limits.
    • Select ANONYMOUS LOGON in the Group or User Name area. Then set the Permissions for ANONYMOUS LOGON to Allow for Remote Access.
  5. After the previous breakthrough I got the following error (oh joy)  : The application encountered an error when attempting to change the state of the 'machinename'.  The hypervisor is not running....WHAT????? Ummmm yes it is......
    Ok turns out there is a very good reason for this as explained here in this Microsoft article.  All I had to do here was enable
    hardware-assisted virtualization in the BIOS.  After doing that it I was able to create my first machine in this environment == Ubuntu 9.

After reading a little further on the internet it seems that my setup at home (using a workgroup) is not the best way to do this and is partly to blame for some of mine and other peoples issues.  All in all the installation was a success but seems a little more confusing than installing ESXi.  Either way my environment is up and running.

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: , , ,

I got the following error the other day (it has been shortened...):

"the web part you attempted to add no longer exists in the closed web parts gallery."

This was a pretty disturbing error...there was no real apparent cause for this problem...nothing in the logs. After messing about with it for a while I figured out that it was a dll version in the GAC that was causing the problem. On my dev box I had an updated version but the version in our prod envs is different.

It would be nice if the server was a little more helpful with its error messages....HTH if you come across it

Technorati Tags: , , , ,