4

I'm struggeling with setting the default value of ArticleStartDate date-time column using PowerShell and CSOM.

Bakground: I have a content type, used by a page layout, inheriting from Article Page and hence inherits the ArticleStartDate field.

What I want to achieve is setting the default date of this column to [Today], globally, or only on one pages list (it really doesn't matter on what level the default values is set).

I have tried numerous variants like

$ctx = Get-SPOContext
$list = Get-SPOList -Identity "Pages"
$ctx.Load($list.Fields)
$ctx.ExecuteQuery()

$articleDateField = $list.Fields | where {$_.InternalName -eq "ArticleStartDate" }
$articleDateField = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.FieldDateTime]).Invoke($ctx, $articleDateField)
$articleDateField.DefaultValue = "[Today]";
$articleDateField.UpdateAndPushChanges($true)
$ctx.ExecuteQuery()

Or the simpler

$ctx = Get-SPOContext
$list = Get-SPOList -Identity "Pages"
$ctx.Load($list.Fields)
$ctx.ExecuteQuery()

$articleDateField = $list.Fields | where {$_.InternalName -eq "ArticleStartDate" }  
$articleDateField.DefaultValue = "[Today]";
$articleDateField.Update()
$ctx.ExecuteQuery()

In neither of the cases I am getting any error messages, but when I retrieve the field again, the default value is not set.

I have noticed that the field is marked as Sealed=TRUE on site level, is this the problem? And if so, can we change that using CSOM or am I stuck?

5

This is possible for ArticleStartDate on O365 but involves modifying the SchemaXml (which isn't the nicest solution I appreciate, but needs must). Note that the below code snippet is in C# but obviously PowerShell is still using CSOM so should be easy to convert

private void DefaultArticleDate(ClientContext clientContext)
{
   string todaysDate = "=[Today]";
   string defaultFormula = "><DefaultFormula>{0}</DefaultFormula></Field>";
   Field article = clientContext.Web.Fields.GetByInternalNameOrTitle("ArticleStartDate");
   clientContext.Load(article);
   clientContext.ExecuteQuery();

   /*Appreciate replacing the XML isnt the nicest way to do this but it works, cant remember if changing Sealed matters here so you can potentially remove this part and just leave in the second .Replace() call*/
   article.SchemaXml = article.SchemaXml.Replace("Sealed=\"TRUE\"", "Sealed=\"FALSE\"").Replace("/>", string.Format(defaultFormula, todaysDate));

   article.UpdateAndPushChanges(true);
   clientContext.ExecuteQuery();
}

Using the SharePoint Online Client Browser we can see this change has been made:

enter image description here

When testing dont forget if you've already used the ArticleStartDate column in a Pages library SP can be funny about updating already used columns, give it a go in a new custom list or fresh site collection if in doubt.

  • This seems to resolve the issue. Acutally the Sealed property does not change, but the = in the formula, together with actually recreating the subweb using the ArticleStartDate got it working. Thanks! – Robert Lindgren Feb 26 '16 at 12:02
  • Looks like the key was to update field on web level and use UpdateAndPushChanges(true) to save it on list. Great answer! – dstarkowski Feb 26 '16 at 18:30
2

It does not work, because you're trying to set DefaultValue which expects literal value. What you want to set is DefaultValueFormula.

The problem is that this property is not exposed in CSOM.

I did manage to set default formula on field a while ago using this:

context.Load(field, f => f.SchemaXml);
context.ExecuteQuery();

var schema = field.SchemaXml;

var document = XDocument.Parse(schema);
var fieldElement = document.Element(XName.Get("Field"));

fieldElement.Elements(XName.Get("Default")).Remove();
fieldElement.Elements(XName.Get("DefaultFormula")).Remove();

if (!String.IsNullOrWhiteSpace(DefaultValue))
{
    var defaultElement = new XElement(XName.Get("Default"));
    defaultElement.Value = DefaultValue;
    fieldElement.Add(defaultElement);
}
if (!String.IsNullOrWhiteSpace(DefaultFormula))
{
    var formulaElement = new XElement(XName.Get("DefaultFormula"));
    formulaElement.Value = DefaultFormula;
    fieldElement.Add(formulaElement);
}

field.SchemaXml = document.ToString(SaveOptions.DisableFormatting);
field.Update();

context.ExecuteQuery();

Edit:
I've checked it with ArticleStartDate in O365 and was unsuccessful. Seems that this method won't work for fields with Sealed='TRUE'.

  • This actually looks supported too me (since you may create fields based on XML definition and there set DefaultValueFormula). I will give it a spin after converting it to PowerShell :) – Robert Lindgren Feb 19 '16 at 15:04
  • I can't seem to get this to work on the ArticleStartDatefield – Robert Lindgren Feb 22 '16 at 7:25
  • Have you tried with any other field? It may be something specific to publishing. I'll check it in the evening. – dstarkowski Feb 22 '16 at 8:38
  • I haven't have time trying on another field. Did you execute the code on the list column or the site column btw? – Robert Lindgren Feb 22 '16 at 8:56
  • 1
    Checked again and it doesn't work for ArticleStartDate. Previously I assumed that missing DefaultValueFormula property in CSOM was the only problem, but it seems that you're right - won't work for sealed fields. Sorry. – dstarkowski Feb 23 '16 at 19:08
-1

Actually I think if field is read-only and sealed then we can’t write to it. So if you want to set value of sealed field then first you have to set its read-only and sealed property to false and then set default value.

$articleDateField.ReadOnlyField = $false
$articleDateField.Sealed = $false
$articleDateField.DefaultValue = "[Today]";
$articleDateField.Update()
$list.Update()
  • 2
    These properties (Sealed and ReadOnlyField) are not exposed in CSOM – Robert Lindgren Feb 19 '16 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.