For you information, "Set-PnPUserSPOUser" works only if your account is already granted as site collection administrator and is not compatible with PnP contexts.
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 $res$user.UserPrincipalName |out-null } } }