Sharepoint Global Site Collection Administrator editor using PowerShell

I finally got round to writing a PowerShell script which allows you to globally add or remove users from Site Collection Administrators.  I had expected to be able to do this using stsadm commands, but it turns out you cannot use stsadm to remove a Site Collection Administrator (although you can add an administrator this way – and the Microsoft documentation suggestions suggests removal works too – it doesnt!).  Instead I had to delve into the Sharepoint object model and figure out where on earth the Site Administrators are set.  Turns out it is in the root site (aka Web in the code) of the site collection, which has a SiteAdministrators property – a collection of SPUser objects.  These need the IsSiteAdmin property setting to false.  That’s how the script works.

The script will also list out the Site Collection Administrators for all Site Collections in a Web Application, which is useful.  Just run the script, then quit it after you have the information you need.  At some point I’ll update the script so this list is formatted in a nicer way.

As with the previous script, you will need to save the supporting functions script in the same directory.  IMPORTANT: You must edit the value of $email-domain at line 13 to match the domain (bit after @) that your users email addresses use.

On with the script:

#######
#
#	edit-spadmins
#
#	Adds or removes site administrators from all site collections in a given web application
#
#	TODO: Check userinput and handle errors gracefully
#
#######
.SPFunctions.ps1;

##  !! Edit the email domain to whatever your users email addresses end with (after the @)
$email-domain = "dunxd.com"

####################################################################################
#
#	Main script
#
####################################################################################
# Preamble
cls;
write-host "###################################################################################

This application adds or removes users from all site collections in
the given Web Application.

Here is a list of all Web Applications on the farm" -foregroundcolor yellow;

# List the GUIDs of all web apps on this farm
List-SPWebApp-GUID;

write-host "Please copy the GUID for the web application you wish to use by selecting then
clicking the right mouse button."  -foregroundcolor yellow;

write-host "
Note that the Central Admin site collection has no name,
but does have a GUID!  Don't select this one by accident!
" -foregroundcolor red;

Write-Host "You can paste the GUID by clicking the Right mouse button again" -ForegroundColor yellow;
# Prompt user for GUID to use
$guid = Read-Host -Prompt "GUID";
$guid = $guid.Trim();

# Check GUID for correct format
Write-Host "Checking GUID";
switch(Check-GUID($guid)){
	"False" { Write-Host "Error: Invalid GUID.  Exiting..." -ForegroundColor red; return;}
}

# Get the specified web app
$webapp = Get-SPWebApp($guid);

# Check that webapp has been got and if not inform user
Write-Host "The following Web App will be affected: " $webapp.name;

# List out the site collections (and their admins) that will be changed and prompt to continue
Write-Host "The following site collections will be affected" -ForegroundColor yellow;
foreach ($site in $webapp.Sites){
	Write-Host $site.url;
	$web = $site.openweb();
	$web.SiteAdministrators | ft LoginName, id;
}

$continue = Read-Host -Prompt "Continue? (y|n)>";
switch($continue){
	"y" {break;}
	default {Write-Host "Exiting..." -ForegroundColor red; return;}
}

# Is this operataion adding or removing users from Site Collection Administrators
Write-Host "Are you adding or removing users from Site Collection Administrators?" -ForegroundColor yellow;
$operation = Read-Host -Prompt "(add|remove)";

switch($operation){
	"add" {
		#Write-Host "The adding functionality has not been written yet" -ForegroundColor red; return;
		Write-Host "Please give a comma delimited list of usernames in format DOMAINusername
		e.g. DOMAINuser1,DOMAINuser2,DOMAINuser3 etc." -ForegroundColor yellow;
		$usernames = Read-Host -Prompt "Users";
		#Split the list on the commas
		$username_array = $usernames.Split(",");

		$time = Measure-Command {
			foreach ($site in $webapp.Sites){
				foreach ($user in $username_array){
					$domain_username = $user.Split("");
					$email = $domain_username[1] + $email-domain;
					$command = "stsadm -o adduser -url " + $site.url + " -userlogin $user -useremail $email -Role `"Full Control`" -username $user -siteadmin";
					Write-Host $command;
					Invoke-Expression $command;
					$count_users++;
				}
				$count_sites++;
			}
		}
		Write-Host $count_users "Admin Accounts added to" $count_sites "in" $time.TotalSeconds "seconds." -ForegroundColor yellow;
	}
	"remove" {
		$count_users = 0;
		# Which user(s) do we want to remove from the Site Collection Administrators list?
		# Collect a comma delimited list of usernames in format DOMAINusername
		Write-Host "Please give a comma delimited list of users to remove from the site collection administrators
		e.g. DOMAINuser1,DOMAINuser2,DOMAINuser3" -ForegroundColor yellow;
		$usernames = Read-Host -Prompt "Users";
		#Split the list on the commas
		$username_array = $usernames.Split(",");
		$time = Measure-Command {
			foreach ($site in $webapp.Sites){
				$web = $site.openweb();
				$admins = $web.SiteAdministrators;
				foreach ($user in $admins){
					# Check to see whether the user name is in the $username-array
					if ($username_array -contains $user.LoginName){
						$user.IsSiteAdmin = $FALSE;
						$user.Update();
						Write-Host "Removed " $user.LoginName " from Site Administrators on " $web.URL;
						$count_users++
					}
				}
				$count_sites++
			}
		}
		Write-Host $count_users "Admin Accounts removed from" $count_sites "in" $time.TotalSeconds "seconds." -ForegroundColor yellow;
	}
	default {Write-Host "You must type add or remove!  Exiting..." -ForegroundColor red; return;}
}
##############################      End of script     #############################

Hope you find that useful.  Take a look through the code to get some ideas for accessing SPUser objects via PowerShell.  I’m sure this is going to be handy in future.

8 thoughts on “Sharepoint Global Site Collection Administrator editor using PowerShell

  1. So to add a SC admin you wrap stsadm, which is ok. I was wondering if there was a powershell only (NO STSADM) way of doing it. Any guidance is appreciated.

  2. It’s a while since I wrote this, so my recollection is not good. I think I ended up using stsadm as it accepted just the username, wheras the Powershell method required getting the user object and applying that to the property. Either that or I couldn’t locate the property, but knew I could set it via stsadm. The documentation was not that helpful, so I went for the path of least resistance. I’d recommend that you look at the properties of a site collection to see if you can identify the property that contains the owner and secondary owner, and then try setting it to DOMAINuser. If that doesn’t work, then I think even if it is possible to do it “purely” stsadm is a quicker solution.

    In Sharepoint 2010, there must be a PowerShell method, since stsadm has been completely replaced by PowerShell.

  3. I believe you have a typo in SPFunctions.ps1 at line 30. The function name (which is called in your spadmin script) should be Get-SPWebApplications.

    As Get-SPWebApplication is already a command, is there any reason why you wouldn’t just use it?

    e.g. Get-SPWebApplication -includecentraladmin | Select Id, DisplayName | Format-Table -AutoSize

  4. And I really *hate* to be pedantic but calling the function script will not work as described. You should be using:

    .SPFunctions.ps1

    • Thanks for your feedback and corrections. I have updated all my SharePoint PowerShell scripts. I changed the function name of Get-SPWebApplication (which was labelled Get-SPWebApplications in the comments in SPFunctions.ps1) to Get-SPWebApps. At the time of writing these scripts, which are for SharePoint 2007, there was very little documentation about how to access different things through PowerShell. Microsoft’s documentation was almost entirely aimed at .Net programmers, not admins using PowerShell. Thanks for letting me know about this function. I have incorporated it into the SPFunctions.ps1 in the function that lists the Web Applications and their GUIs.

  5. Please check the .zip files used for download. For me, on multiple systems, they will not open; corrupted.

    • I am able to download both zip files and open them and their content with no problem. This is working on a Windows 7 computer using the built in zip function of Windows.

      Please try clearing your cache and downloading again.

  6. I’ve had to remove the scripts since migrating to WordPress.com as they don’t allow uploading .zip files. I may find a workaround at some point and return the scripts, but they are pretty old now. If you are interested, you can comment here, leaving your contact details and I’ll send them to you.

Leave a comment