PowerShell Exception calling GetLimitedWebPartManager

Using PowerShell against SharePoint, I was trying to remove a web part from a lot of pages.

Time after time I was receiving this error:

Exception calling “GetLimitedWebPartManager” with “2” argument(s): “Unable to cast COM object of type ‘Microsoft.SharePoint.Li
brary.SPRequestInternalClass’ to interface type ‘Microsoft.SharePoint.Library.ISPRequest’. This operation failed because the Q
ueryInterface call on the COM component for the interface with IID

Turned out that I wasn’t trying to work with the correct page. I was trying to work with a web part on a page in a library, but by script was working with a site page.

PowerShell SharePoint Delete Web Part

Migrated a company from SharePoint 2007 to SharePoint 2010 and hit another small bump in the process.

The core issue was related to the AllItems.aspx page in a given library had a Content Editor web part on the page. Why?  No idea, but when users tried to access the library, the Documents and Library tab were missing from the Ribbon.

This wouldn’t be an issue if I was dealing one library.

In my case, I had a Site Collection with a dozen sites, then under each of those sites were 100+ sites.  So, I only needed to update ~1,000 sites.

Options:
A. Hire someone to edit ALL of those sites / pages.
B. Our great friend PowerShell!

What I’m doing in the script:
Starting at the Site Collection.
Loop on each site.
Looping on each List in the site.
When site = Random Documents dig in a little deeper.
Get the web parts on the AllItems.aspx page.
Loop on the web parts.
If web part title = “Content Editor Web Part”
Delete it.

 $site = Get-SPSite "http://sharepointed.com/SiteCollection"

foreach ($web in $site.AllWebs)
{
foreach($List in $web.Lists)
{
If($list.Title -eq "Random Documents")
{
$webpartmanager = $web.GetLimitedWebPartManager(($web.Url + "/Random%20Documents/Forms/AllItems.aspx"), [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

for($i=0; $i -lt $webpartmanager.WebParts.Count; $i++)
{
if($webpartmanager.WebParts[$i].Title -eq "Content Editor Web Part")
{
$webpartmanager.DeleteWebPart($webpartmanager.Webparts[$webpartmanager.WebParts[$i].ID])
}
}
}
}
$web.Update()
$web.Dispose()
}
$site.Dispose()

Update Default Value of a Date and Time field

Ohhh how handy can PowerShell be!

I needed to change the default value of a Date and Time field for several hundred sites. PowerShell allowed me to update the field on all of my SharePoint sites in a matter of seconds.

#add-pssnapin microsoft.sharepoint.powershell

$spsite=[Microsoft.SharePoint.SPSite]("http://sharepointed.com/customers/")

foreach ($web in $spsite.AllWebs) 

{
    Write-Host $web.name
    
    $List = "List or Library"
    $OpenList = $web.Lists[$List]

    $Field = $OpenList.Fields["My Date Field"]
	$Field.DefaultValue = "[today]"
    $Field.Update($True)
    
    $web.Dispose()

}
$spsite.Dispose()

Update Hyperlink Field in SharePoint with PowerShell

Recently was asked to update the hyperlink field in a SharePoint list. The list had thousands of links pointing to a server we were moving, so the URL in the list needed to updated to reflect the new location. The only options I could think of, were to open SQL Server and do find/update against the content database(s). Well, Microsoft doesn’t like up playing with the SharePoint databases. So I cracked open PowerShell and went to town trying to figure this out.

#Add-PSSnapin Microsoft.SharePoint.PowerShell

$siteUrl = "http://sharepoint/SiteCollection/SiteName"
$webName = “SiteName”
$listName = "Name of your list"
$spSite = new-object Microsoft.SharePoint.SPSite($siteurl)
$spWeb = $spSite.OpenWeb($webName)
$spList = $spWeb.Lists[$listName]

			foreach($Item in $spList.Items )
			{
				$ofldurl= new-object Microsoft.SharePoint.SPFieldUrlValue($Item["URL"])

				$ofldurl.URL = $ofldurl.URL.Replace("Nacho", "Taco")
				$ofldurl.Description = $ofldurl.Description.Replace("Nacho", "Taco")

				$item["URL"] = $ofldurl
				$item.update()
			}

$spWeb.Dispose()

What I’m doing here is replacing part of the URL string with a new word. The script is looking for the string Nacho and replacing it with Taco.

**** update ****
After migrating from SharePoint / WSS 2007 to SharePoint 2010, we started to notice some of our URLs were messed up. Web parts ( Page Viewer) and internal hyperlinks were pointing to an incorrect location.

example:
http://sharepoint/crmsp/customers/sitename/_layouts/1033/mngsubwebs.aspx?view=sites

Notice the 1033, no bueno!

Using the script above, i was able to update the links.

#Add-PSSnapin Microsoft.SharePoint.PowerShell

$siteUrl = "http://sharepoint/SiteCollection/SiteName"
$webName = “SiteName”
$listName = "Name of your list"
$spSite = new-object Microsoft.SharePoint.SPSite($siteurl)
$spWeb = $spSite.OpenWeb($webName)
$spList = $spWeb.Lists[$listName]

			foreach($Item in $spList.Items )
			{
				$ofldurl= new-object Microsoft.SharePoint.SPFieldUrlValue($Item["URL"])

				$ofldurl.URL = $ofldurl.URL.Replace("1033/", "")
				$ofldurl.Description = $ofldurl.Description.Replace($ofldurl.Description, $ofldurl.Description)

				$item["URL"] = $ofldurl
				$item.update()
			}

$spWeb.Dispose()

In SharePoint 2016, the Description property appears broken?
This is the only way I could manage to set the URL and display text:

$newItem[“LinkField”] = "http://taco.com, taco2"

PowerShell SharePoint User Access

Let me start this off by saying I’m new to PowerShell AND I’m sure someone could sum up my code in one line of code.

I was asked to provide a list of all users in a SharePoint Site Collection / Web App. The person asking this, was wanting to see each user, the site and list they had access to. More or less I needed to iterate through all the sites, loop on the user, loop again on the site, then loop on the lists.

So the layout I could provide was:

Site Collection
User Name
Site
List

I’m outputting the results to a file name UserAccess.txt on the C:\ drive.

[System.Reflection.Assembly]::Load(“Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)
[System.Reflection.Assembly]::Load(“Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)

$spsite=[Microsoft.SharePoint.SPSite]("http://sharepoint/")

out-file c:\UserAccess.txt -append

foreach ($Site in $spsite.AllWebs)
{
    "Site Collection Name:  $Site" | out-file c:\UserAccess.txt -append
    foreach ($User in $Site.SiteUsers)
    {
        "--User Name: $User" | out-file c:\UserAccess.txt -append
        foreach ($Site in $spsite.AllWebs)
        {
					$SitePermissions = $Site.Permissions
					foreach($mySitePermission in $SitePermissions)
					{
						if($User.ID -eq $mySitePermission.Member.ID)
						{
                            "----Site Name: $Site" | out-file c:\UserAccess.txt -append
						}
					}

                    foreach($myList in $Site.lists)
        			{

        					$myListPermissions = $myList.Permissions
        					foreach($myListPermission in $myListPermissions)
        					{
        						if($User.ID -eq $myListPermission.Member.ID)
        						{
                                    "------List Name: $MyList" | out-file c:\UserAccess.txt -append
        						}
        					}
        			}

                 $Site.Dispose()
			}
            $Site.Dispose()
        }
    }

Let me know if you have any questions or need any help.

Get Content Database Size

In SharePoint 2010 or 2007 I wasn’t able to find the size of the Content Databases.  For some reason I thought it was displayed in Central Administration, wrong.

Log into one of your SharePoint servers.
Open PowerShell and paste the below code into the PowerShell window.
Run.

[Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | out-null
$prop_Name = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("Name")
$prop_DiskSizeRequired = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("DiskSizeRequired")
$prop_Sites = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("Sites")
[Microsoft.SharePoint.Administration.SPFarm]::Local.Services |? {
$_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPWebService"
} |% {
$_.WebApplications |% {
$_.Name
$_.ContentDatabases |% {
$prop_Name.GetValue($_, $null)
$prop_DiskSizeRequired.GetValue($_, $null) / 1GB
}
}
}

The output will be:
Web App
Content Database Name
Content Database Size in Gigs.

You can change the output displayed size to MB by updating:
$prop_DiskSizeRequired.GetValue($_, $null) / 1GB
$prop_DiskSizeRequired.GetValue($_, $null) / 1MB

PowerShell Query Webpage SharePoint

Using PowerShell, I was looking for a way to query / search a webpage for a string / variable. If the string was found, do something.

When trying to access a SharePoint page, I needed to use the UseDefaultCredentials = $true function, otherwise I was seeing random errors.

Error example:
The remote server returned an error: (401) Unauthorized.
$web = New-Object System.Net.WebClient
$web.UseDefaultCredentials = $true

If ($web.DownloadString(“http://www.yoursite.com/taco.aspx”)| select-string “Taco”)
{
Write-Host “True”
}
Else
{
Write-Host “False”
}

Get Crawl Status Using Powershell

{Edit} I’ve found another way of doing this{/}

Way One:

I needed a way of knowing when a crawl status was set to paused.  Using a combination of Windows Task, Powershell, SharePoint List, and Workflow I was able to come up with a solution.

Process: Windows Task runs every hour (on the server with Central Administration).  This Task runs my Powershell command.  The command checks all my Content Sources for a crawl status of paused. If the status is paused, the command will write an Item to a SharePoint List.  Associated Workflow on the List then sends me an email.

Link to the completed Powershell command: Powershell Crawl Status (you will need to open the file and save it with a .ps1 extension.)

[void] [System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

[void] [System.Reflection.Assembly]::Load("Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

[void] [System.Reflection.Assembly]::Load("Microsoft.Office.Server.Search, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

$SITEURL = "http://win-severname"

$spsite = new-object Microsoft.SharePoint.SPSite ( $SITEURL )
$serverContext = [Microsoft.Office.Server.ServerContext]::Default
$context = [Microsoft.Office.Server.Search.Administration.SearchContext]::GetContext($serverContext)
$sspcontent = new-object Microsoft.Office.Server.Search.Administration.Content($context)
$sspContentSources = $sspcontent.ContentSources

[int]$count

$count=0

foreach ($cs in $sspContentSources)

{
if ($cs.CrawlStatus -eq [Microsoft.Office.Server.Search.Administration.CrawlStatus]::Paused)
{

$count++

}
}

if ($count -gt 0)

{

$spweb = $spsite.OpenWeb()
$splist = $spweb.Lists["ListName"];
$items=$splist.get_items() | where { $_.Title -like '*' }

if ($splist.ItemCount -gt 0)
{
$items | % { $_.Delete() }
}
$newItem = $splist.Items.Add()
$newItem["Title"] = "NewItem"
$newItem.Update()

$spweb.Dispose()
$spsite.Dispose()


}

——————————

How to run a Powershell command from a Scheduled Task.

To run a Powershell command you will need to do the following.

1.In the Actions tab:

a.Click New. The New Action dialog box appears.

2.In Settings, in Program/Script, type:

powershell.exe

3.In Add arguments, type the following:

-command “C:\Powershell Crawl Status.ps1”

4.Click OK.

http://technet.microsoft.com/en-us/library/ee649304(WS.10).aspx

Way Two and the EASY way:


$web = New-Object System.Net.WebClient
$web.UseDefaultCredentials = $true

If ($web.DownloadString(“http://craigslistSpam/ssp/admin/_layouts/listcontentsources.aspx”)| select-string “Paused” -CaseSensitive)
{
$emailFrom = "me@craigslistSpam.com"
$emailTo = "you@craigslistSpam.com"
$subject = "testing"
$body = "test email"
$smtpServer = "this can be found in Outlook"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom, $emailTo, $subject, $body)
}

 

 

 

Powershell delete items in a list or library

There might be a better way to accomplish this… but for now this works.  Just needed a way to delete all the items in a list.

[System.reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)
$spsite = New-Object -TypeName “Microsoft.SharePoint.SPSite” -ArgumentList http://win-vm3$spweb = $spsite.OpenWeb()

$splist = $spweb.Lists[“NameofList”]

$items=$splist.get_items() | where { $_.Title -like ‘*’ }
$items | % { $_.Delete() }

$spweb.Dispose()

$spsite.Dispose()