Change Content Type With PowerShell

Objective:

Change the content type of many files in a single library.

Solution:

Use the following PowerShell script to change the content type instead of editing each file one at a time. In my example, I change the content type from “Document” to “Process”.


function Reset-SPFileContentType ()
{
#Get web, list and content type objects
$web = Get-SPWeb -Identity http://spsite
$list = $web.Lists["Documents"]
$oldCT = $list.ContentTypes["Document"]
$newCT = $list.ContentTypes["Process"]
$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))
{
#Go through each item in the list
$list.Items | ForEach-Object {
#Check if the item content type currently equals the old content type specified
if ($_.ContentType.Name -eq $oldCT.Name)
{
#Check the check out status of the file
if ($_.File.CheckOutType -eq "None")
{
#Change the content type association for the item
$_.File.CheckOut()
write-host "Resetting content type for file" $_.Name "from" $oldCT.Name "to" $newCT.Name
$_["ContentTypeId"] = $newCTID
$_.Update()
$_.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
}
$web.Dispose()
}
Reset-SPFileContentType

Credit to Phil Childs’ article for SharePoint 2010. The script also works for SP 2013. 

Start Workflow on Inbound Email

By default, workflows will not auto start for attachments sent to a library via email.

To enable this functionality, run the following PowerShell script on your SharePoint server.


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$spWebService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$spWebService.DeclarativeWorkflowAutoStartOnEmailEnabled = $true
$spWebService.Update()

Next, make sure your workflow is configured to start automatically when an item is created.

Mass Delete Empty Folders With PowerShell

If you don’t feel like manually deleting empty folders, use this PowerShell script to query and delete all empty folders and subfolders. Make sure you change the $WebURL to your SharePoint site or subsite, and the $listName to your library.


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

function EmptyFolders()
{
$WebURL = "http://sp2013/sites/company"
$webDestination = Get-SPWeb -identity $WebURL
$listName = "Documents"

$query = New-Object Microsoft.SharePoint.SPQuery;
$query.ViewAttributes = "Scope='RecursiveAll'";
$query.RowLimit = 5000
$caml = "<Where>
<Eq>
<FieldRef Name='ContentType' />
<Value Type='Text'>Folder</Value>
</Eq>
</Where>"

$query.Query = $caml

$list = $webDestination.Lists[$listName]
$folder = $list.GetItems($query)
do
{
$query.ListItemCollectionPosition = $folder.ListItemCollectionPosition
for ($index = $folder.Count - 1; $index -gt -1; $index--)
{
if ($folder[$index]["FolderChildCount"].Replace(';#', '') -eq 0 -and $folder[$index]["ItemChildCount"].Replace(';#', '') -eq 0)
{
Write-Host("$($folder[$index]["FolderChildCount"].Replace(';#', '')), $($folder[$index]["ItemChildCount"].Replace(';#', '')), $($folder[$index]["ContentType"]), $($folder[$index].URL)")
$folder[$index].Delete();
$list.Update()
}
}
}
While($query.ListItemCollectionPosition -ne $null)
#$list.Update();
$webDestination.Dispose()
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Operation Completed",0,"Done",0x1)
}
EmptyFolders

Internal Column Names

Document Library Fields:

Display Name Internal Name GUID Type
ID ID {1d22ea11-1e32-424e-89ab-9fedbadb6ce1} Counter
Content Type ID ContentTypeId {03e45e84-1992-4d42-9116-26f756012634} ContentTypeId
Content Type ContentType {c042a256-787d-4a6f-8a8a-cf6ab767f12d} Text
Created Created {8c06beca-0777-48f7-91c7-6da68bc07b69} DateTime
Created By Author {1df5e554-ec7e-46a6-901d-d85a3881cb18} User
Modified Modified {28cf69c5-fa48-462a-b5cd-27b6f9d2bd5f} DateTime
Modified By Editor {d31655d1-1d5b-4511-95a1-7a09e9b75bf2} User
Has Copy Destinations _HasCopyDestinations {26d0756c-986a-48a7-af35-bf18ab85ff4a} Boolean
Copy Source _CopySource {6b4e226d-3d88-4a36-808d-a129bf52bccf} Text
Approval Status _ModerationStatus {fdc3b2ed-5bf2-4835-a4bc-b885f3396a61} ModStat
Approver Comments _ModerationComments {34ad21eb-75bd-4544-8c73-0e08330291fe} Note
URL Path FileRef {94f89715-e097-4e8b-ba79-ea02aa8b7adb} Lookup
Path FileDirRef {56605df6-8fa1-47e4-a04c-5b384d59609f} Lookup
Modified Last_x0020_Modified {173f76c8-aebd-446a-9bc9-769a2bd2c18f} Lookup
Created Created_x0020_Date {998b5cff-4a35-47a7-92f3-3914aa6aa4a2} Lookup
File Size File_x0020_Size {8fca95c0-9b7d-456f-8dae-b41ee2728b85} Lookup
Item Type FSObjType {30bb605f-5bae-48fe-b4e3-1f81d9772af9} Lookup
Effective Permissions Mask PermMask {ba3c27ee-4791-4867-8821-ff99000bac98} Computed
ID of the User who has the item Checked Out CheckedOutUserId {a7b731a3-1df1-4d74-a5c6-e2efba617ae2} Lookup
Is Checked out to local IsCheckedoutToLocal {cfaabd0f-bdbd-4bc2-b375-1e779e2cad08} Lookup
Checked Out To CheckoutUser {3881510a-4e4a-4ee8-b102-8ee8e2d0dd4b} User
Name FileLeafRef {8553196d-ec8d-4564-9861-3dbe931050c8} File
Unique Id UniqueId {4b7403de-8d94-43e8-9f0f-137a3e298126} Lookup
ProgId ProgId {c5c4b81c-f1d9-4b43-a6a2-090df32ebb68} Lookup
ScopeId ScopeId {dddd2420-b270-4735-93b5-92b713d0944d} Lookup
Virus Status VirusStatus {4a389cb9-54dd-4287-a71a-90ff362028bc} Lookup
Checked Out To CheckedOutTitle {9d4adc35-7cc8-498c-8424-ee5fd541e43a} Lookup
Check In Comment _CheckinComment {58014f77-5463-437b-ab67-eec79532da67} Lookup
Checked Out To LinkCheckedOutTitle {e2a15dfd-6ab8-4aec-91ab-02f6b64045b0} Computed
Document Modified By Modified_x0020_By {822c78e3-1ea9-4943-b449-57863ad33ca9} Text
Document Created By Created_x0020_By {4dd7e525-8d6b-4cb4-9d3e-44ee25f973eb} Text
File Type File_x0020_Type {39360f11-34cf-4356-9945-25c44e68dade} Text
HTML File Type HTML_x0020_File_x0020_Type {0c5e0085-eb30-494b-9cdd-ece1d3c649a2} Text
Source Url _SourceUrl {c63a459d-54ba-4ab7-933a-dcf1c6fadec2} Text
Shared File Index _SharedFileIndex {034998e9-bf1c-4288-bbbd-00eacfc64410} Text
Edit Menu Table Start _EditMenuTableStart {3c6303be-e21f-4366-80d7-d6d0a3b22c7a} Computed
Edit Menu Table End _EditMenuTableEnd {2ea78cef-1bf9-4019-960a-02c41636cb47} Computed
Name LinkFilenameNoMenu {9d30f126-ba48-446b-b8f9-83745f322ebe} Computed
Name LinkFilename {5cc6dc79-3710-4374-b433-61cb4a686c12} Computed
Type DocIcon {081c6e4c-5c14-4f20-b23e-1a71ceb6a67c} Computed
Server Relative URL ServerUrl {105f76ce-724a-4bba-aece-f81f2fce58f5} Computed
Encoded Absolute URL EncodedAbsUrl {7177cfc7-f399-4d4d-905d-37dd51bc90bf} Computed
Name BaseName {7615464b-559e-4302-b8e2-8f440b913101} Computed
File Size FileSizeDisplay {78a07ba4-bda8-4357-9e0f-580d64487583} Computed
Property Bag MetaInfo {687c7f94-686a-42d3-9b67-2782eac4b4f8} Lookup
Level _Level {43bdd51b-3c5b-4e78-90a8-fb2087f71e70} Integer
Is Current Version _IsCurrentVersion {c101c3e7-122d-4d4d-bc34-58e94a38c816} Boolean
Select SelectTitle {b1f7969b-ea65-42e1-8b54-b588292635f2} Computed
Select SelectFilename {5f47e085-2150-41dc-b661-442f3027f552} Computed
Edit Edit {503f1caa-358e-4918-9094-4a2cdc4bc034} Computed
owshiddenversion owshiddenversion {d4e44a66-ee3a-4d02-88c9-4ec5ff3f4cd5} Integer
UI Version _UIVersion {7841bf41-43d0-4434-9f50-a673baef7631} Integer
Version _UIVersionString {dce8262a-3ae9-45aa-aab4-83bd75fb738a} Text
Instance ID InstanceID {50a54da4-1528-4e67-954a-e2d24f1e9efb} Integer
Order Order {ca4addac-796f-4b23-b093-d2a3f65c0774} Number
GUID GUID {ae069f25-3ac2-4256-b9c3-15dbc15da0e0} Guid
Workflow Version WorkflowVersion {f1e020bc-ba26-443f-bf2f-b68715017bbc} Integer
Workflow Instance ID WorkflowInstanceID {de8beacf-5505-47cd-80a6-aa44e7ffe2f4} Guid
Source Version (Converted Document) ParentVersionString {bc1a8efb-0f4c-49f8-a38f-7fe22af3d3e0} Lookup
Source Name (Converted Document) ParentLeafName {774eab3a-855f-4a34-99da-69dc21043bec} Lookup
Title Title {fa564e0f-0c70-4ab9-b863-0177e6ddd247} Text
Template Link TemplateUrl {4b1bf6c6-4f39-45ac-acd5-16fe7a214e5e} Text
Html File Link xd_ProgID {cd1ecb9f-dd4e-4f29-ab9e-e9ff40048d64} Text
Is Signed xd_Signature {fbf29b2d-cae5-49aa-8e0a-29955b540122} Boolean
Merge Combine {e52012a0-51eb-4c0c-8dfb-9b8a0ebedcb6} Computed
Relink RepairDocument {5d36727b-bcb2-47d2-a231-1f0bc63b7439} Computed

 

 

Custom List Fields:

Display Name Internal Name GUID Type
ID ID {1d22ea11-1e32-424e-89ab-9fedbadb6ce1} Counter
Content Type ID ContentTypeId {03e45e84-1992-4d42-9116-26f756012634} ContentTypeId
Content Type ContentType {c042a256-787d-4a6f-8a8a-cf6ab767f12d} Text
Title Title {fa564e0f-0c70-4ab9-b863-0177e6ddd247} Text
Modified Modified {28cf69c5-fa48-462a-b5cd-27b6f9d2bd5f} DateTime
Created Created {8c06beca-0777-48f7-91c7-6da68bc07b69} DateTime
Created By Author {1df5e554-ec7e-46a6-901d-d85a3881cb18} User
Modified By Editor {d31655d1-1d5b-4511-95a1-7a09e9b75bf2} User
Has Copy Destinations _HasCopyDestinations {26d0756c-986a-48a7-af35-bf18ab85ff4a} Boolean
Copy Source _CopySource {6b4e226d-3d88-4a36-808d-a129bf52bccf} Text
owshiddenversion owshiddenversion {d4e44a66-ee3a-4d02-88c9-4ec5ff3f4cd5} Integer
Workflow Version WorkflowVersion {f1e020bc-ba26-443f-bf2f-b68715017bbc} Integer
UI Version _UIVersion {7841bf41-43d0-4434-9f50-a673baef7631} Integer
Version _UIVersionString {dce8262a-3ae9-45aa-aab4-83bd75fb738a} Text
Attachments Attachments {67df98f4-9dec-48ff-a553-29bece9c5bf4} Attachments
Approval Status _ModerationStatus {fdc3b2ed-5bf2-4835-a4bc-b885f3396a61} ModStat
Approver Comments _ModerationComments {34ad21eb-75bd-4544-8c73-0e08330291fe} Note
Edit Edit {503f1caa-358e-4918-9094-4a2cdc4bc034} Computed
Title LinkTitleNoMenu {bc91a437-52e7-49e1-8c4e-4698904b2b6d} Computed
Title LinkTitle {82642ec8-ef9b-478f-acf9-31f7d45fbc31} Computed
Select SelectTitle {b1f7969b-ea65-42e1-8b54-b588292635f2} Computed
Instance ID InstanceID {50a54da4-1528-4e67-954a-e2d24f1e9efb} Integer
Order Order {ca4addac-796f-4b23-b093-d2a3f65c0774} Number
GUID GUID {ae069f25-3ac2-4256-b9c3-15dbc15da0e0} Guid
Workflow Instance ID WorkflowInstanceID {de8beacf-5505-47cd-80a6-aa44e7ffe2f4} Guid
URL Path FileRef {94f89715-e097-4e8b-ba79-ea02aa8b7adb} Lookup
Path FileDirRef {56605df6-8fa1-47e4-a04c-5b384d59609f} Lookup
Modified Last_x0020_Modified {173f76c8-aebd-446a-9bc9-769a2bd2c18f} Lookup
Created Created_x0020_Date {998b5cff-4a35-47a7-92f3-3914aa6aa4a2} Lookup
Item Type FSObjType {30bb605f-5bae-48fe-b4e3-1f81d9772af9} Lookup
Effective Permissions Mask PermMask {ba3c27ee-4791-4867-8821-ff99000bac98} Computed
Name FileLeafRef {8553196d-ec8d-4564-9861-3dbe931050c8} File
Unique Id UniqueId {4b7403de-8d94-43e8-9f0f-137a3e298126} Lookup
ProgId ProgId {c5c4b81c-f1d9-4b43-a6a2-090df32ebb68} Lookup
ScopeId ScopeId {dddd2420-b270-4735-93b5-92b713d0944d} Lookup
File Type File_x0020_Type {39360f11-34cf-4356-9945-25c44e68dade} Text
HTML File Type HTML_x0020_File_x0020_Type {4ef1b78f-fdba-48dc-b8ab-3fa06a0c9804} Computed
Edit Menu Table Start _EditMenuTableStart {3c6303be-e21f-4366-80d7-d6d0a3b22c7a} Computed
Edit Menu Table End _EditMenuTableEnd {2ea78cef-1bf9-4019-960a-02c41636cb47} Computed
Name LinkFilenameNoMenu {9d30f126-ba48-446b-b8f9-83745f322ebe} Computed
Name LinkFilename {5cc6dc79-3710-4374-b433-61cb4a686c12} Computed
Type DocIcon {081c6e4c-5c14-4f20-b23e-1a71ceb6a67c} Computed
Server Relative URL ServerUrl {105f76ce-724a-4bba-aece-f81f2fce58f5} Computed
Encoded Absolute URL EncodedAbsUrl {7177cfc7-f399-4d4d-905d-37dd51bc90bf} Computed
File Name BaseName {7615464b-559e-4302-b8e2-8f440b913101} Computed
Property Bag MetaInfo {687c7f94-686a-42d3-9b67-2782eac4b4f8} Lookup
Level _Level {43bdd51b-3c5b-4e78-90a8-fb2087f71e70} Integer
Is Current Version _IsCurrentVersion {c101c3e7-122d-4d4d-bc34-58e94a38c816} Boolean

Credit goes to hvelo who posted this reference list back in 2008. 

Audit Web Part Locations

Through PowerShell, you can export a csv list of every single app and web part and the URLs where they exist. This is useful for keeping track of where apps are visible and who has access to them.

The script will prompt you for the URL. Enter the entire URL of the top site collection site. For example, http://sp2013/sites/company.

When it prompts you for the folder, just enter /.


Param([Parameter(Mandatory=$true)]
[String]
$Url,
[Parameter(Mandatory=$true)]
[ValidateScript({Test-Path $_ -PathType 'Container'})]
[String]
$folder,
[Parameter(Mandatory=$false)]
[String]
$WP
)

if ((gsnp Microsoft.SharePoint.Powershell -EA SilentlyContinue) -eq $null){
asnp Microsoft.SharePoint.Powershell -EA Stop
}

$filename = "WebPartsReport_" + (Get-Date).ToFileTimeUtc().ToString() + ".csv"
$filenamewp = "WebPartsReport_" + $WP.Replace(" ","-") + "_" + (Get-Date).ToFileTimeUtc().ToString() + ".csv"

$logfile = Join-Path $folder $filename
$logfilewp = Join-Path $folder $filenamewp

$urlArray = $Url.Split(",")

$header = "File Url, Web Part Title, Web Part Type, Visible"

ac $logfile $header
ac $logfilewp $header

$logfilecontrol = $null

foreach ($SPsite in $urlArray){
Get-SPSite $SPsite| % {

foreach ($web in $_.AllWebs){

if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web)){

$library = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$pages = $library.PagesList

foreach ($file in $pages.Items){

$fileUrl = $web.Url + "/" + $file.File.Url

$manager = $file.file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);

$webparts = $manager.webparts

$webparts | %{
ac $logfile "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

if ($_.DisplayTitle -match $WP -and -not [string]::IsNullOrEmpty($WP)){
ac $logfilewp "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

$logfilecontrol = 1
}
}
}

$sitepages = [Microsoft.Sharepoint.Utilities.SpUtility]::GetLocalizedString('$Resources:WikiLibDefaultTitle',"core",$web.UICulture.LCID)

$pages = $null
$pages = $web.Lists[$sitepages]

if ($pages -and $pages.ItemCount -gt 0){

foreach ($file in $pages.Items) {
$fileUrl = $web.Url + "/" + $file.File.Url

$manager = $file.file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);

$webparts = $manager.webparts

$webparts | %{
ac $logfile "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

if ($_.DisplayTitle -match $WP -and -not [string]::IsNullOrEmpty($WP)){
ac $logfilewp "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

$logfilecontrol = 1
}
}
}
}
} else {
$sitepages = [Microsoft.Sharepoint.Utilities.SpUtility]::GetLocalizedString('$Resources:WikiLibDefaultTitle',"core",$web.UICulture.LCID)

$pages = $null
$pages = $web.Lists[$sitepages]

if ($pages){

foreach ($file in $pages.Items) {
$fileUrl = $web.Url + "/" + $file.File.Url

$manager = $file.file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);

$webparts = $manager.webparts

$webparts | %{
ac $logfile "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

if ($_.DisplayTitle -match $WP -and -not [string]::IsNullOrEmpty($WP)){
ac $logfilewp "$fileUrl, $($_.DisplayTitle), $($_.GetType().ToString()), $($_.IsVisible)"

$logfilecontrol = 1
}
}
}
}
}
}
}
}

.\notepad.exe $logfile

if ($logfilecontrol -eq 1){
.\notepad.exe $logfilewp
}

Update List/Library Columns With External Content Type Columns

Scenario:

You have a column on a custom list or library that needs to be back-filled with data from an External Content Type (ECT).

Solution:

Create a list from the ECT and use PowerShell to update your custom list’s column with the ECT’s list column.

Creating a list (assuming you already connected an ECT):

Open SharePoint Designer 2013 and navigate to your External Content Types. Click on the ECT you need data from and click “Create List & Form”.

Name the list whatever you want and click OK.

The list will be created in the site or subsite you’re connected to in SharePoint Designer.

Updating Custom List With ECT List Column:

My example shows how to match Customer names in an ECT with corresponding Folders in a document library to update the Status column.  If you need to update every item in a list, comment out line 78, un-comment lines 72 and 81, then remove the query.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get the context - top level site collection
$ctx = Get-SPServiceContext http://sp2013

#Get the scope
$scope = new-object Microsoft.SharePoint.SPServiceContextScope $ctx

#Get the target site collection
$webTarget = Get-SPWeb -identity "http://sp2013/sites/customer"

#Get the ECT List
$list = $webTarget.Lists["Entity List"]

#Array to Hold Result - PSObjects
$ListItemCollection = @()

#Get All List items. Replace -name "Name" with the column name on the ECT list.
#Add more columns if required
$list.Items | foreach {
$ExportItem = New-Object PSObject
$ExportItem | Add-Member -MemberType NoteProperty -name "Entity" -value $_["Entity"]
$ExportItem | Add-Member -MemberType NoteProperty -name "Status" -value $_["Status"]

#Add the object with property to an Array
$ListItemCollection += $ExportItem
}

#Export the result Array to CSV file
$ListItemCollection | Export-CSV "E:\SharePoint\EntityStatus.csv" -NoTypeInformation

#Dispose the web Object
$webTarget.Dispose()

#Pause for 10 seconds for the CSV file to populate all the way.
Start-Sleep 10

function Update-SPList()
{
#Import to destination list
#This section of the PowerShell will loop through the csv file we created and update the Status column in our Customer Folders library.
$csvVariable= Import-CSV -path "E:\SharePoint\EntityStatus.csv"

# Destination site collection. You can use any site, it does not have to be in the same collection as ECT list.
$WebURL = "http://sp2013/sites/customer"

# Destination list name
$listName = "Customer Folders"

#Get the SPWeb object and save it to a variable
$webDestination = Get-SPWeb -identity $WebURL

#Query ONLY folders.
$query = New-Object Microsoft.SharePoint.SPQuery;
$query.Query =
" <Where>

<Eq>
<FieldRef Name='FSObjType' />
<Value Type='Integer'>1</Value>
</Eq>

</Where>";

$list = $webDestination.Lists[$listName]

#If you want to update all items, remove the query and uncomment the following line
#$items = $list.Items

#loop through csv file
foreach($row in $csvVariable)
{
#Updating queried items
$updateitem = $list.GetItems($query) | Where {$_["Title"] -eq $row.Entity}

#Updating all items
#$updateitem = $items | Where {$_["Title"] -eq $row.Entity}

#loop through SharePoint list
Write-Host $row.Entity

$updateitem["Status"] = $row.Status
$updateitem.Update()
}

if ($webDestination)
{
$webDestination.Dispose()
}
}
Update-SPList