Wednesday, December 14, 2011

Scripts to enable, disable & check Office Web Apps site collections

A. Enabling in all site collections

$webAppsFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApps"}).Id
Get-SPSite -limit ALL |foreach{Disable-SPFeature $webAppsFeatureId -url $_.URL }

B. Disabling from all site collections

$ConfirmPreference = 'None'
$webAppsFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApps"}).Id
Get-SPSite -limit ALL |foreach{Disable-SPFeature $webAppsFeatureId -url $_.URL }

C. Enabling in all site collection within MySite Web Apps

$webAppsFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApps"}).Id
Get-SPSite -WebApplication <web app url> -limit all |foreach{Enable-SPFeature $webAppsFeatureId -url $_.URL }

D. Enabling in a single site collection

$webAppsFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApps"}).Id
$singleSiteCollection = Get-SPSite -Identity <site coll url>
Enable-SPFeature $webAppsFeatureId -Url $singleSiteCollection.URL

E. List sites which doesn't have Office Web Apps activated


Get-SPFeature -Site <site coll url> | where {$_.DisplayName -eq "OfficeWebApps"}

$SiteColls = @(Get-SPSite -WebApplication <web app > -Limit ALL)

foreach ($site in $SiteColls)

{
$feature= Get-SPFeature -Site $site.URL | where {$_.DisplayName -eq "OfficeWebApps"}

if ($feature -eq $Null)
{
write-host "OfficeWebApps is not activated at " , $site.URL
}

}

While activating OWA (using scripts A or C), I got some error which says couldn't activate because exceeded quota. But none of the site collection has exceeded quota. And there was no easy way to identify which site collection was not activated with OWA. Hence, the code (E).

Friday, November 25, 2011

SharePoint 2010 Survey Issue

My user complained about an issue yesterday. Users not able to submit responses to her survey.

Below is the error.



When I checked the survey question's setting, I found the “Enforce unique values:” was set to Yes. I changed to No and issue was resolved.



 

Wednesday, November 23, 2011

SharePoint 2010 SQL Queries To Get Largest Documents

Below are queries that we can use to list down the top 100 largest documents in a SharePoint 2010 content DB

1. Query to list 100 largest document

Select top 100 D.DirName, D.LeafName, D.Size
From <content db name>.dbo.AllDocs D With (NOLOCK)
Order by D.Size desc

2. If we need to filter based on a specific site collections, we can use query below

Select top 100 D.DirName, D.LeafName, D.Size
from <content db name>.dbo.AllDocs D With (NOLOCK)
join <content db name>.dbo.Webs W With (NOLOCK)
on D.SiteId=W.SiteId
where W.FullUrl='<url>'
order by D.Size Desc

3. To further filter in a specific file extension (in this case its avi), we can use the query below

select top 100 D.DirName, D.LeafName, D.Size
from <content db name>.dbo.AllDocs D With (NOLOCK)
join <content db name>.dbo.Webs W With (NOLOCK)
on D.SiteId=W.SiteId
where W.FullUrl='<url>'
and D.Extension = 'avi'
order by D.Size Desc

 

4. Total document size. You need to cast as bigint , otherwise most likely to get  arithmetic overflow

select D.Extension, SUM(CAST(D.Size as BIGINT)) AS [Total Size]
<content db name>.dbo.AllDocs D With (NOLOCK)
group by D.Extension
order by [Total Size] desc

 

Calculated Field Formulas

MSDN article for calculated field formulas: http://msdn.microsoft.com/en-us/library/bb862071.aspx

Tuesday, November 22, 2011

Multiple views in InfoPath 2010 forms

I have not used InfoPath much before until recently when I was asked to proof-of-concept (POC) a approval form in SharePoint. So I explored SharePoint 2010 for providing storage and routing engine (workflow) and InfoPath 2010 for designing the form.  Contrary to my initial expectation, I was actually pleasantly surprised with what I learned about InfoPath 2010. There are a few cool features that I find very useful for form designing. One of them is Views.

We can create multiple views for the same form. In my case, I created a form submitter view, approver view, add approver view and Watcher view. The first 3 are self-explanatory. The Watcher view is a read-only and will be activated when the form has been fully approved or being viewed by persons other than the original form submitter or approvers.

To create a view, you have to click on the Page Design tab and click New View. Once, the views are created, we can use the rules to activate them accordingly. In my case, I created rules during form load. To get there, Click on the Data tab and choose Form Load. On the Rules window, create rules and add conditions and actions ( = switch views).

In this example, Submitter view will be activated/shown when the current user is the form submitter. By the way, you can also switch to another view based on a button click.



Have fun with InfoPath 2010 !!.

Thursday, November 10, 2011

Error while visual upgrade

After mounting MySites DB, we performed the visual upgrade using the commands below:

$webapp = Get-SPWebApplication <web apps url>
foreach ($s in $webapp.sites)
{$s.VisualUpgradeWebs() }

but encountered the below error

Exception calling "VisualUpgradeWebs" with "0" argument(s): "Access is denied.
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At line:2 char:22
+ {$s.VisualUpgradeWebs <<<< () }
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

This is because at least one or more of the site collections are in read-only.

To find out which ones, run the commands below

$webapp = Get-SPWebApplication <web apps url>
foreach ($s in $webapp.sites)
{$s | Get-SPSite  | Where {$_.readonly -eq "true" }} ; readonly is the column name !!


We then need to unlock those sites

Set-SPSite -Identity <site collection url> -LockState unlock

Manual creation of a MySite Site Collection

It just happens that sometimes we need to do something out of the normal process. In this case, I had to manually create a MySite site collection for a user.

Manual creation using UI doesn't give any error message but it doesn't work. Site was created & the structure in place but when I click My Contents (content if for a different user), nothing happens.

So I tried using PowerShell. Below is the code that I used, which was adapted from another blog post.

$mysiteHostUrl = "<your MySite Host URL>"
$mysite = Get-SPSite $mysiteHostUrl
$context = [Microsoft.Office.Server.ServerContext]::GetContext($mysite)
$upm =  New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $upm.GetEnumerator()
foreach($profile in $AllProfiles)
{
   if ($profile.DisplayName -like "User Name")
   {    
      if($profile.PersonalSite -eq $Null)
      {
           write-host "Creating personal site for ", $profile.DisplayName
           $profile.CreatePersonalSite()
           write-host "Personal site created"
      }
      else
      {
           write-host $profile.DisplayName ," has already personal site"
      }
   }
}
$mysite.Dispose();

A Few important notes:

1. Initially, when I test this in my dev environment, the line below returned null all the time even though the personal site exist.

$profile.PersonalSite

I guess something is wrong with the User Profile Service (UPS). When I tried the code in another environment, it returned the expected values. So we need to verify first if the our UPS is working fine before attempting to run the code.

2. If line below gives you an error,

$upm =  New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

give the account you are running the powershell full control in 2 places - see below



Code above was adapted from: http://blog.bugrapostaci.com/2011/10/03/create-all-users-personal-site-via-powershell-script-sharepoint-2010/

Wednesday, September 7, 2011

Retrieving SharePoint List programatically

Code below gets you the list object

string srListURL = <list url>

SPSite mySite = new SPSite(strListURL);
SPWeb myWeb = mySite.OpenWeb();

try
{

SPList myList = myWeb.GetList(strListURL);

}

catch(Exception)

{

//error handling here

}

Friday, August 12, 2011

Listing a site's owners or users with full control

Code below will list down a site's owners or users with full control

//first try the code below, should work most of the time

//unless users/admins mess up with the default groups

try
{

SPGroup myOwnerGroup = myWeb.AssociatedOwnerGroup;
foreach (SPUser myOwner in myOwnerGroup.Users)
{

//do what needs to be done here

}
}

catch (Exception ex)
{
//just ignore & proceed with the fall back mechanism to get the owners
}

//if the code above didn't return any values then the code below is the fall back mechanism

SPSite mySite = new SPSite(<website url>);
SPWeb myWeb = mySite.OpenWeb();

try
{
foreach (SPUser myWebUser in myWeb.AllUsers)
{

if (myWeb.DoesUserHavePermissions(myWebUser.LoginName, SPBasePermissions.ManagePermissions))
{

//do what needs to be done here

}
}

}
catch (Exception ex)
{

//error processing here

}

Wednesday, July 20, 2011

Customizing SharePoint 2007 "Access Denied" Page

In SharePoint 2010, we can run the powershell command below to "tell" SharePoint that we have our own "Custom Access Denied" page & which web applications should use that custom page.

Set-SPCustomLayoutsPage -Identity <None | AccessDenied | Confirmation | Error | Login | RequestAccess | Signout
| WebDeleted> -RelativePath <String> -WebApplication <SPWebApplicationPipeBind>
[-AssignmentCollection <SPAssignmentCollection>] [-Confirm [<SwitchParameter>]] [-WhatIf [<SwitchParameter>]]

However, we don't have the same feature in SharePoint 2007. Below is a workaround to achieve just that. Explanation follows.

1. First make a backup copy of out of box version of the  AccessDenied.aspx file. Keep it safe somewhere.

2. Open the Accessdenied.aspx file in your favourite editor (Notepad? Visual Studio?)

3. Insert the code below in the file between the last register statement line and content place holder code

<script runat="server">

protected void Page_Load(object sender, EventArgs e)
{
string strIncoming = Page.Request.Url.AbsoluteUri.ToLower();

string strTargetURL = "";
string strSource = Request.QueryString["Source"];
string strType = Request.QueryString["type"];
string strQuery = "";

///Check if its customized web apps
if (IsCADeniedWebApp(strIncoming))
{

//check  if user is trying to sign in as another user
if (!strIncoming.Contains("loginasanotheruser"))
{
strQuery = "Source=" + strSource + "&Type=" + strType;
strTargetURL = "/_layouts/<your custom folder>/<your custom page>" + strQuery;

SPUtility.Redirect(strTargetURL, SPRedirectFlags.Default, HttpContext.Current);
}
}
}

private bool IsCADeniedWebApp(string strURL)
{
try
{
string strWebApp = "";
string[] arrWebApps = File.ReadAllLines("C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\12\\TEMPLATE\\LAYOUTS\\<your custom folder>\\CustomisedWebApps.txt");
int intNumberOfWebApps = arrWebApps.Length;

for (int i = 0; i < intNumberOfWebApps; i++)
{
if (arrWebApps[i] != null)
{
strWebApp = arrWebApps[i].Trim();
if (strWebApp != "")
{
if (strURL.Contains(strWebApp))
return true;
}
}
}

return false;
}
catch (Exception ex)
{
return false;
}
}
</script>

The code makes use of a text file which contains the list of web apps that will use the customized access denied page.

Basically, the code above will check for 2 conditions.

i) if the URL that user accessing belongs to a web apps that uses customized access denied page. If not, just ignore it.

ii) if user is trying to login as another user.  For some reason, MS is re-using the AccessDenied.aspx to handle "signing in as another user".

If, the URL belongs to the web apps that uses customized access denied page and user is not trying to sign in as another user, the code will redirect the user to another page. this is where you need to add your custom code.In my case, i will display the list of users with full control to the site or resource.

Monday, April 18, 2011

Exception from HRESULT: 0x80040D1B error was displayed when trying to access the search settings from SSP

If you get this error -->

Exception from HRESULT: 0x80040D1B

when you try to access the search settings from SSP, check whether you have any duplicate entries in

 \\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\12.0\Search\Applications\{site GUID}\Gather\Portal_Content\Extensions\ExtensionList.

If you do, remove it, stop and start the MOSS Search service again.

I accidentally created duplicate entries in the list above when deployed PDF iFilter and got the error above.

Below is what you will see in your event viewer,

--------------------------------

The gatherer object cannot be initialized.

Context: Application '<>_SSP_Admin', Catalog 'Portal_Content'

Details:
    A duplicate extension entry exists in the registry. The duplicate extension should be deleted, but all other extensions are unaffected.   (0x80040d0b)

-------------------------------------------

Friday, April 1, 2011

No users in SharePoint 2010 after successfull profile import

Well, to start with, to say it is successful is misleading but that is the scenario we faced.

In our brand new SharePoint 2010 farm, we configured profile synch from AD. Everything looks cool but no users was found. Not sure where they are going but the data is simply not in the user profile store. Luckily google and technet forum helped :-).  No error messages and no clue until I came across a technet post which I believe was written for SharePoint 2007 but I gave it a try.

But first, try to search for the users. SharePoint 2010 does not list the users. You need to search for them. Just type any letter and search. If no values returned, then you can try the below steps.

This what I did

1. From the Admin Tools --> Servicess Stopped the SharePoint Timer service

2. From the Central Admin --> Services on Server, stopped both the User Profile Service and User Profile Synchronization Service

3. Navigated to the C:\ProgramData\Microsoft\SharePoint\Config\<GUID> folder

4. Removed all the other xml files

5. Edited the cache.ini file to replace the value with 1 and saved the file

6. Started back the SharePoint Timer service, waited till all the xml files were recreated and the number on cache.ini file return to its original value

7. Started back the User Profile Service and User Profile Synchronization Service

8. Then under CA --> Application Management --> Manage Service Application --> User Profile --> Start Profile Synchronization

9. Waited and it worked :-)

10. The users will not be listed. You need to search for them.

Ref:  Technet forum post

Wednesday, March 30, 2011

Setting up Adobe PDF iFilter 9 for SharePoint 2007

I am posting this for my own future reference :-p and other newbies like me :-).

I downloaded the Adobe Pdf iFilter from here. And then followed the instructions.

But I got error (below)

Crawled (The filtering process could not process this item.This might be because you do not have the latest file filter for this type of item. Install the corresponding filter and retry your crawl. )

So when I googled around, I was pointed to many forums and blogs on how to overcome the error.  I find this article very informative especially when it mentioned about checking the second registry key.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\12.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf]

But after I made the changes, I was still getting the error. After troubleshooting for a while. I found out that I made a silly mistake !! I forgot about the curly brackets. I changed the registry values for the two keys above to {E8978DA6-047F-4E3D-9C78-CDBE46041603} and it works perfectly now.