Zhaobab
2/5/2015 - 6:09 PM

Copy account's (users and groups), to an other site. Edit login's prefix part in the same time.

Copy account's (users and groups), to an other site. Edit login's prefix part in the same time.

[GENERAL]
url_communities=http://rbla-sp2010-002/sites/communaute
url_one=http://rbla-sp2010-002/sites/test_one_romain
namingconvention_prefix=SG-ONE-
namingconvention_suffix=-R
newgroupowners=rbla\administrator
logfilepath=C:\Users\blanchardro\Desktop\GroupMigrationLogs\
logfilename=group_migration
numberoflogfilestokeep=30
# ----------------------------------------------
# Author: Romain Blanchard
# Date: 29.03.2013
# Description: Copy account's (users and groups), to an other site. Edit login's prefix part in the same time. 
# ----------------------------------------------

## Import Powershell module if the script is launched from normal powershell commandline
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

## Function that reads the INI configuration file
function Convert-IniFile ($file)
{
    $REGEX_INI_COMMENT_STRING = ";"
    $REGEX_INI_SECTION_HEADER = "^\s*(?!$($REGEX_INI_COMMENT_STRING))\s*\[\s*(.*[^\s*])\s*]\s*$"
    $REGEX_INI_KEY_VALUE_LINE = "^\s*(?!$($REGEX_INI_COMMENT_STRING))\s*([^=]*)\s*=\s*(.*)\s*$"

    $ini = @{}
    switch -regex -file $file {
        "$($REGEX_INI_SECTION_HEADER)" {
            $section = $matches[1]
            $ini[$section] = @{}
        }
        "$($REGEX_INI_KEY_VALUE_LINE)" {
            $name,$value = $matches[1..2]
            if ($name -ne $null -and $section -ne $null)
            {
                $ini[$section][$name] = $value
            }
        }
    }
    $ini
}

## Function to create a new SharePoint group
function New-SPGroup {
	 [CmdletBinding()]
    Param(
    [string]$Web,
    [string]$GroupName,
    [string]$OwnerName,
    [string]$MemberName,
    [string]$Description
    )
    $SPWeb = Get-SPWeb $Web
    if ($SPWeb.SiteGroups[$GroupName] -ne $null){
        throw "Group $GroupName already exists!"   
    }
    if ($SPWeb.Site.WebApplication.UseClaimsAuthentication){
        $op = New-SPClaimsPrincipal $OwnerName -IdentityType WindowsSamAccountName
        $mp = New-SPClaimsPrincipal $MemberName -IdentityType WindowsSamAccountName
        $owner = $SPWeb | Get-SPUser $op
        $member = $SPWeb | Get-SPUser $mp
    }
    else {
    $owner = $SPWeb | Get-SPUser $OwnerName
    $member = $SPWeb | Get-SPUser $MemberName
    }
$SPWeb.SiteGroups.Add($GroupName, $owner, $member, $Description)
$SPGroup = $SPWeb.SiteGroups[$GroupName]
$SPWeb.RoleAssignments.Add($SPGroup)
$SPWeb.Dispose()
return $SPGroup
}
cls

## Read the INI config file (be carefull beacause we read in the current console location)
$iniFile = Convert-IniFile("config.ini")

## Prepare LOGS
$date = Get-Date -format yyyyMMdd
$logfilename = $iniFile["GENERAL"]["logfilename"]
$logfilename_new = $logfilename + "_" + $date + ".csv"
$logfilepath = $iniFile["GENERAL"]["logfilepath"]
$numberoflogfilestokeep = $iniFile["GENERAL"]["numberoflogfilestokeep"]
$logfile = $logfilepath + $logfilename_new
$logfile_exist = Test-path $logfile
if ($logfile_exist -eq "True"){ remove-item -path $logfile -Confirm:$false }
write-output "Web;Group;Message" | out-file -filepath $logfile -append

## Delete old logs files
$files = Get-ChildItem $logfilepath -Recurse | where-object {$_.Name -ilike "$logfilename*"} | Sort-Object Name
$c = $files.Count
if ($c -gt $numberoflogfilestokeep)
{
	do
	{
		$filepath = $logfilepath + $files[0]
		remove-item -path $filepath -Confirm:$false
		$files = Get-ChildItem $logfilepath -Recurse | where-object {$_.Name -ilike "$logfilename*"} | Sort-Object Name
		$c--
	}
	until ($c -le $numberoflogfilestokeep)
}

## Get/Set script variables
$url_communities = $iniFile["GENERAL"]["url_communities"]
$url_one = $iniFile["GENERAL"]["url_one"]
$namingconvention_prefix = $iniFile["GENERAL"]["namingconvention_prefix"]
$namingconvention_suffix = $iniFile["GENERAL"]["namingconvention_suffix"]
$newgroupowners = $iniFile["GENERAL"]["newgroupowners"]
$CommunitiesSite = Get-SPSite $url_communities
$CommunitiesWeb = $CommunitiesSite.OpenWeb()
$ONESite = Get-SPSite $url_one
$ONEWeb = $ONESite.OpenWeb()

## Foreach site in communities site collection
foreach($web in $CommunitiesWeb.Webs)
{
	try
	{
		## Clean web's title name for group naming convention
		$webname = $web.Title.Replace("'","").Replace("\","").Replace("/","").Replace("[","").Replace("]","").Replace(":","").Replace("|","").Replace("<","").Replace(">","")
		$webname = $webname.Replace("+","").Replace("=","").Replace(";","").Replace(",","").Replace("?","").Replace("*","").Replace("@","").Replace(" ","")
		$groupname = $namingconvention_prefix + $webname + $namingconvention_suffix
		$groupdescription = "Users of $web website."
		
		## Select group in target website if already exist
		if ($ONEWeb.SiteGroups[$groupname] -ne $null)
		{
			$currentgroup = $ONEWeb.SiteGroups[$groupname]
		}
		
		## Create and select group in target website if doesn't exist
		else
		{
			$currentgroup = New-SPGroup -Web $url_one -GroupName $groupname -OwnerName $newgroupowners -MemberName $newgroupowners -Description $groupdescription
			write-output "$ONEWeb;$groupname;$groupname group has been created." | out-file -filepath $logfile -append
		}
		
		## Foreach groups in the current website
		foreach ($group in $web.Groups)
		{
			## Does not select sharepoint useless groups
			if (($group.Name -notcontains "Style Resource Readers") -or ($group.Name -eq "Viewers"))
			{				
				foreach ($user in $group.Users)
				{
					## if real user
					if($user.UserLogin.Contains("red\"))
					{
						$user = $user.UserLogin.Replace("i:0#.w|","")
						
						try
						{
							$currentgroup.AddUser($user, $user.Email, $user.Name,"")
							write-output "$web;$currentgroup;$user has been added to the group $currentgroup." | out-file -filepath $logfile -append
						}
						catch
						{
							write-output "$web;$currentgroup;Cannot add user $user to the group $currentgroup. More: $_" | out-file -filepath $logfile -append
						}
						
					}
					elseif ($user.UserLogin.Contains("c:0"))
					{
						$sid = $user.UserLogin.Replace("c:0+.w|","")
						$securitygroupname = [adsi]"LDAP://<SID=$sid>"
						$user = $securitygroupname.Properties.Item("CN")
						
						$ensured_user = $web.EnsureUser($user)					
						$currentgroup.AddUser($ensured_user)
						write-output "$web;$currentgroup;$user security group has been added to the group $currentgroup." | out-file -filepath $logfile -append
					}
				}
			}
		}
	}
	catch
	{
		write-output "$web;N/A;$_" | out-file -filepath $logfile -append
	}
}