Category Archives: SharePoint

Sharing service apps between farms.

See http://technet.microsoft.com/en-us/magazine/hh528474.aspx Section 8

Run this PS on both farms and exchange certs:

$rootCert = (Get-SPCertificateAuthority).RootCertificate
$rootCert.Export(“Cert”) | Set-Content D:\Certs\ConsumingFarmRoot.cer -Encoding byte
$stsCert = (Get-SPSecurityTokenServiceConfig).LocalLoginProvider.SigningCertificate
$stsCert.Export(“Cert”) | Set-Content D:\Certs\ConsumingFarmSTS.cer -Encoding byte

Then you can use Central admin (Security->Manage Trusts) to enter these in.

From the Consuming Farm, run get-farm | Select ID to get the ID of the consuming farm.

$farmID = <ID from your farm>
$security = Get-SPTopologyServiceApplication | Get-SPServiceApplicationSecurity
$claimProvider = (Get-SPClaimProvider System).ClaimProvider
$principal = New-SPClaimsPrincipal -ClaimType "http://schemas.microsoft.com/sharepoint/2009/08/claims/farmid" -ClaimProvider $claimProvider -ClaimValue $farmID
Grant-SPObjectSecurity -Identity $security -Principal $principal -Rights "Full Control"
Get-SPTopologyServiceApplication | Set-SPServiceApplicationSecurity -ObjectSecurity $security

Using Powershell to get a list of user IDs from AD

One of my network admin friends needed an easy way to provide some users with a list of names vs AD account names.

In many organizations, this is easy to guess, for example if my name is  Jack Basement, my id might be jbasement, but in this case, it wasn’t that easy so we needed to go to AD.

There are AD cmdlets, but they are not in powershell by default.

If you have the Remote Server Administration Tools for Windows 7 installed, then you’ll find a link to “Active Directory Module for Windows PowerShell” in your administrator tools menu.

 

Using that we can easily get a list of the users needed and select just the columns we want

for example

Get-ADUser -identity domain\user #gets info on that user
 
Get-ADUser -filter {name - like "jack*"} #returns all the people named Jack

We can combine that with the select statement such as this:

Get-ADUser -filter {name - like "jack*"} | Select name, SamAccountname

Which gives us a nice list

and

Get-ADUser -filter {name - like "jack*"} | Select name, SamAccountname | convertto-csv

which will out put it as a comma separated CSV (Perfect for importing into Excel)

and

Get-ADUser -filter {name - like "jack*"} | Select name, SamAccountname | convertto-csv | out-file userlist.txt

which outputs the same thing, but to a file.

 

Now one neat trick, is that often you want to output all the users of a group in AD (technically this is called an Organizational Unit, or OU)

There is an LDAP filter type we can use for this

Whats cool here is that LDAP filters are sometimes a pain to get “just right” so we can cheat:

We can use the distinguished name of a known user in that group and grab the group from that

so for example

Get-ADUser -identity domain\bJack

results in a bunch of output, the first field is the distingished name and we can copy and paste that for our next command

Get-ADUser -filter * -SearchBase = "OU=mygroup,DC=basementjack,DC=com"

this outputs all the users in that OU

again we can chain for flexibility

Get-ADUser -filter * -SearchBase = "OU=mygroup,DC=basementjack,DC=com" select name, SamAccountName | sort-object name

 

Lastly don’t forget get-help

Get-Help Get-ADUser -examples

shows a few good examples.
 

 

Cleaning up Newsgator controls from SharePoint

On our farm, we have multiple URLS, multiple site collections etc.

One of them has a social add in called newsgator social sites.

I kept seeing errors in the ULS logs of other sites saying things like:

Failed to create a custom control from assembly ‘NewsGator.NewsManager.Web’ .. The type is not registered as safe.

I know from experience that this means the control isn’t listed in the web.config for the given site, nor should it be – I don’t have, nor want newsgator to have anything to do with the site in question.

I also know that the errors aren’t really hurting anything, but if nothing else they are making the ULS logs a little bigger and honestly, I don’t want a farm that has known errors in it.

So I set out to understand where they were coming from and how to safely get rid of them.

Finding these in the ULS logs

They are all over our ULS logs, but it’s nice to have  a quick way to validate if they are still there so I did a search with the windows Findstr command:

findstr /C:"is not allowed for web" *.log

 

The first thing I wanted to do was see if there was an obvious, easy fix – ie from site settings, site features, or site collection features, is there a newsgator feature that’s enabled that I can just turn off?

I tried this and no, there wasn’t

The solution turned out to be painfully simple.

In the ULS logs, there were entries like this:

Failed to create a custom control 'CustomMenu_NewsStreamAdmin', feature 'NewsGator.NewsManager_Actions' (id:16c89384-881d-44aa-a6f5-f66301596851) using attributes (ControlSrc='', ControlAssembly='NewsGator.NewsManager.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1b9791f4e4509c7', ControlClass='NewsGator.NewsManager.Web.NewsStreamAdminActions': System.ArgumentException: The control with assembly name 'NewsGator.NewsManager.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1b9791f4e4509c7' class name 'NewsGator.NewsManager.Web.NewsStreamAdminActions' is not allowed for web
at URL 'https://nonnewsgatorsite.mydomain.com'. The type is not registered as safe.

The error above is always paired with another less descriptive error – but the error above turns out to have all the information we need – the id. (In this case id 16c89384-881d-44aa-a6f5-f66301596851)

In powershell, Get-SPFeature will list all the features on the farm – in my case it showed the above ID.

Now, given that newsgator is legitimately installed on our farm and on ONE web application (URL) I didn’t want to remove it from the farm!

What was helpful was the command:

get-spfeature  -webapplication https://myurl.mydomain.com

This showed that the feature was associated with that web application and it also showed that it was webapplication scoped.

So next I used the command

Disable-SPFeature -Identity 16c89384-881d-44aa-a6f5-f66301596851 -URL https://myurl.mydomain.com

I had to do this for a few different features – pulling the ID from the ULS logs and running the disable command- While I’m sure it potentially could be automated, I preferred handling it “Hands On” doing them one at a time and confirming my SharePoint sites still worked as expected.

After that, the errors in the ULS log stopped for that site, and get-spfeature -webapplication https://myurl.mydomain.com no longer showed that feature.

It was a great feeling to get these nagging recurring ULS entries to stop!
 

 

 

Remove Stuck Item from FAST search

I manage a fast installation with a few million documents.

Something went wrong and FAST is returning results for files that no longer exist.

The “Normal” way to fix this is to do another crawl of the content source – In this case, it did not work.

The “best” way to fix this is to reset the index and re-crawl all the content.

Unfortunately, because of the size of our fast install, this is not practical – it takes over a week to index everything.

In other words, fixing this problem the “right” way will also bring down fast for at least a week for some content – not good.

On a support call with Microsoft – they told me of a quick way to remove individual results – it’s not quite as effective as a full index reset, but it has it’s place – for example – say that a confidential document got crawled, and the summary is showing up in search results. You’d want to get that out of the way right away – this approach can be good for that.

First download the free tool FS4SP Query Logger by Mikael Svenson – I found version 3 on codeplex with a quick internet search.
Run this on the fast server and click the start logging button, then go do your search using whatever search page is returning the bad results.
Once you see your search term show up on the upper left, look at the result XML and find the result.
you’ll want to grab the value of the “contentid” field – it will look something like this:

 <FIELD NAME="contentid">ssic://SomeNumberHere</FIELD>

Be sure the Area of XML you are looking at matches the search result you are trying to eliminate!

now, also on the fast server, open a FAST powershell command.
enter the command:
DOCPUSH -c sp -U -d ssic://YourNumberHere

Just like that, your search result should stop appearing in search results.

—————————————————————————–

As a side note, while we were looking at some things, we used a clever powershell command to search multiple directories for some text

 select-string <longIDnumberrepresentingwhatwewerelookingfor> [0-9]\*[0-9]\index_data\urlmap_sorted.txt

Select-string is like Grep in Unix or Findstr in windows – it looks for strings.
what was neat here was the Regular expression for the path it limited the search to just a few key directories. – ie
\2\232131231231\index_data\urlmap_sorted.txt
and
\3\4223453\index_data\urlmap_sorted.txt

A few quick commands to tell if FAST search is working

This post applies to users of Microsoft FAST search for SharePoint 2010.

Here are a few commands you can run on the FAST server to see if it’s healthy and also to get a feel if the back end is working in co-operation with the front end crawlers.

nctrl status will show if all the fast services are started and running.

indexerinfo status dumps some xml -the key piece here is the partitions – if you run indexerinfo status a few times, you should see some movement on these (percents will change)

Corrupt WMI fix

My good friend Jeremy shared this simple WMI fix.

Winmgmt/?

Winmgmt /backup filename
Winmgmt /verifyrepository
if that fails, try
Winmgmt /salvagerepository
[if that fails, as a last resort:]
[Winmgmt /resetrepository]

SharePoint 2010 Session State Service

Sharepoint has two state service commands that threw me for a loop

first there is get-SPSessionStateService
then there is get-SPStateServiceApplication

Here’s an article from MSDN that talks about the differences
http://blogs.msdn.com/b/markarend/archive/2010/05/27/using-session-state-in-sharepoint-2010.aspx

In Central Admin->Manage Service Applications these show up as follows:

Get-SPSessionStateService -> shows as type “SharePoint Server ASP.NET Session State Service”
Get-SPStateServiceApplication-> shows as type “State Service” and hopfully “State Service Proxy”

While you can easily delete both from Central admin, you can create neither of them from the service applications page.

Creating a new SPStateServiceApplication (and proxy) is relatively easy: 3 lines of powershell:

# from  http://technet.microsoft.com/en-us/library/ee704548.aspx
$serviceApp = New-SPStateServiceApplication -Name ""
New-SPStateServiceDatabase -Name "" -ServiceApplication $serviceApp
New-SPStateServiceApplicationProxy -Name "" -ServiceApplication $serviceApp -DefaultProxyGroup

Creating a new SPSessionStateService, on the other hand is a little more involved…

How do I know?

I’m glad you asked….

I ran into an issue where an access report would not display because “session state is not turned on” it didn’t say which one, and through some trial and error, I now understand it was likely looking for the service returned by get-SPSessionStateService.

For me that returned a blank line with no database entry so I thought I’d be best to delete it and recreate it from scratch.

I was wrong.

While deleting and recreating the SPStateServiceApplication is easy, the SPSessionStateService was not easily done in SP2010 with the included powershell commands.

Fortunately I found this article: http://ikarstein.wordpress.com/2010/12/14/error-while-enabling-session-state-service-on-sharepoint-2010/ Which had the steps to recreate the service manually.

I enabled the ASP.Net state windows service, then followed the article above, stopping about half way through, before the provisioning part.

To Provision it, I used Enable-SPSessionStateService -DefaultProvision

Get-SPSessionStateService now returns a complete row, with a database server, and DB name, and ID and best of all Enabled = True

So to summarize my problem,
MS Access services reports needed “SPSessionStateService” which also uses the windows service “ASP.Net State Service”

In troubleshooting, I wasn’t aware of the difference between states so I deleted the “wrong” one in an attempt to reset it.
A little digging and I now have a better understanding of the issue and of the two different state services.

I hope this helps!

Simple Powershell script connect to servers as a different user

A common practice in IT is to have a separate admin account to connect to servers.

Often in day to day administration of SharePoint servers, it’s necessary to connect to the c$ or d$ share to look at a log file, copy an installer, etc…

You can do this from windows, and it will usually prompt you for credentials, but that can be a pain if you regularly connect to a bunch of machines that need different credentials.

This script will prompt you for a password, then use that password along with a pre-defined user account and server list to connect you to each server in advance.

function mapdrives
{
   #Update these variables for your environment:
   $account = "domain\useraccout"
   $serverlist = @("Server1", "Server2", "Server3", "Etc...")
 
   $SecurePwd = read-host -assecurestring "Enter password for $account"
   $pwd = ConvertTo-PlainText($SecurePwd)
 
   foreach ($Server in $ServerList)
     {
        net use \\$server /d
        net use \\$Server /user:$account $pwd
     }
   write-host "Done mapping drives"  
}
 
# This function came from Oisin Grehan, MVP 
# via:  http://www.vistax64.com/powershell/159190-read-host-assecurestring-problem.html
Function ConvertTo-PlainText( [security.securestring]$secure ) 
{
   $marshal = [Runtime.InteropServices.Marshal]
   $marshal::PtrToStringAuto( $marshal::SecureStringToBSTR($secure) )
}
 
mapdrives

Simple PowerShell to Enable BLOB Cache on multiple SharePoint sites.

I needed to enable / configure BLOB caching on multiple sharepoint sites.

This is done by editing the web.config of each SharePoint site, on each SharePoint server.

I wrote this down and dirty script so I would not need to edit all the web.config’s by hand (I had about 20 web.configs to touch)

Note that since its just editing the web.config, we don’t need to run this in a SharePoint shell – I ran it from an ordinary PowerShell command prompt on my workstation.

The script:

 
Echo "Run this script under an admin account with rights to the servers being hit"
 
$dir = "\\Server\c$\inetpub\wwwroot\wss\VirtualDirectories"
$currentDate = (get-date).tostring("mm_dd_yyyy-hh_mm_ss")
# loop through each subdirectory to find each sharepoint site.
foreach ($subdir in dir $dir)
{
   #  Here In my case, all my SharePoint sites had mydomain.com as part of the folder names,
   #  So the contains statement was an easy way to only touch the web.config's of actual SharePoint sites
   #  while leaving alone central admin and other non-SharePoint websites IIS had.
 
   if($subdir.Name.Contains("mydomain.com"))
   {
        $path = $dir + "\" + $subdir.name + "\Web.config"
        echo $path
 
        $backup = $path + "_$currentDate.bak"
        $xml = New-Object XML
        $xml.Load($path)
        $xml.Save($backup)
        $element = $xml.configuration.SharePoint.BlobCache
        echo $element
        $element.location = "X:\BlobCache\14"
        $element.enabled = "true"
        $element.maxSize = "5"
        echo $element
        $xml.Save($path) 
   }
}

Sharepoint Search: Fix for Office 2007 titles not showing up properly in search results

If search results from SharePoint (not Fast) search are not showing the right title, and instead are showing a few words from the content of the document, theres a registry setting you can set to fix that.

The registry setting will be found on any machine running sharepoint search (Central admin-> Manage servers in this farm will show you which boxes have this role)

These powershell commands will show what the value is currently (or an error if its not found – a good sign that you’re on the wrong machine!)

  $RegKey ="\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager\"
  Cd hklm:\$RegKey 
  $key = "EnableLastModifiedOverride"
  Get-ItemProperty -path. -name $key | Select $key
  $key = "EnableOptimisticTitleOverride" 
  Get-ItemProperty -path. -name $key | Select $key

(you can see the registry entries in the code, you can edit these manually if you’d like)

This script changes the values to 0, fixing the office 2007 issue in SP2010 search:

$RegKey ="HKLM:\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager\"
set-ItemProperty -path $RegKey -name EnableLastModifiedOverride  -value 0
set-ItemProperty -path $RegKey -name EnableOptimisticTitleOverride -value 0

After you’re done with the above, restart the Sharepoint search service and do a full crawl – it is not necessary to reset the index.

Tips for installing the SharePoint 2013 preview

I recently ran into a few issues installing SharePoint 2013 that can easily be avoided by installing in a given order.

Firstly for the quick install, this seemed problem free:
1) Build a new windows 2008R2 SP1 Standard edition VM
(I gave mine 3GB of ram)
1a) I joined it to a domain (I did not build the VM as a domain controller)
2) be sure you have an internet connection
3) install sharepoint 2013 preview, choose the standdalone version. (the one that will install the free version of SQL2008 R2
This seemed to work fine.

The trouble came when I tried to install it with the latest version of SQL
Here’s what I did:
(Warning: this fails!)
1) Build a new windows 2008 R2 SP1 standard edition VM
2) Install the RTM version of SQL2012 – it needed .net 4 and IIS
(I think this is where things went wrong, SQL2012 configued IIS with .net 4, not 4.5)
3) tried to run sharepoint install – it failed on the pre-reqs – it seems in my case it could not determine if IIS was setup with .net properly. I even tried the old aspnet_regiis -i command to force it but still the pre-req installer would stop at that point.

I must admin, I was in a hurry to see the new SharePoint so I didn’t take additional troubleshooting steps (I could have downloaded the rest of the prereq’s manually and tried the SharePoint install, but I did not)

Instead I figured I’d try a different approach – first I tried the install I listed at the top of this article – that worked like a champ, but I wanted the SQL2012 based install.

Next I did this:
1) new VM with Windows Server 2008 R2 SP1
2) Run the pre-req installer from the sharepoint 2013 install iso.
(this configured IIS, and ASP.net 4.5)
3) Do NOT run the SharePoint installer
4) Install SQL 2012 – since IIS and ASP.net 4.5 are already installed it should leave them alone.
5) Come back and do the SharePoint install
It’s installing now – I’ll post the results when it’s done.

Setting the default 3 groups in SharePoint from PowerShell

I ran into this today –

Tagging on /_Layouts/permsetup.aspx to a site’s url brings up a list of the 3 standard groups for a site:

  • one for visitors
  • one for members
  • one for owners

Today when I tried to change one through the GUI, It threw an error.
The ULS logs were a mess, and not wanting to loose a day opening a case with MS I tried PowerShell.

The solution is fairly easy.
Grab a pointer to the web in question with:

$web = get-spweb http://www.yoururl.com/sites/MainSite/subsite

You can see all the web’s properties with:

$web | fl

The 3 that we’re interested in are:

  • AssociatedVisitorsGroup
  • AssociatedMembersGroup
  • AssociatedOwnersGroup

We can set these with PowerShell easily:

$web.AssociatedVisitorsGroup = $web.SiteGroups["Nameofthegroup"]
$web.update()

A list of Sharepoint Virtual File paths

This will start out to be an incomplete list, but should grow with time.
These are links that are sometimes handy to have when the UI doesn’t display them.

 

 

 

Path and file explanation
_layouts/viewlists.aspx Same as site actions->View all content
_catalogs/masterpage/Forms/AllItems.aspx View master pages for this site collection.
_layouts/changesitemasterpage.aspx Changes the master page for the site collection (must be called from the site collection url, not a subweb url)
_layouts/permsetup.aspx assings the 3 magic groups to a sharepoint web called from a web or subweb url
_catalogs/lt/Forms/AllItems.aspx List template Gallery
_catalogs/solutions/Forms/AllItems.aspx Site Template (/Solutions) Gallery
_layouts/settings.aspx Site Settings
_layouts/user.aspx A list of all groups and users in a given Site
_layouts/groups.aspx A list of all groups in a given Site Collection
_layouts/AreaTemplateSettings.aspx This screen chooses what site templates are available when creating a new site in a given site collection
_layouts/quiklnch.aspx An almost odd list view of the quick launch items –
but not the one you get to from site settings.
This is linked to from the “getting started” web part.
_layouts/qlreord.aspx Same as above – this one lets you sort the quick launch items.
_layouts/AdminRecycleBin.aspx End User Recycle Bin.
_layouts/AdminRecycleBin.aspx?View=2 Deleted from End User Recycle Bin.
Pagename.aspx?contents=1 View the web parts on a page – good for times when a web part keeps a page from rendering in normal mode.

Get all sharepoint users users in the farm with Powershell to a CSV file

This is a script that gets each sharepoint site on the farm, enumerates all the site collections and webs and dumps them to the screen as well as a CSV file.

The Current date and time is always appended to the file name so you don’t have to worry about wiping out previous results.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#getalluserseverywhere
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
 
$timestamp = get-date -format "yyyyMMdd_hhmmtt"
$filenameStart = "AllFARMUsers"
$logfile = ("{0}{1}.csv" -f $filenamestart, $timestamp)
 
$header = "type,user,group,weburl,webname"
$header | out-file -FilePath $logfile
 
$iissitelist = get-spwebapplication 
foreach($onesite in $iissitelist)
{
 
	foreach ($SiteCollection in $onesite.sites)
	{
		write-host $SiteCollection -foregroundcolor Blue	
		foreach ($web in $SiteCollection.Allwebs)
		{ 
			 write-host "    " $web.url $web.name "users:" -foregroundcolor yellow
			 # Write-host "        " $web.users | select name 
			 foreach ($userw in $web.users)
			 {
				#if ($userw -like "domain\*")
				#{
					write-host "        " $userw -foregroundcolor white
					#$msg = ("{0},{1} user:{2}" -f $web.url,$web.name, $userw)
					$msg = ("RootUser,{0},-,{1},{2}" -f $userw, $web.url,$web.name) 
					$msg | out-file -FilePath $logfile  -append
				#  }
			   }
 
 
			 foreach ($group in $web.Groups)
			{
						Write-host "        " $web.url $group.name: -foregroundcolor green
				 foreach ($user in $group.users)
				 { 
					# if ($user -like "Domain\*")
					 #{   
						  Write-host "            " $user -foregroundcolor white
						  #$msg = ("{0},{1},group:{2}, user:{3}" -f $web.url, $web.name, $group, $user)
						  $msg = ("GroupUser,{0},{1},{2},{3}" -f $user, $group, $web.url, $web.name)
						  $msg | out-file -FilePath $logfile  -append
					 #}
				 }
			}	
			$web.Dispose()
		}
 
	}
}

Sharepoint Powershell to add a user from a trusted domain to sharepoint

Our sharepoint farm was in Domain A and we wanted to grant rights to a group in Domain B.
It worked fine from the GUI but powershell add-spuser or new-spuser failed – both stating the user ID we were adding was no good.
Specifically this was for Mysites – we had thousands of them so doing it by hand wasn’t an option.

1
2
3
4
5
6
7
8
$app = Get-SPWebApplication -Identity https://www.siteInDomainA.com
foreach($site in $app.Sites)
{
    write-host "Updating $site"
    $web = $site.RootWeb
    $web.AllUsers.Add("DomainB\Domain Users", [System.String]::Empty, "Domain Users", [System.String]::Empty)
    Set-SPUser -Identity 'DomainB\Domain Users' -Web $web.Url -AddPermissionLevel 'Read'
}

Remove a stuck timer job in SharePoint using Powershell

I recently had a stuck timer job in our sharepoint farm.
It seemed like an easy thing for Powershell, but it turned out to be one step more complicated – I’m not sure why, but here’s the solution I used – thanks to Todd from the Vendor I was working on for providing the fix!

We can use the Cmdlet get-SPTimerJob to see all timerjobs in our sharepoint farm.

If we add a nice little where clause, we can limit the list to a single item:

Get-SPTimerJob | where {$_.name -like "Name of your stuck job"}

Normally I’ve been able to assign the results to a variable

ie like this:

$badjob = Get-SPTimerJob | where {$_.name -like "Name of your stuck job"}

Which works.
What didn’t work however was this:

$badjob.delete()

For some reason, I got an error that there was no delete method.
Weird.

So instead:

Get-SPTimerJob | where {$_.name -like "Name of your stuck job"} |fl
# I then read the ID from the output of the above (note I added | fl at the end) 
# and I copied and pasted it into this command:
$badjobTake2 = Get-SPTimerJob -ID (pasted the ID here)
$badjobTake2.Delete()  #this worked

I’m not sure what the difference is, maybe I even fat fingered it the first time..
but that’s how it got resolved.

Enable Versions on every SharePoint Site with PowerShell (updated with logging)

The Script below will list the version status of every site in your farm.
Note that as the script is below, it only reports, you’ll need to uncomment 3 lines if you want it to make the changes.

It’s a good idea to run the script once or twice before you do that, so you have a log of what settings were.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
 
$timestamp = get-date -format "yyyMMdd_hhmmtt"
$filenameprefix = "VersionScriptoutput"
$logfile = ("{0}_{1}.csv" -f $filenameprefix, $timestamp)
 
$header = "ListURL,Enabled"
$header | out-file -filepath $logfile
 
# tip - the script as is will pull every sharepoint site (at the IIS level) in your farm.
# if you want to filter this to a single IIS site,
# remove the # from the middle of the next line and enter your site's url
 
$iissitelist = get-spwebapplication # | where {$_.url -eq "https://www.yoursite.com/"}
foreach ($iissite in $iissitelist)
{
	foreach ($SiteCollection in $iissite.sites)
	{
		write-host $SiteCollection -foregroundcolor Blue
		foreach ($oneweb in $SiteCollection.allwebs)
		{
		   write-host  $iissite.url $oneweb -foregroundcolor Green
		   #now this is is where we look at the lists
		   $lists = $oneweb.lists
		   foreach ($list in $lists)
		   {
			  if($list.EnableVersioning -eq $false)
			  {
				  write-host  $iissite.url $oneweb"/"$list"/ is a not using versions" -foregroundcolor yellow
				  $msg = ("{0}/{1},false" -f  $oneweb.url, $list.rootfolder)	
			           $msg | out-file -filepath $logfile -append
                                       # note!
                                       # if you actually want to make the changes, uncomment the next 3 lines!
				  #$list.Enableversioning = $true
				  #$List.MajorVersionLimit = 3
				  #$list.update()
			  }
			  else
			  {
				  Write-host  $iissite.url $oneweb"/"$list"/ has versions enabled! "
				  $msg = ("{0}/{1},true" -f  $oneweb.url,$list.rootfolder)				  
                                       $msg | out-file -filepath $logfile -append
			  }
		   } 
		}
	}
}

Powershell to enable Versioning for every list and library in a given sharepoint site

Update – A newer version of this script exists here- I’ve left this one here for search results, and because it’s scoped at the web level, whereas the new one is scoped at the IIS level.

This script will enable Versioning for every list and document library in a given sharepoint site.

I’d originally written it to just do document libraries, but changed my mind – things like announcements and calendars are lists, and they are equally important to protect. Same with some of the default libraries like “Site Assets”

Note that if the script sees that versioning is already enabled, it tells you – so no harm running the script more than once.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
$web = get-spweb "http://www.yoursharepointurl.com/sites/yoursite/"
$lists = $web.lists
foreach ($list in $lists)
{
    if($list.EnableVersioning -eq $false)
    {
         write-host $list.title "is a not using versions"
         $list.Enableversioning = $true
         $List.MajorVersionLimit = 5
         $list.update()
    }
    else
    {
         Write-host $list.title " is set for up to " $list.MajorVersionLimit "previous versions"
    }
}

PowerShell to activate a SharePoint 2010 feature on every site collection in a web app

I recently was given a WSP to add to our farm.

In this case after the WSP was installed and deployed we needed to activate the feature at the site collection level.
Thats usually easy enough to do through the UI, but in this particular case we had a web application which had over a dozen site collections.

ie:

  • http://jack.com
  • http://jack.com/blog
  • http://jack.com/marketing
  • 10 more like the above…

Activating it at http://jack.com from the UI was fine, but when the user navigated to http://jack.com/blog they were stumbling onto another site collection, and the feature wasn’t activated there.

To activate it on every Site collection meant that I’d have to a) know what each site collection was, and b) visit that site, and activate the feature.

Too much work.

What was needed was a simple script that would loop though each site collection, enabling the feature on each one.

The script below is a result of that need…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
 # this script enables a feature on every site collection on a given web app
 
 Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
 $webs =  get-spsite -webapplication "http://www.yoursharepointURL.com"
 $feature = "YourFeatureName" #this might not be what you expect it to be, best to do get-spfeature | Select displayname
 
  Foreach ($oneweb in $webs)
  {
    write-host $oneweb
    $siteFeature = get-spfeature -site $oneweb | Where {$_.displayname -eq $feature}
    if ($siteFeature -eq $null)
    {
      Write-Host "Activating Site level Features at $oneweb" -foregroundcolor Yellow
      Enable-SPFeature -Identity $Feature -URL $oneweb.URL -Confirm:$False
    }
    else
    {
      Write-Host "Feature $feature is already activated on $oneweb" -foregroundcolor green
    }
  }

If you look at the simple logic, you’ll see you can run it more than once – and the second time you run it, it should display an all green list indicating that all the site collections already have the feature activated.

Sharepoint 2010 ULS logs – How to keep them in SQL

This is another “Wow that was easy!” SharePoint items…

Open Central Admin
Go to the Monitoring section, then under “Timer Jobs”, select “Review job definitions”

There’s a timer job called “Diagnostic Data Provider: Trace Log”

It’s disabled by default, enable it and it will create new tables and a view on your logging database. (I think by default this is named WSS_Logging)
Leave it enabled (mine is set to run every 10 minutes)

Open SQL server Management studio and connect to your sharepoint DB server.
expand the WSS_Logging DB
Expand Views
Look for the new view called “ULSTraceLog”

I usually right click on the view name and “Select Top 1000 Rows”
Then from there I can add a where clause to the query thats on screen,
most often it’s
WHERE CorrelationID = ‘abcd-efg-hijk-lmnop-qrstuv’

Another tip- in the results (which on my system default to the “grid” view),
Right Click, Select All, then
Right Click, Copy with headers
you can then paste this into Excel and it’s pretty readable if you need to email it to someone.

As a side note, I’ve enabled this on a handful of farms and it seems to auto trim the DB sizes – so you don’t need to worry about the DB filling up over time.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# set site collection owner for all sites...
# 1-2012
Add-PSSnapin Microsoft.SharePoint.PowerShell
 
# $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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 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 = @("DOMAIN\USERID" , "DOMAIN\USERID2")
$AccountList = @("domain\tom", "domain\dick", "domain\harry")
 
# $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