SharePoint 2010 – Disaster Recovery

Recently out of normal development routine I was discussing with my development team regarding the IT side of SharePoint 2010.

One of the aspects we were discussing about was the “Disaster Recovery.” Being developers, “Disaster Recovery” was a mere term rather than an important IT aspect for them and I fastly realized it was slightly boring for them.

Post discussion I decided to give them some links so that they can refer when needed. Found out following were some of the links they can quickly read and understand.

Disaster Recovery for SharePoint 2010
Configure Disaster Recovery Farm with SharePoint 2010
SharePoint Server 2010 – 10 Steps to Disaster Recovery

Setting password for Managed Account

Password for Managed Account in SharePoint 2010 can be set in the following ways.

Set a new password for Managed Account

#If there is only one managed account, the following line could be written as: 
#$inputManagedAcct = Get-SPManagedAccount

$inputManagedAcct = Read-Host "Enter managed account as Domain\User"

#Input the desired new password
$inputPasswd = Read-Host "Enter new password for managed account" –AsSecureString 

#Change the password for the managed account to the new value Set-SPManagedAccount -Identity $inputManagedAcct -NewPassword $inputPasswd

To update the account password to a new automatically generated value, from the Windows PowerShell command prompt, type the following:

Set-SPManagedAccount –Identity domain\user -AutoGeneratePassword $true

Update the password for a Managed Account that has already been reset through Active Directory

If the password for a managed service account has been manually changed outside of SharePoint (such as directly in Active Directory), you can update the password to the new value in SharePoint 2010 as follows

#If there is only one managed account, the following line could be written as: 
#$inputManagedAcct = Get-SPManagedAccount

$inputManagedAcct = Read-Host "Enter managed account as Domain\User:" 
#Input the Managed Account $inputPasswd = Read-Host "Enter password from Active Directory for managed account:" –AsSecureString 

#Change the password in SharePoint for the managed account to the new value 
Set-SPManagedAccount -Identity $inputManagedAcct -ExistingPassword $inputPasswd –UseExistingPassword $true

To update the account password to a already changed password, from the Windows PowerShell command prompt, type the following:

Set-SPManagedAccount -Identity domain\user -UseExistingPassword

For more information look at http://blogs.technet.com/b/seanearp/archive/2011/01/25/updating-passwords-on-sharepoint-2010.aspx

Access Denied – SharePoint code execution

When doing certain code operations in SharePoint like getting list of templates will lead to “Access Denied” exceptions. For such instances we can wrap the code within the following lines to execute code with elevated privileges.

SPSecurity.RunWithElevatedPrivileges(delegate()
{
        //Code goes here
});

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.

We were developing a Server Object Model based functionality in SharePoint involving site creation using template. During development we use to get the following error in quick watch window.

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.

To solve this issue we added the following code before the actual statement and issue was solved.

SPSecurity.CatchAccessDeniedException = false;

 

Deleting a file from library using SharePoint ASMX web service

The following is the code for deleting a particular file from a library using SharePoint ASMX web service.
The technique involves identifying the document ID using “GetListItems” of the file and then executing “UpdateListItems”

public string DeleteFileFromSharePoint(string siteUrl, string libraryName, string fileName, FileDeleteInput input)
    {
        Lists listService = new Lists(); //Web reference of http://<server>/sites/<site>/_vti_bin/lists.asmx
        listService.Url = "http://<server>/sites/<site>/_vti_bin/lists.asmx";
        listService.UseDefaultCredentials = true;
        string sourceUrl = fileName;
        string output = string.Empty;

        try
        {
            int fileId = GetFileIdFromList(siteUrl, libraryName, fileName, listService.Url);

            XmlDocument doc = new XmlDocument();
            XmlElement Batch = doc.CreateElement("Batch");
            Batch.SetAttribute("OnError", "Continue");
            Batch.SetAttribute("ListVersion", "1");
            Batch.SetAttribute("ViewName", "");
            string strBatch = "<Method ID='1' Cmd='Delete'>";
            strBatch += "<Field Name='ID'>" + fileId + "</Field>";
            strBatch += "<Field Name='FileRef'>" + siteUrl + libraryName + "/" + fileName + "</Field>";
            strBatch += "</Method>";
            Batch.InnerXml = strBatch;

            XmlNode returnvalue = listService.UpdateListItems(libraryName, Batch);

            if (returnvalue.InnerXml.Contains("0x00000000"))
            {
                output = "Success: File Deleted";
            }
            else if (returnvalue.InnerXml.Contains("Invalid file name"))
            {
                output = "Failure: No such file exists";
            }
            else if (returnvalue.InnerXml.Contains("Access denied"))
            {
                output = "Failure: No such file exists";
            }
            else
            {
                output = "Failure: File couldn't be deleted";
            }
        }
        catch (SoapException ex)
        {
            throw ex;
        }
        catch (Exception)
        {
            throw ex;
        }
        return output;
    }

    protected int GetFileIdFromList(string siteUrl, string libraryName, string fileName, string serviceUrl)
    {
        int id = 0;

        Lists listService = new Lists(); //Web reference of http://<server>/sites/<site>/_vti_bin/lists.asmx
        listService.Url = serviceUrl;
        listService.UseDefaultCredentials = true;

        // Build the CAML Query
        System.Text.StringBuilder queryStringBuilder = new System.Text.StringBuilder();
        queryStringBuilder.Append("     <Query>");
        queryStringBuilder.Append("         <Where>");
        queryStringBuilder.Append("             <Eq>");
        queryStringBuilder.Append("                  <FieldRef Name=\"FileLeafRef\" />");
        queryStringBuilder.Append("                  <Value Type=\"Text\">" + fileName + "</Value>");
        queryStringBuilder.Append("             </Eq>");
        queryStringBuilder.Append("        </Where>");
        queryStringBuilder.Append("    </Query>");

        XmlDocument query = new XmlDocument();
        query.LoadXml(queryStringBuilder.ToString());

        //Build the View Query 
        queryStringBuilder.Clear(); // Clear the string builder
        queryStringBuilder.Append("    <ViewFields>");
        queryStringBuilder.Append("    <FieldRef Name=\"ID\" /><FieldRef Name=\"Title\" /><FieldRef Name=\"Name\" />");
        queryStringBuilder.Append("    </ViewFields>");

        XmlDocument viewFields = new XmlDocument();
        viewFields.LoadXml(queryStringBuilder.ToString());

        //Build the CAML Query Options
        queryStringBuilder.Clear(); // Clear the string builder
        queryStringBuilder.Append("    <QueryOptions>");
        queryStringBuilder.Append("         <Folder>" + libraryName + "/</Folder> />");
        queryStringBuilder.Append("    </QueryOptions>");

        XmlDocument queryOptions = new XmlDocument();
        queryOptions.LoadXml(queryStringBuilder.ToString());

        XmlNode listItems = listService.GetListItems(libraryName, null, query, viewFields, null, queryOptions, null);

        foreach (XmlNode outerNode in listItems.ChildNodes)
        {
            if (outerNode is XmlWhitespace)
                continue;
            else
            {
                if (outerNode.Name == "rs:data")
                {
                    foreach (XmlNode innerNode in outerNode.ChildNodes.OfType<XmlNode>())
                    {
                        if (innerNode is XmlWhitespace)
                            continue;
                        else
                        {
                            id = Int32.Parse(innerNode.Attributes["ows_ID"].Value.ToString());
                        }
                    }
                }
            }
        }

        return id;
    }

 

Using SharePoint 2010’s OOB search result to search in a particular library

There was a requirement to have a search text box and a button in landing page and show OOB search result from a single document library.

After doing some analysis on OOB search the following is the code which we came up with.

The technique is use the query string with query items “k=query”, “cs=This List” & “u=list’s absolute url”. Underlined items are the items which change dynamically.

http://server/sites/site/_layouts/OSSSearchResults.aspx?k=MyQuery&cs=This List&u=http://server/sites/site/MyLibrary

<div>
    <script type="text/javascript">
        function Search() {
            var libraryName = 'Library'; //Library Name            
            var url = window.location.protocol + "//" + window.location.host + _spPageContextInfo.siteServerRelativeUrl; //http://server/sites/<sitecollection> orhttp://server/sites/<sitecollection>/site
            var searchUrl = url + '/_layouts/OSSSearchResults.aspx';

            var queryText = document.getElementById('querybox').value;
            var queryUrl = searchUrl + '?k=' + queryText + '&cs=This List&u=' + url + '/' + libraryName; //http://server/sites/<sitecollection>/_layouts/OSSSearchResults.aspx?k=<Query from input box>&cs=This List&u=http://server/sites/<site>/<Library Name>

            window.navigate(queryUrl);
            //alert(queryUrl);
        }            
    </script>
    <input id="querybox" name="querybox" />
    <input onclick="Search()" name="SearchInLibrary" value="Search In Adapter Document Library" type="button" />
</div>

The HTTP request is unauthorized with client authentication scheme ‘Ntlm’. The authentication header received from the server was ‘NTLM’

For one of the SharePoint implementation I was suppose to call the SharePoint 2010 ASMX service within a Custom WCF services hosted in a different server than the SharePoint 2010 host.

So as usual I added the service reference (PS: The add web reference is not available in WCF solution). Then I was getting the following error whenever the ASMX method was hit in the WCF.

"The HTTP request is unauthorized with client authentication scheme ‘Ntlm’. The authentication header received from the server was ‘NTLM’"

After breaking my head for few minutes, decided to hit the Google and got the solution in the source mentioned at the end.

So finally the code which worked is listed below.

 
  EndpointAddress endpoint = new EndpointAddress(new Uri("http://SharePointserver/_vti_bin/InvoiceServices.svc"));

  BasicHttpBinding httpBinding = new BasicHttpBinding();

  httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

  httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

  InvoiceServicesClient myClient = new InvoiceServicesClient(httpBinding, endpoint);

  myClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

  //Invoke the service method here…

Source: http://stackoverflow.com/questions/2608887/sharepoint-web-services-the-http-request-is-unauthorized-with-client-authenti

Note, in the above it might look like half of the link is missing and actually it works.