Friday, December 2, 2011

A PowerShell script to determine if accounts are locked

With all of the service accounts that SharePoint 2010 uses and the fact that our infrastructure people are useless, I created this little PowerShell script so I could quickly identify any issues with our service accounts:

cls

$accounts = "sps10_config,sps10_farm,sps10_services,sps10_apps,sps10_sql"

foreach ($account in $accounts.Split(",")){
Write-Host "$account - " -NoNewLine
NET USER $account /DOMAIN | FIND /I "Account active"
}

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Thursday, September 8, 2011

Clear Timer Job Cache with PowerShell!!

Here is a little script I developed to clear the SharePoint Timer Job cache which sits in the %ALLUSERSPROFILE%\Microsoft\SharePoint\Config\{guid} directory. You often need to do this when deploying sites and generally doing stuff within SharePoint to prevent random OWSTIMER issues that interfere with your junk.

I use another script that stops and restarts all SharePoint services so stopping the SharePoint Timer Job Service is not part of this script. You may want to edit this script to stop this service at the beginning and start it again at the end. It's a one-liner to do...

$timerServiceName = "SharePoint 2010 Timer";
$timerService = Get-Service -Name $timerServiceName

if ($timerService.Status -eq "Running")
{
Write-Host -ForegroundColor Red $timerServiceName "is still running";
Break
}

$configDb = Get-SPDatabase | ? {$_.TypeName -eq "Configuration Database"}
$guid = $configDb.Id

Remove-Item "$env:AllUsersProfile\Microsoft\SharePoint\Config\$guid\*.xml"
Set-Content "$env:AllUsersProfile\Microsoft\SharePoint\Config\$guid\cache.ini" "1"

Tuesday, May 10, 2011

Migrate User Account

I am moving users from one domain to another. I am using SPFarm.MigrateUser.

Why, oh, why did Microsoft make the SPSite.MigrateUser internal?? All the farm level migrate user does is loop through all site collections updating users at a site level, so why not allow the developer the flexibility to manage this themselves.

I have a situation where some users need to get migrated to newdomain\username and other users to a claims-based user id of i:0#.w|newdomain\username.

Using the farm level migration, the migration of users needs to be managed very carefully now otherwise windows authenticated and claims authentication user ids can get mixed up!!!

A fix for Content Type Inherits True with Pages

A few of you may have come across issues with SharePoint 2010 and the handling of Inherits="TRUE". When you inherit from the Page content type, you now get all sorts of unexpected issues. The big issue we had was when we overrode a fieldref in a child content type, (eg changing display name or whether it is required) the field was duplicated in the Pages library.

It's weird, in some respects SharePoint knew they were the same field, in other places it thought they were two different fields. eg. it displays the field twice while editing, but both fields have the same display name/required field.

So to fix the problem, when overriding a field ref in a child content type you need to add ShowInEditForm and ShowInDisplayForm to FALSE (yes in capital letters!)

eg.

<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Title" Required="TRUE" ShowInEditForm="FALSE" ShowInDisplayForm="FALSE"/>
<FieldRef ID="{9da97a8a-1da5-4a77-98d3-4bc10456e700}" Name="Comments" DisplayName="Description" Required="FALSE" ShowInEditForm="FALSE" ShowInDisplayForm="FALSE" />

Wednesday, April 27, 2011

Content Types in SharePoint 2010

It appears in 2010 when you have a boolean in your ContentType definition, the value MUST be in UPPERCASE.

In 2007, it respected any variation of True, true, TRUE etc. In 2010, you get no errors with having booleans in another case, it just does not work.

Monday, April 18, 2011

The object specified does not belong to a list

I started getting the "The object specified does not belong to a list" error on a SharePoint site I migrated from 2007 to 2010. The code I "inherited" worked fine in 2007 but raised an error in 2010.

After some investigation, the problem ended up being that an SPFile was constructed in a parent web instead of the web in which the actual file resided using SPWeb.GetFile(url).

So to fix the problem, make sure you construct your SPFile object (using GetFile anyway) in the SPWeb in which the file resides.

eg. if the file lives here: \ParentSite\SubSite\Pages\Page.aspx, make sure the SPWeb you are using is "Subsite".

Wednesday, March 9, 2011

Setting Version on Masterpage

Pretty simple one here that I had trouble finding anything while googling so I thought I'd add it. If you want to mark a masterpage (or custom action or whatever) as a v4 (SPS 2010) item while provisioning a site, you use the "UIVersion" property.

<File Url="SomeV4.master" Type="GhostableInLibrary"/>
   <Property Name="Title" Value="Some Master Page v4" />
   <Property Name="MasterPageDescription" Value="SomeMaster Page" />
   <Property Name="ContentType" Value="Publishing Master Page" />
   <Property Name="UIVersion" Value="4" />
</File>

(sorry about formatting - I don't have my nice VS add-in installed)

Friday, February 18, 2011

Proxy Settings in Machine.Config

With the our migrations to SharePoint 2010, decided to move our proxy settings to the machine.config files as opposed to web.configs. The infrastucture guys change the URL too often (they alse haven't provided us with a DNS entry) which means we have to edit the config files of multiple web applications and extensions.

Steps required:

1. Add the following to the machine.config:


  <system.net>

    <defaultProxy useDefaultCredentials="true">

      <proxy usesystemdefault="False" proxyaddress="http://proxy.address" bypassonlocal="True" />

    </defaultProxy>

  </system.net>





2. Remove the defaultProxy from section from your web.config files.


PS. The machine.config to edit can be found at: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG.

Thursday, February 17, 2011

Add New Web Part to Web Part Gallery Broken?

I have a site in SharePoint 2010 running in 2007 mode (don't ask me why? ask the business users). It seems there may be a bug when in the web part gallery that does not allow you to add new web parts (in 2007 mode only). I had a look through the page source and there is definitely some issues with the javascript on the "New" button.

Hopefully, we won't be in 2007 mode for too long, so we are just gonna roll with a workaround. Go to following page and you can add web parts to the web part gallery:

http://{siteurl}/_layouts/NewDwp.aspx

Monday, October 18, 2010

SharePoint 2010 Modifying UI Version in PowerShell

To change UI version of a SharePoint 2010 site between 2007 and 2010 you can use the following PowerShell code:

$site = Get-SPSite -identity http://{site url}

To 2007 mode:

$site | Get-SPWeb -limit all | ForEach-Object { $_.UIversion = 3; $_.UIVersionConfigurationEnabled = $false; $_.update(); }

To 2010 mode:

$site | Get-SPWeb -limit all | ForEach-Object { $_.UIversion = 4; $_.UIVersionConfigurationEnabled = $false; $_.update(); }

Wednesday, October 6, 2010

PowerShell - Stopping the annoying confirm messages

To stop those annoying confirm messages (i.e. "Are you sure you want to perform this action?") , do this:

$ConfirmPreference = "None"


the end

Looping through all SharePoint 2010 sites with PowerShell

Just needed to loop through all SPS2010 sites and disable and enable a feature. The following PowerShell script does this. (this outputs the site url so I can observe the progress)


$site = Get-SPSite -identity http://{siteurl}


$site | Get-SPWeb -limit all | ForEach-Object { Write-Host $_.Url; Disable-SPFeature -Identity {featureid} -url $_.Url; Enable-SPFeature -Identity {featureid} -url $_.Url }

Friday, October 1, 2010

SharePoint 2010: One or more field types are not installed properly

We started migrating our old SharePoint 2007 sites to SharePoint 2010. It all has been going pretty smoothly, until we found a pesky little problem when creating new subsites:

"One or more field types are not installed properly. Go to the list settings page to delete these fields."

Not much more detail in the ULS logs to describe which field is not installed properly. After some Googling and experimentation the problem was determined to be the changes between SharePoint 2007 and 2010 in the "Relationship List" (http://{siteurl}/Relationships%20List/AllItems.aspx).

Basically to fix the problem, you need to deactivate the SharePoint Server Publishing Infrastructure feature, delete the relationship list and reactivate the SharePoint Server Publishing Infrastructure feature.

The following PowerShell is all you need:

Disable-SPFeature -Identity F6924D36-2FA8-4f0b-B16D-06B7250180FA -Url http://{siteurl}


$site = Get-SPSite -Identity http://{siteurl}

$site.RootWeb.GetList("Relationships List").Delete()


Enable-SPFeature -Identity F6924D36-2FA8-4f0b-B16D-06B7250180FA -Url http://{siteurl}

Wednesday, June 30, 2010

Add Proxy Settings to web.config file of SharePoint with Powershell

I recently needed to modify the default proxy settings in the web.config file of our SharePoint apps. This was done manually to start with, but after many deployments in multiple environments, doing this manually was a chore and often forgotten. I therefore worked on the following PowerShell script that did what we needed.

The following script changes the default proxy settings of:


  <system.net>

    <defaultProxy>

      <proxy autoDetect="true" />

    </defaultProxy>

  </system.net>




to:


  <system.net>

    <defaultProxy useDefaultCredentials="true">

      <proxy usesystemdefault="False" proxyaddress="http://proxy.address" bypassonlocal="True" />

    </defaultProxy>

  </system.net>




Sorry about the crappiness of the cut-and-paste, but this might give you enough help to get you going:


function AddWebConfigModification([Microsoft.SharePoint.Administration.SPWebApplication] $webApp=$(throw 'Parameter -webApp is missing!'),

                                  [string] $name=$(throw 'Parameter -name is missing!'), 

                                  [string] $path=$(throw 'Parameter -path is missing!'), 

                                  [string] $owner=$(throw 'Parameter -owner is missing!'), 

                                  [string] $sequence=0, 

                                  [Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType] $modificationType=$(throw 'Parameter -modificationType is missing!'), 

                                  [string] $value=$(throw 'Parameter -value is missing!'))

{

    $modification = New-Object -TypeName "Microsoft.SharePoint.Administration.SPWebConfigModification";

    $modification.Name = $name;

    $modification.Path = $path;

    $modification.Owner = $owner;

    $modification.Sequence = $sequence;

    $modification.Type = $modificationType;

    $modification.Value = $value;    

    $webApp.WebConfigModifications.Add($modification);    

}

 

function AddProxySettings([string]$url=$(throw 'Parameter -url is missing!'))

{

    $webApp = GetWebApp($url);    

    $owner = "GUID_HERE";    

    $ensureAttribute = [Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType]::EnsureAttribute; 

 

    AddWebConfigModification -webApp $webApp -owner $owner -modificationType $ensureAttribute -path "configuration/system.net/defaultProxy" -name "useDefaultCredentials" -value "true";

    AddWebConfigModification -webApp $webApp -owner $owner -modificationType $ensureAttribute -path "configuration/system.net/defaultProxy/proxy" -name "usesystemdefault" -value "False";

    AddWebConfigModification -webApp $webApp -owner $owner -modificationType $ensureAttribute -path "configuration/system.net/defaultProxy/proxy" -name "proxyaddress" -value "http://proxy.address";    

    AddWebConfigModification -webApp $webApp -owner $owner -modificationType $ensureAttribute -path "configuration/system.net/defaultProxy/proxy" -name "bypassonlocal" -value "True";    

    AddWebConfigModification -webApp $webApp -owner $owner -modificationType $ensureAttribute -path "configuration/system.net/defaultProxy/proxy" -name "autoDetect" -value "True";    

 

    [Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplyWebConfigModifications();

}

Tuesday, September 1, 2009

How to update a SharePoint item while retaining the modified by and date information

In my current project I need to move documents from one document library to another with version history and last modified infomation etc. This works great using SPImport and SPExport.

When the document is moved to the new location, I have a further process of modifiying the values of one of the fields. I needed to do this without modifying the Modified or Modified By fields.

Here is how I did it:

foreach (SPListItem listItem in list.Items)
 {
     var modifiedBy = listItem[SPBuiltInFieldId.Modified_x0020_By];
     var modifiedDate = listItem[SPBuiltInFieldId.Modified];
 
     listItem[_documentTypeFieldName] = GetDocumentType();
     listItem[SPBuiltInFieldId.Modified_x0020_By] = modifiedBy;
     listItem[SPBuiltInFieldId.Modified] = modifiedDate;
     listItem.Update();
 }

BTW. Using Update() creates a new version here. You can not create a new version by using UpdateOverwriteVersion().

Friday, August 21, 2009

Useful code for modifying a Site

I am currently working on a project that needs to support the clients SharePoint implementation. They do everything directly in production, so I have created a site definition to reproduce there site structure. One feature I created to help me with this is basically a web scoped feature that modifies the site with custom changes I want in code (I am a programmer after all!!).

The following code does some interesting stuff:
  • Creates a document library in code
  • Sets the document library title, enables versioning and allows content types in the document library
  • Finds a site content type and associates it with the document library
  • Changes the content type order so it contains just my content type
  • Sets the default page of the site to the default view of the document library
  • Adds some of my content type fields to the default view


public class ProjectSiteReceiver : SPFeatureReceiver
{
    private string _documentLibraryTitle = "Project Documents";
 
    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
        using (SPWeb web = (SPWeb)properties.Feature.Parent)
        {
            SPListTemplateType templateType = SPListTemplateType.DocumentLibrary;
            Guid listId = web.Lists.Add(_documentLibraryTitle, null, templateType);
 
            SPList list = web.Lists[listId];
            list.Title = _documentLibraryTitle;
            list.EnableVersioning = true;
            list.ContentTypesEnabled = true;
            list.Update();          
 
            SPContentType contentType = web.GetContentType("Project Document");
            SPContentType listContentType = list.ContentTypes.Add(contentType);
            listContentType.Update();
 
            List<SPContentType> contentTypeList = new List<SPContentType>();
            contentTypeList.Add(listContentType);
            list.RootFolder.UniqueContentTypeOrder = contentTypeList;
            list.RootFolder.Update();
 
            SPFolder webFolder = web.RootFolder;
            webFolder.WelcomePage = list.DefaultView.Url;
            webFolder.Update();
 
            SPView view = list.DefaultView;
            view.ViewFields.Add("Project ID");
            view.ViewFields.Add("Project Type");
            view.Update();
        }
    }
 
    public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
    {
        using (SPWeb web = (SPWeb)properties.Feature.Parent)
        {
            SPList list = web.GetListByName(_documentLibraryTitle);
            list.Delete();
        }
    }
 
    public override void FeatureInstalled(SPFeatureReceiverProperties properties)
    {
    }
 
    public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
    {
    }
}




PS: Sorry GetContentType and GetListByName are my own custom extension methods. There isn't much to them really, just better error handling then using the default SharePoint API methods with square brackets.

PPS: You also need to set the welcome page back to the default in the FeatureDeactivating method:

SPFolder webFolder = web.RootFolder;
webFolder.WelcomePage = "default.aspx";
webFolder.Update();

Opening SPFile from full file URL

I had to implement a custom search to find documents matching certain criteria. I could easily find a document and retrieve its "Path" (full url). From this URL, I needed to get the associated SPFile object. This took longer then I thought it warranted.

Here is the solution:

string fileUrl = dt.Rows[0]["Path"].ToString();
 
using (SPSite site = new SPSite(fileUrl))
{
    using (SPWeb web = site.OpenWeb())
    {
        SPFile file = web.GetFile(fileUrl);
 
        if (!file.Exists)
            throw new ApplicationException("Could not find document");
 
        return file;
    }
}

Wednesday, August 12, 2009

Sharepoint Assembly Platform

I recently started a project which consisted of a set of assemblies deployed to the GAC. While integrating with a larger application, the assemblies build configuration were modified to build on x86 Platform (32-bit) explicitly. This was done believing that if they were built as 32-bit, both 32-bit and 64-bit applications could use them.

This worked fine in a 32-bit environment. However, when deploying to a 64-bit environment I was getting "file not found" errors. After some looking into the C:\windows\assembly\gac_msil directory on the server I noticed there where multiple directories there:

  • gac_msil
  • gac32
  • gac64


After some research I discovered that on a 64-bit server, assemblies built as:

Any CPU: go into the gac_msil directory and can be used by either 32-bit or 64-bit processes.

x86: go into the gac32 directory and can only seen and used by 32-bit processes.

x64: go into the gac64 directory and can only be seen and used by 64-bit processes.

My conclusion: leave the build configuration as "Any CPU" !!!!

Monday, August 10, 2009

Unable to move web part

I had an error with not being able to move webparts from in a page. Something like this:



After a bit of research I found the the problem was related to web part zones having a relative position in the CSS. See http://www.sharepointblogs.com/tmt/archive/2007/11/01/CSS-causes-JavaScript-error-while-moving-Web-Parts-in-edit-mode.aspx .

There are a few ways mooted online to fix this problem, but the best solution for me was to set the position of body css element to relative also:

body
{
    position:relative;
}

Problem solved...

Friday, July 17, 2009

Item Adding Event firing on a move

I have an ItemAdding event handler that generates a unique id for a document across document libraries and sites. The event handler is attached to the base content type.

All was going well until I started moving documents. A move fires the ItemAdding event, which recreates a new number for a document.

As the FileMoving and FileMoved event handlers are useless, I needed away to tell if the ItemAdding event is a new document or a moved document.

I eventually worked out a way...In the SPItemEventProperties object is a property named ListItemId. This will be 0 for new items, and a number greater then 0 for an existing item (it is in fact the ID of the record in the existing document library).