Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: added support for shared channel creation #2308

Merged
merged 6 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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