Showing posts with label Sharepoint list. Show all posts
Showing posts with label Sharepoint list. Show all posts

Monday, August 12, 2013

Exception setting „Hidden” Cannot change Hidden attribute for this field”

Requirements:
Requirements was to remove the Taxonomy field „Parent Company” from the Sharepoint List  as this field is not used by anyone.
Issue:
Issue with the „Parent Company” field deleting with PowerShell script. After the script run the following error message has appeared. „Exception setting „Hidden” Cannot change Hidden attribute for this field”
Investigation:
This is an internal issue in SharePoint2010.
The common issue description can be found here: http://blogs.msdn.com/b/spblog/archive/2013/04/27/sps2010-field-cannot-be-made-again-visible-if-defined-to-be-hidden-using-visual-studio-2010.aspx .
During development the field „Parent Company” was created usisng xml definition in Visual Studio 2010 and a field attribute „Hidden” was set to value „True” (true if the field is hidden; otherwise, false.)
<Field
       ID="{747FC1CF-FCED-44EB-B895-568E9F423174}"
        Name="ALLegalCompanyTaxHTField1"
        StaticName="ALLegalCompanyTaxHTField1"
        Type="Note"
        Overwrite="TRUE"
        RowOrdinal="0"
        DisplayName="$Resources:IntranetGroupDirectory,Fields_ParentCompany_DisplayName;"
        Group="$Resources:IntranetGroupDirectory,GroupDirectory_CT_Group;"
        Description="$Resources:IntranetGroupDirectory,Fields_ParentCompany_Description;"
        Hidden ="TRUE">
  </Field>
An taxonomy field consists of  two fields (example: „Parent Company” can be seen on screenhot)
The „Parent Company” is a taxonomy field and consists of two fields definition ALLegalCompany and ALLegalCompanyTaxHTField1
<Field
        ID="{B5FE2B9E-CDF9-4B4A-B34C-85650481A280}"
        Name="ALLegalCompany"
        StaticName="ALLegalCompany"
        Type="TaxonomyFieldType"
        ShowField="Term1033"
        Overwrite="TRUE"
        Mult="TRUE"
        DisplayName="$Resources:IntranetGroupDirectory,Fields_ParentCompany_DisplayName;"
        Group="$Resources:IntranetGroupDirectory,GroupDirectory_CT_Group;"
        Description="$Resources:IntranetGroupDirectory,Fields_ParentCompany_Description;"
        Hidden ="FALSE">
</Field>
The field ALLegalCompany has „Hidden” proeprty set value to False.
The field ALLegalCompanyTaxHTField1 has property „Hidden” set to True that caused the difficulties to delete this field.
Fields in SharePoint can be added using xml definition via Visual Studio, but cannot be delete that way, therefore the Powershell commands must be used to delete fields from Lists or Content Type. But the field „Parent Comapny” cannot be deleted that’s way using scrips, because fields should be visible and property „Hidden” is set to false. Property „Hidden” cannot be set to false, because this property depends (relies) on other property called „CanToggleHidden” and it’s value should be set to True. „CanToggleHidden” property is Read-only and  and it’s value cannot be change directly, because there is no setter method (this is a SharePoint property that stored in native assemly (SPField) and was developed that way, the reason of that fact is unknown).
To be possible to change property Hidden to false, the property „CanToggleHidden” value should be set to True in a field definition, the way like in this example below (but in this case the property is absent at all in the field definition).
<Field
        ID="{747FC1CF-FCED-44EB-B895-568E9F423174}"
        Name="ALLegalCompanyTaxHTField1"
        StaticName="ALLegalCompanyTaxHTField1"
        Type="Note"
        Overwrite="TRUE"
        RowOrdinal="0"
        DisplayName="$Resources:IntranetGroupDirectory,Fields_ParentCompany_DisplayName;"
        Group="$Resources:IntranetGroupDirectory,GroupDirectory_CT_Group;"
        Description="$Resources:IntranetGroupDirectory,Fields_ParentCompany_Description;"
        Hidden ="TRUE"
   CanToggleHidden ="TRUE">
  </Field>
By default CanToggleHidden is return false as it is not presented in the definition. Adding the property and deploy solution don’t change the field defintion.
If we have a look in code at the „Hidden” property setter in assembly Microsoft.SharePoint.SPField  it also sets „CanToggleHidden” property to true, but cannot be reached because it is value by default is false and throw the error message shown in the picture above „Exception setting „Hidden” Cannot change Hidden attribute for this field”.
this.SetFieldBoolValue("CanToggleHidden", true)
[ClientCallable]
    public bool Hidden
    {
      get
      {
        if (this.HasExternalDataSource)
        {
          return SPExternalList.IsFieldHidden(this);
        }
        return this.GetFieldBoolValue("Hidden", 4);
      }
      [ClientCallableExceptionConstraint(FixedId="1", ErrorCode=-2146232832, Condition="Thrown when attempting to set Hidden property for a field that does not allow this property to be toggled.", ErrorType=typeof(SPException))]
      set
     {
        if (!this.CanToggleHidden)
        {
          throw new SPException(SPResource.GetString("HiddenAttributeUpdateNotAllowed", new object[0]));
        }
        this.SetFieldBoolValue("Hidden", value);
        this.SetFieldBoolValue("CanToggleHidden", true);
      }
    }

Solution:
Solution was found to use reflection to change property „CanToggleHidden” value to True, cahnge Hidden property to false and delete the field from the List via PowerShell

PowerShell example:

$web = Get-SPWeb  "http://sharepoint/
$listLegComp = $web.Lists["YourList"]
$pcFieldTax = $listLegComp.Fields.GetFieldByInternalName("ALLegalCompanyTaxHTField1")
$pcField = $listLegComp.Fields.GetFieldByInternalName("ALLegalCompany")
if(!$pcFieldTax.CanToggleHidden)
{
   $bindingFlags = [Reflection.BindingFlags] "NonPublic,Instance"
   [System.Type] $type = $pcFieldTax.GetType()
   [Reflection.MethodInfo] $mdInfo = $type.GetMethod("SetFieldBoolValue",$bindingFlags)
   $object = [System.Object] @("CanToggleHidden",$true)
   $mdInfo.Invoke($pcFieldTax,$object)
   $pcFieldTax.Hidden = $false
   $pcFieldTax.AllowDeletion = $true
   $pcFieldTax.Update()
     
}
if(!$pcField.CanToggleHidden)
{
   $bindingFlags = [Reflection.BindingFlags] "NonPublic,Instance"
   [System.Type] $type = $pcField.GetType()
   [Reflection.MethodInfo] $mdInfo = $type.GetMethod("SetFieldBoolValue",$bindingFlags)
   $object = [System.Object] @("CanToggleHidden",$true)
   $mdInfo.Invoke($pcField,$object)
   $pcField.Hidden = $false
   $pcField.AllowDeletion = $true
   $pcField.Update() 
}

$pcFieldTax.Delete()
$pcField.Delete()
$listLegComp.Update()
$web.Dispose()

Tuesday, July 9, 2013

Change permissions level for the groups in a SharePoint 2010 List or Library

Hi, Recently I needed to breake inherirites for a list on  Sharepoint 2010 site page and change the group permissions to specific one. So here is a powershell script that does the job. You will need to change $OwnerGroupName, $web = Get-SPWeb  $SiteUrl and $list = $web.Lists["<ListName>"]; to your own values.

Task:

Only users in site owner group can have "Full Control"  permissions for specific list on this site. Other groups permissions should be changed to "Read"



What Powershell script does:

1. It breaks inheritance from site
2. Gets all groups on the site
3. Goes via a list role assignments

and

4  If group name is equal to list Role Assignments removes group existing permissions and assign new role with "Read" permissions


Scripts:

[string]$OwnerGroupName = "Owners";

$web = Get-SPWeb  "<SiteUrl>";


$list = $web.Lists["<ListName>"];

$groupCollection =  $web.Groups;

 if ($list -ne $null)
  {
    if (!$list.HasUniqueRoleAssignments)
      {
    $list.BreakRoleInheritance($true);
      }
   $web.AllowUnsafeUpdates = $true;
           foreach ($group in $groupCollection)
{
                Write-Host $group.Name
                if ($group.Name -ne $OwnerGroupName)
                {
                    $roleColl = $list.RoleAssignments
foreach($roleAss in $roleColl){
 
if($roleAss.Member.Name -eq $group.Name){

$permissions = $roleAss.RoleDefinitionBindings
$roleColl.Remove($group)

$roleDef = $web.RoleDefinitions["Read"]
$roleAssign = New-Object Microsoft.SharePoint.SPRoleAssignment($group)
$roleAssign.RoleDefinitionBindings.Add($roleDef)
$list.RoleAssignments.Add($roleAssign)
break
}
}        
    }
}  
$web.AllowUnsafeUpdates = $false;
}