From 32677fdff2e5b221a6ecbcbbd744eda24e95a716 Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Sat, 5 Oct 2024 21:02:49 +0300 Subject: [PATCH] Refactor File cmdlets to use PnP Core SDK, improved user profile cmdlets connections (#4388) Co-authored-by: Gautam Sheth --- CHANGELOG.md | 3 +++ src/Commands/Files/RemoveFile.cs | 20 +++++++++---------- src/Commands/Files/RenameFile.cs | 19 +++++++++--------- src/Commands/Files/SetFileCheckedIn.cs | 17 ++++++++++------ src/Commands/Files/SetFileCheckedOut.cs | 8 ++++---- src/Commands/Files/UndoFileCheckedOut.cs | 7 ++++--- src/Commands/Principals/ExportUserInfo.cs | 2 +- .../UserProfiles/ExportUserProfile.cs | 2 +- .../UserProfiles/RemoveUserProfile.cs | 4 ++-- 9 files changed, 45 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67cb21e3f..3400fa6ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - `New-PnPContainerType` will temporarily disable standard containers to be created due to changed being applied at Microsoft to allow this to be possible in the future [#4125](https://github.com/pnp/powershell/pull/4125) - Renamed `Get-PnPLabel` cmdlet to `Get-PnPRetentionLabel`. [#4387](https://github.com/pnp/powershell/pull/4387) - `Add-PnPNavigationNode` cmdlet updated to now support `-OpenInNewTab` parameter for different types of navigation. [#3969](https://github.com/pnp/powershell/pull/3969) +- `Remove-PnPFile` , `Rename-PnPFile`, `Set-PnPFileCheckedIn`, `Set-PnPFileCheckedOut` & `Undo-PnPFileCheckedOut` cmdlets now use PnP Core SDK behind the scenes. +- `Set-PnPFileCheckedIn` cmdlet now expects `CheckInType` to be of type `PnP.Core.Model.SharePoint.CheckinType` instead of the earlier one based on CSOM. ### Fixed @@ -42,6 +44,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fix `Get-PnPSiteTemplate -PersistMultiLanguageResources` not working correctly for xml file types. [#4326](https://github.com/pnp/powershell/pull/4326) - Fix `Add-PnPDataRowsToSiteTemplate` setting keyColumn to null when not passed. [#4325](https://github.com/pnp/powershell/pull/4325) - Fix `Connect-PnPOnline` not working correctly when `-DeviceLogin` and `-LaunchBrowser` both are specified. It used to open it in a popup. Now it correctly launches the browser. [#4325](https://github.com/pnp/powershell/pull/4345) +- `Export-PnPUserInfo`, `Export-PnPUserProfile` and `Remove-PnPUserProfile` cmdlets now work properly with proper `-Connection` parameter if specified. ### Removed diff --git a/src/Commands/Files/RemoveFile.cs b/src/Commands/Files/RemoveFile.cs index 5c35ae07f..fa697636f 100644 --- a/src/Commands/Files/RemoveFile.cs +++ b/src/Commands/Files/RemoveFile.cs @@ -1,4 +1,4 @@ -using Microsoft.SharePoint.Client; +using PnP.Core.Model.SharePoint; using PnP.Framework.Utilities; using PnP.PowerShell.Commands.Model.SharePoint; using System.Management.Automation; @@ -30,25 +30,25 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(SiteRelativeUrl))) { - var webUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); - ServerRelativeUrl = UrlUtility.Combine(webUrl, SiteRelativeUrl); + var pnpWeb = Connection.PnPContext.Web; + pnpWeb.EnsureProperties(w => w.ServerRelativeUrl); + + ServerRelativeUrl = UrlUtility.Combine(pnpWeb.ServerRelativeUrl, SiteRelativeUrl); } - var file = CurrentWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(ServerRelativeUrl)); - ClientContext.Load(file, f => f.Name); - ClientContext.ExecuteQueryRetry(); + + IFile file = Connection.PnPContext.Web.GetFileByServerRelativeUrl(ServerRelativeUrl); + file.EnsureProperties(f => f.Name); if (Force || ShouldContinue(string.Format(Resources.Delete0, file.Name), Resources.Confirm)) { if (Recycle) { var recycleResult = file.Recycle(); - ClientContext.ExecuteQueryRetry(); - WriteObject(new RecycleResult { RecycleBinItemId = recycleResult.Value }); + WriteObject(new RecycleResult { RecycleBinItemId = recycleResult }); } else { - file.DeleteObject(); - ClientContext.ExecuteQueryRetry(); + file.Delete(); } } } diff --git a/src/Commands/Files/RenameFile.cs b/src/Commands/Files/RenameFile.cs index 50c0a8c08..955961b9c 100644 --- a/src/Commands/Files/RenameFile.cs +++ b/src/Commands/Files/RenameFile.cs @@ -1,8 +1,7 @@ using System.Management.Automation; -using Microsoft.SharePoint.Client; - using Resources = PnP.PowerShell.Commands.Properties.Resources; using PnP.Framework.Utilities; +using PnP.Core.Model.SharePoint; namespace PnP.PowerShell.Commands.Files { @@ -28,20 +27,20 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == "SITE") { - var webUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); - ServerRelativeUrl = UrlUtility.Combine(webUrl, SiteRelativeUrl); + var pnpWeb = Connection.PnPContext.Web; + pnpWeb.EnsureProperties(w => w.ServerRelativeUrl); + + ServerRelativeUrl = UrlUtility.Combine(pnpWeb.ServerRelativeUrl, SiteRelativeUrl); } - var file = CurrentWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(ServerRelativeUrl)); - ClientContext.Load(file, f => f.Name, f => f.ServerRelativePath); - ClientContext.ExecuteQueryRetry(); + IFile file = Connection.PnPContext.Web.GetFileByServerRelativeUrl(ServerRelativeUrl); + file.EnsureProperties(f => f.Name, f => f.ServerRelativeUrl); if (Force || ShouldContinue(string.Format(Resources.RenameFile0To1, file.Name, TargetFileName), Resources.Confirm)) { - var targetPath = string.Concat(file.ServerRelativePath.DecodedUrl.Remove(file.ServerRelativePath.DecodedUrl.Length - file.Name.Length), TargetFileName); - file.MoveToUsingPath(ResourcePath.FromDecodedUrl(targetPath), OverwriteIfAlreadyExists ? MoveOperations.Overwrite : MoveOperations.None); + var targetPath = string.Concat(file.ServerRelativeUrl.Remove(file.ServerRelativeUrl.Length - file.Name.Length), TargetFileName); - ClientContext.ExecuteQueryRetry(); + file.MoveTo(targetPath, OverwriteIfAlreadyExists ? MoveOperations.Overwrite : MoveOperations.None); } } } diff --git a/src/Commands/Files/SetFileCheckedIn.cs b/src/Commands/Files/SetFileCheckedIn.cs index 0be0a4f10..bed60645b 100644 --- a/src/Commands/Files/SetFileCheckedIn.cs +++ b/src/Commands/Files/SetFileCheckedIn.cs @@ -1,13 +1,13 @@ using System.Management.Automation; -using Microsoft.SharePoint.Client; - +using PnP.Core.Model.SharePoint; +using CheckinType = PnP.Core.Model.SharePoint.CheckinType; namespace PnP.PowerShell.Commands.Files { [Cmdlet(VerbsCommon.Set, "PnPFileCheckedIn")] public class SetFileCheckedIn : PnPWebCmdlet { - [Parameter(Mandatory = true, Position=0, ValueFromPipeline=true)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)] public string Url = string.Empty; [Parameter(Mandatory = false)] @@ -23,10 +23,15 @@ protected override void ExecuteCmdlet() { // Remove URL decoding from the Url as that will not work. We will encode the + character specifically, because if that is part of the filename, it needs to stay and not be decoded. Url = Utilities.UrlUtilities.UrlDecode(Url.Replace("+", "%2B")); - - CurrentWeb.CheckInFile(Url, CheckinType, Comment); + + IFile file = Connection.PnPContext.Web.GetFileByServerRelativeUrl(Url); + + file.Checkin(Comment, CheckinType); + if (Approve) - CurrentWeb.ApproveFile(Url, Comment); + { + file.Approve(Comment); + } } } } diff --git a/src/Commands/Files/SetFileCheckedOut.cs b/src/Commands/Files/SetFileCheckedOut.cs index 3f956440f..98a34b9c4 100644 --- a/src/Commands/Files/SetFileCheckedOut.cs +++ b/src/Commands/Files/SetFileCheckedOut.cs @@ -1,13 +1,12 @@ using System.Management.Automation; -using Microsoft.SharePoint.Client; - +using PnP.Core.Model.SharePoint; namespace PnP.PowerShell.Commands.Files { [Cmdlet(VerbsCommon.Set, "PnPFileCheckedOut")] public class SetFileCheckedOut : PnPWebCmdlet { - [Parameter(Mandatory = true, Position=0, ValueFromPipeline=true)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)] public string Url = string.Empty; protected override void ExecuteCmdlet() @@ -15,7 +14,8 @@ protected override void ExecuteCmdlet() // Remove URL decoding from the Url as that will not work. We will encode the + character specifically, because if that is part of the filename, it needs to stay and not be decoded. Url = Utilities.UrlUtilities.UrlDecode(Url.Replace("+", "%2B")); - CurrentWeb.CheckOutFile(Url); + IFile file = Connection.PnPContext.Web.GetFileByServerRelativeUrl(Url); + file.Checkout(); } } } diff --git a/src/Commands/Files/UndoFileCheckedOut.cs b/src/Commands/Files/UndoFileCheckedOut.cs index 86179ad8f..5dfa81fb3 100644 --- a/src/Commands/Files/UndoFileCheckedOut.cs +++ b/src/Commands/Files/UndoFileCheckedOut.cs @@ -1,6 +1,5 @@ using System.Management.Automation; -using Microsoft.SharePoint.Client; - +using PnP.Core.Model.SharePoint; namespace PnP.PowerShell.Commands.Files { @@ -15,7 +14,9 @@ protected override void ExecuteCmdlet() // Remove URL decoding from the Url as that will not work. We will encode the + character specifically, because if that is part of the filename, it needs to stay and not be decoded. Url = Utilities.UrlUtilities.UrlDecode(Url.Replace("+", "%2B")); - CurrentWeb.UndoCheckOutFileAsync(Url); + IFile file = Connection.PnPContext.Web.GetFileByServerRelativeUrl(Url); + file.UndoCheckout(); + } } } diff --git a/src/Commands/Principals/ExportUserInfo.cs b/src/Commands/Principals/ExportUserInfo.cs index e9441e860..17793e6fe 100644 --- a/src/Commands/Principals/ExportUserInfo.cs +++ b/src/Commands/Principals/ExportUserInfo.cs @@ -33,7 +33,7 @@ protected override void ExecuteCmdlet() AdminContext.Load(site); AdminContext.ExecuteQueryRetry(); var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); - var results = RestHelper.Get>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", AdminContext, false); + var results = RestHelper.Get>(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) { diff --git a/src/Commands/UserProfiles/ExportUserProfile.cs b/src/Commands/UserProfiles/ExportUserProfile.cs index bd63bb554..202adafa1 100644 --- a/src/Commands/UserProfiles/ExportUserProfile.cs +++ b/src/Commands/UserProfiles/ExportUserProfile.cs @@ -21,7 +21,7 @@ protected override void ExecuteCmdlet() hostUrl = hostUrl.Substring(0, hostUrl.Length - 1); } var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); - var results = RestHelper.Get>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetUserProfileProperties(accountName=@a)?@a='{normalizedUserName}'", AdminContext, false); + var results = RestHelper.Get>(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetUserProfileProperties(accountName=@a)?@a='{normalizedUserName}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) { diff --git a/src/Commands/UserProfiles/RemoveUserProfile.cs b/src/Commands/UserProfiles/RemoveUserProfile.cs index 4e66b6e0b..8a78354f7 100644 --- a/src/Commands/UserProfiles/RemoveUserProfile.cs +++ b/src/Commands/UserProfiles/RemoveUserProfile.cs @@ -27,11 +27,11 @@ protected override void ExecuteCmdlet() if (!ParameterSpecified(nameof(UserId))) { - RestHelper.Post(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a)?@a='{normalizedUserName}'", AdminContext); + RestHelper.Post(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a)?@a='{normalizedUserName}'", AdminContext); } else { - RestHelper.Post(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a,userId='{UserId}')?@a='{normalizedUserName}'", AdminContext); + RestHelper.Post(Connection.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a,userId='{UserId}')?@a='{normalizedUserName}'", AdminContext); } WriteVerbose($"Completed deletion of user profile {LoginName}");