All posts by Jack

Powershell script to add a list of users to the site collection administrators group of every site on your SharePoint 2010 farm.

I wanted a way to inject myself as a site collection admin into every site in sharepoint, Note, I’m not talking about the primary/secondary that you can set in Central admin.
I’m talking about that group you can only get to from within each site itself. Or in this case, with the powershell script below…
Note that it takes an array of names – if you have a team of admins or developers that all need access, you can put all their names in the list.

# set site collection owner for all sites...
# 1-2012
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

# $AccountList is an array of Windows Identities in the format of $AccountList = @("DOMAIN\USERID" , "DOMAIN\USERID2")
$AccountList = @("LAB\Jack", "Lab\tom", "Lab\dick", "lab\harry")

#this gets an array of objects representing the sites at the IIS level:
$IISSites = Get-SPWebApplication
Foreach($oneIISSite in $IISSites)
{
   #using .Sites, we can get a list of the site collections
   foreach ($SharepointSiteCollection in $oneIISSite.Sites)
   {
      write-host $SharepointSiteCollection.url -ForegroundColor Cyan
      $spweb = Get-SPWeb $SharepointSiteCollection.url
      
      #now we have the website, so lets look at each account in our array
      foreach ($Account in $AccountList)
      {
         #lets see if the user already exists
         Write-host "Looking to see if User " $account " is a member on " $SharepointSiteCollection.url -foregroundcolor Blue
         $user = Get-SPUSER -identity $Account -web $SharepointSiteCollection.url -ErrorAction SilentlyContinue #This will throw an error if the user does not exist
         if ($user -eq $null)
         {
            #if the user did NOT exist, then we will add them here.
            $SPWeb.ALLUsers.ADD($Account, "", "", "Added by AdminScript")
            $user = Get-SPUSER -identity $Account -web $SharepointSiteCollection.url
            Write-host "Added user $Account to URL $SPWeb.URL" -Foregroundcolor Magenta
         }
         else
         {
            Write-host "user $Account was already in URL " $SPWeb.URL -Foregroundcolor DarkGreen
         }
         if ($user.IsSiteAdmin -ne $true)
         {
            $user.IsSiteAdmin = $true
            $user.Update()
            Write-host "$account has been made an admin on $SPWeb.URL" -Foregroundcolor Magenta
         }
         else
         { 
         Write-host "$account was already an admin on $SPWeb.URL" -Foregroundcolor DarkGreen
         }
     }
     $SharePointSiteCollection.Dispose()
}
}

 

Here’s another version of the script, this one also takes an array of top level URL’s

It’s handy if you have lots of url’s on your site and only want to work with a few of them.

# set site collection owner for all sites...
# 2-2013 Jack

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$logfile = "Powershelloutput.log"

# $AccountList is an array of Windows Identities in the format of $AccountList = @("DOMAINUSERID" , "DOMAINUSERID2")
$AccountList = @("domaintom", "domaindick", "domainharry")

# $iisSiteList is an array of top level IIS site URLs
$iisSiteList = @("http://site1.yoururl.com", "http://anothersite.yoururl.com")

# this is from an earlier version of the script
# That scrip looks at all SP sites on the farm, I've left the old code here for reference
# this gets an array of objects representing the sites at the IIS level:
##  $IISSites = Get-SPWebApplication

Foreach($oneIISSite in $IISSiteList)
{
  #using .Sites, we can get a list of the site collections
  #so really what were saying is for each SharepointSiteCollection
  
  #this code is altered a bit, since we're using an array of top level site names.
  # we need to use (Get-SPWebApplication $oneIISSite).Sites
  # which is the same as $sitelist = Get-SPWebApplication $oneIISSite
  #                      $sitelist.sites
  foreach ($SharepointSiteCollection in (Get-SPWebApplication $oneIISSite).Sites)
  {
       $msg = $SharepointSiteCollection.url
       write-host  -ForegroundColor Cyan $msg
       Add-Content $logfile $msg
       
       $spweb = Get-SPWeb $SharepointSiteCollection.url
     
       #now we have the website, so lets look at each account in our array
       foreach ($Account in $AccountList)
       {
           #lets see if the user already exists  
           $msg = "Looking to see if User " + $account + " is a member on " + $SharepointSiteCollection.url
           Write-host -foregroundColor Blue $msg
           Add-Content $logfile $msg
           
           $user = Get-SPUSER -identity $Account -web $SharepointSiteCollection.url -ErrorAction SilentlyContinue #This will throw an error if the user does not exist
           if ($user -eq $null)
           { #if the user did NOT exist, then we will add them here.
               $SPWeb.ALLUsers.ADD($Account, "", "", "Added by AdminScript")
               $user = Get-SPUSER -identity $Account -web $SharepointSiteCollection.url        
               $msg = "Added user $Account to URL $SPWeb.URL"
               Write-host -Foregroundcolor Magenta $msg
               Add-Content $logfile $msg
           }
            else
           {
                $msg = "user $Account was already in URL " + $SPWeb.URL 
                Write-host -ForegroundColor DarkGreen $msg
                Add-Content $logfile $msg
           }
            
           if ($user.IsSiteAdmin -ne $true)
           {
             $user.IsSiteAdmin = $true
             $user.Update()
             $msg = "$account has been made an admin on $SPWeb.URL"
             Write-host  -Foregroundcolor Magenta $msg
             Add-Content $logfile $msg
           }
           else
           {
             $msg = "$account was already an admin on $SPWeb.URL" 
             Write-host -ForegroundColor DarkGreen $msg
             Add-Content $logfile $msg
             
           }
       }      
        
     $SharepointSiteCollection.Dispose()
  }
 } 
$msg = "=============== ALL DONE ================"
Write-host -ForegroundColor DarkGreen $msg
Add-Content $logfile $msg

 

Codeplex projects for Sharepoint

Some neat projects exist on codeplex.com that relate to sharepoint

FAST Search Query Analyzer: http://fastforsharepoint.codeplex.com/

Sharepoint content Migration tool: http://spdeploymentwizard.codeplex.com/

Sharepoint Feature Administration and Clean Up Tool: http://featureadmin.codeplex.com/

Sharepoint Farm Report: http://spsfarmreport.codeplex.com/ (an .exe – somewhat jumbled html output)

Sharepoint 2010 Farm Poster http://spposter.codeplex.com/ (some nice Powershell scripts)

 

 

 

2 possible solutions to PDF’s not displaying in browser when served up from SharePoint

I’ve run into this situation a few times and the fix was pretty easy.

The scenario goes like this: A user clicks a PDF file in sharepoint and can’t open it in the browser (instead they have to open it in Adobe Reader)

I’ve seen two fixes for this:
1) involved adding the mime type to the web app – this was a little elusive to me at first – sharepoint keeps tabs on mime types separately than IIS does – I had originally looked in IIS and thought everything was ok..
This can be checked with powershell
$Web = Get-SPWebApplication “http://mysharepointsite.myurl.com”
$Web.AllowedInlineDownloadedMimeTypes – this will list out all the mime types,
if you dont see “application/pdf” in the list, then you can add it like this:
$Web.AllowedInlineDownloadedMimeTypes.Add(“application/pdf”)
$web.Update()

So that was the first approach.

The next approach involved looking at the ‘safe’ settings for a document library – this too was a little elusive, becasue this is generally set at the site collection level – I don’t even think there is an option in the gui to set this for a document library in SharePoint 2010 (RTM) So again it’s gotta be done with powershell

I documented that here:  http://basementjack.com/uncategorized/pdfs-not-openi…oint-2010-site/ ‎

PDF’s not opening in browser from a sharepoint 2010 site?

I had this problem enough times that I wanted to capture the solution.

First of all, credit goes to Craig Lussier on the Technet forms, his post has the full solution and background.

http://social.technet.microsoft.com/Forums/en-US/sharepoint2010setup/thread/2f66404e-5193-46d3-b6b1-45cf72410432?prof=required

I used the above solution and it worked great.

I also found a script that I did not try. The script is described as being able to change this setting system wide by looping through each document library in each subsite of a given site – it could come in handy. (the script is by the same poster – Craig Lussier – Thanks Craig!

http://gallery.technet.microsoft.com/scriptcenter/Set-SPDocumentLibrary-0426781c

The code below is from the first link above, I’ve copied it here in case MS ever changes the link structure and the original post can’t be found. 

# SPAssignment
$gc = Start-SPAssignment

#Get Web
$web = $gc | Get-SPWeb "http://yourspweburl"

#Get Document Library
$docLib = $web.lists["Your Document Library Title"]

#View all properties/methods of the Document Library and you'll see that BrowserFileHandling is a property
$docLib | Get-Member

#See the current BrowserFileHandling setting for the Document Library
$docLib.BrowserFileHandling

#If you need to change it from Strict to Permissive
$docLib.BrowserFileHandling = "Permissive"
$docLib.Update()

# End SPAssgment
$gc | Stop-SPAssignment

Scope Sharepoint FAST search to a file share

Ok this took a bit of wrangling and some new understandings on my part to understand.

I was trying to index a file share of content, and create a FAST search page that would ONLY search that content. Since the FAST server had tons of other stuff on it, I needed to create a scope to narrow down the search. 

I used this powershell command to create the scope – this is key – you can’t do this from the sharepoint GUI (As of Sharepoint 2010 SP)

New-SPEnterpriseSearchQueryScope -SearchApplication “FAST Search Query SSA” -Name thisisthescopename -Description “A scope for a file share” -DisplayInAdminUI 1 -ExtendedSearchFilter “contentsource:nameofcontentsource”

Some explanation – the -SearchApplication is the name of our FAST query SSA – yours might be named differently

The -ExtendedSearchFilter nees some explanation,

First, the word contentsource needs to be in lower case – I had orignally tried it in mixed case (ContentSource) and that didn’t work

Next, the :nameofcontentsource – this is the artificial name you gave the content source over in your FAST Content SSA – it’s NOT the URL, UNC Path etc.. of the content!

for example, if in your FAST Content SSA, you created a content source on \server1files and called it myfiles

then your ExtendedSearchFilter would look like this: “contentsource:myfiles”

Ok so that’s the end of my explanation of the command itself.

After a few minutes the scope is created and we can test it in a normal FAST search site in sharepoint

Lets say that we indexed a bunch of content on monkeys and we want to see if it turns up in our new scope.

We would search for scope:thisisthescopename monkey

If we get the results we want, then we know the scope is working.

One step beyond this, we can create a special search page for this scope,

create a new FAST search site in sharepoint.

do a bogus search on the sites home page so that it shows you the results page

Edit the results page in the browser

find the web part at the bottom that displays the results

edit that web part

On the right hand side of the page, are the web parts properties, one of them is ‘scope’

put thisisthescopename in that web part and save the page (don’t forget to check in/publish if needed too)

now on your newly modified search page, when you enter a search for monkey, it will limit it to your scope.

Clear FAST Search Content Collection

I had a stubborn FAST Server installation that continued to return search results, even after the content source was removed from FAST!

After stumbling around, someone on the FAST forums at Microsoft suggested clearing the sp collection, but didn’t say how.

Here’s how:

On the fast server, there will be a shortcut to launch a FAST powershell prompt – open that

Enter the command

Clear-FastSearchContentCollection sp

That should clear it out – you’ll need to do full crawls on all your content sources after this is done to repopulate the index, so it’s best not to do this to a production box without understanding how long search will be down.

Also note that in FAST Search for Sharepoint, pretty much everything is stored in the SP collection – It’s my understanding that as of right now, you can only have one collection in FAST for SP.

Snippet of XSLT to create a link to the parent folder of an item in a search result

I wanted to add a link to the parent folder of an item in FAST search results.

I had found an article that said I could use the “SiteName” property.

Unfortunately, this content wasn’t from a SharePoint site, it was from a File Share.

The “SiteName” only returned \\Server\Sharename for each result, never the folder path

For example \\Server\ShareFolder1\SubFolderA\myfile.txt is where the file is

SiteName retured \\ServerShare

I wanted \\Server\Share\Folder1\SubFolderA

The following XSLT uses a few chained string commands to return the desired results

<xsl:if test="isdocument = 'True'">
   <br/>
   <a>
      <xsl:attribute name="href">
         <xsl:value-of select="substring(url,1,string-length(url) - string-length(title))"/>
      </xsl:attribute>
      <i>Link to Containing Folder</i>
   </a>
</xsl:if>