Metadata Defaults for Folders

Setting Metadata Defaults for Folders

SharePoint Libraries can be configured with metadata defaults for documents added to specific folders.  Column Defaults are manually configurable in Library Settings.  For each folder that has metadata defaults, the folder is marked with a green stamp.  Any document added to the folder gets the default metadata by default.

Metadata Defaults configuration in Library Settings

This configuration can be done using PowerShell.  In this example, I have created Folder Content Types, by defining them as inheriting from the Folder Content Type, then adding metadata to the folder Content Types.  This makes it easy to then assign the metadata defaults.

 We can clear away any existing metadata defaults on a folder using these commands to grab a metadata defaults object, then call the RemoveAllFieldDefaults() method:

[Microsoft.Office.DocumentManagement.MetadataDefaults] $columnDefaults = new-object Microsoft.Office.DocumentManagement.MetadataDefaults($JPLib);
$nuthin=$columnDefaults.RemoveAllFieldDefaults($JPFolder.Folder); 
$columnDefaults.update()

We can assign a metadata default for one field for one folder using these commands:

[Microsoft.Office.DocumentManagement.MetadataDefaults] $columnDefaults = new-object Microsoft.Office.DocumentManagement.MetadataDefaults($JPLib);
$nuthin=$columnDefaults.SetFieldDefault($JPFolder.Folder, $InternalName, $AssignmentValue);
$columnDefaults.update()

Before we get to the script, it is very important to note that get SPSite and SPWeb object must be acquired using the precise correct case. It seems the case-sensitive XML underlying these calls is affected by incorrect case; the folders will get the green stamp, but the metadata defaults won’t be applied unless the case is exactly correct. To get around this problem, you can grab all SPSites for a Web Application, and pipe them to get the SPWebs, to process. The only problem with that approach is the extreme memory inefficiency. More than that, until the objects are totally released, the changes accrue in the SQL Transaction Log until released, allowing .NET to commit them.

Also note the SPFolder object does not require an update(), as the metadata default methods handle the update.

Here’s the full script:

#already matched to the Claim Folder Fields on 9/4/12 to confirm all necessary fields are included. no changes actually made.
#Added CT filtering on these folder CTs: Claim Acct Folder|Claims Common Folder
[system.reflection.assembly]::LoadWithPartialName("Microsoft.Sharepoint") 
$Action="WipeAndApplyDefaults"
#$Action="ApplyDefaults"
#$Action="WipeDefaults"
$FolderFields="Field1,Field2,Field3"
$FolderFieldsArr=$FolderFields.split(",");
$baseURL="http ://sharepoint/ManagedPath/"
$SiteURL="http ://sharepoint/ManagedPath/a"
$OutputSuffix="A"
$mylogfile=$mylogfile="L:PowerShellLoggingMetadataDefaults$($OutputSuffix).csv"
#$WebAppHeading="http ://sharepoint"
Write-Host ("$(get-date) Running script assign metadata defaults to folders")
if ($siteurl)
{
write-host $site.Url
$WebScope=start-SPAssignment 
$TargetWeb=$WebScope | Get-SPWeb $siteURL;
$ListOfLists = @();
# Loop through all doc libs
$lists=$TargetWeb.lists;
$listsCount=$lists.count
for ($ii=0; $ii -lt $listsCount; $ii++)
{
$JPlib=$lists[$ii];
if ( ($JPlib.BaseType -ne "DocumentLibrary") -or ($JPlib.hidden) )
{
# forget the rest and return to top
Write-Host -foregroundcolor darkred "fast test skipping Library: $($JPlib)";   
}
elseif ($JPLib.Title -Match "Photo|Image|SitesAssets|CustomizedsReports|Templates|Pages|Picture|cache|style")
{
# forget the rest and return to top
Write-Host -foregroundcolor darkred "fast test skipping Library because it mentions $Matches: $($JPlib)";   
}
else
{
$ListOfLists += $JPlib.title;
}
}
$TargetWeb.dispose();
$JPlib=$null;
stop-SPAssignment $WebScope
foreach ($CurrentLib in $ListofLists)
{
$WebScope=start-SPAssignment 
$TargetWeb=$WebScope | Get-SPWeb $siteURL;
$JPlib=$TargetWeb.lists[$CurrentLib];
$JPlib.title
if ($JPlib -eq $null)
{
Write-Host "COULD NOT GET LIB $($CurrentLib)"
continue;
}
$JPFolders=$JPlib.Folders;
$JPCount=$JPFolders.get_count();
for ($i=0; $i -lt $JPCount; $i++)  #Do not use ItemCount, that one includes folders!
{	
$JPFolder=$JPFolders[$i];
$CT=$JPFolder.contenttype.name;
if ($CT -notmatch "Folder CT1|Folder CT2")
{
Write-Host "+" -NoNewline
if (($Action -eq "WipeDefaults") -or ($Action -eq "WipeAndApplyDefaults"))
{
[Microsoft.Office.DocumentManagement.MetadataDefaults] $columnDefaults = new-object Microsoft.Office.DocumentManagement.MetadataDefaults($JPLib);
$nuthin=$columnDefaults.RemoveAllFieldDefaults($JPFolder.Folder); 
$columnDefaults.update()
}
if (($Action -eq "ApplyDefaults") -or ($Action -eq "WipeAndApplyDefaults"))
{
foreach ($FF in $FolderFieldsArr)
{
try
{
if ($JPFolder[$FF] -ne $null)
{
$TargetField=$JPFolder.Fields[$FF];
$InternalName=$TargetField.InternalName; 
if (($TargetField.type -eq "DateTime") -or ($TargetField.type -eq "Date"))
{
$AssignmentValue=Get-Date $JPFolder[$FF] -Format u; #Z style universal format for assignment
}
else
{
$AssignmentValue=$JPFolder[$FF].tostring()
} #Leaves open all kinds of field type challenges, such as Managed Metadata
if ($AssignmentValue -ne $null)
{
[Microsoft.Office.DocumentManagement.MetadataDefaults] $columnDefaults = new-object Microsoft.Office.DocumentManagement.MetadataDefaults($JPLib);
$nuthin=$columnDefaults.SetFieldDefault($JPFolder.Folder, $InternalName, $AssignmentValue); 
$columnDefaults.update()
}
}
}
catch 
{
Write-Host "problem with field $($FF)"
} #must have been a field I shouldn't be poking, no biggie
}
} #Action=ApplyDefaults
#folder update is not required, columnDefault update propagates immediately
}
} # loop for items
$JPlib.Update();
$JPlib=$null;		
$Targetweb.update()
$TargetWeb.dispose();
Stop-SPAssignment $WebScope
} #Only process this lib
}# Lib loop
Write-Host "SCRIPT COMPLETE $(get-date)"
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *