From 65422453a6047cb01f3f9831cd53d7b364773562 Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Fri, 22 Dec 2023 11:02:21 +0200 Subject: [PATCH 1/2] Feature #3422 - improve file conversion code --- CHANGELOG.md | 2 +- documentation/Convert-PnPFile.md | 182 +++++++++++++++++++++++++ documentation/Convert-PnPFileToPdf.md | 151 -------------------- src/Commands/Files/ConvertFile.cs | 152 +++++++++++++++++++++ src/Commands/Files/ConvertFileToPdf.cs | 153 --------------------- 5 files changed, 335 insertions(+), 305 deletions(-) create mode 100644 documentation/Convert-PnPFile.md delete mode 100644 documentation/Convert-PnPFileToPdf.md create mode 100644 src/Commands/Files/ConvertFile.cs delete mode 100644 src/Commands/Files/ConvertFileToPdf.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index c2a0e152e..00091b3e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added `-IsDataAccessInCardDesignerEnabled` to `Set-PnPTenant` which allows for configuring Viva Connections Adaptive Cards to connect to backend services for their data [#3635](https://github.com/pnp/powershell/pull/3635) - Added `Remove-PnPContainer` cmdlet to remove the SharePoint embed container. [#3629](https://github.com/pnp/powershell/pull/3629) -- Added `Convert-PnPFileToPdf` cmdlet which allows for a file to be converted to PDF [#3435](https://github.com/pnp/powershell/pull/3435) +- Added `Convert-PnPFile` cmdlet which allows for a file to be converted to from one format to another. [#3435](https://github.com/pnp/powershell/pull/3435) - Added `Merge-PnPTerm` cmdlet which allows merging of one term into another. [#3638](https://github.com/pnp/powershell/pull/3638) ### Contributors diff --git a/documentation/Convert-PnPFile.md b/documentation/Convert-PnPFile.md new file mode 100644 index 000000000..be64541ac --- /dev/null +++ b/documentation/Convert-PnPFile.md @@ -0,0 +1,182 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Convert-PnPFile.html +external help file: PnP.PowerShell.dll-Help.xml +title: Convert-PnPFile +--- + +# Convert-PnPFile + +## SYNOPSIS +Converts a file to another format + +## SYNTAX + + +### Save to local path +```powershell +Convert-PnPFile -Url -Path [-Force] +``` + +### Return as memorystream +```powershell +Convert-PnPFile -Url -AsMemoryStream +``` + +### Save to SharePoint Online (Same SiteCollection) +```powershell +Convert-PnPFile -Url -Folder +``` + +## DESCRIPTION +Allows converting of a file from SharePoint Online. The file contents can either be directly saved to local disk, or stored in memory for further processing, or Can be uploaded back to SharePoint Online SiteCollection + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Document.docx" -AsMemoryStream +``` + +Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream + +### EXAMPLE 2 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Document.docx" +``` + +Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream + +### EXAMPLE 3 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Document.docx" -Path "C:\Temp" +``` + +Retrieves the file and converts to PDF, and save it to the given local path + +### EXAMPLE 4 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Document.docx" -Path "C:\Temp" -Force +``` + +Retrieves the file and converts to PDF, and save it to the given local path. Force parameter will override the existing file in the location where the document gets saved. + +### EXAMPLE 5 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Test/Book.xlsx" -Folder "/sites/demo/Shared Documents/Archive" +``` + +Retrieves the file and converts to PDF, and save it to the given Document library (Folder) in SharePoint Online (same site collection) + +### EXAMPLE 6 +```powershell +Convert-PnPFile -Url "/sites/demo/Shared Documents/Test/Book.png" -ConvertToFormat Jpg -Folder "/sites/demo/Shared Documents/Archive" +``` + +Retrieves the file and converts to JPG, and save it to the given Document library (Folder) in SharePoint Online (same site collection) + +## PARAMETERS + +### -Url +The URL (server or site relative) to the file + +```yaml +Type: String +Parameter Sets: (All) +Aliases: ServerRelativeUrl, SiteRelativeUrl + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ConvertToFormat +The format to which you want the file to be converted. Default is PDF. + +The following values are valid transformation targets and their supported source extensions: + +| Target | Description | Supported source extensions +|:------|:-----------------------------------|--------------------------------- +| glb | Converts the item into GLB format | cool, fbx, obj, ply, stl, 3mf +| html | Converts the item into HTML format | eml, md, msg +| jpg | Converts the item into JPG format | 3g2, 3gp, 3gp2, 3gpp, 3mf, ai, arw, asf, avi, bas, bash, bat, bmp, c, cbl, cmd, cool, cpp, cr2, crw, cs, css, csv, cur, dcm, dcm30, dic, dicm, dicom, dng, doc, docx, dwg, eml, epi, eps, epsf, epsi, epub, erf, fbx, fppx, gif, glb, h, hcp, heic, heif, htm, html, ico, icon, java, jfif, jpeg, jpg, js, json, key, log, m2ts, m4a, m4v, markdown, md, mef, mov, movie, mp3, mp4, mp4v, mrw, msg, mts, nef, nrw, numbers, obj, odp, odt, ogg, orf, pages, pano, pdf, pef, php, pict, pl, ply, png, pot, potm, potx, pps, ppsx, ppsxm, ppt, pptm, pptx, ps, ps1, psb, psd, py, raw, rb, rtf, rw1, rw2, sh, sketch, sql, sr2, stl, tif, tiff, ts, txt, vb, webm, wma, wmv, xaml, xbm, xcf, xd, xml, xpm, yaml, yml +| pdf | Converts the item into PDF format | doc, docx, epub, eml, htm, html, md, msg, odp, ods, odt, pps, ppsx, ppt, pptx, rtf, tif, tiff, xls, xlsm, xlsx + +For more information, check [this link](https://pnp.github.io/pnpcore/using-the-sdk/files-intro.html#converting-files). + + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Default value: Pdf +Accept pipeline input: False +Accept wildcard characters: False +``` + + +### -AsMemoryStream + +```yaml +Type: SwitchParameter +Parameter Sets: Return as memorystream + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Path +Local path where the file should be saved + +```yaml +Type: String +Parameter Sets: Save to local path + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + + +### -Force +Overwrites the file if it exists. + +```yaml +Type: SwitchParameter +Parameter Sets: Save to local path, Upload to SharePoint + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Folder +The destination library in the site + +```yaml +Type: FolderPipeBind +Parameter Sets: (UPLOADTOSHAREPOINT) + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Convert-PnPFileToPdf.md b/documentation/Convert-PnPFileToPdf.md deleted file mode 100644 index 658e50ee1..000000000 --- a/documentation/Convert-PnPFileToPdf.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -Module Name: PnP.PowerShell -schema: 2.0.0 -applicable: SharePoint Online -online version: https://pnp.github.io/powershell/cmdlets/Convert-PnPFileToPDF.html -external help file: PnP.PowerShell.dll-Help.xml -title: Convert-PnPFileToPDF ---- - -# Convert-PnPFileToPDF - -## SYNOPSIS -Converts a file to Pdf - -## SYNTAX - - -### Save to local path -```powershell -Convert-PnPFileToPDF -Url -Path [-Force] -``` - -### Return as memorystream -```powershell -Convert-PnPFileToPDF -Url -AsMemoryStream -``` - -### Save to SharePoint Online (Same SiteCollection) -```powershell -Convert-PnPFileToPDF -Url -Folder -``` - -## DESCRIPTION -Allows converting of a file from SharePoint Online. The file contents can either be directly saved to local disk, or stored in memory for further processing, or Can be uploaded back to SharePoint Online SiteCollection - -## EXAMPLES - -### EXAMPLE 1 -```powershell -Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -AsMemoryStream -``` - -Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream - -### EXAMPLE 2 -```powershell -Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -``` - -Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream - -### EXAMPLE 3 -```powershell -Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -Path "C:\Temp" -``` - -Retrieves the file and converts to PDF, and save it to the given local path - -### EXAMPLE 4 -```powershell -Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -Path "C:\Temp" -Force -``` - -Retrieves the file and converts to PDF, and save it to the given local path. Force parameter will override the existing file in the location where the document gets saved. - -### EXAMPLE 5 -```powershell -Convert-PnPFileToPDF -Url "/sites/SampleTeamSite/Shared Documents/Nishkalank's/Book.xlsx.docx" -Folder "Archive" -``` - -Retrieves the file and converts to PDF, and save it to the given Document library (Folder) in SharePoint Online (Same SiteCollection). Returns the saved file information in the console. - - - -## PARAMETERS - -### -Url -The URL (server or site relative) to the file - -```yaml -Type: String -Parameter Sets: (All) -Aliases: ServerRelativeUrl, SiteRelativeUrl - -Required: True -Position: 0 -Default value: None -Accept pipeline input: True (ByValue) -Accept wildcard characters: False -``` - - -### -AsMemoryStream - -```yaml -Type: SwitchParameter -Parameter Sets: Return as memorystream - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Path -Local path where the file should be saved - -```yaml -Type: String -Parameter Sets: Save to local path - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - - -### -Force -Overwrites the file if it exists. - -```yaml -Type: SwitchParameter -Parameter Sets: Save to local path - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Folder -The destination library in the site - -```yaml -Type: FolderPipeBind -Parameter Sets: (UPLOADTOSHAREPOINT) - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -## RELATED LINKS - -[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/src/Commands/Files/ConvertFile.cs b/src/Commands/Files/ConvertFile.cs new file mode 100644 index 000000000..4673ede3e --- /dev/null +++ b/src/Commands/Files/ConvertFile.cs @@ -0,0 +1,152 @@ +using Microsoft.SharePoint.Client; +using PnP.Core.Model.SharePoint; +using PnP.Framework.Utilities; +using PnP.PowerShell.Commands.Base.PipeBinds; +using System.IO; +using System.Management.Automation; + +namespace PnP.PowerShell.Commands.Files +{ + [Cmdlet(VerbsData.Convert, "PnPFile")] + public class ConvertFile : PnPWebCmdlet + { + private const string URLTOPATH = "Save to local path"; + private const string URLASMEMORYSTREAM = "Return as memorystream"; + private const string UPLOADTOSHAREPOINT = "Upload to SharePoint"; + + [Parameter(Mandatory = true, ParameterSetName = URLTOPATH, Position = 0, ValueFromPipeline = true)] + [Parameter(Mandatory = true, ParameterSetName = URLASMEMORYSTREAM, Position = 0, ValueFromPipeline = true)] + [Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT, Position = 0, ValueFromPipeline = true)] + [Alias("ServerRelativeUrl", "SiteRelativeUrl")] + public string Url; + + [Parameter(Mandatory = false, ParameterSetName = URLTOPATH)] + [Parameter(Mandatory = false, ParameterSetName = URLASMEMORYSTREAM)] + [Parameter(Mandatory = false, ParameterSetName = UPLOADTOSHAREPOINT)] + public ConvertToFormat ConvertToFormat = ConvertToFormat.Pdf; + + [Parameter(Mandatory = true, ParameterSetName = URLTOPATH)] + public string Path = string.Empty; + + [Parameter(Mandatory = false, ParameterSetName = URLTOPATH)] + [Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT)] + public SwitchParameter Force; + + [Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT)] + [ValidateNotNullOrEmpty] + public FolderPipeBind Folder; + + [Parameter(Mandatory = false, ParameterSetName = URLASMEMORYSTREAM)] + public SwitchParameter AsMemoryStream; + + protected override void ExecuteCmdlet() + { + if (string.IsNullOrEmpty(Path)) + { + Path = SessionState.Path.CurrentFileSystemLocation.Path; + } + else if (!System.IO.Path.IsPathRooted(Path)) + { + Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); + } + + // 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")); + + var webUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); + var serverRelativeUrl = string.Empty; + if (!Url.ToLower().StartsWith(webUrl.ToLower())) + { + serverRelativeUrl = UrlUtility.Combine(webUrl, Url); + } + else + { + serverRelativeUrl = Url; + } + + IFile sourceFile = PnPContext.Web.GetFileByServerRelativeUrl(serverRelativeUrl, p => p.VroomDriveID, p => p.VroomItemID); + + WriteVerbose("Converting file to the specified format"); + var convertedFile = sourceFile.ConvertTo(new ConvertToOptions { Format = ConvertToFormat }); + + var fileName = System.IO.Path.GetFileNameWithoutExtension(sourceFile.Name); + var newFileName = fileName + "." + ConvertToFormat.ToString(); + + switch (ParameterSetName) + { + case URLTOPATH: + + var fileOut = System.IO.Path.Combine(Path, newFileName); + if (System.IO.File.Exists(fileOut) && !Force) + { + WriteWarning($"File '{sourceFile.Name}' exists already. Use the -Force parameter to overwrite the file."); + } + else + { + WriteVerbose("Saving file to the disc."); + using FileStream fs = new(fileOut, FileMode.Create); + convertedFile.CopyTo(fs); + } + + break; + + case URLASMEMORYSTREAM: + + var stream = new MemoryStream(); + convertedFile.CopyTo(stream); + WriteObject(stream); + break; + + case UPLOADTOSHAREPOINT: + + WriteVerbose("Uploading file to the specified folder"); + var folder = EnsureFolder(); + var uploadedFile = folder.UploadFile(newFileName, convertedFile, Force); + + try + { + ClientContext.Load(uploadedFile, f => f.Author, f => f.Length, f => f.ModifiedBy, f => f.Name, f => f.TimeCreated, f => f.TimeLastModified, f => f.Title); + ClientContext.ExecuteQueryRetry(); + } + catch (ServerException) + { + // Assume the cause of the exception is that a principal cannot be found and try again without: + // Fallback in case the creator or person having last modified the file no longer exists in the environment such that the file can still be downloaded + ClientContext.Load(uploadedFile, f => f.Length, f => f.Name, f => f.TimeCreated, f => f.TimeLastModified, f => f.Title); + ClientContext.ExecuteQueryRetry(); + } + + WriteObject(uploadedFile); + WriteVerbose("File uploaded."); + break; + + } + } + + /// + /// Ensures the folder to which the file is to be uploaded exists. Changed from using the EnsureFolder implementation in PnP Framework as that requires at least member rights to the entire site to work. + /// + /// The folder to which the file needs to be uploaded + private Folder EnsureFolder() + { + // First try to get the folder if it exists already. This avoids an Access Denied exception if the current user doesn't have Full Control access at Web level + CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); + + Folder folder = null; + try + { + folder = Folder.GetFolder(CurrentWeb); + folder.EnsureProperties(f => f.ServerRelativeUrl); + return folder; + } + // Exception will be thrown if the folder does not exist yet on SharePoint + catch (ServerException serverEx) when (serverEx.ServerErrorCode == -2147024894) + { + // Try to create the folder + folder = CurrentWeb.EnsureFolder(CurrentWeb.RootFolder, Folder.ServerRelativeUrl); + folder.EnsureProperties(f => f.ServerRelativeUrl); + return folder; + } + } + } +} \ No newline at end of file diff --git a/src/Commands/Files/ConvertFileToPdf.cs b/src/Commands/Files/ConvertFileToPdf.cs deleted file mode 100644 index 5bd29e31f..000000000 --- a/src/Commands/Files/ConvertFileToPdf.cs +++ /dev/null @@ -1,153 +0,0 @@ -using Microsoft.SharePoint.Client; -using PnP.Framework.Utilities; -using System.Management.Automation; -using PnP.PowerShell.Commands.Base; -using PnP.PowerShell.Commands.Utilities.REST; -using System.IO; -using PnP.PowerShell.Commands.Base.PipeBinds; - -namespace PnP.PowerShell.Commands.Files -{ - [Cmdlet(VerbsData.Convert, "PnPFileToPDF")] - public class ConvertFileToPDF : PnPWebCmdlet - { - private const string URLTOPATH = "Save to local path"; - private const string URLASMEMORYSTREAM = "Return as memorystream"; - private const string UPLOADTOSHAREPOINT = "Upload to SharePoint"; - - [Parameter(Mandatory = true, ParameterSetName = URLTOPATH, Position = 0, ValueFromPipeline = true)] - [Parameter(Mandatory = true, ParameterSetName = URLASMEMORYSTREAM, Position = 0, ValueFromPipeline = true)] - [Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT, Position = 0, ValueFromPipeline = true)] - [Alias("ServerRelativeUrl", "SiteRelativeUrl")] - public string Url; - - [Parameter(Mandatory = true, ParameterSetName = URLTOPATH)] - public string Path = string.Empty; - - [Parameter(Mandatory = false, ParameterSetName = URLTOPATH)] - public SwitchParameter Force; - - [Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT)] - [ValidateNotNullOrEmpty] - public FolderPipeBind Folder; - - [Parameter(Mandatory = false, ParameterSetName = URLASMEMORYSTREAM)] - public SwitchParameter AsMemoryStream; - - protected override void ExecuteCmdlet() - { - if (string.IsNullOrEmpty(Path)) - { - Path = SessionState.Path.CurrentFileSystemLocation.Path; - } - else if (!System.IO.Path.IsPathRooted(Path)) - { - Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); - } - - Url = Utilities.UrlUtilities.UrlDecode(Url.Replace("+", "%2B")); - var serverRelativeUrl = GetServerRelativeUrl(Url); - var fileObj = GetFileByServerRelativePath(serverRelativeUrl); - var sourceFileName = fileObj.Name.ToString().Substring(0, fileObj.Name.ToString().LastIndexOf(".")); - var apiUrl = GeneratePdfApiUrl(Url, sourceFileName, fileObj); - byte[] response = RestHelper.GetByteArrayAsync(Connection.HttpClient, apiUrl, GraphAccessToken).GetAwaiter().GetResult(); - var fileToDownloadName = !string.IsNullOrEmpty(sourceFileName) ? sourceFileName : "Download"; - - switch (ParameterSetName) - { - case URLTOPATH: - var fileOut = System.IO.Path.Combine(Path, $"{fileToDownloadName}.pdf"); - if (!Directory.Exists(Path)) - { - throw new PSArgumentException("Path does not exists"); - } - if (!Force && System.IO.File.Exists(fileOut)) - { - WriteWarning($"File '{fileToDownloadName}' exists already. Use the -Force parameter to overwrite the file."); - } - else - { - System.IO.File.WriteAllBytes(fileOut, response); - WriteObject($"File saved as {fileOut}"); - } - break; - - case URLASMEMORYSTREAM: - var stream = new MemoryStream(response); - WriteObject(stream); - break; - - case UPLOADTOSHAREPOINT: - var targetLibrary = EnsureFolder(); - Stream fileStream = new MemoryStream(response); - var targetFileName = $"{fileToDownloadName}.pdf"; - var uploadedFile = targetLibrary.UploadFileAsync(targetFileName, fileStream, true).GetAwaiter().GetResult(); - ClientContext.Load(uploadedFile); - try - { - ClientContext.ExecuteQueryRetry(); - } - catch (ServerException) - { - ClientContext.Load(uploadedFile, f => f.Length, f => f.Name, f => f.TimeCreated, f => f.TimeLastModified, f => f.Title); - ClientContext.ExecuteQueryRetry(); - } - WriteObject(uploadedFile); - break; - } - } - - private string GetServerRelativeUrl(string url) - { - var webUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); - return url.ToLower().StartsWith(webUrl.ToLower()) ? url : UrlUtility.Combine(webUrl, Url); - } - - private Microsoft.SharePoint.Client.File GetFileByServerRelativePath(string serverRelativeUrl) - { - var fileListItem = CurrentWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl)); - ClientContext.Load(fileListItem, f => f.Exists, f => f.ListItemAllFields, f => f.ListId, f => f.Name); - ClientContext.ExecuteQueryRetry(); - if (fileListItem.Exists) - { - return fileListItem; - } - else - { - throw new PSArgumentException($"No file found with the provided Url {serverRelativeUrl}", "Url"); - } - } - - private string GeneratePdfApiUrl(string url, string sourceFileName, Microsoft.SharePoint.Client.File fileObj) - { - var siteId = PnPContext.Site.Id.ToString(); - var listId = fileObj.ListId.ToString(); - var itemId = fileObj.ListItemAllFields.Id.ToString(); - return $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/lists/{listId}/items/{itemId}/driveItem/content?format=pdf"; - } - - - private Folder EnsureFolder() - { - // First try to get the folder if it exists already. This avoids an Access Denied exception if the current user doesn't have Full Control access at Web level - CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); - - Folder library = null; - try - { - library = Folder.GetFolder(CurrentWeb); - library.EnsureProperties(f => f.ServerRelativeUrl); - return library; - } - // Exception will be thrown if the library does not exist yet on SharePoint - catch (ServerException serverEx) when (serverEx.ServerErrorCode == -2147024894) - { - // create the library - CurrentWeb.CreateList(ListTemplateType.DocumentLibrary, Folder.ServerRelativeUrl, false, true, "", false, false); - library = Folder.GetFolder(CurrentWeb); - library.EnsureProperties(f => f.ServerRelativeUrl); - return library; - } - } - } -} From b7278b0bbfbb66b90492466e19e0e78923241346 Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Fri, 22 Dec 2023 11:03:55 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00091b3e8..7faffa3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added `-IsDataAccessInCardDesignerEnabled` to `Set-PnPTenant` which allows for configuring Viva Connections Adaptive Cards to connect to backend services for their data [#3635](https://github.com/pnp/powershell/pull/3635) - Added `Remove-PnPContainer` cmdlet to remove the SharePoint embed container. [#3629](https://github.com/pnp/powershell/pull/3629) -- Added `Convert-PnPFile` cmdlet which allows for a file to be converted to from one format to another. [#3435](https://github.com/pnp/powershell/pull/3435) +- Added `Convert-PnPFile` cmdlet which allows for a file to be converted to from one format to another. [#3435](https://github.com/pnp/powershell/pull/3435) and [#3643](https://github.com/pnp/powershell/pull/3643) - Added `Merge-PnPTerm` cmdlet which allows merging of one term into another. [#3638](https://github.com/pnp/powershell/pull/3638) ### Contributors