Awhile back I ran into an issue where I had some site collection backups that failed to complete.  No big deal, but this caused the locks on the site collection to remain in place, as I curiously found my administrator account with deny permissions on all sites in the site collection.  This begs the question “What other site collections could be locked?”  That becomes a real problem if you have a large number of site collections.  Who wants to check each one in Central Administration one by one?  Being the non-developer type, I turn to my trusty friend PowerShell. 

First, what are we talking about specifically?  In Central Administration, click Application Management, then under Site Collections, click Configure quotas and locks.  Choose your web application/site collection, and view it’s status:

SNAGHTML8b6ebc

Before we look at unlocking it to solve our initial problem, let’s take a quick peek at how to set a lock as things are a little different.  We have a few options. 

Setting a Lock on a Site Collection

  • STSADM
    • stsadm -o setsitelock -url <Site-collection-url> -lock <Lock-Type>
  • PowerShell
    • Set-SPSite -identity "<Site-collection-url>" –lockstate <Lock-Type>

Where Lock-Type is:

  • Unlock
  • NoAdditions
  • ReadOnly
  • NoAccess

A site lock is also set automatically when a site collection backup is run (add –nositelock on the command to prevent this).  As a side note, the fine folks at Microsoft made a goof in the help text for the Set-SPSite cmdlet (or updated the command without fixing the help text).  For the Adding Content Prevented selection, the help for the command says to use Content for the lock type.  This is wrong and the command will error.  That’s really helpful!  You should use NoAdditions.

Getting the Lock Type for a Site Collection

So I needed a way to show me the lock status of all site collections in the farm.  I searched around and couldn’t find one so I decided to write one.  If you just need to get the status of one site collection, that’s easy.  You could use STSADM:

stsadm -o getsitelock -url <Site-collection-url>

Unfortunately, there really isn’t a one-line equivalent in PowerShell to “get” locks for site collections that I know of.  If you list out the properties of the site collection object, there is no property called “Lock State” or similar.  The lock values shown in the UI are actually stored across 4 different properties in the site collection object:

  • ReadOnly
  • ReadLocked
  • WriteLocked
  • LockIssue

Let’s see how this works.  Go into the UI, set a value (or use the PowerShell or STSADM above).  Then you can see the combination of values of the settings by running the following PowerShell command:

Get-SPSite <Site-collection-url> | select ReadOnly,Readlocked,WriteLocked,LockIssue | ft –autosize

image

So now you work out the combinations of values for each “lock type”.  Here they are:

  • When UI value “Unlocked
    • ReadOnly = false
    • ReadLocked = false
    • WriteLocked = false
  • When UI value “Adding Content Prevented
    • ReadOnly = false
    • ReadLocked = false
    • WriteLocked = true
  • When UI value “Read Only
    • ReadOnly = true
    • ReadLocked = false
    • WriteLocked = true
  • When UI value “No Access
    • ReadOnly = null
    • ReadLocked = null
    • WriteLocked = null

When No Access is set, that puts an explicit Deny permission on the site collection, which prevents the values from being read.  Therefore it shows null values.  Who wants to remember all that?  How can we tie all this together and get a value for these easily?

Getting the Lock Type for All Site Collections

Now comes the fun part.  We know the value combinations, but how can we see the single UI value for all site collections?  Use this script.

   1: Add-pssnapin Microsoft.SharePoint.Powershell -ErrorAction silentlycontinue
   2: $sites = get-spsite -limit all | foreach {
   3:   write-host "Checking lock for site collection: " $_.RootWeb.Title -foregroundcolor blue
   4:     if ($_.ReadOnly -eq $false -and $_.ReadLocked -eq $false -and $_.WriteLocked -eq $false)
   5:        { write-host "The site lock value for the site collection"$_.RootWeb.Title "is:  Unlocked" -foregroundcolor Green}
   6:          if ($_.lockissue -ne $null) {
   7:          write-host "The additional text was provided for the lock: " $_.LockIssue -foregroundcolor Green}
   8:     elseif ($_.ReadOnly -eq $false -and $_.ReadLocked -eq $false -and $_.WriteLocked -eq $true)
   9:        { write-host "The site lock value for the site collection"$_.RootWeb.Title "is:  Adding Content Prevented" -foregroundcolor Green}
  10:     elseif ($_.ReadOnly -eq $true -and $_.ReadLocked -eq $false -and $_.WriteLocked -eq $true)
  11:        { write-host "The site lock value for the site collection"$_.RootWeb.Title "is:  Read-only" -foregroundcolor Green}
  12:     elseif ($_.ReadOnly -eq $null -and $_.ReadLocked -eq $null -and $_.WriteLocked -eq $null)
  13:        { write-host "The site lock value for the site collection"$_.RootWeb.Title "is:  No Access" -foregroundcolor Green}    
  14: }

What are we doing here?

  1. It reads in the list of all site collections, and passes that into a foreach loop
  2. It runs a check for the correct combination of values for each lock state for each site collection
  3. When a combination if statements = true, it write out the corresponding lock state for that site collection

The output will look like this:

image

Sweet!  I will try and work on making this into a nice table for export, but for now it gets the job done.  You could certainly extend the script with additional nesting that when it found something other than Unlocked, it would run the Set-SPSite command to undo the lock.  Enjoy!