SharePoint Administrator's that run this script usually want to answer one of the following questions:

    1. Is Anonymous Access enabled anywhere in my Site Collection.  If so, where?
    2. I want to confirm Anonymous Access is enabled  in a specific location
    3. I want to collect a record of how Anonymous Access is setup for an entire Site Collection.
   
Anonymous Access can be set at 3 different levels.


Web Application
This is configurable in Central Administrator:

AnonymousBlog1

 

Site
This is configurable within a given Site by selecting Site Actions, Site Permissions, and click the Anonymous Access button from the Ribbon:

AnonymousBlog2

 

List\Document Library
Assuming you configured Lists and Libraries option at the Site Level (above screenshot), then you can enable Anonymous Access for any given List or Document Library belonging to that site.  To do this:  access the specified list and select the following from the ribbon: 

Library\Library Permissions Button\Anonymous Access Button

AnonymousBlog4

Note:  Anonymous Access cannot be set on a specific item in a list.

 

 

Checking For Anonymous Access (Out of the Box)
At the very least, you want to check if the Web Application and Specified sites are enabled with Anonymous Access.
If you check the site level and Anonymous is set for "Lists and Libraries", then you would further inspect the desired List or Library to see if Anonymous Access is enabled (above screenshot).   

If you've been through this exercise before, your well aware this can be a cumbersome and time consuming task if you have hundreds of sites and hundreds or even thousands of lists in each site for a given Site Collection.

 

 

Checking for Anonymous Access (Automatically)
I wrote a PowerShell script to do the heavy lifting and traverse all Sites, Lists, and Libraries in a given Site Collection to check if Anonymous Access is enabled at any level.   If Anonymous Access is enabled at any level, a log file in CSV format with more information on what's enabled and where it's enabled.  

How does the script work?   Check the following scenario:

Scenario: Single Site Collection contains four  sites.

Site 1:   http://wfe:3131
Site Level:  Anonymous Access is set for Lists and Libraries
List\Library:  I configured one list and one document library with Anonymous Access

Site 2:  http://wfe:3131/SubSite
Site Level:  Anonymous Access is set as "Entire Web Site"

Note:  The other 2 sites were created off of Site 1 since it's a publishing site and inherits the settings from the root site (Site 1 - above).

Running the PowerShell Script looks like:   (Yes, I used Magenta)

AnonymousBlog3

From the screenshot above, notice Anonymous Access is Enabled so a CSV file was created which looks like:

AnonymousBlog5

Let’s discuss the columns from the above screenshot in more detail:

Column - Level:  The level indicates at what level Anonymous Access is enabled.   If Level equals "Site Level: Lists and Libraries", then we will go and check the List and Libraries to see if Anonymous Access is enabled.  As you can see, Anonymous Access is Enabled and configured on two lists.  

Column - URL:  The URL where Anonymous is enabled.  If the level is Web Application, it will only put the name of the Web Application where it's enabled in the URL field.


Configured List\Lib:  This column will flag yes if Anonymous Access is enabled and configured for a given List\Library.  What I mean by configured is the view items check box is checked for Anonymous Access. (See screenshot under List\Document Level above.)

 

Note:  This PowerShell script is tested only on SharePoint 2010

Instructions for running the script:

1. Copy the below script and save it in notepad
2. Save it with a anyfilename.ps1 extension
3. To run, copy the file to a SharePoint Server
4. Select Start\Microsoft SharePoint 2010 Products\SharePoint 2010 Management Shell
5. Browse to directory holding the copied script file
6. Run the script: .\anyfilename.ps1 (assuming anyfilename is the name of the file)


<# ==============================================================
//
// Microsoft provides programming examples for illustration only,
// without warranty either expressed or implied, including, but not
// limited to, the implied warranties of merchantability and/or
// fitness for a particular purpose.
//
// This sample assumes that you are familiar with the programming
// language being demonstrated and the tools used to create and debug
// procedures. Microsoft support professionals can help explain the
// functionality of a particular procedure, but they will not modify
// these examples to provide added functionality or construct
// procedures to meet your specific needs. If you have limited
// programming experience, you may want to contact a Microsoft
// Certified Partner or the Microsoft fee-based consulting line at
// (800) 936-5200.
//
// For more information about Microsoft Certified Partners, please
// visit the following Microsoft Web site:
//
https://partner.microsoft.com/global/30000104
//
// Author: Russ Maxwell (russmax@microsoft.com)
//
// ---------------------------------------------------------- #>

[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

Start-SPAssignment -Global

######################################
##Creating and Returning a DataTable##
######################################
function createDT()
{
    ###Creating a new DataTable###
    $tempTable = New-Object System.Data.DataTable
   
    ##Creating Columns for DataTable##
    $col1 = New-Object System.Data.DataColumn("Anonymous Access")
    $col2 = New-Object System.Data.DataColumn("Level")
    $col3 = New-Object System.Data.DataColumn("URL")
    $col4 = New-Object System.Data.DataColumn("Configured List\Lib")
       
    ###Adding Columns for DataTable###
    $tempTable.columns.Add($col1)
    $tempTable.columns.Add($col2)
    $tempTable.columns.Add($col3)
    $tempTable.columns.Add($col4)
   
    return ,$tempTable
}

#####################################
##Check WebApp for Anonymous Access##
#####################################
function checkwebappAnon()
{
    $webAnon = $site.IISAllowsAnonymous.tostring()
    $tempanonCheck = 0;   
    if ($webAnon -eq "true")
    {
        #Add a row to DataTable
        $row = $dTable.NewRow()
        $row["Anonymous Access"] = "Enabled"
        $row["Level"] = "WebApplication"
        $row["URL"] = $site.WebApplication.Name
        $dTable.rows.Add($row)
    }
   
}


######################################
##Check the Site for Anonymous Access#
######################################
function checksiteAnon()
{
    $tempanonCheck = 0
    $checkWeb = $web.AllowAnonymousAccess.tostring()
    $checkWebState = $web.AnonymousState.tostring()
    $webMask = $web.AnonymousPermMask64.tostring()
    Write-Host
    Write-Host "Checking how Anonymous is set up on site: " $web.Url -ForegroundColor Magenta
   
    if(($checkWeb -eq "True") -and ($checkWebState -eq "On"))
    {   
        #Add a row to DataTable#
        $row = $dTable.NewRow()
        $row["Anonymous Access"] = "Enabled"
        $row["Level"] = "Site Level: Entire WebSite"
        $row["URL"] = $web.Url.tostring()
        $dTable.rows.Add($row)
        $tempResult = 1
    }
   
    elseif(($checkWeb -eq "False") -and ($checkWebState -eq "Enabled") -and ($webMask -eq "Open"))
    {
        #Add a row to DataTable#
        $row = $dTable.NewRow()
        $row["Anonymous Access"] = "Enabled"
        $row["Level"] = "Site Level: Lists and Libraries"
        $row["URL"] = $web.Url.tostring()
        $dTable.rows.Add($row)
        $tempResult = 2
    }
   
    else
    {
        $tempResult = 3
    }
   
    return $tempResult
}


############################################
##Check List\Libraries for Anonymous Access#
############################################
function checklistAnon()
{
  ###Checking each list and library for anonymous access###
  $lists = $web.lists
  $count1 = $lists.count
  $hasAnon = 0
 
  Write-Host "Checking " $lists.count " lists\libaries for Anonymous Access" -ForegroundColor Magenta
 
  ###Setting String Vars###
  $defMask1 = "OpenWeb"
  $defMask2 = "EmptyMask"
  $defTax = "TaxonomyHiddenList"
 
  foreach($list in $lists)
  {
    $listUrl = $web.url + "/" + $list.Title
      $listMask = $list.AnonymousPermMask.tostring()
    $tax = $list.Title.ToString()
   
    ##Checking List eventhough Anonymous Access was disabled at SPWeb Level##
    if(($webResult -eq '3') -and ($defTax.CompareTo($tax) -ne '0'))
    {
          if($listMask.CompareTo($defMask2) -ne '0')
        {
          if($listMask.CompareTo($defMask1) -eq '0')
             {
            #Anonymous Access is Enabled but not Configured on list\library#
               $row = $dTable.NewRow()
            $row["Anonymous Access"] = "Enabled"
            $row["Level"] = "List\Library"
            $row["URL"] = $listUrl
            $row["Configured List\Lib"] = "No"
            $dTable.rows.Add($row)
            $hasAnon++
           }
          else
             {
           #Anonymous Access Enabled and Configured on list\library#
               $row = $dTable.NewRow()
            $row["Anonymous Access"] = "Enabled"
            $row["Level"] = "List\Library"
            $row["URL"] = $listUrl
            $row["Configured List\Lib"] = "Yes"
            $dTable.rows.Add($row)
               $hasAnon++
          }
        }
    }
       
     elseif(($webResult -eq '2') -and ($defTax.CompareTo($tax) -ne '0'))
        {
          if(($listMask.CompareTo($defMask2) -ne '0') -and ($listMask.CompareTo($defMask1) -ne '0'))
        {
           #Anonymous Access Enabled and Configured on list\library#
               $row = $dTable.NewRow()
            $row["Anonymous Access"] = "Enabled"
            $row["Level"] = "List\Library"
            $row["URL"] = $listURL
            $row["Configured List\Lib"] = "Yes"
            $dTable.rows.Add($row)
            $hasAnon++
        }
      }
    $count1--
    if($count1 % '10' -eq '0')
    {
     Write-Host "Total # of lists\libraries left to check: " $count1 -ForegroundColor DarkYellow
    }
  }
  Write-Host
  Write-Host "Total # of lists\libraries with Anonymous Access Enabled: " $hasAnon -ForegroundColor Cyan
}
           


########################
###Script Starts Here###
########################
$output = Read-Host "Enter a location for the output file (For Example: c:\logs\)"
$filename = Read-Host "Enter a filename"
$url = Read-Host "Please enter the URL of desired site collection and press enter"

###Getting a new DataTable###
[System.Data.DataTable]$dTable = createDT

###Getting Site Collection###
$site = Get-SPSite $url

###Checking if WebApp has Anonymous set###
checkwebappAnon

###Gathering web collection###
$webs = $site.Allwebs
$count = $webs.Count
Write-Host "Checking for Anonymous Access on " $count " Sites" -ForegroundColor Magenta

foreach($web in $webs)
{   
    $webResult = 0
    ###calling function to check anonymons on spweb###
    $webResult = checksiteAnon
   
    if(($webResult -eq '2') -or ($webResult -eq '3'))
    {
        Write-Host "Checking for Anonymous Access on List and Libraries" -ForegroundColor Magenta
        ###calling function to check anonymons on lists and libs###
        checklistAnon
    }
   
    $count--
   
    if($count -ne '0')
    {
      Write-Host
      Write-Host "Total # of sites left to check: " $count -ForegroundColor DarkYellow
    }
   
    else{Write-Host "Operation Completed" -ForegroundColor DarkYellow}
}

if($dTable -ne $null)
{
    $name = $output + "\" + $filename + ".csv"
    $dTable | Export-Csv $name -NoTypeInformation
    Write-Host "Anonymous Access was detected" -ForegroundColor Green
    Write-Host "Log File Created: " $name
}
else
{
    Write-Host "Anonymous Access is Disabled for the entire Site Collection" -ForegroundColor Green
            Write-Host "No Log File Created" -ForegroundColor Green
}

Write-Host "Script Complete"

Stop-SPAssignment -Global

 

Thanks!

Russ Maxwell, MSFT   Black Sheep