Skip to content

Instantly share code, notes, and snippets.

@jgregmac
Created January 8, 2016 19:42
Show Gist options
  • Select an option

  • Save jgregmac/c463d8fb015f2f5e684e to your computer and use it in GitHub Desktop.

Select an option

Save jgregmac/c463d8fb015f2f5e684e to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Migrate-SPUsers Script, by J. Greg Mackinnon (derrived from unattributed script found on the Internet)
Used to document and convert user and group entries in SharePoint from Windows or Claims provider format to a new Claims provider format.
.DESCRIPTION
This script can be executed in two modes:
In "Document" mode (the default), a CSV file will be generated that enumerates all SharePoint users and groups recorded in all SharePoint "webs", and shows the new account details that will be applied.
In "Convert" mode, the changes generated in the CSV files from "Document" mode will be applied.
This two-step process makes it possible to review the planned migration before committing.
.PARAMETER oldProvider
Mandatory string variable.
Specifies the original Windows account domain or claims provider prefix.
Enter the Old Provider Name (Example -> Domain\ or i:0#.f|MembershipProvider|)
.PARAMETER newProvider
Mandatory string variable.
Specifies the new claims provider prefix to which users and groups will be migrated.
Enter the New User Provider Name (Examples -> "Domain\" or "i:0e.t|MembershipProvider|")
.PARAMETER newSuffix
Mandatory string variable.
Specifies the new UPN-style sufix to be appended to user accounts at conversion time.
Enter the UPN suffix for the new provider, if desired (Example -> "@domain.com")
.PARAMETER newGroupProvider
Mandatory string variable.
Specifies the new claim prefix to be applied to existing group assignments at conversion time.
Enter the New Group Provider Name (Examples -> "Domain\", "c:0-.t|MembershipProvider|domain.com\")
.PARAMETER ignoreFilter
Optional string variable.
A filter in regular expression format that will be used to exclude matching results from the oldProvider search.
.PARAMETER webApplication
Optional string variable.
If supplied, the documentation process will be processed for all sites within the specified Web Application
Provide the URL of the WebApplication for which to migrate users.
.PARAMETER contentDB
Optional string variable.
If supplied, the documentation process will be processed for all sites within a specified Content Database.
.PARAMETER SPSite
Optional string variable.
If supplied, the documentation process will
Provide the URL of the SharePoint site collection for which to migrate users.
.PARAMETER convert
Switch parameter. If specified, the script will run in "convert" mode. If excluded, the script will run in the default "document" mode.
.PARAMETER csvPath
Mandatory string parameter.
Enter the path to which to save the MigrateUsers.csv file. (i.e. C:\migration)
.EXAMPLE
.\Migrate-SPUsers.ps1 -webApplication 'https://sharepoint.myschool.edu' -oldProvider 'GUEST\' -newProvider 'i:0e.t|adfs.myschool.edu|' -newSuffix '@guest.myschool.edu' -csvPath c:\local\temp -newGroupProvider 'c:0-.t|adfs.myschool.edu|guest.myschool.edu\'
Documents the migration process for all users in the Web Application "https://sharepoint.myschool.edu". The generated CSV file will be saved to c:\local\temp\MigrateUsers.csv
.EXAMPLE
.\migrate-SPUsers.ps1 -convert -csvPath C:\local\temp
Processes all users documented in the MigrateUsers.csv file under c:\local\temp, performing the user/group migrations generated by the "document" process in the previous example.
#>
[cmdletBinding(DefaultParameterSetName='document')]
param (
[parameter(
ParameterSetName='document',
Mandatory=$true,
HelpMessage='Enter the Old Provider Name (Example -> Domain\ or i:0#.f|MembershipProvider|)'
)]
[string]$oldProvider,
[parameter(
ParameterSetName='document',
Mandatory=$true,
HelpMessage='Enter the New User Provider Name (Examples -> "Domain\" or "i:0e.t|MembershipProvider|")'
)]
[string]$newProvider,
[parameter(
ParameterSetName='document',
Mandatory=$true,
HelpMessage='Enter the UPN suffix for the new provider, if desired (Example -> "@domain.com")'
)]
[string]$newSuffix,
[parameter(
ParameterSetName='document',
Mandatory=$true,
HelpMessage='Enter the New Group Provider Name (Examples -> "Domain\", "c:0-.t|MembershipProvider|domain.com\")'
)]
[string]$newGroupProvider,
[parameter(
ParameterSetName='document',
HelpMessage='Enter a regular expression that will be used to filter out matching old provider results. (Example -> "domain\\[a-zA-Z0-9]+-admin")'
)][string]$ignoreFilter,
[parameter(
ParameterSetName='document',
Mandatory=$false,
HelpMessage='Provide the URL of the WebApplication for which to migrate users.'
)]
[ValidatePattern('^http[s]*://[A-Za-z]+\.[A-Za-z]+')]
[string]$webApplication,
[parameter(
ParameterSetName='document',
Mandatory=$false,
HelpMessage='Provide the URL of the SharePoint site collection for which to migrate users.'
)]
[ValidatePattern('^http[s]*://\w+\.\w+')]
[string]$SPSite,
[parameter(
ParameterSetName='document',
Mandatory=$false,
HelpMessage='Provide the name of the SharePoint Content Database for which to migrate users.'
)]
[string]$contentDB,
[parameter(
ParameterSetName='convert',
Mandatory=$true
)]
[switch]$convert,
[parameter(
Mandatory=$true,
HelpMessage='Please enter the path to which to save the MigrateUsers.csv file. (i.e. C:\migration)'
)]
[ValidateScript({Test-Path $_ -PathType Container})]
[string]$csvPath
)
Set-PSDebug -Strict
add-pssnapin microsoft.sharepoint.powershell -ea Stop
Import-Module ActiveDirectory -ea Stop
$objCSV = @()
[string]$out = ''
switch($PSCmdlet.ParameterSetName) {
"convert" {
$objCSV = Import-CSV "$csvPath\MigrateUsers.csv"
foreach ($object in $objCSV) {
$user = Get-SPUser -identity $object.OldLogin -web $object.SiteCollection
write-host "Moving user:" $user "to:" $object.NewLogin "in site:" $object.SiteCollection
try {
move-spuser -identity $user -newalias $object.NewLogin -ignoresid -Confirm:$false `
-ea Stop
} catch {
#Something very wrong is happening here. All group objects are failing to migrate...
write-error "An error occurred when attempting to migrate the user."
}
}
} # End "convert"
"document" {
Write-Host ""
$sites = @()
if($WebApplication) {
$out = 'Gathering Site Collections from: ' + $webApplication
write-host -foregroundColor Yellow $out
$sites = get-spsite -WebApplication $webApplication -Limit All
} elseif ($SPSite) {
$out = 'Retrieving single Site Collection: ' + $SPSite
write-host -foregroundColor Yellow $out
$sites = get-spsite $SPSite
} elseif ($contentDB) {
$out = 'Retrieving Site Collections from Database: ' + $ContentDB
write-host -foregroundColor Yellow $out
$sites = get-spsite -ContentDatabase $contentDB -Limit All
} else {
$out = 'Gathering Sites Collections from the local farm. Dangerous!'
write-host -foregroundColor Red $out
$sites = get-spsite -Limit All
}
foreach($site in $sites) {
$out = "Evaluating site: " + $site.url
write-host -foregroundColor Cyan $out
#Initialize $webs as an array
# (needed to prevent the next foreach from attempting to loop a non-array variable.)
$webs = @()
$webs = $site.AllWebs
$out = " Site has " + $webs.count + " webs."
write-host -foregroundColor Cyan $out
foreach($web in $webs) {
$out = " Evaluating web: " + $web.url
write-host -foregroundColor Green $out
# Get all of the users in a site
$users = @()
$users = get-spuser -web $web -Limit All #added "-limit" since some webs may have large user lists.
# Loop through each of the users in the site
foreach($user in $users) {
# Create an array that will be used to split the user name from the domain/membership provider
$a=@()
$displayname = $user.DisplayName
$userlogin = $user.UserLogin
if(($userlogin -like "$oldprovider*") -and ($objCSV.OldLogin -notcontains $userlogin)) {
# Separate the user name from the domain/membership provider
if($userlogin.Contains('|')) {
$a = $userlogin.split("|")
$username = $a[1]
if($username.Contains('\')) {
$a = $username.split("\")
$username = $a[1]
}
}
elseif($userlogin.Contains('\')) {
$a = $userlogin.split("\")
$username = $a[1]
}
# Create the new username based on the given input
if ($user.IsDomainGroup) { #object is a domain group
[string]$newGrpName = ''
#Group display name may be outdated. Lookup the current samAccountName
# Using the SID on-file in SharePoint.
$grpSid = $user.sid
try { #Retrieval of AD Group could fail. We need a fallback...
$adGrp = Get-ADGroup -Identity $grpSid -ea Stop
$newGrpName = $adGrp.samAccountName
} catch {
$newGrpName = $username
}
[string]$newalias = $newGroupProvider + $newGrpName
} else { #object is a user account
[string]$newalias = $newprovider + $username + $newsuffix
}
# Create a PS Custom Object for each row in the export CSV:
$userProps = @{
OldLogin = $userLogin
NewLogin = $newAlias
SiteCollection = $site.Url
}
$objUser = New-Object -TypeName PSObject -Property $userProps
# Add the custom object to the export CSV array:
$objCSV += $objUser
}
} #End foreach user
$web.dispose()
} #End foreach web
$site.Dispose()
} #End foreach site
write-host
$out = 'Finished gathering user data.'
write-host $out -ForegroundColor Yellow
if ($ignoreFilter) {
$out = 'Results filter defined. filtering output...'
write-host $out -ForegroundColor Yellow
$objCSV = $objCSV | ? {$_.oldLogin -NotMatch $ignoreFilter}
}
out-file -force c:\local\temp\MigrateUsers2.csv
write-host "Writing to file..."
$objCSV | Export-Csv "$csvPath\MigrateUsers.csv" -NoTypeInformation -Force
write-host 'done!'
} # End "document"
} # End switch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment