Pages

Wednesday, March 6, 2013

SharePoint 2013, Server in the Farm show “Upgrade Available”

 

Background

SharePoint 2013 was installed and updated with patches that give you the version 15.0.4433.1506.  After all the server install is complete, you will notice that the Servers in the Farm displayes “Upgrade Available”, as well as following warning “To get more detailed information about the local upgrade status, run: stsadm.exe -o localupgradestatus”

image

When you follow above steps or look up the Upgrade Status screens on the Central administration, everything looks good, yet the farm status continues to show, Upgrade Available.

 

Issue

I did not face any functional issues but was just annoyed by the status warnings.

Solution

image

image

Restart IIS

image

Technorati Tags:

Friday, May 6, 2011

How to open each file in new window in Excel 2010

 

Overview

You are using Excel 2010 (May for for Excel 2007 as well). You want to open each file in Excel as separate window. By default Excel 2010 (and Excel 2007) opens each file within the Excel Program. Excel 2010 and 2007 are designed as MDI applications.

Disclaimer

This is not Microsoft supported option. Although this has worked well for me, use caution as this approach includes on undocumented registry changes suggested by many other internet search results. It was confusing to try out all the options and get the result correct.  I wanted to share clearly given my situation what has worked.

Other Considerations

Being able to open each file in new window means being able to run new instance of Excel.exe program, that means you are using more memory. So use caution while trying to open more files when you have your excel program configured for this situation.

My Platform

  • Windows 7 x64 Ultimate (I Guess any editions might result with same behavior)

  • Office Professional Plus 2010 (I Guess any editions might result with same behavior)

    My Settings

    To make .xlsx file open in new window.

  • Open registering editing tool.

  • Navigate to “HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\Open”

  • Right click on “Open” note and and export to file to save as backup.

  • Go to “Command” node.

  • Update the “Default” key to below value

    "C:\Program Files\Microsoft Office\Office14\EXCEL.EXE" /e "%1"


  • Rename the “Command” key below the “Default” key to “CommandOld”

  • Rename the “ddeexec”  Node to “ddeexecOld”

    You should see your registry changes similar to below pictures after change has been made:

    image

    image

    Now give it shot by open the “.xlsx”  files, you will see each file is opened in new window.

    Beware each Excel.xxxx  registry key is for each type of file that Excel as association with.

    For other type of extension based files fine below nodes and based on that I guess you can figure out your other type of files that you want to open to be configured the same.

    File Type to Open Registry sub key File Version
    For .xlsx Excel.sheet.12 Excel 2010 file
    For .xls Excel.sheet.8 Excel 2003-2007 file
    For .csv Excel.CSV Comma separated file

    Happy Excelling with more windows!

    Technorati Tags:
  • Friday, April 8, 2011

    How to programmatically copy Web Level, List level and List Item Level Security Information for SharePoint Sites

     

    [Note : This post is part of  my main blog “Moving Large MOSS 2007 Sites” and “SharePoint 2010 Migration”]

    Some Background

    [See my other blog on Drawbacks of current List Export and Import MOSS 2007 Content Migration APIs]

    How to fix this gap?

    Well, there are SharePoint APIs you can use to copy all the necessary missing security information. But there needs to be an order to perform the process most efficiently. Follow below order of steps:

    • First you will be creating a new site collection, or you may already have your target importing site collection existing.
    • In any case before you perform your Import, you want to first copy over the Custom Permission Level.
    • Next you want to perform your usual Import with All security Included. (settings.IncludeSecurity = SPIncludeSecurity.All)
    • Above Import process will ensure to import all the Users and SharePoint Groups and any OOTB Permission Levels as applicable.
    • Now you want to Copy all the Web level Permission Assignments. Having all ready  copied the custom permission levels, this step will ensure all the permission assignments are appropriately copied over.
    • Next you can attend for each of the lists and libraries you have imported, copy the Permission Assignments.
    • Next you can attend for each Items in your lists and libraries you have imported, copy the Item Level Permission Assignments.

     

    Below are the methods for each of these above tasks:

    Your call order:

    1. PrepareNewSiteCollection();//Here either create the new site collection in preparation for Import, or simply establish your site collection SPSite object.

    2. CopyWebRoleAssignments(); //Here copy the web level permission levels.

    3. PerformListExportImporting(); //Here perform your List Export and Import.

    4. CopyWebRoleAssignments();//Here perform your Web level Permission Assignments copy.
    5. CopyListRoleAssignments(); //Here finally copy your List and List item level permissions.

     

    Common Methods:

            public static void CopyWebRoles(SPWeb sourceWeb, SPWeb destinationWeb)
    {

    //First copy Source Web Role Definitions to the Destination Web
    foreach (SPRoleDefinition roleDef in sourceWeb.RoleDefinitions)
    {
    //Skip WSS base permission levels
    if (roleDef.Type != SPRoleType.Administrator
    && roleDef.Type != SPRoleType.Contributor
    && roleDef.Type != SPRoleType.Guest
    && roleDef.Type != SPRoleType.Reader
    && roleDef.Type != SPRoleType.WebDesigner
    )
    {
    //handle additon of existing permission level error
    try { destinationWeb.RoleDefinitions.Add(roleDef); }
    catch (SPException) { }
    }
    }


    }


    public static void CopyWebRoleAssignments(SPWeb sourceWeb, SPWeb destinationWeb)
    {

    //Copy Role Assignments from source to destination web.
    foreach (SPRoleAssignment sourceRoleAsg in sourceWeb.RoleAssignments)
    {
    SPRoleAssignment destinationRoleAsg = null;

    //Get the source member object
    SPPrincipal member = sourceRoleAsg.Member;

    //Check if the member is a user
    try
    {
    SPUser sourceUser = (SPUser)member;
    SPUser destinationUser = destinationWeb.AllUsers[sourceUser.LoginName];
    if (destinationUser != null)
    {
    destinationRoleAsg = new SPRoleAssignment(destinationUser);
    }
    }
    catch
    { }

    if (destinationRoleAsg == null)
    {
    //Check if the member is a group
    try
    {
    SPGroup sourceGroup = (SPGroup)member;
    SPGroup destinationGroup = destinationWeb.SiteGroups[sourceGroup.Name];
    destinationRoleAsg = new SPRoleAssignment(destinationGroup);
    }
    catch
    { }
    }

    //At this state we should have the role assignment established either by user or group
    if (destinationRoleAsg != null)
    {

    foreach (SPRoleDefinition sourceRoleDefinition in sourceRoleAsg.RoleDefinitionBindings)
    {
    try { destinationRoleAsg.RoleDefinitionBindings.Add(destinationWeb.RoleDefinitions[sourceRoleDefinition.Name]); }
    catch { }
    }

    if (destinationRoleAsg.RoleDefinitionBindings.Count > 0)
    {
    //handle additon of an existing permission assignment error
    try { destinationWeb.RoleAssignments.Add(destinationRoleAsg); }
    catch (ArgumentException) { }
    }

    }

    }

    //Finally update the destination web
    destinationWeb.Update();

    }


    public static void CopyListRoleAssignments(SPList sourceList, SPList destinationList)
    {
    //First check if the Source List has Unique permissions
    if (sourceList.HasUniqueRoleAssignments)
    {

    //Break List permission inheritance first
    destinationList.BreakRoleInheritance(true);

    //Remove current role assignemnts
    while (destinationList.RoleAssignments.Count > 0)
    {
    destinationList.RoleAssignments.Remove(0);
    }


    //Copy Role Assignments from source to destination list.
    foreach (SPRoleAssignment sourceRoleAsg in sourceList.RoleAssignments)
    {
    SPRoleAssignment destinationRoleAsg = null;

    //Get the source member object
    SPPrincipal member = sourceRoleAsg.Member;

    //Check if the member is a user
    try
    {
    SPUser sourceUser = (SPUser)member;
    SPUser destinationUser = destinationList.ParentWeb.Users.GetByEmail(sourceUser.Email);
    destinationRoleAsg = new SPRoleAssignment(destinationUser);
    }
    catch
    { }

    if (destinationRoleAsg == null)
    {
    //Check if the member is a group
    try
    {
    SPGroup sourceGroup = (SPGroup)member;
    SPGroup destinationGroup = destinationList.ParentWeb.SiteGroups[sourceGroup.Name];
    destinationRoleAsg = new SPRoleAssignment(destinationGroup);
    }
    catch
    { }
    }

    //At this state we should have the role assignment established either by user or group
    if (destinationRoleAsg != null)
    {

    foreach (SPRoleDefinition sourceRoleDefinition in sourceRoleAsg.RoleDefinitionBindings)
    {
    try { destinationRoleAsg.RoleDefinitionBindings.Add(destinationList.ParentWeb.RoleDefinitions[sourceRoleDefinition.Name]); }
    catch { }
    }

    if (destinationRoleAsg.RoleDefinitionBindings.Count > 0)
    {
    //handle additon of an existing permission assignment error
    try { destinationList.RoleAssignments.Add(destinationRoleAsg); }
    catch (ArgumentException) { }
    }

    }

    }

    //Does not require list update
    //destinationList.Update();
    }
    else
    //No need to assign permissions
    return;



    }

    public static void CopyListItemsRoleAssignments(SPList sourceList, SPList destinationList)
    {
    foreach (SPListItem sourceListitem in sourceList.Items)
    {
    CopyListItemRoleAssignments(sourceListitem, destinationList.GetItemById(sourceListitem.ID));
    }

    }
    public static void CopyListItemRoleAssignments(SPListItem sourceListItem, SPListItem destinationListItem)
    {
    //First check if the Source List has Unique permissions
    if (sourceListItem.HasUniqueRoleAssignments)
    {

    //Break List permission inheritance first
    destinationListItem.BreakRoleInheritance(true);
    destinationListItem.Update();

    //Remove current role assignemnts
    while (destinationListItem.RoleAssignments.Count > 0)
    {
    destinationListItem.RoleAssignments.Remove(0);
    }
    destinationListItem.Update();

    //Copy Role Assignments from source to destination list.
    foreach (SPRoleAssignment sourceRoleAsg in sourceListItem.RoleAssignments)
    {
    SPRoleAssignment destinationRoleAsg = null;

    //Get the source member object
    SPPrincipal member = sourceRoleAsg.Member;

    //Check if the member is a user
    try
    {
    SPUser sourceUser = (SPUser)member;
    SPUser destinationUser = destinationListItem.ParentList.ParentWeb.AllUsers[sourceUser.LoginName];
    if (destinationUser != null)
    {
    destinationRoleAsg = new SPRoleAssignment(destinationUser);
    }
    }
    catch
    { }

    //Not a user, try check if the member is a Group
    if (destinationRoleAsg == null)
    {
    //Check if the member is a group
    try
    {
    SPGroup sourceGroup = (SPGroup)member;
    SPGroup destinationGroup = destinationListItem.ParentList.ParentWeb.SiteGroups[sourceGroup.Name];
    if (destinationGroup != null)
    {
    destinationRoleAsg = new SPRoleAssignment(destinationGroup);
    }
    }
    catch
    { }
    }

    //At this state we should have the role assignment established either by user or group
    if (destinationRoleAsg != null)
    {

    foreach (SPRoleDefinition sourceRoleDefinition in sourceRoleAsg.RoleDefinitionBindings)
    {
    try { destinationRoleAsg.RoleDefinitionBindings.Add(destinationListItem.ParentList.ParentWeb.RoleDefinitions[sourceRoleDefinition.Name]); }
    catch { }
    }

    if (destinationRoleAsg.RoleDefinitionBindings.Count > 0)
    {
    //handle additon of an existing permission assignment error
    try { destinationListItem.RoleAssignments.Add(destinationRoleAsg); }
    catch (ArgumentException) { }
    }

    }

    }

    //Ensure item update metadata is not affected.
    destinationListItem.SystemUpdate(false);
    }
    else
    //No need to assign permissions
    return;



    }



     





    Technorati Tags:

    Drawbacks of current List Export and Import MOSS 2007 Content Migration APIs

     

    [Note : This post is part of  my main blog “Moving Large MOSS 2007 Sites” and “SharePoint 2010 Migration”]

    Some Background.

    Suppose you are considering using the SharePoint Content Migration API for copying your SharePoint content from one site to another site. Consider below tested scenarios on what you will actually get out of the API usage results  for your implementation.

    When you are using SharePoint SPWeb Object as source to Export/Import API Process, you will get the SharePoint Permissions, SharePoint Users and the SharePoint Groups as well as Site Permissions. In additionally since all the List and list items are part of the larger scope of the SPWeb, you will also get the entire list and list item level permissions copied as well.

    Other than security all of your metadata, date and time stamps is all retained. Hence you are covered for the most part. (Excluding any of your customizations, workflows, alerts etc. which you are responsible to appropriately make the transition).

    I have experienced a lack of security data being transferred appropriately when it comes to Export/Importing anything  below the SPWeb object.

    What security information does SharePoint List Export/Import API Process copy?

    • Copies only the Users/AD Groups  and the SharePoint Groups and their members.
    Source Target
    image image
    Users
    image
    Users
    image
    Users are missing.
    Permission Levels
    image
    Permission levels
    image
    Custom Permission Level(s) are missing
    (Publishing Portal specific Permission Levels will also be missed if the target site collection is not a Publishing Site which is fine).

     

    What security information does SharePoint List Export/Import API Process not copy?

    • Does not copy Web Level Permission Assignments.
    • Does not copy List/Lib Level Permission Assignments (Other than the OOTB Groups and OOTB Permission Levels).
    • Does not copy List/Lib Item/Folder Level Permission Assignments (Other than the OOTB Groups and permission levels).
    Source Target
    Web Level Permissions
    image
    Web level Permissions
    image

    All Web Level permission assignments are missing.
    Library Level Permissions
    image
    Library Level Permissions
    image

    All Library Level permission assignments are missing.
    Library Item Level Permissions
    image
    Library Item Level Permissions
    image
    All Library Item Level permission assignments are missing.

     

    How to fix this gap?

    See my other blog on How to programmatically copy Web Level, List level and List Item Level Security Information for SharePoint Sites

    Thursday, April 7, 2011

    SharePoint (MOSS 2007) Export and Import API specifics (PRIME)

     

    [Note : This post is part of  my main blog “Moving Large MOSS 2007 Sites” and “SharePoint 2010 Migration”]

    [Also see my other blog on Drawbacks of current List Export and Import Content Migration APIs]

    [Also see my other blog on Copying Web Level, List level and List Item Level Security Information]

    Overview

    There are several good references (refer to my main blog on SharePoint 2010 Migration) when it comes to SharePoint Export and Import API. I still wanted to call out as reference to all of the options that will need to be appropriately set to get your export and import going.

    Export Specifics

    Below I am listing all the possible Export Settings properties following by my comments:

    Basic Object definition properties to be set:

    SPExportObject exportObject = new SPExportObject();
    exportObject.Id = web.ID;
    exportObject.IncludeDescendants = SPIncludeDescendants.All;
    exportObject.Type = SPDeploymentObjectType.Web;

     

    Export Specific settings:

    SPExportSettings settings = new SPExportSettings();

    //Standard Options
    settings.SiteUrl = web.Url;
    settings.FileLocation = exportFolderPath;
    string exportImportSubFolder = YourExportFolder;

     

    Export Log File settings:
    string exportLogFile = YourExportLogFilename;
    if(System.IO.File.Exists(YourExportLogFilename))
    {
        File.Delete(YourExportLogFilename);
    }
    settings.LogFilePath = YourExportLogFilename;


    Export general Settings:
    settings.FileCompression = false;
    settings.ExcludeDependencies = true;
    settings.OverwriteExistingDataFile = true;

    Export events to be disabled Settings:
    settings.HaltOnNonfatalError = false;
    settings.HaltOnWarning = false;


    Export configurable Settings:
    settings.IncludeSecurity = SPIncludeSecurity.All;
    settings.IncludeVersions = .All;
    settings.CommandLineVerbose = true; 
    settings.ExportMethod = SPExportMethodType.ExportAll;


    Note this  settings if you want to mock-run the export:                   
    settings.TestRun = true;  
                        
    As best practice run the validate, your try catch can catch early error much before the Export is kicked off:
    settings.Validate();


    Final Export Run Settings:
    settings.ExportObjects.Add(exportObject);
    SPExport export = new SPExport(settings);
    export.Run();

     

    Import Specifics

    Basic Object definition properties to be set:
    SPImportSettings settings = new SPImportSettings();
    settings.SiteUrl = YourNewSiteCollection.Url;
    //Assign the importing parent web URL
    settings.WebUrl = DestinationWebURL;

    Set the file locations for where the exported data is located:
    settings.FileLocation = YourImportFolderPath;

    Set the Import log file name. Delete first if exists from he previous run, otherwise it will append and could get large:
    if (System.IO.File.Exists(YourImportLogFile))
    {
        File.Delete(YourImportLogFile);
    }
    settings.LogFilePath = YourImportLogFile;

    No need to set compressed since we will be importing from an uncompressed export:
    settings.FileCompression = false;

    Set to false to be able reparent in a new site collection:
    settings.RetainObjectIdentity = false; 

    You want all the security to be included (See my other blog on .... ):
    settings.IncludeSecurity = SPIncludeSecurity.All;

    You want to set to all to import all user date time into:
    settings.UserInfoDateTime = SPImportUserInfoDateTimeOption.ImportAll;

    You want to supress the events to increase your import performance:
    settings.HaltOnNonfatalError = false;
    settings.HaltOnWarning = false;
    settings.SuppressAfterEvents = false;

    You want to get all the versions:
    settings.UpdateVersions = SPUpdateVersions.Append;

    Verbose log will generate detailed log while running:
    settings.CommandLineVerbose = true;

    As best practice run the validate, your try catch can catch early errors much before the Import is kicked off:
    settings.Validate();

    Final Import Run Settings:
    SPImport import = new SPImport(settings);
    import.Run();

    How to programmatically lock SharePoint Site Collection while Exporting and other maintenance work

     

    [Note : This post is part of  my main blog “Moving Large MOSS 2007 Sites” and “SharePoint 2010 Migration”]

    In order to ensure your export remains consistent through the process of Export and then till the completion of Import, consider Read Locking your Exporting Site Collection.  

    Lets see how these  UI settings for the locks map to the code options:

    SPSite.WriteLocked

    image_thumb1

    SPSite.ReadOnly

    image_thumb2

    SPSite.ReadLocked

    image_thumb3

    Below I am sharing my code base for implementing the ReadOnly locks. Few things to note:

    • When you are assigning any lock, it is important that you first assign the LockHint before setting the Lock as the site collection becomes the respective lock mode.
    • When you are removing any lock, it is important that you first setting the given Lock false. as the site collection becomes released from the respective lock mode. Then clear off the lock hint.

    Your Call order

    1. LockSiteCollection(SiteCollection);
    2. Perform Your Export/Import here
    3. UnLockSiteCollection(SiteCollection);

    Common Methods you can use:

     

           private void LockSiteCollection(SPSite Site)
    {
    //Try lock the Portal Site Collection
    try
    {
    Site.LockIssue = “Your Lock reason”;
    }
    //handle prior left out read only locks due to errors.
    catch (UnauthorizedAccessException)
    {
    Site.ReadOnly = false;
    Site.LockIssue = “Your Lock reason”;
    }
    Site.ReadOnly = true;

    }


    private void UnLockSiteCollection(SPSite Site)
    {

    Site.ReadOnly = false;
    Site.ReadLocked = false;
    Site.WriteLocked = false;
    Site.LockIssue = "";
    }




    Technorati Tags:

    Site Collection Creation and re-parenting

    [Note : This post is part of  my main blog “Segregating Large MOSS 2007 Sites” and “SharePoint 2010 Migration”]

    When you are importing a SPWeb or an SPWeb tree in to a new Site Collection, you will want to first create new site collection.  Now moving a given SPWeb as Root Web in to a new Site Collection is called re-parenting. From the above references you will get the more on this. But something I wanted to emphasize and clarify why we should create a new Site Collection via an STSADM  createsite as supposed to SPWebApplication.CreateSite().

    SPWebApplication.CreateSite().

    Result: 

    • Site Collection
    • -->Rootweb is created with given Template Type (STS/MPS/Custom)

    What happens here: you can only import on top of the RootWeb. So the end result is that your imported web is always a sub web of the rootweb.

     

    STSADM  createsite

    Result: 

    • Site Collection
    • -->Rootweb is created with Blank Template Type (NOT STS/MPS/Custom)

    What happens here: you can import in to the RootWeb. So the end result is that your imported web can be at rootweb level.