Skip to content

Commit

Permalink
Added -Identity parameter to the Get-PnPFileSharingLink extending…
Browse files Browse the repository at this point in the history
… its flexibility (#4093)

* Added implementation

* Added PR reference

* Added another sample on filtering for sharing links without expirations set

* Code cleanup

---------

Co-authored-by: Gautam Sheth <[email protected]>
  • Loading branch information
KoenZomers and gautamdsheth authored Jul 16, 2024
1 parent e69c830 commit a25ffc7
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Added
- Added in depth verbose logging to all cmdlets which is revealed by adding `-Verbose` to the cmdlet execution [#4023](https://github.com/pnp/powershell/pull/4023)
- Added `-CoreDefaultShareLinkScope` and `-CoreDefaultShareLinkRole` parameters to `Set-PnPTenant` cmdlet. [#4067](https://github.com/pnp/powershell/pull/4067)
- Added `-Identity` parameter to the `Get-PnPFileSharingLink` cmdlet allowing for the retrieval of sharing links based on the file's unique identifier, file instance, listitem instance, or server relative path and supporting retrieval of sharing links for multiple files, such as all in a document library [#4093](https://github.com/pnp/powershell/pull/4093)

### Fixed
- `Get-PnPTeamsChannel` and `Get-PnPTeamsPrimaryChannel` returning `unknownFutureValue` as MembershipType instead of `shared` [#4054]https://github.com/pnp/powershell/pull/4054

### Changed
- Fixed `Update-PnPTeamsUser` cmdlet to throw a better error message when after a user is removed from a Team but is still in the connected M365 group, for the few seconds that the 2 are out of sync. [#4068](https://github.com/pnp/powershell/pull/4068)
- Changed `-FileUrl` on `Get-PnPFileSharingLink` to become obsolete. Please switch to using `-Identity` instead, passing in the same value [#4093](https://github.com/pnp/powershell/pull/4093)

### Removed

Expand Down
68 changes: 62 additions & 6 deletions documentation/Get-PnPFileSharingLink.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Retrieves sharing links to associated with the file.
## SYNTAX

```powershell
Get-PnPFileSharingLink -FileUrl <String> [-Connection <PnPConnection>]
Get-PnPFileSharingLink -Identity <FilePipeBind> [-Verbose] [-Connection <PnPConnection>]
```

## DESCRIPTION
Expand All @@ -26,10 +26,52 @@ Retrieves sharing links for a file.

### EXAMPLE 1
```powershell
Get-PnPFileSharingLink -FileUrl "/sites/demo/Shared Documents/Test.docx"
Get-PnPFileSharingLink -Identity "/sites/demo/Shared Documents/Test.docx"
```

This will fetch sharing links for `Test.docx` file in the `Shared Documents` library.
This will fetch sharing links for `Test.docx` file in the `Shared Documents` library based on the server relative url.

### EXAMPLE 2
```powershell
Get-PnPFileSharingLink -Identity eff4c8ca-7b92-4aa2-9744-855611c6ccf2
```

This will fetch sharing links for the file in the site with the provided unique identifier, regardless of where it is located.

### EXAMPLE 3
```powershell
Get-PnPListItem -List "Documents" | Get-PnPFileSharingLink
```

This will fetch sharing links for all files in the `Documents` library.

### EXAMPLE 4
```powershell
Get-PnPListItem -List "Documents" -Id 1 | Get-PnPFileSharingLink
```

This will fetch sharing links for the file in the `Documents` library with Id 1.

### EXAMPLE 5
```powershell
Get-PnPFile -Url "/sites/demo/Shared Documents/Test.docx" | Get-PnPFileSharingLink
```

This will fetch sharing links for the passed in file.

### EXAMPLE 6
```powershell
Get-PnPFileInFolder -Recurse -ExcludeSystemFolders -FolderSiteRelativeUrl "Shared Documents" | Get-PnPFileSharingLink
```

This will fetch sharing links for all files in the `Shared Documents` library, including the files in subfolders, excluding the ones in hidden internal system folders.

### EXAMPLE 7
```powershell
Get-PnPFileInFolder -Recurse -ExcludeSystemFolders -FolderSiteRelativeUrl "Shared Documents" | Get-PnPFileSharingLink | ? ExpirationDateTime -eq $null
```

This will fetch sharing links for all files in the `Shared Documents` library, including the files in subfolders, excluding the ones in hidden internal system folders where no expiration has been set on the sharing of the file.

## PARAMETERS

Expand All @@ -47,11 +89,11 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -FileUrl
The file in the site
### -Identity
The server relative path to the file, the unique identifier of the file, the listitem representing the file, or the file object itself to retrieve the sharing links for.
```yaml
Type: String
Type: FilePipeBind
Parameter Sets: (All)

Required: True
Expand All @@ -61,6 +103,20 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -Verbose
When provided, additional debug statements will be shown while executing the cmdlet.
```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)
139 changes: 139 additions & 0 deletions src/Commands/Base/PipeBinds/FilePipeBind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using System;
using Microsoft.SharePoint.Client;
using System.Management.Automation;
using PnP.Core.Model.SharePoint;
using PnP.Core.Services;

namespace PnP.PowerShell.Commands.Base.PipeBinds
{
public sealed class FilePipeBind
{
#region Properties

public Guid? Id { get; private set; }
public File File { get; private set; }
public IFile CoreFile { get; private set; }
public ListItem ListItem { get; private set; }
public string ServerRelativeUrl { get; private set; }

#endregion

#region Constructors

public FilePipeBind()
{
}

public FilePipeBind(Guid id)
{
Id = id;
}

public FilePipeBind(ListItem listItem)
{
ListItem = listItem;
}

public FilePipeBind(File file)
{
File = file;
}

public FilePipeBind(IFile coreFile)
{
CoreFile = coreFile;
}

public FilePipeBind(string id)
{
if (Guid.TryParse(id, out Guid fileGuid))
{
Id = fileGuid;
}
else
{
ServerRelativeUrl = id;
}
}

#endregion

#region Methods

internal IFile GetCoreFile(PnPContext context, Cmdlet cmdlet = null)
{
if(CoreFile != null)
{
cmdlet?.WriteVerbose("File determined based on CoreFile instance");
return CoreFile;
}

if (File != null)
{
cmdlet?.WriteVerbose("File will be retrieved based on CSOM File instance");
File.EnsureProperties(f => f.UniqueId);
return context.Web.GetFileById(File.UniqueId);
}

if (ListItem != null)
{
cmdlet?.WriteVerbose("File will be retrieved based on CSOM ListItem instance");
ListItem.EnsureProperties(i => i.File);
return context.Web.GetFileById(ListItem.File.UniqueId);
}

if (Id.HasValue)
{
cmdlet?.WriteVerbose("File will be retrieved based on file id");
return context.Web.GetFileById(Id.Value);
}

if (!string.IsNullOrEmpty(ServerRelativeUrl))
{
cmdlet?.WriteVerbose("File will be retrieved based on server relative url");
return context.Web.GetFileByServerRelativeUrl(ServerRelativeUrl);
}

throw new PSInvalidOperationException("No information available to retrieve file");
}

internal File GetFile(ClientContext context, Cmdlet cmdlet = null)
{
if (File != null)
{
cmdlet?.WriteVerbose("File determined based on CSOM File instance");
return File;
}

if (CoreFile != null)
{
cmdlet?.WriteVerbose("File will be retrieved based on PnP Core File instance");
CoreFile.EnsureProperties(f => f.UniqueId);
return context.Web.GetFileById(File.UniqueId);
}

if (ListItem != null)
{
cmdlet?.WriteVerbose("File will be retrieved based on CSOM ListItem instance");
ListItem.EnsureProperties(i => i.File);
return context.Web.GetFileById(ListItem.File.UniqueId);
}

if (Id.HasValue)
{
cmdlet?.WriteVerbose("File will be retrieved based on file id");
return context.Web.GetFileById(Id.Value);
}

if (!string.IsNullOrEmpty(ServerRelativeUrl))
{
cmdlet?.WriteVerbose("File will be retrieved based on server relative url");
return context.Web.GetFileByServerRelativeUrl(ServerRelativeUrl);
}

throw new PSInvalidOperationException("No information available to retrieve file");
}

#endregion
}
}
46 changes: 34 additions & 12 deletions src/Commands/Security/GetFileSharingLink.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
using PnP.Framework.Utilities;
using PnP.Core.Model.Security;
using PnP.Core.Model.SharePoint;
using PnP.Framework.Utilities;
using System;
using System.Management.Automation;
using PnP.PowerShell.Commands.Base.PipeBinds;

namespace PnP.PowerShell.Commands.Security
{
{
[Cmdlet(VerbsCommon.Get, "PnPFileSharingLink")]
[OutputType(typeof(IGraphPermissionCollection))]
public class GetFileSharingLink : PnPWebCmdlet
{
[Parameter(Mandatory = true)]
private const string ParameterSet_BYFILEURL = "By file url";
private const string ParameterSet_BYIDENTITY = "By identity";

[Obsolete("Use Identity parameter instead")]
[Parameter(Mandatory = true, ParameterSetName = ParameterSet_BYFILEURL)]
public string FileUrl;

[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = ParameterSet_BYIDENTITY)]
public FilePipeBind Identity;

protected override void ExecuteCmdlet()
{
var serverRelativeUrl = string.Empty;
var ctx = Connection.PnPContext;
IFile file;

ctx.Web.EnsureProperties(w => w.ServerRelativeUrl);

if (!FileUrl.ToLower().StartsWith(ctx.Web.ServerRelativeUrl.ToLower()))
if (ParameterSpecified(nameof(Identity)))
{
serverRelativeUrl = UrlUtility.Combine(ctx.Web.ServerRelativeUrl, FileUrl);
file = Identity.GetCoreFile(PnPContext, this);
}
else
{
serverRelativeUrl = FileUrl;
}
var serverRelativeUrl = string.Empty;
var ctx = Connection.PnPContext;

var file = ctx.Web.GetFileByServerRelativeUrl(serverRelativeUrl);
ctx.Web.EnsureProperties(w => w.ServerRelativeUrl);

if (!FileUrl.ToLower().StartsWith(ctx.Web.ServerRelativeUrl.ToLower()))

Check warning on line 39 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'

Check warning on line 39 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'
{
serverRelativeUrl = UrlUtility.Combine(ctx.Web.ServerRelativeUrl, FileUrl);

Check warning on line 41 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'

Check warning on line 41 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'
}
else
{
serverRelativeUrl = FileUrl;

Check warning on line 45 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'

Check warning on line 45 in src/Commands/Security/GetFileSharingLink.cs

View workflow job for this annotation

GitHub Actions / build

'GetFileSharingLink.FileUrl' is obsolete: 'Use Identity parameter instead'
}

file = ctx.Web.GetFileByServerRelativeUrl(serverRelativeUrl);
}

WriteVerbose("Retrieving file sharing details from Microsoft Graph");
var sharingLinks = file.GetShareLinks();

WriteObject(sharingLinks?.RequestedItems, true);
Expand Down

0 comments on commit a25ffc7

Please sign in to comment.