0

Good morning all.

I have a dilemma - our SP tenant has been set with UK region, but with US locale. and this causes problems with American date formats etc.

I have run the following PS script to change all sites' locale to UK:

$LocaleId = 2057 # UK
$TimeZoneId = 2 # London
$credentials = Get-Credential
Connect-PnPOnline https://tenant.sharepoint.com/sites/yoursite -Credentials $credentials
$sites=Get-PnPTenantSite
foreach($site in $sites){
Connect-PnPOnline $site.Url -Credentials $credentials
$web = Get-PnPWeb -Includes RegionalSettings,RegionalSettings.TimeZones
$timeZone = $web.RegionalSettings.TimeZones | Where-Object {$_.Id -eq $TimeZoneId}
$web.RegionalSettings.LocaleId = $LocaleId
$web.RegionalSettings.TimeZone = $timeZone
$web.Update()
Invoke-PnPQuery
}

The script changed SP sites to UK locale, but all OneDrive sites came as "Access Denied" because of unique permissions.

So I was thinking the solution is to add the account running the script as secondary admin to users OneDrive sites, run the above script and remove the secondary admin account at the end of the script and leave the original permissions to all sites.

Adding to the script above something as:

#Store 2nd Admin account into a variable
$adminAcctToAdd = "[email protected]"

#Add 2nd Site Collection admin
Set-SPOUser -Site $url.PersonalUrl -LoginName $adminAcctToAdd -IsSiteCollectionAdmin $true

Run the above locale change script and at the end remove the secondary admin:

Set-SPOUser -Site $url.PersonalUrl -LoginName $adminAcctToRemove -IsSiteCollectionAdmin $false

Any help how to bolt that together?

Much appreciated! Best!

1 Answer 1

0

The major trick is being able to grant your "SharePoint Administrator" account as site collection administrator temporarily for that operation without changing the default Site Owner.

The PnP command to help you in that case is "Set-PnPTenantSite" and some CSOM usages in an old school way to avoid PnP context mixed-up.

For you information, "Set-SPOUser" works only if your account is already granted as site collection administrator and is not compatible with PnP contexts.

The PS script below would help you.

Import-Module SharePointPnPPowerShellOnline

$tenantName = "<YOUR_TENANT_NAME>"
$localeId = 2057 # UK
$timeZoneId = 2 # London


#Connect to SPO Tenant
$cnx = Connect-PnPOnline "https://$tenantName-admin.sharepoint.com" -UseWebLogin -ReturnConnection


#Get Tenant CSOM instance
$tenant = new-object Microsoft.Online.SharePoint.TenantAdministration.Tenant([Microsoft.SharePoint.Client.ClientRuntimeContext]$cnx.Context)
function Remove-PnPTenantSiteCollectionAdministrator{
    param([string]$siteUrl, [string[]]$users)
    $ctx = $tenant.Context;
    $targetSite = $tenant.GetSiteByUrl($siteUrl);
    $ctx.Load($targetSite);
    $ctx.ExecuteQuery();

    $users |%{
        $user = $targetSite.RootWeb.EnsureUser($_);
        $ctx.Load($user)
        $ctx.ExecuteQuery();
        if($user.IsSiteAdmin){
            $user.IsSiteAdmin = $false;
            $user.Update();
        }
    }
    $ctx.ExecuteQuery();
}
function Get-PnPTenantSiteAuthor{
    param([string]$siteUrl)
    $ctx = $tenant.Context;
    $targetSite = $tenant.GetSiteByUrl($siteUrl);
    $author = $targetSite.RootWeb.Author
    $ctx.Load($author);
    $ctx.ExecuteQuery()
    [pscustomobject]@{
        LoginName = $author.LoginName
        DisplayName = $author.Title
        UserPrincipalName = $author.UserPrincipalName
        Email = $author.Email
    }
}

#Get current UserName
$tenantWeb = Get-PnPWeb
$tenantWeb.Context.Load($tenantWeb.CurrentUser)
$tenantWeb.Context.ExecuteQuery()
$currentUser = $tenantWeb.CurrentUser



#Get All sites then execute
Get-PnPTenantSite | %{
    $site = $_;
    
    #Grant current user as admin if it's not already it's own
    if($site.OwnerEmail -ne $currentUser.Email){
        $site.Url | Set-PnPTenantSite -Owners $currentUser.Email |out-null
    }

    $user = Get-PnPTenantSiteAuthor $site.Url

    try{
        $ctx = $tenant.Context;

        $targetSite = $tenant.GetSiteByUrl($site.Url);
        $web = $targetSite.RootWeb;

        $timeZones = $web.RegionalSettings.TimeZones
        $ctx.Load($timeZones)
        $ctx.ExecuteQuery()

        $timeZone = $timeZones | ?{ $_.Id -eq $timeZoneId }

        $web.RegionalSettings.LocaleId = $localeId
        $web.RegionalSettings.TimeZone = $timeZone

        $web.Update()
        $ctx.ExecuteQuery()
    
    }
    finally{
    
        #Remove Current User as admin except for it's own
        if($site.OwnerEmail -ne $currentUser.Email){
            Remove-PnPTenantSiteCollectionAdministrator $site.Url $currentUser.LoginName |out-null
        }
        #ensure owner is the real owner
        if([string]::IsNullOrEmpty($site.Owner)){
            $site.Url | Set-PnPTenantSite -Owners $user.UserPrincipalName |out-null
        }

    }

}
1
  • Thank you Vladimir!. I will need to test it and if successful - will go through change request procedure. How to modify to test on couple of sites before running it to whole tenant? Many thanks!
    – SPfearful
    Commented Apr 14, 2021 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.