Skip to content

Commit

Permalink
Feature: added support for shared channel creation (#2308)
Browse files Browse the repository at this point in the history
* Feature: added support for shared channel creation

* Adding new parameter to documentation

* Cleanup and renaming

* Added changelog entry

Co-authored-by: Koen Zomers <koen@zomers.eu>
  • Loading branch information
gautamdsheth and KoenZomers committed Sep 12, 2022
1 parent 9955430 commit 1cb1fca
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 48 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added `MailEnabled`, `PreferredDataLocation`, `PreferredLanguage` and `SecurityEnabled` parameters to `New-PnPMicrosoft365Group` cmdlet. [#2268](https://github.com/pnp/powershell/pull/2268)
- Added `-DraftVersionVisibility` parameter to the `Set-PnPList` cmdlet to specify draft item security for list items. [#2285](https://github.com/pnp/powershell/pull/2285)
- Added support for `-ErrorAction:Stop` to PnP PowerShell cmdlets. Notice that if you were using this in combination with the specific try/catch [System.Management.Automation.PSInvalidOperationException], it will no longer catch the exception. It will throw an `System.Management.Automation.ErrorRecord` exception instead. Remove the `-ErrorAction:Stop` parameter from your cmdlet or catch this new exception type to avoid this behavior. [#2288](https://github.com/pnp/powershell/pull/2288)
- Added ability to create shared Teams channels using `Add-PnPTeamsChannel -ChannelType Shared` [#2308](https://github.com/pnp/powershell/pull/2308)
- Added support for `IsLoopEnabled` properties in `Get-PnPTenant` and `Set-PnPTenant` cmdlets to to enable/disable loop components in the tenant. [#2307](https://github.com/pnp/powershell/pull/2307)

### Changed
- Changed to no longer require `https://` to be prefixed when using `Connect-PnPOnline -Url tenant.sharepoint.com` [#2139](https://github.com/pnp/powershell/pull/2139)
- `Get-PnPAvailableSensitivityLabel` cmdlet now uses the non-deprecated Graph API to retrieve sensitivity label. [#2234](https://github.com/pnp/powershell/pull/2234)
- Improved `Get-PnPMicrosoft365Group` cmdlet to better check the Id, DisplayName and MailNickname of Microsoft 365 Group. [#2258](https://github.com/pnp/powershell/pull/2258)
- Improved `Get-PnPStorageEntity` cmdlet when `Key` parameter is specified. [#2275](https://github.com/pnp/powershell/pull/2275)
- Improved `Get-PnPAuthenticationRealm` cmdlet to use `HTTP Client` instead of obsolete `WebRequest` class. [#2304](https://github.com/pnp/powershell/pull/2304)
- Creating private Teams channels formerly using `Add-PnPTeamsChannel -Private` should now use `Add-PnPTeamsChannel -ChannelType Private` instead [#2308](https://github.com/pnp/powershell/pull/2308)
- Improved `Get-PnPAuthenticationRealm` cmdlet to use `HTTP Client` instead of `WebRequest`. [#2304](https://github.com/pnp/powershell/pull/2304)

### Removed
- Marked `-Resource` parameter from `Get-PnPAccessToken` cmdlet as obsolete as it was not used anymore anyway. It will be removed in a future version. [#2182](https://github.com/pnp/powershell/pull/2182)
Expand Down
48 changes: 29 additions & 19 deletions documentation/Add-PnPTeamsChannel.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@ title: Add-PnPTeamsChannel

* Microsoft Graph API: Group.ReadWrite.All

Adds a channel to an existing Microsoft Teams instance.
Adds a channel to an existing Microsoft Teams team.

## SYNTAX

### Public channel
### Standard channel
```powershell
Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> [-Description <String>] [-IsFavoriteByDefault <Boolean>] [<CommonParameters>]
Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> [-ChannelType Standard] [-Description <String>] [-IsFavoriteByDefault <Boolean>]
```

### Private channel
```powershell
Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> -OwnerUPN <String> [-Description <String>] [-Private] [<CommonParameters>]
Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> -ChannelType Private -OwnerUPN <String> [-Description <String>]
```

### Shared channel
```powershell
Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> -ChannelType Shared -OwnerUPN <String> [-Description <String>] [-IsFavoriteByDefault <Boolean>]
```

## DESCRIPTION
Expand All @@ -38,21 +43,28 @@ Add-PnPTeamsChannel -Team <TeamsTeamPipeBind> -DisplayName <String> -OwnerUPN <S
Add-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName "My Channel" -IsFavoriteByDefault $true
```

Adds a new channel to the specified Teams instance and marks the channel as by default visible for members.
Adds a new standard channel to the Team specified by its identifier and marks the channel as by default visible for members.

### EXAMPLE 2
```powershell
Add-PnPTeamsChannel -Team MyTeam -DisplayName "My Channel"
Add-PnPTeamsChannel -Team "My Team" -DisplayName "My standard channel"
```

Adds a new channel to the specified Teams instance
Adds a new standard channel to the Team specified by its name.

### EXAMPLE 3
```powershell
Add-PnPTeamsChannel -Team MyTeam -DisplayName "My Channel" -Private -OwnerUPN user1@domain.com
Add-PnPTeamsChannel -Team "HR" -DisplayName "My private channel" -ChannelType Private -OwnerUPN user1@domain.com
```

Adds a new private channel to the Team specified by its name and sets the provided user as the owner of the channel.

### EXAMPLE 4
```powershell
Add-PnPTeamsChannel -Team "Logistical Department" -DisplayName "My shared channel" -ChannelType Shared -OwnerUPN user1@domain.com
```

Adds a new private channel to the specified Teams instance
Adds a new shared channel to the Team specified by its name and sets the provided user as the owner of the channel.

## PARAMETERS

Expand All @@ -71,7 +83,7 @@ Accept wildcard characters: False
```

### -DisplayName
The display name of the new channel. Letters, numbers and spaces are allowed.
The display name of the new channel. Letters, numbers, and spaces are allowed.

```yaml
Type: String
Expand All @@ -89,7 +101,7 @@ Allows you to specify if the channel is by default visible for members

```yaml
Type: Boolean
Parameter Sets: Public channel
Parameter Sets: Standard channel, Shared channel

Required: False
Position: Named
Expand All @@ -103,7 +115,7 @@ The User Principal Name (email) of the owner of the channel.

```yaml
Type: String
Parameter Sets: Private channel
Parameter Sets: Private channel, Shared channel

Required: True
Position: Named
Expand All @@ -112,14 +124,14 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -Private
Specify to mark the channel as private.
### -ChannelType
Allows specifying the type of channel to be created. Possible values are Standard, Private, and Shared.

```yaml
Type: SwitchParameter
Parameter Sets: Private channel
Parameter Sets: (All)

Required: True
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Expand All @@ -142,6 +154,4 @@ Accept wildcard characters: False

## RELATED LINKS

[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)


[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)
23 changes: 23 additions & 0 deletions src/Commands/Enums/TeamsChannelType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace PnP.PowerShell.Commands.Enums
{
/// <summary>
/// Defines the types of channels that can be created in a Microsoft Teams team
/// </summary>
public enum TeamsChannelType
{
/// <summary>
/// Standard channel accessible by all team members
/// </summary>
Standard,

/// <summary>
/// Private channel only accessible by those explicitly given permissions to the channel
/// </summary>
Private,

/// <summary>
/// Shared channel allowing for collaboration between multiple tenants
/// </summary>
Shared
}
}
70 changes: 45 additions & 25 deletions src/Commands/Teams/AddTeamsChannel.cs
Original file line number Diff line number Diff line change
@@ -1,67 +1,87 @@
using PnP.PowerShell.Commands.Attributes;
using PnP.PowerShell.Commands.Base;
using PnP.PowerShell.Commands.Base.PipeBinds;
using PnP.PowerShell.Commands.Enums;
using PnP.PowerShell.Commands.Model.Graph;
using PnP.PowerShell.Commands.Utilities;
using System;
using System.Management.Automation;

namespace PnP.PowerShell.Commands.Graph
{
[Cmdlet(VerbsCommon.Add, "PnPTeamsChannel")]
[Cmdlet(VerbsCommon.Add, "PnPTeamsChannel", DefaultParameterSetName = ParameterSET_STANDARD)]
[RequiredMinimalApiPermissions("Group.ReadWrite.All")]
public class AddTeamsChannel : PnPGraphCmdlet
{
private const string ParameterSET_PRIVATE = "Private channel";
private const string ParameterSET_PUBLIC = "Public channel";
private const string ParameterSET_PRIVATE = "Private channel type";
private const string ParameterSET_STANDARD = "Standard channel type";
private const string ParameterSET_SPECIFIC = "Specific channel type";

[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PUBLIC)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_STANDARD)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PRIVATE)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_SPECIFIC)]
public TeamsTeamPipeBind Team;

[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PUBLIC)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_STANDARD)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PRIVATE)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_SPECIFIC)]
public string DisplayName;

[Parameter(Mandatory = false, ParameterSetName = ParameterSET_PUBLIC)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSET_STANDARD)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSET_PRIVATE)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSET_SPECIFIC)]
public string Description;

[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PRIVATE)]
[Obsolete("Use TeamMembershipType instead.")]
public SwitchParameter Private;

[Parameter(Mandatory = true, ParameterSetName = ParameterSET_SPECIFIC)]
public TeamsChannelType ChannelType;

[Parameter(Mandatory = true, ParameterSetName = ParameterSET_SPECIFIC)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSET_PRIVATE)]
public string OwnerUPN;

[Parameter(Mandatory = false, ParameterSetName = ParameterSET_PUBLIC)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSET_SPECIFIC)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSET_STANDARD)]
public bool IsFavoriteByDefault;

protected override void ExecuteCmdlet()
{
var groupId = Team.GetGroupId(Connection, AccessToken);
if (groupId != null)
if (groupId == null)
{
throw new PSArgumentException("Group not found");
}

switch (ParameterSetName)
{
try
case ParameterSET_PRIVATE:
ChannelType = TeamsChannelType.Private;
break;

case ParameterSET_STANDARD:
ChannelType = TeamsChannelType.Standard;
break;
}

try
{
var channel = TeamsUtility.AddChannelAsync(AccessToken, Connection, groupId, DisplayName, Description, ChannelType, OwnerUPN, IsFavoriteByDefault).GetAwaiter().GetResult();
WriteObject(channel);
}
catch (GraphException ex)
{
if (ex.Error != null)
{
var channel = TeamsUtility.AddChannelAsync(AccessToken, Connection, groupId, DisplayName, Description, Private, OwnerUPN, IsFavoriteByDefault).GetAwaiter().GetResult();
WriteObject(channel);
throw new PSInvalidOperationException(ex.Error.Message);
}
catch (GraphException ex)
else
{
if (ex.Error != null)
{
throw new PSInvalidOperationException(ex.Error.Message);
}
else
{
throw;
}
throw;
}
}
else
{
throw new PSArgumentException("Group not found");
}

}
}
}
10 changes: 7 additions & 3 deletions src/Commands/Utilities/TeamsUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -602,18 +602,22 @@ public static async Task<HttpResponseMessage> DeleteChannelAsync(string accessTo
return await GraphHelper.DeleteAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}", accessToken);
}

public static async Task<TeamChannel> AddChannelAsync(string accessToken, PnPConnection connection, string groupId, string displayName, string description, bool isPrivate, string ownerUPN, bool isFavoriteByDefault)
public static async Task<TeamChannel> AddChannelAsync(string accessToken, PnPConnection connection, string groupId, string displayName, string description, TeamsChannelType channelType, string ownerUPN, bool isFavoriteByDefault)
{
var channel = new TeamChannel()
{
Description = description,
DisplayName = displayName,
};
if (isPrivate)
if (channelType == TeamsChannelType.Private)
{
channel.MembershipType = "private";
}
if (isPrivate)
if(channelType == TeamsChannelType.Shared)
{
channel.MembershipType = "shared";
}
if (channelType == TeamsChannelType.Private || channelType == TeamsChannelType.Shared)
{
channel.Type = "#Microsoft.Graph.channel";
var user = await GraphHelper.GetAsync<User>(connection, $"v1.0/{GetUserGraphUrlForUPN(ownerUPN)}", accessToken);
Expand Down

0 comments on commit 1cb1fca

Please sign in to comment.