-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1606 from gautamdsheth/feature/603
Feature #603 - added cmdlet to rename site URL
- Loading branch information
Showing
4 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
--- | ||
Module Name: PnP.PowerShell | ||
title: Rename-PnPTenantSite | ||
schema: 2.0.0 | ||
applicable: SharePoint Online | ||
external help file: PnP.PowerShell.dll-Help.xml | ||
online version: https://pnp.github.io/powershell/cmdlets/Rename-PnPTenantSite.html | ||
--- | ||
|
||
# Rename-PnPTenantSite | ||
|
||
## SYNOPSIS | ||
This command starts a rename of a site on a SharePoint Online site. You can change the URL, and optionally the site title along with changing the URL. | ||
|
||
This will not work for Multi-geo environments. | ||
|
||
## SYNTAX | ||
|
||
```powershell | ||
Rename-PnPTenantSite [[-Identity] <SPOSitePipeBind>] [[-NewSiteUrl] <String>] [[-NewSiteTitle] <string>] | ||
[[-SuppressMarketplaceAppCheck] [<SwitchParameter>]] [[-SuppressWorkflow2013Check] [<SwitchParameter>]] [-Connection <PnPConnection>] [<CommonParameters>] | ||
``` | ||
|
||
## DESCRIPTION | ||
|
||
## EXAMPLES | ||
|
||
### EXAMPLE 1 | ||
```powershell | ||
$currentSiteUrl = "https://<tenant>.sharepoint.com/site/samplesite" | ||
$updatedSiteUrl = "https://<tenant>.sharepoint.com/site/renamed" | ||
Rename-PnPTenantSite -Identity $currentSiteUrl -NewSiteUrl $updatedSiteUrl | ||
``` | ||
|
||
Starts the rename of the SharePoint Online site with name "samplesite" to "renamed" without modifying the title. | ||
|
||
## PARAMETERS | ||
|
||
### -Connection | ||
Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. | ||
|
||
```yaml | ||
Type: PnPConnection | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -Identity | ||
Specifies the full URL of the SharePoint Online site collection that needs to be renamed. | ||
```yaml | ||
Type: SPOSitePipeBind | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: True | ||
Accept wildcard characters: False | ||
``` | ||
### -NewSiteUrl | ||
Specifies the full URL of the SharePoint Online site collection to which it needs to be renamed. | ||
```yaml | ||
Type: String | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -NewSiteTitle | ||
Specifies the new title of of the SharePoint Site. | ||
```yaml | ||
Type: String | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -SuppressMarketplaceAppCheck | ||
Suppress checking compatibility of marketplace SharePoint Add-ins deployed to the associated site. | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -SuppressWorkflow2013Check | ||
Suppress checking compatibility of SharePoint 2013 Workflows deployed to the associated site. | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -SuppressBcsCheck | ||
Suppress checking compatibility of BCS connections deployed to the associated site. | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: True | ||
Accept wildcard characters: False | ||
``` | ||
### -Wait | ||
Wait till the renaming of the new site collection is successfull. If not specified, a job will be created which you can use to check for its status. | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: (All) | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
## RELATED LINKS | ||
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
using Microsoft.SharePoint.Client; | ||
using PnP.Framework.Http; | ||
using PnP.PowerShell.Commands.Base; | ||
using PnP.PowerShell.Commands.Base.PipeBinds; | ||
using PnP.PowerShell.Commands.Model; | ||
using PnP.PowerShell.Commands.Utilities; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Management.Automation; | ||
using System.Net.Http; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
|
||
namespace PnP.PowerShell.Commands.Admin | ||
{ | ||
[Cmdlet(VerbsCommon.Rename, "PnPTenantSite")] | ||
public class RenameTenantSite : PnPAdminCmdlet | ||
{ | ||
[Parameter(Mandatory = true)] | ||
[ValidateNotNullOrEmpty] | ||
public SPOSitePipeBind Identity { get; set; } | ||
|
||
[Parameter(Mandatory = true)] | ||
[ValidateNotNullOrEmpty] | ||
public string NewSiteUrl { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
[ValidateNotNullOrEmpty] | ||
public string NewSiteTitle { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter SuppressMarketplaceAppCheck { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter SuppressWorkflow2013Check { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter SuppressBcsCheck { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter Wait { get; set; } | ||
|
||
protected override void ExecuteCmdlet() | ||
{ | ||
ClientContext.ExecuteQueryRetry(); // fixes issue where ServerLibraryVersion is not available. | ||
|
||
int optionsBitMask = 0; | ||
if (SuppressMarketplaceAppCheck.IsPresent) | ||
{ | ||
optionsBitMask |= 8; | ||
} | ||
if (SuppressWorkflow2013Check.IsPresent) | ||
{ | ||
optionsBitMask |= 16; | ||
} | ||
if (SuppressBcsCheck.IsPresent) | ||
{ | ||
optionsBitMask |= 128; | ||
} | ||
|
||
var body = new | ||
{ | ||
SourceSiteUrl = Identity.Url, | ||
TargetSiteUrl = NewSiteUrl, | ||
TargetSiteTitle = NewSiteTitle ?? null, | ||
Option = optionsBitMask, | ||
Reserve = string.Empty, | ||
OperationId = Guid.Empty | ||
}; | ||
|
||
var tenantUrl = UrlUtilities.GetTenantAdministrationUrl(ClientContext.Url); | ||
|
||
var results = Utilities.REST.RestHelper.PostAsync<SPOSiteRenameJob>(HttpClient, $"{tenantUrl.TrimEnd('/')}/_api/SiteRenameJobs?api-version=1.4.7", ClientContext, body, false).GetAwaiter().GetResult(); | ||
if (!Wait.IsPresent) | ||
{ | ||
if (results != null) | ||
{ | ||
WriteObject(results); | ||
} | ||
} | ||
else | ||
{ | ||
bool wait = true; | ||
var iterations = 0; | ||
|
||
var method = new HttpMethod("GET"); | ||
|
||
var httpClient = PnPHttpClient.Instance.GetHttpClient(ClientContext); | ||
|
||
var requestUrl = $"{tenantUrl.TrimEnd('/')}/_api/SiteRenameJobs/GetJobsBySiteUrl(url='{Identity.Url}')?api-version=1.4.7"; | ||
|
||
while (wait) | ||
{ | ||
iterations++; | ||
try | ||
{ | ||
using (HttpRequestMessage request = new HttpRequestMessage(method, requestUrl)) | ||
{ | ||
request.Headers.Add("accept", "application/json;odata=nometadata"); | ||
request.Headers.Add("X-AttemptNumber", iterations.ToString()); | ||
PnPHttpClient.AuthenticateRequestAsync(request, ClientContext).GetAwaiter().GetResult(); | ||
|
||
HttpResponseMessage response = httpClient.SendAsync(request, new System.Threading.CancellationToken()).Result; | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
var responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); | ||
if (responseString != null) | ||
{ | ||
var jsonElement = JsonSerializer.Deserialize<JsonElement>(responseString); | ||
|
||
if (jsonElement.TryGetProperty("value", out JsonElement valueProperty)) | ||
{ | ||
var siteRenameResults = JsonSerializer.Deserialize<List<SPOSiteRenameJob>>(valueProperty.ToString()); | ||
|
||
if (siteRenameResults != null && siteRenameResults.Count > 0) | ||
{ | ||
var siteRenameResponse = siteRenameResults[0]; | ||
if (!string.IsNullOrEmpty(siteRenameResponse.ErrorDescription)) | ||
{ | ||
wait = false; | ||
throw new PSInvalidOperationException(siteRenameResponse.ErrorDescription); | ||
} | ||
if (siteRenameResponse.JobState == "Success") | ||
{ | ||
wait = false; | ||
WriteObject(siteRenameResponse); | ||
} | ||
else | ||
{ | ||
Task.Delay(TimeSpan.FromSeconds(30)).GetAwaiter().GetResult(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception) | ||
{ | ||
if (iterations * 30 >= 300) | ||
{ | ||
wait = false; | ||
throw; | ||
} | ||
else | ||
{ | ||
Task.Delay(TimeSpan.FromSeconds(30)).GetAwaiter().GetResult(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
|
||
namespace PnP.PowerShell.Commands.Model | ||
{ | ||
/// <summary> | ||
/// Contains information about an ongoing SharePoint Online site collection rename | ||
/// </summary> | ||
public class SPOSiteRenameJob | ||
{ | ||
/// <summary> | ||
/// State the rename process is in | ||
/// </summary> | ||
public string JobState { get; set; } | ||
|
||
/// <summary> | ||
/// Id of the site that is being renamed | ||
/// </summary> | ||
public Guid? SiteId { get; set; } | ||
|
||
/// <summary> | ||
/// Unique identifier of the rename job | ||
/// </summary> | ||
public Guid? JobId { get; set; } | ||
|
||
/// <summary> | ||
/// Unknown | ||
/// </summary> | ||
public Guid? ParentId { get; set; } | ||
|
||
/// <summary> | ||
/// Person or process having initiated the rename | ||
/// </summary> | ||
public string TriggeredBy { get; set; } | ||
|
||
/// <summary> | ||
/// Error code, if any | ||
/// </summary> | ||
public int? ErrorCode { get; set; } | ||
|
||
/// <summary> | ||
/// Error description, if any | ||
/// </summary> | ||
public string ErrorDescription { get; set; } | ||
|
||
/// <summary> | ||
/// Url of the site collection before the rename | ||
/// </summary> | ||
public string SourceSiteUrl { get; set; } | ||
|
||
/// <summary> | ||
/// Url of the site collection after the rename | ||
/// </summary> | ||
public string TargetSiteUrl { get; set; } | ||
|
||
/// <summary> | ||
/// Unknown | ||
/// </summary> | ||
public object TargetSiteTitle { get; set; } | ||
|
||
/// <summary> | ||
/// Unknown | ||
/// </summary> | ||
public int? Option { get; set; } | ||
|
||
/// <summary> | ||
/// Unknown | ||
/// </summary> | ||
public object Reserve { get; set; } | ||
|
||
/// <summary> | ||
/// Unknown | ||
/// </summary> | ||
public object SkipGestures { get; set; } | ||
} | ||
} |