Forum Discussion

phil_tannay's avatar
phil_tannay
Copper Contributor
Mar 07, 2025

When creating a new team from a template with powershell add new private channel and members

Hi All,

I have a powershell script I am using to create and populate new teams from a template and add owners and users via .csv,

Everything seem to work fine except the private team in the template is not copied to the new teams.

Is there a way to copy the private team with its members from the template? if not how can I add a new private team and add users from a .csv file to my existing script.

Import-Module Microsoft.Graph.Teams

Connect-MgGraph -Scope Group.ReadWrite.All

Connect-MicrosoftTeams

$ProgressPreference = 'SilentlyContinue'

#########################

#Variable definition:

$DefaultModelTeam = "Team template ID"

$MembersFilePath = "C:\Users\t130218\Desktop\owlimport_365.csv"

$OwnersFilePath = "C:\Users\t130218\Desktop\TeamOwners.csv"

#########################

Function CreaTeam{

param(

        [Parameter(Position=0)]

        [string]$displayName,

 

        [Parameter(Position=1)]

        [string]$description

    ) 

begin{

    $params = @{

    partsToClone = "apps,tabs,settings,channels"

        displayName = $displayName

    description = $description

    mailNickname = $displayName

    #visibility = "public"

               }

    #Disable "Crea" button in order to avoid duplicate Teams creation

    $btnCrea.enabled=$false

    #Message output and waiting time countdown for allow new Tean creation finalization

    $lblMessaggio.text="Creazione Team in corso..."

    $teamId= $txtTemplate.text

    Copy-MgTeam -TeamId $teamId -BodyParameter $params

    $lblTeamId.text = "Attendere 20 secondi"

    Start-Sleep -Seconds 5

    $lblTeamId.text = "Attendere 15 secondi"

    Start-Sleep -Seconds 5

    $lblTeamId.text = "Attendere 10 secondi"

    Start-Sleep -Seconds 5

    $lblTeamId.text = "Attendere 5 secondi"

    Start-Sleep -Seconds 5

    #The Teamid of the team that was just created can only be discovered via Team name search

    $newTeam= Get-MgGroup | Where-Object {$_.DisplayName -like $displayName}

    $lblTeamId.text=$newTeam.Id

    #Get Team members from the CSV 

    $TeamUsers =  Import-Csv $MembersFilePath -delimiter ";" 

    #Iterate through each row obtained from the CSV and add to Teams as a Team member

    $TeamUsers | ForEach-Object { 

        Add-TeamUser -GroupId $newTeam.id -User $_.m365_email -Role Member

        Write-host "Added User:"$_.m365_email -f Green 

        }

    #Get Team owners from the CSV 

    $TeamOwners =  Import-Csv $OwnersFilePath -delimiter ";" 

    #Iterate through each row obtained from the CSV and add to Teams as a Team member

    $TeamOwners | ForEach-Object { 

        Add-TeamUser -GroupId $newTeam.id -User $_.m365_email -Role Owner

        Write-host "Added Owner:"$_.m365_email -f Green 

        }

    }

}

Add-Type -AssemblyName System.Windows.Forms

[System.Windows.Forms.Application]::EnableVisualStyles()

$CorsoTeams                      = New-Object system.Windows.Forms.Form

$CorsoTeams.ClientSize           = New-Object System.Drawing.Point(1200,575)

$CorsoTeams.text                 = "Corso Teams - Crea Struttura"

$CorsoTeams.TopMost              = $false

$lblNomeCorso                    = New-Object system.Windows.Forms.Label

$lblNomeCorso.text               = "Nome del corso"

$lblNomeCorso.AutoSize           = $true

$lblNomeCorso.width              = 25

$lblNomeCorso.height             = 10

$lblNomeCorso.location           = New-Object System.Drawing.Point(40,79)

$lblNomeCorso.Font               = New-Object System.Drawing.Font('Microsoft Sans Serif',10)

$btnCrea                         = New-Object system.Windows.Forms.Button

$btnCrea.text                    = "Crea"

$btnCrea.width                   = 150

$btnCrea.height                  = 67

$btnCrea.location                = New-Object System.Drawing.Point(373,298)

$btnCrea.Font                    = New-Object System.Drawing.Font('Microsoft Sans Serif',16)

$btnChiudi                       = New-Object system.Windows.Forms.Button

$btnChiudi.text                  = "Chiudi"

$btnChiudi.width                 = 150

$btnChiudi.height                = 67

$btnChiudi.location              = New-Object System.Drawing.Point(628,298)

$btnChiudi.Font                  = New-Object System.Drawing.Font('Microsoft Sans Serif',16)

$lblDataCorso                    = New-Object system.Windows.Forms.Label

$lblDataCorso.text               = "Data del corso"

$lblDataCorso.AutoSize           = $true

$lblDataCorso.width              = 25

$lblDataCorso.height             = 10

$lblDataCorso.location           = New-Object System.Drawing.Point(39,143)

$lblDataCorso.Font               = New-Object System.Drawing.Font('Microsoft Sans Serif',10)

$lblDescrizione                    = New-Object system.Windows.Forms.Label

$lblDescrizione.text               = "Descrizione (facoltativa)"

$lblDescrizione.AutoSize           = $true

$lblDescrizione.width              = 25

$lblDescrizione.height             = 10

$lblDescrizione.location           = New-Object System.Drawing.Point(39,210)

$lblDescrizione.Font               = New-Object System.Drawing.Font('Microsoft Sans Serif',10)

$txtDataCorso                    = New-Object system.Windows.Forms.TextBox

$txtDataCorso.multiline          = $false

$txtDataCorso.width              = 150

$txtDataCorso.height             = 40

$txtDataCorso.enabled            = $true

$txtDataCorso.location           = New-Object System.Drawing.Point(370,134)

$txtDataCorso.Font               = New-Object System.Drawing.Font('Microsoft Sans Serif',20)

$txtNomeTeam                     = New-Object system.Windows.Forms.TextBox

$txtNomeTeam.multiline           = $false

$txtNomeTeam.width               = 405

$txtNomeTeam.height              = 40

$txtNomeTeam.enabled             = $true

$txtNomeTeam.location            = New-Object System.Drawing.Point(370,75)

$txtNomeTeam.Font                = New-Object System.Drawing.Font('Microsoft Sans Serif',20)

$txtDescrizione                    = New-Object system.Windows.Forms.TextBox

$txtDescrizione.multiline           = $false

$txtDescrizione.width               = 405

$txtDescrizione.height              = 40

$txtDescrizione.enabled             = $true

$txtDescrizione.location            = New-Object System.Drawing.Point(370,210)

$txtDescrizione.Font                = New-Object System.Drawing.Font('Microsoft Sans Serif',20)

$btnChiudi                       = New-Object system.Windows.Forms.Button

$btnChiudi.text                  = "Chiudi"

$btnChiudi.width                 = 150

$btnChiudi.height                = 67

$btnChiudi.location              = New-Object System.Drawing.Point(628,298)

$btnChiudi.Font                  = New-Object System.Drawing.Font('Microsoft Sans Serif',16)

$lblMessaggio                       = New-Object system.Windows.Forms.Label

$lblMessaggio.text                  = "INSERIRE I DATI"

$lblMessaggio.AutoSize              = $true

$lblMessaggio.width                 = 25

$lblMessaggio.height                = 10

$lblMessaggio.location              = New-Object System.Drawing.Point(40,493)

$lblMessaggio.Font                  = New-Object System.Drawing.Font('Microsoft Sans Serif',10)

$lblTemplate                      = New-Object system.Windows.Forms.Label

$lblTemplate.text                  = "Modello Team utilizzato:"

$lblTemplate.AutoSize              = $true

$lblTemplate.width                 = 25

$lblTemplate.height                = 10

$lblTemplate.location              = New-Object System.Drawing.Point(40,400)

$lblTemplate.Font                  = New-Object System.Drawing.Font('Microsoft Sans Serif',8)

$txtTemplate                   = New-Object system.Windows.Forms.TextBox

$txtTemplate.multiline           = $false

$txtTemplate.width               = 405

$txtTemplate.height              = 40

$txtTemplate.enabled             = $true

$txtTemplate.text                = $DefaultModelTeam

$txtTemplate.location            = New-Object System.Drawing.Point(370,400)

$txtTemplate.Font                = New-Object System.Drawing.Font('Microsoft Sans Serif',14)

$lblTeamId                       = New-Object system.Windows.Forms.Label

$lblTeamId.text                  = ""

$lblTeamId.AutoSize              = $true

$lblTeamId.width                 = 25

$lblTeamId.height                = 10

$lblTeamId.location              = New-Object System.Drawing.Point(540,493)

$lblTeamId.Font                  = New-Object System.Drawing.Font('Microsoft Sans Serif',10)

$CorsoTeams.controls.AddRange(@($lblNomeCorso,$btnCrea,$lblDataCorso,$txtDataCorso,$txtNomeTeam,$btnChiudi,$lblMessaggio,$lblDescrizione,$txtDescrizione, $lblTeamId,$lblTemplate,$txtTemplate   ))

$txtDataCorso.text=Get-Date -Format "dd/MM/yyyy"

$btnCrea.Add_Click({

$NomeTeamCompleto=$txtNomeTeam.text+" - "+$txtDataCorso.text

CreaTeam $NomeTeamCompleto $txtDescrizione.text

$lblMessaggio.text= "Team creato - TeamId:"

})

$btnChiudi.Add_Click({$CorsoTeams.Close()})

[void]$CorsoTeams.ShowDialog()

6 Replies

  • phil_tannay's avatar
    phil_tannay
    Copper Contributor

    Hi Schnittlauch, 

    There are no errors. So far the script is functioning correctly in the creation of the team from the template. However my understanding is that private channels can not be copied from the template. 

    So after the team is created from the template I need to make an addition to the script to create an additional private channel and add members from the TeamOwners.csv

    Thanks and regards,

    Phil

  • phil_tannay's avatar
    phil_tannay
    Copper Contributor

    Hi Schnittlauch, 

    There are no errors. So far the script is functioning correctly in the creation of the team from the template. However my understanding is that private channels can not be copied from the template. 

    So after the team is created from the template I need to make an addition to the script to create an additional private channel and add members from the TeamOwners.csv

    Thanks and regards,

    Phil

  • Benjamin_Fore's avatar
    Benjamin_Fore
    Copper Contributor

    I'm guessing private channels aren't included in the clone.  But you could get the originals and copy the info to a new channel in the new team starting with
    Get-MgTeamChannel -TeamId $teamId -Filter "membershipType eq 'private'"

    On a related note, a similar Team clone script we use has been failing to duplicate channel tabs.   Does your template team have tabs beyond the default?   If so, are they still being duplicated?  (Trying to narrow this down, and am not finding many people at all using Team clone/copy.)

  • Schnittlauch's avatar
    Schnittlauch
    Iron Contributor

    Could you provide more details?
    Do you get any errors?
    Have you tried to run it manually line by line and check each variable if the value of the variable is correct?
    If you run the line of code which adds the the users to the team what is the error message?

     

    You are working with $ProgressPreference = 'SilentlyContinue'

    Change this to "continue" to get more information about errors.

    Please update with details :)

    BR Schnittlauch
    PS: Please mark answers as solved, when they are.

    • phil_tannay's avatar
      phil_tannay
      Copper Contributor

      Hi Schnittlauch,

      No I am not getting any errors. The script is working as planned. 

       

      I want to make an addition to the script so that during the creation of the team a new private channel is created and populated with users from the TeamOwners.csv

    • phil_tannay's avatar
      phil_tannay
      Copper Contributor

      Hi, I am not getting any errors. 

      The script is working properly. I need to add to it so that after the team is created from the template a new private channel is created using and adding member from the CSV user to add the owners to the team. 

Resources