Monday, October 22, 2012

Removing a web part from a page recursively with Powershell

This week we were making some changes to the content on our orders pages, we decided to remove a web part that was showing some static content and replace it with an SSRS report that I blogged about earlier. I needed this to quickly remove a web part off of each of my 500+ orders sites, so Powershell was looking like the tool of choice for this operation, and let me just take a moment to say I am stoked that at last I am spending more time in Powershell to do even simple things that are now too slow going through the SharePoint UI, removing or adding web parts via Powershell is an awesome way to do it. I was able to pick at a few samples I found online and create something that worked for me.

 

Friday, October 19, 2012

Using Powershell to add a file from a shared drive to a SharePoint Document Library

One of our older systems was outputting reports to a shared folder on our network, we needed an automated way to grab the file and add it to a SharePoint Document Library. So time to break out the Powershell ISE and see if we can do this with out breaking a sweat. First make sure the service account has access to both the network share and the SharePoint Document Library, otherwise you will spend a bit of time trying to troubleshoot your script. The script is pretty well commented so no need to further explain.

Monday, October 1, 2012

Add/Update SharePoint Webpart with Powershell

I recently had a request to add a banner with the Site Title - Site Description on a yellow background to everyone of my 500 SharePoint Orders Dashboard sites front pages I had created. For jobs this big I always break out Powershell!

I decided to use a Content Editor web part that pointed to a script located in a shared Document Library at the root of my site collection. By doing this I can add an empty Content Editor Web Part to each of my 500 dashboard pages, programatically setting it's properties and placement on the page. I will call this web part Title Banner Web Part and it needs to be placed into the Header zone and it had to be the 1st one in that zone.

How this is going to work depends on using a web part page, which I am already doing, that has the out of the box masterpage so we can target a specific class named s4-pagedescription and a div with an id of ctl00_PlaceHolderSiteName_onetidProjectPropertyTitle to get the information we want. I found these by going to my page that I needed the banner on and using F12 to open the IE developer tools and then locating the 2 items I needed in the html.







Once I had my banner looking the way I wanted I saved the file as TitleBannerWebPart.txt and uploaded it to my a scripts document library located on the root site of my site collection that has domain users with read permissions. You can test out the script by pasting it into a content editor web part and saving the page. I keep my scripts like this so that if a system wide change is required I can update one or two lines of code and be good to go.

Now that I have my script ready we are going to log into our server and open up the Powershell ISE and get to work using a content editor web part and set it's properties to point to our banner script stored in the root document library called scripts and set the height to 80 and the Chrome Style to None so we do not see the title or border of the web part.

## CONTACT INFO
## ------------------------------------------------
## CREATED   : 2013.03.30
## MODIFIED  :
## AUTHOR    : Jason Lasby 
## EMAIL     : digitalslavery@gmail.com 
##
## DESCRIPTION
## ------------------------------------------------
## Script to loop through a set of Subsites and  
## add a content editor web part to a page stored in 
## the SitePages Document Library named Dashboard.aspx
## 
## EXPLANATION
## ------------------------------------------------
## This example illustrates how to dynamically loop
## through a set of sub sites and add a web part 
## to a page in a set of sites that use the same page layout
## and are configured with the same web parts, think about 
## a company dashboard site where each department may 
## report standard data like who is in who is out, 
## work related accidents, finance data, shipping
## information, etc... We can loop through our sites
## and add/update or remove web parts for all sites at once.
##
## BEGIN
## ------------------------------------------------
## Load up the snapin so Powershell can work with SharePoint
## if the snapin was already loaded don't alert the user
Add-PSSnapin microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
## Clear any errors or output to the screen
CLS
## Set variables
## This variable will be the site where I want to start
$parentSite = "http://sp2010/dashboards"

$webPartProperty_Title = "Title Banner Web Part"
$webPartProperty_ZoneName = "Header"
$webPartProperty_Height = "80"
$webPartProperty_Width = ""
$webPartProperty_Visible = $true
## All content editor web parts will point to this script
$webPartProperty_Link = "http://sp2010/dashboards/scripts/spservicesTest.txt"

Start-SPAssignment -Global
$site = Get-SPWeb $parentSite
$webSites = $site.Webs
foreach($webSite in $webSites)
{
    $order = $webSite.Name
    $page = $webSite.GetFile("/dashboards/$order/SitePages/Dashboard.aspx") 
    $webPartManager = $webSite.GetLimitedWebPartManager($page, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
 foreach($webPart in $webPartManager.WebParts)
 {
  $listOfAllWebParts = $webPart.Title
 }
 ## Check the page to see if the web part was already on it
 if($listOfAllWebParts -eq $webPartProperty_Title)
 {
  Write-Host "$webSite already had web part on it."
 }
 ## Create the web part and set some of it's properties
 else
 {
  $cewp = New-Object Microsoft.SharePoint.WebPartPages.ContentEditorWebPart
  $cewp.ContentLink = $webPartProperty_Link
     $cewp.Title = $webPartProperty_Title
     $cewp.Height = $webPartProperty_Height
     $cewp.Width = $webPartProperty_Width
  $cewp.Visible = $webPartProperty_Visible
  $cewp.ChromeType = "None"
     $cewp.HorizontalAlign = "Center" 
     ## The AddWebPart takes 3 arguments, first is the web part name, 
     ## then the zone id 
     ## and finally the order number where you want the web part to show in the zone
     $webPartManager.AddWebPart($cewp, $webPartProperty_ZoneName, 0)
     $webPartManager.SaveChanges($cewp)
     $webSite.Dispose()
  Write-Host "Webpart was created for Order $order"
 }
}

Stop-SPAssignment -Global



Showing an SSRS Report in a SharePoint Modal Dialog

One of the challenges I have had recently was trying to integrate the awesome features of SQL Server Reporting Services and SharePoint. Our installation of SSRS is in SharePoint Integrated mode so if you are following along you will need to make sure you are running the same setup.

My objective with this project was to add a Content Editor web part to all 500 of our dashboard sub sites that pointed to a single file that use some javascript to open a SharePoint modal dialog window with the report in it. This report had open in a  window that was 1024x800 in order to see the whole report. Also for this particular project I was not worried about refreshing my dashboard page once the modal window was closed, so that is not included in this script.

I created a document library called scripts that lives in the root site of my site collection, inside I created a text file called reports.txt, every single content editor webpart points to this file. The final thing to note here is that I am getting the order number from the url, which also happens to be my sub sites name, I need this number to pass to my report so it will generate no matter which Order dashboard you go to.


// Here I centered the button to the middle of the web part

Wednesday, July 11, 2012

Recover an application that is not visible on your screen in Windows 7

I recently had somehow moved my Outlook program off one of my two monitors and was not able to get it back, I would open the program and I could see the icon in the tray but there was no getting it back on the screen until I came across this cool little trick: Select the icon in the tray and then hold down the Windows key and press the right arrow and poof it will magically appear on your screen!

Thursday, July 5, 2012

Using Powershell to mass update a SharePoint Hyperlink field


Scenario:
You have a SharePoint List that contains all of your site's subsites, one of the columns in the List is used to point to the URL of the subsite. Using a foreach loop and comparing values in the List to the name of the sub site you can update the hyperlink column like so:

#add-pssnapin microsoft.sharepoint.powershell
$web = get-spweb -identity "https://dashboard.company/.com"
# We have to use the @ sign specify that this will be an array
$subsites = @($web.webs)
foreach($subsite in $subsites)
       {
        # The hyperlink field has 2 columns the URL and the Description
        $itemUrl = $subsite.Url
        $itemDesc = $subsite.Title
        #We filter the list to make sure we do not get
        # any items named Temp
        if($itemDesc -ne "temp")
        {
        # Get the List we want to update
        $listWeb = Get-SPWeb -identity "https://dashboard.company.com/orders"
        $list = $listWeb.Lists["Your List Name"]
        # We have to use the @ sign specify that this will be an array
        $items = @($list.Items)
        foreach($item in $items)
        {
            $siteUrl = $item["Your Column Name"]
            $to = $item["Task Order"]
            # We want to match up each List item with the right Title of each site
            if($itemDesc -eq $to)
            {
            # Set the name of the hyperlink column in a variable
            $siteUrl = $item["Your Column Name"]
            # You have to enclose the variables in quotes for the vaules
            # to be passed
            $siteUrl = "$itemUrl, $itemDesc"
            $item["Your Column Name"] = $siteUrl
            $item.update()
            # Print out the sub site name to the console window
            # goes faster if you do not print it out           
            $siteUrl
            $listWeb.Dispose()
            }
          }
        }
    }
$web.Dispose()

Wednesday, May 30, 2012

I was recently setting up a new virtual test box for SharePoint to work on developing a new project and was trying to mimic my production network with sever and site collection names, however I was getting a prompt to enter my username and password but even entering my credentials I was still not able to access my site. My dev server name was SP2010-SP which is where my central admin site was as well as my first site collection, even this site was giving me issues with login, to make it more interesting I created 2 additional sites at dashboard.company.com and portal.company.com using host headers so I could use port 80. The solution that worked was to do the following:

Specify host names (Preferred method if NTLM authentication is desired)
To specify the host names that are mapped to the loopback address and can connect to Web sites on your computer, follow these steps:
  1. Set the DisableStrictNameCheckingregistry entry to 1. For more information about how to do this, click the following article number to view the article in the Microsoft Knowledge Base:
    281308  (http://support.microsoft.com/kb/281308/ ) Connecting to SMB share on a Windows 2000-based computer or a Windows Server 2003-based computer may not work with an alias name
  2. Click Start, click Run, type regedit, and then click OK.
  3. In Registry Editor, locate and then click the following registry key:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  4. Right-click MSV1_0, point to New, and then click Multi-String Value.
  5. Type BackConnectionHostNames, and then press ENTER.
  6. Right-click BackConnectionHostNames, and then click Modify.
  7. In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
  8. Quit Registry Editor, and then restart the IISAdmin service.

Thursday, May 24, 2012

The holy grail for SharePoint developers just getting started

While recently looking for some code samples for creating a custom web part I came across this little gem from Microsoft, the SharePoint 2010 Code Samples 101 download located here: http://code.msdn.microsoft.com/SharePoint-2010-101-Code-da251182

This is a great collection of Visual Studio Solutions written in C# to get you started on your next custom project for SharePoint 2010.

Tuesday, May 22, 2012

Create a SharePoint sub site from a site export

Our issue was some 3rd party web parts were not allowing us to save a site as a template through the normal way of going into the Site Actions > Site Settings > Save Site as a template.

Our solution involved using Powershell to do an export of the site we wanted to use as a template. The main challenge with this is that you need to first create a SharePoint site, then do an Import-SPWeb to restore the site that was exported, then set the title and description. (This works with both http and https sites.)

# Define root site where the shell of the sub site will be created under
$site = "https://portal/"
   
Write-Host "Please enter the Title of the site to create"       
$webTitle = Read-Host "Please enter the title of the site you wish to create"    
$newSiteUrl = "https://portal/$webTitle"     
# Create empty subsite
$web = New-SPWeb $newSiteUrl -name $webTitle -UseParentTopNav
# Use the base SharePoint template of STS#1
$web.ApplyWebTemplate("STS#1")
# Give the site a name
$web.Name = $webTitle
# Apply changes
$web.Update()
# Since we are using a custom template for the sites we will want to set some variables
$templateName = "https://portal/$webTitle"
$templateLocation = "C:\Temp\Template\site.bak"
# Restore the site from the back up
Import-SPWeb $templateName -Path $templateLocation -IncludeUserSecurity
# We need to update some properties of the restored site, so we set the site as a variable
$web = (Get-SPWeb -Identity "https://portal/$webTitle")
# Once the site is restored this will overwrite the title and description which we set here
$web.title =$webTitle
$web.description = "Template Site"
# Update the site
$web.update()
# Clean it up
$web.dispose()
  
Write-Host "The Installation is complete please visit the site at" $web.URL

Monday, April 16, 2012

SharePoint 2010 Table of Contents web part using javascript

One of the things I love about SharePoint is the ability to quickly create solutions utilizing the html web part or the content editor web part, lately I have been using the html web part as it is just a bit friendlier to use when adding client side code to handle tasks.

Today I have been trying to find an easy way to list all the sub sites in order to create a Table of Contents for our users, and while there are several ways you can do this without having to use code the Tree view and the actual Table of Contents web parts just were not meeting my needs, so a little javascript magic to the rescue!

Add a html web part to your page and then click the edit web part
Click the source editor button in the properties dialog box on the right
and paste in this script:


This script will loop through your sub sites and display a list of sites, I took it one step further and made each item a link that will take you to the site listed.

Tuesday, April 3, 2012

Powershell error when creating a new SharePoint Site

I ran into another odd problem with my SharePoint 2010 deployment yesterday.  I was trying to create a new site using the New-SPWeb PowerShell command and I kept getting the following error message:

PS C:\Users\rsmw> new-spweb http://sharepoint.local/newspweb
New-SPWeb : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:10 + new-spweb <<<<  http://sp2010.mps.k12.mi.us/warrensm2
 + CategoryInfo          : InvalidData:
(Microsoft.Share....SPCmdletNewWeb:SPCmdletNewWeb) [New-SPWeb],
UnauthorizedAccessException
 + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletNewWeb
 
The account I was logged in with was a farm administrator and I could create sites through the web interface.   Apparently, I needed to add the farm administrator account to the Owners group of the parent site in order to create a new site. After that, all was good to go.

Sunday, April 1, 2012

Using PowerShell to set SharePoint 2010 MasterPage Recursively

During a recent development project to create a custom branded MasterPage for our 2010 portal, the page I had created had an EventReceiver that set the MasterPage to my custom MasterPage, however I forgot to enclose one of my vars with a semi colon and the page deployed but would not render, I kept getting a SharePoint error saying File not found!!! Even after retracting the solution with Visual Studio I kept getting the same error. I needed some way to reset the MasterPage to v4.master, enter PowerShell, my favorite way to work with admin task. Thanks to Todd Lindt's quick post found here:
http://www.toddklindt.com/blog/Lists/Posts/Post.aspx?ID=226

The master page setting is scoped at the web level, so the first thing I did was use Get-SPWeb to get a variable for the web I want to change. There are two properties that control the master page settings; MasterUrl and CustomMasterUrl. The former controls the master page used to render the System pages (the ones that start with /_layouts) and the latter controls the master page used to render the content pages.


To alter those settings for a publishing site at http://sharepoint/, use the following PowerShell script:

$web = Get-SPWeb http://sharepointurl/
$web.CustomMasterUrl = "/_catalogs/masterpage/customMasterPage.master"
$web.MasterUrl = "/_catalogs/masterpage/customMasterPage.master"
$web.Update()
This changes the master page for both settings and content to a customMasterPage.master. You can also set it to the default v4.master if you just need to reset it to the default masterpage. Since we're doing this with PowerShell it's easy to loop through a group of webs and set their master pages to whatever you like