SharePoint change document set and items content type to a new content type

I’ll put it simply:

This is a PowerShell script that you can use to change a content type of a library or list to another one. This script can identify between Document Sets and library or list items.


param (
[string]$WebsiteUrl = "http://portal.spdev.com/",
[string]$OldCTName = "DSTestCT",
[string]$NewCTName = "DSTestCT"
)

if ( (Get-PSSnapin -Name MicroSoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin MicroSoft.SharePoint.PowerShell
}

function Reset-ListContentType ($WebUrl, $ListName, $OldCTName, $NewCTName)
{
$web = $null
try
{
$web = Get-SPWeb $WebUrl

$list = $web.Lists.TryGetList($ListName)
$oldCT = $list.ContentTypes[$OldCTName]

$isChildOfCT = $list.ContentTypes.BestMatch($rootNewCT.ID).IsChildOf($rootNewCT.ID);
if($oldCT -ne $null -and $isChildOfCT -eq $false)
{
$hasOldCT = $true
$isFoldersCTReseted = Reset-SPFolderContentType –web $web -list $list –OldCTName $OldCTName –NewCTName $NewCTName
Reset-SPFileContentType –web $web -list $list –OldCTName $OldCTName –NewCTName $NewCTName
Remove-ListContentType –web $web -list $list –OldCTName $OldCTName –NewCTName $NewCTName
if($hasOldCT -eq $true)
{
Add-ListContentType –web $web -list $list –OldCTName $OldCTName –NewCTName $NewCTName
if($isFoldersCTReseted -eq $true)
{
Set-SPFolderContentType –web $web -list $list –OldCTName $OldCTName –NewCTName $NewCTName
}
}
}


}catch
{

}
finally
{
if($web)
{
$web.Dispose()
}
}

}

function Remove-ListContentType ($web, $list, $OldCTName, $NewCTName)
{


$oldCT = $list.ContentTypes[$OldCTName]

$isChildOfCT = $list.ContentTypes.BestMatch($oldCT.ID).IsChildOf($oldCT.ID);

if($isChildOfCT -eq $true)
{
$list.ContentTypes.Delete($oldCT.ID)
}
$web.Dispose()

return $isChildOfCT
}

function Add-ListContentType ($web, $list, $OldCTName, $NewCTName)
{



$list.ContentTypes.Add($rootNewCT)

$web.Dispose()
}

function Reset-SPFolderContentType ($web, $list, $OldCTName, $NewCTName)
{
#Get web, list and content type objects

$isFoldersCTReseted = $false


$isChildOfCT = $list.ContentTypes.BestMatch($rootNewCT.ID).IsChildOf($rootNewCT.ID);

$oldCT = $list.ContentTypes[$OldCTName]
$folderCT = $list.ContentTypes["Folder"]
$newCT = $rootNewCT

$newCTID = $newCT.ID

#Check if the values specified for the content types actually exist on the list
if (($oldCT -ne $null) -and ($newCT -ne $null))
{
$list.Folders | ForEach-Object {

if ($_.ContentType.ID.IsChildOf($rootNewCT.ID) -eq $false -and $_.ContentType.ID.IsChildOf($oldCT.ID) -eq $true -and $_.Folder.ProgID -eq "Sharepoint.DocumentSet")
{
Write-Host "Found a document set: " $_.Name "Processing document set"
$item = $list.GetItemById($_.ID);
$item["ContentTypeId"] = $folderCT.Id
$item.Update()
$isFoldersCTReseted = $true
}
}
}

$web.Dispose()

return $isFoldersCTReseted
}

function Set-SPFolderContentType ($web, $list, $OldCTName, $NewCTName)
{
#Get web, list and content type objects



$folderCT = $list.ContentTypes["Folder"]
$newCT = $list.ContentTypes[$NewCTName]

#Check if the values specified for the content types actually exist on the list
if (($newCT -ne $null))
{
$list.Folders | ForEach-Object {
if ($_.ContentType.ID.IsChildOf($newCT.ID) -eq $false -and $_.ContentType.ID.IsChildOf($folderCT.ID) -eq $true -and $_.Folder.ProgID -eq "Sharepoint.DocumentSet")
{
$item = $list.GetItemById($_.ID);
$item["ContentTypeId"] = $newCT.Id
$item.Update()
}
}
}

$web.Dispose()
}


function Reset-SPFileContentType ($web, $list, $OldCTName, $NewCTName)
{
#Get web, list and content type objects



$isChildOfCT = $list.ContentTypes.BestMatch($rootNewCT.ID).IsChildOf($rootNewCT.ID);

$oldCT = $list.ContentTypes[$OldCTName]
$folderCT = $list.ContentTypes["Folder"]
$newCT = $rootNewCT

$newCTID = $newCT.ID

#Check if the values specified for the content types actually exist on the list
if (($oldCT -ne $null) -and ($newCT -ne $null))
{
$list.Folders | ForEach-Object {
if ($_.ContentType.ID.IsChildOf($rootNewCT.ID) -eq $false -and $_.ContentType.ID.IsChildOf($oldCT.ID) -eq $true)
{
$_["ContentTypeId"] = $folderCT.Id
$_.Update()
}
}
#Go through each item in the list
$list.Items | ForEach-Object {
Write-Host "Item present CT ID :" $_.ContentType.ID
Write-Host "CT ID To change from :" $oldCT.ID
Write-Host "NEW CT ID to change to:" $rootNewCT.ID

#Check if the item content type currently equals the old content type specified
if ($_.ContentType.ID.IsChildOf($rootNewCT.ID) -eq $false -and $_.ContentType.ID.IsChildOf($oldCT.ID) -eq $true)
{
#Check the check out status of the file
if ($_.File.CheckOutType -eq "None")
{
Change the content type association for the item
$item = $list.GetItemById($_.ID);
$item.File.CheckOut()
write-host "Resetting content type for file: " $_.Name "from: " $oldCT.Name "to: " $newCT.Name

$item["ContentTypeId"] = $newCTID
$item.UpdateOverwriteVersion()
Write-Host "Item changed CT ID :" $item.ContentType.ID
$item.File.CheckIn("Content type changed to " + $newCT.Name, 1)
}
else
{
write-host "File" $_.Name "is checked out to" $_.File.CheckedOutByUser.ToString() "and cannot be modified"
}
}
else
{
write-host "File" $_.Name "is associated with the content type" $_.ContentType.Name "and shall not be modified"
}
}
}
else
{
write-host "One of the content types specified has not been attached to the list"$list.Title
return
}

$web.Dispose()
}

$web = Get-SPWeb $WebsiteUrl
$rootWeb = $web.Site.RootWeb;
$rootNewCT = $rootWeb.AvailableContentTypes[$NewCTName]

Foreach ($list in $web.Lists) {
Write-Host $list.BaseType
if($list.Hidden -eq $false -and $list.BaseType -eq "DocumentLibrary")
{
Write-Host "Processing list: " $list.Title
Reset-ListContentType –WebUrl $WebsiteUrl –ListName $list.Title –OldCTName $OldCTName –NewCTName $NewCTName
}
}

$web.Dispose()

 

Advertisements

Did You Know!? Content Organizer – Drop Off Libary for document routing

If you did not know (I didn’t 🙂 ) there is a feature (yes an actual SP feature) that you can enable to have routing possibilities for your documents. What this means is that people can drop documents in a predefined library where you can apply rules how these documents are routed to other location based on the metadata or content type selection and choices made when a document is uploaded. So if this sounds like something you might need for your client below are a few link that might help you on your journey.

http://office.microsoft.com/en-us/sharepoint-server-help/create-content-organizer-rules-to-route-documents-HA101807927.aspx#_Toc258333537

http://sharepointempower.com/2013/03/drop-off-library-in-sharepoint-2010/

Did You Know!?: SharePoint Webparts and libraries

Hello again!

I decided to start a new blogging category named “Did You Know!?”. The idea behind this is that I write tips and tricks you might not think of or may not have heard but will help you and make you life easier.

TOC:

Content Query WebPart – Audience targeting

Custom views for document library or lists webparts

So here we go:

Content Query WebPart – Audience targeting:

If you did not know you can filter content of the CQWP(and also in the code if you are using CrossListQueryInfo and CrossListQueryCache) by enabling Audience Targeting to the webpart.

What do you need to do to make it to work:

– Enable the CQWP Audience targeting – from the webpart properties

cqwp audience

– Enable your content source to support audience targeting – Example: your library or list – from the list/library settings

Go to your library settings => Under “General Settings” => Select “Audience Targeting Settings” => Then enable Audience targeting by checking the checkbox.

After this you will get a new field to your list named as “Target Audiences”. Now when you create or edit items you will be able to chose an audience to that item. When a CQWP has audience targeting enabled what will happen is that the webpart will check the item audience targeting values and compare them to the user profile audiences. If the user is part of the items audience then the item will show up in the CQWP

– Configure your user profile service to support audience targeting

This is the tricky part. You need to configure a whole lot of places to get your audience targeting for a user to work so that webpart and other content related queries etc filter data properly.

I will do it in three parts the configuration:

1. Configure a Term Set in your Manage Metadata Service. Let’s say named “Location” that has 10 different countries your organization is interested in. This I will not explain in much detail. I hope you are familiar with MMS.

article mms

2. Go to your user profile service and create a new User Property(The picture below as an example). Also take notice(I do not remember exactly) but the privacy settings needs to set to everyone for this field to work properly.

new user property

3. Next assign to a user profile(s) a desired location to the newly created field.

4. Then lets create a new audience. In your user profile service go to “Manage Audiences”. Then Press the “New Audience” button. In the next view give the audience a name and an owner. And remember to select the rule strategy. I chose “Satisfy any of the rules so that I may include many rules to a single audience. This way I can aggregate two or more location to an audience and have any of them apply to an item and user.

5. In the next step select as an “Operand” property and select the location property we created and as the operator I would chose “Contains”. Next in the Value field select a value.

audience

6. Now all you have to do is compile the audience. Press “Compile Audience”. After the compilation is complete you should see how many members are apart of this audience. Next when you assign this audience to an item any user from is apart of this audience through his location value that corresponds to the audience location values are going to see the CQWP item.

Custom views for document library or lists webparts:

You are able to create custom Views for your library or list webparts that show you content from your library. You are not limited to what you get once you add a documents library to a page as a webpart. BUT there is a catch!!! If you do select and existing view and use it to display content in a certain manner in a page YOU WILL NOT have a reference to that view in you library BUT A COPY held in the webpart. So lets say that you have a view that lists the TOP 5 newest documents in your library. You decided to add the document library webpart to a page, you then select this TOP 5 view, what happens is that you will get a copy that is not related to the original view of that document library. SO if you make changes to the view in the document library view those changes will not be seen in your webpart because it is not a reference. So remember this when you use a view from a library or list into your webpart.