Fix deleted AD users from SharePoint

This is a small PowerShell script that will fix issues with removed SharePoint users. You may encounter problems if you remove an AD user but the later re-create it with the same AD user login. If such cases this script might help you with possible SharePoint issues. If this does not help then try to remove the user profile and run a full user profile synchronization and run the script again.


$sites = Get-SPSite http://portal.spdev.com

foreach ($site in $sites) {
$groups = $site.RootWeb.sitegroups
foreach ($group in $groups) {
foreach ($user in $group.users) {
# Skip All Authenticated Users, General groups
if ($user.userlogin -eq "c:0(.s|true" -or $user.userlogin -eq "c:0!.s|windows") {
continue;
}
if ($user.IsDomainGroup) {
# Skip Security Groups
}
else {
# Get user login
$splitline = $user.userlogin.split("\");
$samid = $splitline[1];
if ($user.userlogin.contains("AD domain name"))
{
if ($user.userlogin.contains("part of your login name")) {
Write-Host "user Found" $user.userlogin
$group.removeuser($user);
$site.RootWeb.SiteUsers.Remove($user.userlogin);
}
else {
Write-Host $user.userlogin
}
}
}
}
}
}

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()

 

Disassembling PowerShell commands to see how they work

If you ever wonder how PowerShell commands operate, what they do when you call them or how you can find out with the following commands what DLL the command is using and you can open the DLL with a disassembler like ILSpy.

$commandDetailsObj=Get-Command “your PS command here”

$commandDetailsObj.DLL

That is it, simple as that :).

 

PowerShell script how to backup lists and restore them in another location through list templates

Ok, this is one way of doing this. Perhaps this is useful in a situation where you need to backup lists with their data from an older SharePoint version and restore it in another SharePoint version. Preferably doing this quickly without worrying about site templates or something more than the list and its data.

The script below gets lists in a target web location, saves them as list templates and download them in the hard drive.

Approach 1: Export the list through Export-SPWeb and restore with Import-SPWeb

param (
 [string]$SPSiteFilter = "http://portal.spdev.com/",
 [string]$SPWebFilter = "http://portal.spdev.com/",
 [string]$SPWebFilterRelative = "",
 [string]$destination = "C:\\temp"
 )
 
 $site = Get-SPWeb $SPSiteFilter
 
 
 # Get the webs lists and save them as list templates
 $lists = $site.lists
Foreach ($list in $lists) {
Write-Host $list.BaseType
 if($list.Hidden -eq $false -and $list.BaseType -eq "GenericList")
 {
 Write-Host $list.Title + " " + $list.RootFolder.ServerRelativeUrl
 
 $filePath = $destination + "\" + $list.Title + ".cmp"
 $itemURL = $SPWebFilterRelative + $list.RootFolder.ServerRelativeUrl
 Write-Host $filePath
 Write-Host $itemURL
 Write-Host $SPWebFilter
 export-spweb -identity $SPWebFilter -path $filePath -itemurl $itemURL –includeusersecurity
 #$list.SaveAsTemplate($list.Title+ " " + $ListTempalteIDPostFix,$list.Title,"Site list Backup",1)
 }
 }

 $site.Dispose()
param (
 [string]$SPSiteFilter = "http://portal.spdev.com/subsite/",
 [string]$source = "C:\\temp"
 )
 
 $site = Get-SPWeb $SPSiteFilter
 
 Get-ChildItem $source -Filter *.cmp | 
Foreach-Object {
 Write-Host $_.FullName
 #Upload the list temaplte to the list templates gallery
 Import-SPWeb -identity $SPSiteFilter -path $_.FullName –force
 
}

$site.Dispose()

Approach 2: As list templates


param (
[string]$SPSiteFilter = "http://site/",
[string]$SPWebFilter = "http://site/myweb/",
[string]$ListTempalteIDPostFix = "SU",
[string]$destination = "C:\\temp"
)

$site = Get-SPSite $SPSiteFilter
$web = Get-SPWeb $SPWebFilter
$templatesLibrary = $site.RootWeb.GetListFromUrl("/_catalogs/lt/Forms/AllItems.aspx")

if(!$templatesLibrary)
{
Write-Host "List template gallery not found. Program execution halted."
return
}

# Get the webs lists and save them as list templates
$lists = $web.lists
Foreach ($list in $lists) {
Write-Host $list.BaseType
if($list.Hidden -eq $false -and $list.BaseType -eq "GenericList")
{
Write-Host $list.Title
$list.SaveAsTemplate($list.Title+ " " + $ListTempalteIDPostFix,$list.Title,"Site list Backup",1)
}
}

# Read the list templates from the gallery and save them to the hard drive
$folder = $templatesLibrary.RootFolder
foreach ($file in $folder.Files) {
#Ensure destination directory
$destinationfolder = $destination

#Download file
$binary = $file.OpenBinary()
$stream = New-Object System.IO.FileStream($destinationfolder + "/" + $file.Name), Create
$writer = New-Object System.IO.BinaryWriter($stream)
$writer.write($binary)
$writer.Close()

}
For ($i=$folder.Files.Count; $i -gt 0 -or $i -eq 0; $i--)
{
$folder.Files[$i].Delete()
}

$web.Dispose()
$site.Dispose()

This script uploads the list templates into the targeted SharePoint site.

param (
[string]$SPSite = "http://portal3.dev.com/sites/sc",
[string]$SiteTemplatesLocation = "C:\\temp",
[string]$SiteTemplatesGalleryName = "List Template Gallery"
)
# $site = Get-SPSite $SPSiteFilter
# $web = Get-SPWeb $SPSiteFilter
# $templatesLibrary = $site.RootWeb.GetListFromUrl("/_catalogs/lt/Forms/AllItems.aspx")
# $Files = $templatesLibrary.RootFolder.Files

Function UploadListTemplate($WebURL, $TemplateFilePath)
{
#Get the Web
$web = Get-SPWeb $WebURL
#Get the List template Gallery Folder
$TemplateFolder = $web.GetFolder($SiteTemplatesGalleryName)
#Get the Files collection
$TemplateFileCollection = $TemplateFolder.Files
#Get the Template file from Local File system
$TemplateFile = Get-ChildItem $TemplateFilePath

#Open the File in Read mode and Add to Templates collection
$TemplateFileCollection.Add("_catalogs/lt/$($TemplateFile.Name)", $TemplateFile.OpenRead(), $true)
Write-Host "Done!Template has been uploaded!!"
$web.Dispose()

}

Get-ChildItem $SiteTemplatesLocation -Filter *.stp |
Foreach-Object {
Write-Host $_.FullName
#Upload the list temaplte to the list templates gallery
UploadListTemplate $SPSite $_.FullName

}

This script will create the lists based on the list templates NOTICE that this does not differentiate between existing list templates not uploaded with the script above.

 param (
 [string]$SPSiteFilter = "http://portal3.dev.com/sites/sc",
 [string]$ListTempalteIDPostFix = "SU",
 [string]$destination = "C:\\temp"
 )

 $site = Get-SPSite $SPSiteFilter
 $web = Get-SPWeb $SPSiteFilter

 # Create lists based on the list templates
$site.GetCustomListTemplates($web) |
Foreach-Object {
if($web.Lists.TryGetList($_.Name.Replace($ListTempalteIDPostFix,"")) -eq $null)
{
 $web.Lists.Add($_.Name.Replace($ListTempalteIDPostFix,""), $_.Description, $_)
 }
}

 $web.Dispose()
 $site.Dispose()
 

If your list has content that is too large to save as a template try to run this script and remember to change to the default value which I think should be: 52428800


$docSize = 500000000
$webservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webservice.MaxTemplateDocumentSize = $docSize
$webservice.Update()

Prerequisites for custom list templates

SharePoint List must meet the following criteria to move a list by using a list template (source):

  • The list must contain less than 10 megabytes (MB) of list data.
  • You must be a member of a site group with the Manage Lists right on the source site and on the destination site. By default, the Manage Lists right is included in the Web Designer and Administrator site groups.
  • The source site and the destination site must be based on the same site template.

PowerShell SharePoint Updating list item Authors and Editors

Notice this code snippet assumes that you have already retrieved your list item also this code can be used to keep the original author and editor of an item while making changes to list items through a script with admin privileges.

Also notice that for some reason I had to use on the item level Update() instead of SystemUpdate(). No idea why, very weird since I know that on C# it is definitely SystemUpdate() to be used if you want to preserve the original editor.

Anyway here is the code snippet:



$author = $item["Author"]
 $editor = $item["Editor"]

Write-Host "Original author: " $author
 Write-Host "Original editor: " $editor
 $authorLogin = New-Object Microsoft.SharePoint.SPFieldUserValue ($web, $author)

 $editorLogin = New-Object Microsoft.SharePoint.SPFieldUserValue ($web, $editor)
 $itemOwners = $list.GetItemById($item.ID)
 $replacedUserAuthor =$web.EnsureUser($authorLogin.User.LoginName)
 $replacedUserEditor =$web.EnsureUser($editorLogin.User.LoginName)

 #$replacedUserAuthor = get-SPuser -Web $web -Identity $authorLogin.User.LoginName
 #$replacedUserEditor =get-SPuser -Web $web -Identity $editorLogin.User.LoginName

 Write-Host "Updating the author field with: " $replacedUserAuthor
 Write-Host "Updating the editor field with: " $replacedUserEditor
 $itemOwners["Author"] = $replacedUserAuthor;
 $itemOwners["Editor"] = $replacedUserEditor;
 $itemOwners.Update();


 Also another snippet on how to print a full stack trace in powershell. The magic key is the “format-list –force” command after the exception:

Try
{
#your code logic here
}
 Catch
 {
 Add-Content $filename $_.Exception |format-list –force
 Write-Host -ForegroundColor Red $_.Exception |format-list –force
 }

SharePoint Online – PowerShell, CSOM and Tools

Here are some links on how to access and modify your SharePoint Online sites and data. These might come in handy to someone whom is starting with SharePoint Online:

SharePoint Online Management Shel

Index of Windows PowerShell for SharePoint Online cmdlets

Windows PowerShell for SharePoint Online reference

SharePoint Client Browser for SharePoint Online and SharePoint on-premise

SharePoint Online Client Components SDK

Check out this great link for more info on how to use these tools:

http://blogs.technet.com/cfs-file.ashx/__key/telligent-evolution-components-attachments/01-9981-00-00-03-63-30-65/sharepoint-online-administration-with-powershell.pdf

Good to Know: Windows Server 2012 – Part 4

Hi this is my part four of resources for Windows Server 2012(and older ones also):

Add-DnsServerDirectoryPartition http://technet.microsoft.com/en-us/library/jj649942(v=wps.620).aspx
Add-DnsServerPrimaryZone http://technet.microsoft.com/en-us/library/jj649876(v=wps.620).aspx
Adding a Reverse Lookup Zone http://technet.microsoft.com/en-us/library/cc961414.aspx
Add-PswaAuthorizationRule http://technet.microsoft.com/en-us/library/jj592890(v=wps.620).aspx
Add-VMRemoteFx3dVideoAdapter http://technet.microsoft.com/en-us/library/hh848520(v=wps.620).aspx
Authorize a DHCP server in Active Directory http://technet.microsoft.com/en-us/library/cc759688(v=ws.10).aspx
Block Inheritance http://technet.microsoft.com/en-us/library/cc731076.aspx
Configure a Server Core Server with Sconfig.cmd http://technet.microsoft.com/en-us/library/jj647766.aspx
Configure Memory and Processors http://technet.microsoft.com/en-us/library/cc742470.aspx
Delegate Control of an Organizational Unit http://technet.microsoft.com/en-us/library/cc732524.aspx
Deploy Clustered Storage Spaces http://technet.microsoft.com/en-us/library/jj822937.aspx 
Deploying a GlobalNames Zone http://technet.microsoft.com/en-us/library/cc731744.aspx
Deploying Microsoft RemoteFX on a Single Remote Desktop Virtualization Host Server Step-by-Step Guide http://technet.microsoft.com/en-us/library/ff817586(v=ws.10).aspx
Deploying Network Load Balancing (NLB) and Virtual Machines on Windows Server 2008 R2 http://blogs.msdn.com/b/clustering/archive/2010/07/01/10033544.aspx
Deployment Image Servicing and Management Command-Line Options http://technet.microsoft.com/en-us/library/dd744382(v=ws.10).aspx
Dsadd http://technet.microsoft.com/en-us/library/cc753708(v=ws.10).aspx
Enable-VMRemoteFXPhysicalVideoAdapter http://technet.microsoft.com/en-us/library/hh848506(v=wps.620).aspx
Enforce a Group Policy Object Link http://technet.microsoft.com/en-us/library/cc753909.aspx
Evaluation Versions and Upgrade Options for Windows Server 2012 http://technet.microsoft.com/en-us/library/jj574204.aspx
Evaluation Versions and Upgrade Options for Windows Server 2012 http://technet.microsoft.com/en-us/library/jj574204.aspx
Get-DnsServerDiagnostics http://technet.microsoft.com/en-us/library/jj649883(v=wps.620).aspx
Grant a Member the Right to Logon Locally http://technet.microsoft.com/en-us/library/ee957044(v=ws.10).aspx
How to remove data in Active Directory after an unsuccessful domain controller demotion http://support.microsoft.com/kb/216498
How User Account Control Works http://technet.microsoft.com/en-us/library/jj574202.aspx
Hyper-V Dynamic Memory Configuration Guide http://technet.microsoft.com/en-us/library/ff817651(v=ws.10).aspx
Hyper-V Virtual Switch Explained, Part 2 http://www.altaro.com/hyper-v/hyper-v-virtual-switch-explained-part-2/ 
Hyper-V Virtual Switch Overview http://technet.microsoft.com/en-us/library/hh831823.aspx
ImageX Command-Line Options http://technet.microsoft.com/en-us/library/cc749447(v=ws.10).aspx
Install-PswaWebApplication http://technet.microsoft.com/en-us/library/jj592894(v=wps.620).aspx
Install-RemoteAccess http://technet.microsoft.com/en-us/library/hh918408(v=wps.620).aspx
Internet Protocol Version 6 Address Space http://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xml
Link a Group Policy Object http://technet.microsoft.com/en-us/library/cc732979.aspx
Loopback processing with merge or replace http://technet.microsoft.com/en-us/library/cc782810(v=ws.10).aspx
Manage Multiple, Remote Servers with Server Manager http://technet.microsoft.com/en-us/library/hh831456.aspx
Managing a Server Core installation: Overview http://technet.microsoft.com/en-us/library/ee441255(v=ws.10).aspx
Migrate Print and Document Services to Windows Server 2012 http://technet.microsoft.com/en-us/library/jj134150.aspx
Operations master roles http://technet.microsoft.com/en-us/library/cc773108(v=ws.10).aspx
Print and Document Services Overview http://technet.microsoft.com/en-us/library/hh831468.aspx
Remote Desktop Gateway Manager http://technet.microsoft.com/en-us/library/cc725706.aspx
Remove-ADComputer http://technet.microsoft.com/en-us/library/ee617250.aspx
Remove-WindowsFeature http://technet.microsoft.com/en-us/library/ee662310.aspx
Sc config http://technet.microsoft.com/en-us/library/cc990290(v=ws.10).aspx
Security Tools to Administer Windows Server 2012 http://technet.microsoft.com/en-us/library/jj730960.aspx
Set up recovery actions to take place when a service fails http://technet.microsoft.com/en-us/library/cc738230(v=ws.10).aspx
Set-BCAuthentication http://technet.microsoft.com/en-us/library/hh848404(v=wps.620).aspx
Set-DnsServer http://technet.microsoft.com/en-us/library/jj649845(v=wps.620).aspx
Set-DnsServerDsSetting http://technet.microsoft.com/en-us/library/jj649874.aspx
Set-DnsServerForwarder http://technet.microsoft.com/en-us/library/jj649887(v=wps.620).aspx
Set-DnsServerSetting http://technet.microsoft.com/en-us/library/jj649909.aspx
Set-GPPermissions http://technet.microsoft.com/en-us/library/ee461038.aspx
Set-WSManInstance http://technet.microsoft.com/en-us/library/hh849875.aspx
Set-WSManQuickConfig http://technet.microsoft.com/en-us/library/hh849867.aspx
Storage Pools… Dive right in! http://blogs.technet.com/b/canitpro/archive/2012/12/13/storage-pools-dive-right-in.aspx
Switching Between the GUI and Server Core in Windows Server 2012 http://www.petri.co.il/switching-gui-server-core-windows-server-2012.htm
Troubleshooting Windows Firewall with Advanced Security in Windows Server 2012 http://social.technet.microsoft.com/wiki/contents/articles/13894.troubleshooting-windows-firewall-with-advanced-security-in-windows-server-2012.aspx
Updating root hints http://technet.microsoft.com/en-us/library/cc758353(v=ws.10).aspx
Using System Configuration (msconfig) http://windows.microsoft.com/en-us/windows-vista/using-system-configuration
Using the Set-Service Cmdlet http://technet.microsoft.com/en-us/library/ee176963.aspx
Verifying Your Basic DNS Configuration http://technet.microsoft.com/en-us/library/cc959303.aspx
What’s New in Hyper-V for Windows Server 2012 http://technet.microsoft.com/en-us/library/hh831410.aspx
What’s New in Hyper-V for Windows Server 2012 http://technet.microsoft.com/en-us/library/hh831410.aspx
Windows and GPT FAQ http://msdn.microsoft.com/en-us/library/windows/hardware/gg463525.aspx