Get SharePoint Site Owner and/or Site Admin

One of the things you might have to do as an admin in a large organization is to find out if a particular user is a SharePoint Site Owner and Admin. I had to do this when a long time SharePoint developer left the company.

They are not the same thing, no matter what you may read.
You can find a discusion on the difference here:

http://techtrainingnotes.blogspot.com/2008/03/sharepoint-site-administrator-vs-site.html

This script will sort through all the owners and members of the site admin group on a given server. It will locate your user if they are an Owner or an admin on any SharePoint site on that server.

It uses the SharePoint snapin and at least where I work, I need to run it as the Farm Administrator.
The output is a tab delimited file that opens up nicely in Excel.

 


Function SiteAdmin($site){
$siteUrl = $site.url
$rootSite = New-Object Microsoft.SharePoint.SPSite($siteUrl)
$spWebApp = $rootSite.WebApplication

foreach($site in $spWebApp.Sites)
{
    foreach($siteAdmin in $site.RootWeb.SiteAdministrators | where {$_.LoginName -Like $user})
		{
	  Add-Content -Path $strPath "`t`t$($siteAdmin.ParentWeb.Url) `t $($siteAdmin.DisplayName) `t $($siteAdmin.LoginName)"
		}
	}
}

Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$user = Read-Host "Input user name or part thereof to find [Contoso\User*]"
$date = Get-Date
$comp = $env:computername
$strPath = $filename = "E:\Reports\users.txt"
IF(Test-Path $filename) { Remove-Item $strPath }
Add-Content -Path $strPath "$User Owner and\or Admin `t$comp `t$date`n"
Add-Content -Path $strPath "Site.Url `tSite Owner `tParentWeb Url `tSiteAdmin DisplayName `tSiteAdmin LoginName"

$Sites = Get-SPSite -Limit All
ForEach ($site in $Sites) {
	SiteAdmin($site)
	If ($site.owner -Like $user) {
	Add-Content -Path $strPath "$($Site.Url) `t $($Site.Owner)"
	}
	$site.Dispose()
}

 

Advertisements

My SharePoint 2010 Powershell tutorial for SharePoint 200 developers

Serge Luca's Blog (SharePoint MVP)

Here is an extract of the Powershell module of my  SharePoint 2010 for developers course.

 

1.1 lab.introduction to Powershell

In this lab, you will work out a number of exercises that have to do with Powershell.

In Lab1 you will discover the main Powershell concepts; in Lab 2, you will apply these concepts.

1.1.1 Lab 1.discovering Powershell

1. Start the Sharepoint 2010 Management Shell.

clip_image002

2. To get help, type:

Get-help

3. To see all the commands available, type :

4. To see how to use Get-Command, type get-help get-Command; you will notice the Noun option:

clip_image003

5. To get the list of all Sharepoint commands, type:

You will notice familiar cmdlets like Get-SPUser, Get- SPWeb, Get- SPSite,…

Sharepoint commands are organized as verb-noun like Enable-SPFeature.

You can type Get-Command –Noun SPFeature*or Get-Command –verb Enable.

6. In Powershell, there…

View original post 1,291 more words

Get SharePoint Users and Groups Info

This script uses the SharePoint commands to gather all the users and groups with access to your Central Administration SP site.
It mails the report using SMTP and it will upload the report to a SharePoint site.
This script must be run as a Farm Administrator to get complete results.

It puts it out in a HTML format. It is usefull for those security audits that come up from time to time.
The is adapted from the code I found here which puts out the results in a quasi XML format.
:

#Function to send out email 
function sendMail($emailTo,$outFile) 
{ 
    $smtpServer = "smtp.org" #<-- Your SMTP mail server
    $emailFrom = "$machineName@yourdomain.com"  
    $subject = "$MachineName SharePoint Users Info - $date" 
    $body = "See Attached."  
	
	If ($outFile -eq $null) {
		# no attachement
		$body += $Results
        Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject  -Body $body -SmtpServer $smtpServer 
	}
	Else
	{
		# with $outfile as attachement
        Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject  -Body $body -Attachments $outFile -SmtpServer $smtpServer
    }
} 

function DisplayWeb #-web SPWeb -depth int -parentWeb SPWeb
{
   if($args[0].HasUniquePerm -eq "True")
  {
    $UserAccess = DetermineUserAccess $args[0] ($args[1] + 1)
  }
  

  if($args[0].Webs -ne $Null)
  {
    # RECURSIVELY SEARCH SUBWEBS
    foreach ($spSubWeb in $args[0].Webs)
    {
      $subWeb = DisplayWeb $spSubWeb ($args[1] + 2)
      $spSubWeb.Dispose()
    }
    # END CONTAINED SUBSITES ENTITY
   
  }

  # END SITE ENTITY
  Return $subWeb
}

function DisplayMissingParametersMessage
{
  #Write-Output "You are missing a parameter for 'Site URL'"
  $script:siteURL = Read-Host "Enter Site URL"
}
<#
This report must be run as a Farm Administrator to get complete results.
The report will mail itself to a person or group and upload the report file to a 
SharePoint site. ("http://sharepoint/Shared%20Documents")
:: Usage:
.\SP Security Report.ps1' "http://ServerName:51234" <-- Change the server name as appropriate.


#>
############
# MAIN
############

Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#IF MISSING PARM FOR SITE URL, ASK FOR INPUT TO FILL
if($args.length -eq 0)
{
  DisplayMissingParametersMessage
}

[string]$siteUrl = $args[0]
[string]$searchScope = $args[1]
[string]$userToFind = $args[2]

#Import-module active*
$server = $env:computername
$date = ( get-date ).ToString('MM-dd-yyyy')
$MachineName = $env:COMPUTERNAME
$u = @()
$rootSite = New-Object Microsoft.SharePoint.SPSite($siteUrl)
$spWebApp = $rootSite.WebApplication

#IF SEARCH SCOPE SPECIFIED FOR SITE, ONLY SEARCH SITE
if($searchScope -eq "-site")
{
  DisplaySiteCollection $rootSite 1
}
#ELSE SEARCH ENTIRE WEB APP
else
{
  #DisplayWebApplication $spWebApp 1
}

# Create Webpage Header
$z = "<!DOCTYPE html PUBLIC `"-//W3C//DTD XHTML 1.0 Strict//EN`"  `"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd`">"
$z = $z + "<html xmlns=`"http://www.w3.org/1999/xhtml`">"
$z = "<head><style>"
$z = $z + "TABLE{border-width: 2px;border-style: solid;border-color: black;border-collapse: collapse;}"
$z = $z + "TH{border-width: 2px;padding: 4px;border-style: solid;border-color: black;background-color:lightblue;text-align:left;font-size:14px}"
$z = $z + "TD{border-width: 1px;padding: 4px;border-style: solid;border-color: black;font-size:12px}"
$z = $z + "</style></head><body>"
$z = $z + "<H4>SharePoint Users Report for $env:COMPUTERNAME Central Admin $date</H4>"
$z = $z + "<table><colgroup><col/><col/><col/><col/><col/><col/><col/></colgroup>"
$z = $z + "<tr><th>Web App</th><th>Web</th><th>Site Collection</th><th>Site User</th><th>SPGroup</th><th>SPGroupMembers</th><th>Local Group</th></tr>"
$MainWebApp = $spWebApp
$MainDisplayWeb = DisplayWeb 
$subSite = @()

ForEach ($site in $SpWebApp){
$MainSiteCollection = @()
$a = $site.Sites 
	forEach ($a1 in $a) {
	$sSite = $a1.ToString().split("=")
		$SubSite = $subSite + $sSite[1]
	$MainSiteCollection = "$MainSiteCollection $sSite <br>"
	}
}

$z = $z + "<tr><td>$MainWebApp</td><td>$MainDisplayWeb</td><td>$MainSiteCollection</td><td></td></tr>"

ForEach ($site in $SubSite){
$siteUser = @()
$u1 = @()
$SPGroups = @()
$MainSPGroupMembers = @()
$rSite = New-Object Microsoft.SharePoint.SPSite($site)
$x = $rSite.rootweb
$x1 = $x.users

ForEach ($i in $x1) { 
$u = $i.UserLogin
$u2 = $u.ToString().split(".")
$u1 = "$u1  $u2 <br>"
$siteUser = "$u1<br>"
 }
foreach($group in $rsite.RootWeb.SiteGroups)
{	
    $b = $group.Name 
    $sGroup = $b.ToString().split(".")
	$SPGroup = $sGroup[0]
	$SPGroups = ($SPGroup)
	$LocalGrp = @()
	$lgn = @()
	$lgm = @()
	$MemberName = @()
	$x1 = @()
	$x = $null
	foreach ($user in $group.Users)
    {    
		$D = $user.UserLogin
			$D1 = $D.ToString().split(".")
			$D2 = $D.ToString().split("\")
			$SPGroupMembers = "$D1"
			$MainSPGroupMembers = ("$MainSPGroupMembers $SPGroupMembers <br>")
		If ($User.IsDomainGroup) {
			$x = $user
			$lgn = $x
			$x1 = $x1 + $x 
			forEach ($x2 in $x1) {
			$Lgm = $Null
			$y = $Null
			$gName = $x2.ToString().split("\")
			$groupName = $gName[1]
			  #BEGIN - CODE ADAPTED FROM SCRIPT CENTER SAMPLE CODE REPOSITORY
			  #http://www.microsoft.com/technet/scriptcenter/scripts/powershell/search/users/srch106.mspx
			  #GET AD GROUP FROM DIRECTORY SERVICES SEARCH
			  $strFilter = "(&(objectCategory=Group)(name="+($groupName)+"))"
			  $objDomain = New-Object System.DirectoryServices.DirectoryEntry
			  $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
			  $objSearcher.SearchRoot = $objDomain
			  $objSearcher.Filter = $strFilter
				$colProplist = ("name","member")
				foreach ($i in $colPropList)
					{
					$catcher = $objSearcher.PropertiesToLoad.Add($i)
					}
						$colResults = $objSearcher.FindAll()

				#END - CODE ADAPTED FROM SCRIPT CENTER SAMPLE CODE REPOSITORY
				  foreach ($objResult in $colResults)
				  {
					foreach ($member in $objResult.Properties.member)
					{
					  $indMember = [adsi] "LDAP://$member"
					    $y = $domain + ($indMember.Name) 
						$Lgm = ("$Lgm <tr><td>$y</td></tr>")
						}
					 }
			}	
			$LocalGrp = ("$LocalGrp <TABLE><td><strong>$lgn</strong></td><td>$Lgm</td></tr></TABLE>")
			}
	}
	$lgnlgm = $Localgrp
	$z = $z + "<tr><td></td><td>$site</td><td></td><td>$siteUser</td><td>$SPGroups</td><td>$MainSPGroupMembers</td><td>$lgnlgm</td><tr>"
	}
	$rSite.Dispose()
}

# Create Table
$surl = $siteUrl.ToString().split("/")
$s = "CA"
# $s = $surl[2]
# $s = ($s -replace ":", "-") 
$MainWebApp = $spWebApp
$MainDisplayWeb = DisplayWeb
$z = $z + "</table></body></html>"

# Adjust Path
$OutFileName = ("G:\Reports\" + $server + "-" + $s + "-SharePoint Security Report-" + $date + ".html")
#
Out-File -FilePath $OutFileName -InputObject $z -Encoding ASCII	
#End Table
$OutFileItem = Get-Item -Path $OutFileName
Write-Host " Report available here: $OutFileItem" -Foregroundcolor Yellow
sendMail user@yourmai.com $OutFileItem #<--- Change email address

# upload the report to a SharePoint site
$userName = Read-Host "Enter your username"
$password = Read-Host "Enter your password"
 
 $path = "G:\Reports"; #<--- Change directory
 $destination = "http://sharepoint/Shared Documents"; 
 $securePasssword = ConvertTo-SecureString $password -AsPlainText -Force;
 $credentials = New-Object System.Management.Automation.PSCredential ($userName, $securePasssword);
 #$credentials = [System.Net.CredentialCache]::DefaultCredentials; 
 $webclient = New-Object System.Net.WebClient;
 $webclient.Credentials = $credentials; 
 Get-ChildItem $path | Where-Object {$_.Extension -eq ".html"} | 
 ForEach-Object { $webclient.UploadFile($destination + "/" + $_.Name, "PUT", $_.FullName); 
 }
#CLEANUP
$rootSite.Dispose()

Automates a SharePoint 2010 installation

###### Start Posh Script ######## 

<#
.Script Name
New-SPInstallation.ps1 

.SYNOPSIS
Automates a SharePoint 2010 installation.

.DESCRIPTION
The script automates a SharePoint 2010 installation.
Requires that the binaries are installed on the server.

.PARAMETER databaseName
Name of the configuration database.

.PARAMETER databaseServer
Name of the database server.

.PARAMETER centralAdminDatabase
Name of the Central Administration content database.

.PARAMETER port
Port to use.

.PARAMETER windowsAuthProvider
NTLM or Kerberos, default set to NTLM.

.PARAMETER userName
Farm Administrator account in the format ‘domain\username’.

.PARAMETER password
Pasword for the Farm Administrator account.

.PARAMETER passPhrase
Farm password, used to add new machines to the farm.
#>

param(
[string]$databaseName,
[string]$databaseServer,
[string]$centralAdminDatabase,
[string]$port,
[string]$windowsAuthProvider = "NTLM",
[string]$userName,
[string]$password,
[string]$passPhrase
)
Add-PSSnapin Microsoft.SharePoint.Powershell
$Host.Runspace.ThreadOptions = "ReuseThread"

# Converting password strings to secure strings
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$securePassPhrase = ConvertTo-SecureString -String $passPhrase -AsPlainText -Force

# Creating a PSCredential object
$psCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, $securePassword

# New Configuration Database
New-SPConfigurationDatabase -DatabaseName $databaseName -DatabaseServer $databaseServer -AdministrationContentDatabaseName $centralAdminDatabase -Passphrase $securePassPhrase -FarmCredentials $psCredentials

# Install help files
Install-SPHelpCollection -All

# Install services
Install-SPService

# Install Features
Install-SPFeature -AllExistingFeatures

# Create a new Central Administration
New-SPCentralAdministration -Port $port -WindowsAuthProvider $windowsAuthProvider

# Copy shared application data
Install-SPApplicationContent

###### End Posh Script ######## 

We can run this script by typing the following:

New-SPInstallation.ps1 -databaseName “My config DB” `
-databaseServer “SqlServer01” `
-centralAdminDatabase “My Admin_ContentDB” -port 5057 `
-username “ps\admin” `
-password “SecretP@assword” -passphrase “JoinDoain”

How do I check and Update a web.config file (XML)

I am working on a script to check for a particular node in a web.config file for the SharePoint Team.
The idea is to check if the node exist. If so, check to see if the request limits are set to “maxAllowedContentLength”,”83886080″
If so, all is well. If not set “maxAllowedContentLength”,”83886080″.
If the node does not exist, add it.
I am also logging my results and traping any errors. You may want to add or delete directories in the $xdir array. The -recurse function is an all or nothing sort of thing. Excluding directories is not supported. Hopefully in the next release!

BTW: if you copy this, you will need to remove the back ticks (`) from the begining of lines 73-79. I had to add them so WordPress would show the (Greater than, Less than) properly.

###### Start Posh Script ########

function write-log([string]$info){
if($loginitialized -eq $false){
#$FileHeader > $logfile
$script:loginitialized = $True
}
$info >> $logfile
}
#---------Logfile Info----------#
$script:UseInfo = $($(get-date -format MM/dd/yyyy-HH:mm:ss) + '`t' + $env:username + '`t')

Trap [Exception] {
write-log $('$UseInfo`t$_. - Line:(' + $($_.InvocationInfo.ScriptLineNUmber)+':'+$($_.InvocationInfo.OffsetInLine)+ ') ' + $($_.InvocationInfo.Line))
continue
}

$xdir = @('_app_bin','_vti_pvt','App_Browsers','App_GlobalResources','aspnet_client','bin','wpcatalog','wpresources')
$LogPath = Test-Path 'E:\LogFiles\ps\UpdateWebConfig' -pathType container
If ($LogPath) {
$script:logfile = 'E:\LogFiles\ps\UpdateWebConfig\WebConfig Update - $(get-date -format MMddyy-HHmmss).log'
$script:loginitialized = $false
} Else { New-Item 'E:\LogFiles\ps\UpdateWebConfig' -type directory
$script:logfile = 'E:\LogFiles\ps\UpdateWebConfig\WebConfig Update - $(get-date -format MMddyy-HHmmss).log'
$script:loginitialized = $false
}
$d = Get-Date -f MMddyy-HHmmss
Write-log '***Application Information***'
Write-log 'Filename: UpdateWebConfig.ps1'
Write-Log 'Created by: $env:username'
Write-Log 'Last Modified: $d'
Write-Log '***Application Information***'
Write-log

$ErrorActionPreference = 'SilentlyContinue'
$rl = '83886080'
#$wc = Get-ChildItem -Recurse C:\Scripts\xml -include *.config
$wc = Get-ChildItem -Recurse E:\inetpub\wwwroot\wss\VirtualDirectories -include web.config |
where {$xdir -notcontains (Split-Path $_.DirectoryName -Leaf -EA SilentlyContinue)}

$XML = New-Object xml

foreach ($item in $wc){
$wtc = gc $item | Select-String 'requestLimits' -quiet
If ($wtc) {
$XML.load($Item)
$wcToChange = $XML.configuration.'system.webServer'.security.requestFiltering.requestLimits.GetAttribute('maxAllowedContentLength')
If ($wcToChange -eq $rl) {
Write-Host '$item is OK' -ForegroundColor Green
write-log '$item is OK'
write-log
}
Else {
Write-Host '$item is NOT OK maxAllowedContentLength = $wcToChange' -ForegroundColor Red
write-log '$item is NOT OK maxAllowedContentLength = $wcToChange'
$XML.Save('$Item.bak-$d')
write-log 'Backup File: `t$Item.bak-$d'
$XML.configuration.'system.webServer'.security.requestFiltering.requestLimits.SetAttribute('maxAllowedContentLength','83886080')
$wtc = $XML.configuration.'system.webServer'.security.requestFiltering.requestLimits.GetAttribute('maxAllowedContentLength')
$XML.Save([Console]::Out)
$XML.Save($Item)
write-log '$item is NOW OK maxAllowedContentLength = $rl'
write-log }
} Else {
$XML.load($Item)
Write-Host '$item is NOT OK' -ForegroundColor Red
Write-Host 'Need to Add RequestFiltering' -ForegroundColor Red
write-log 'Need to Add RequestFiltering to web.config file'
$XML.Save('$Item.bak-$d')
write-log 'Backup File: `t$Item.bak-$d'
# new system.webServer node and child nodes
[Xml]$sweb = @'
`<system.webServer>
`<security>
`<requestFiltering>
`<requestLimits maxAllowedContentLength='83886080'/>
`</requestFiltering>
`</security>
`</system.webServer>
'@

# import and set the new system.webServer node
$newNode = $XML.ImportNode($sweb.'system.webServer', $true)
# append new system.webServer node
[Void]$XML.configuration.AppendChild($newNode)
# check (this displays the results on the screen)
$XML.Save($Item)
write-log $item
write-log `"requestLimits maxAllowedContentLength='83886080'"
write-log 'added to web.config file'
write-log
}
}

############# End POSH Script ###############