How to create Microsoft 365 groups in bulk with sharepoint site and Teams using Powershell

About the Task

This week I received a request to create Microsoft 365 groups in bulk using Powershell. I tried to use New-UnifiedGroup command (part of EXO V2 Powershell Module) to create Microsoft 365 group which worked fine for creation of the group but this command did not create corresponding Sharepoint site. Therefore, I utilized New-PnPMicrosoft365Group command (part of PnP.Powershell powershell module). In this blog post, I have explained in detail on how to use New-PnPMicrosoft365Group command and create Microsoft 365 group(s).

First Step is to Install PnP.Powershell Module and authenticate using Connect-PnPOnline to Sharepoint before we can run New-PnPMicrosoft365Group cmdlet. There are many different ways you can authenticate to Sharepoint using <strong>Connect-PnPOnline</strong>. Two specific methods which we will see in this blog post, One method is to use -UseWebLogin which does not work with New-PnPMicrosoft365Group and Other One is using App Only Azure Active Directory which works fine with New-PnPMicrosoft365Group. This is the authentication method we will be using today to complete our task.

To Find out more information about various Authentication Methods while using connect-PnPOnline. Please check the link: Connect-PnPOnline (Connect to a Sharepoint Site)

Install PnP.Powershell

To Install PnP.Powershell Module on your system. Open Powershell Console as an Administrator and Type below Command:

Install-Module -Name PnP.PowerShell

Lets see what happens when we use -useWebLogin switch with Connect-PnPOnline command. Open Powershell as Administrator, type below command and Press Enter. Make sure PnP.Powershell Module is installed on the system otherwise below commmand will not work.

Connect-PnPOnline -Url https://<yoursitename>.sharepoint.com -UseWebLogin

A small window will pop-up on the screen, Enter your administrator credentials to authenticate to Sharepoint.

Now we will test New-PnPMicrosoft365Group command. As you can see in below screenshot New-PnPMicrosoft365Group cmdlet does not work with a WebLogin/Cookie based connection. Therefore we will use App based authentication using Azure Active Directory and then use New-PnPMicrosoft365Group command to create Microosft 365 groups. In the next section, I will be creating and configuring an Azure App Registration for App based authentication.

Azure AD App Registration

To Create an App registration, Login on Azure Portal (https://portal.azure.com) -> Azure Active Directory -> App registrations and click on New registration.

Provide a Name of the Application, Select Who can use this application or access this API ? and click on Register.

Once the Application is registered, Click on Overview link and then copy the Client ID. Client ID will be used when we will connect to Sharepoint via Connect-PnPOnline Command.

API Permissions

Next step is to provide minimum permissions to this app for our task. For this, click On API Permissions and then click on Add a Permission.

Click on Microsoft Graph on Request API Permissions Pane.

Click on Application Permissions

Search for Group and Provide Group.ReadWrite.All Permission.

Search for directory and Provide Directory.ReadWrite.All Permission.

Grant Admin Consent

Admin Consent Granted

Certificates & Secrets

Next Step is to create a self-signed certificate and upload it to the app PnP Powershell which we registered in Azure Active Directory and granted consent in previous steps. Let’s see how we can generate and upload the certificate.

For creating a self-signed certificate, I have used a script which you can copy from below Microsoft Docs Link: https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread.

Once you have copied the script and saved it in a .ps1 file. Use below command to generate a self signed certificate. Please note that the Date Format is YYYY-MM-dd. Change the Startdate and EndDate according to your certificate expiry requirements.

.\Create-SelfSignedCertificate.ps1 -CommonName "TechPress" -StartDate 2021-08-13 -EndDate 2022-08-13

Generated SelfSignedCertifcate Folder looks on my system. You can choose any name for the Folder or Certificate.

Upload Certificate

Click on Certificates & Secrets Link in Azure AD App PnP Powershell and then click on Upload Certificate.

Select .cer file to upload.

Certificate .cer file / Public Key is uploaded.

Create Microsoft365 Groups

For Creating Microsoft 365 Group(s), We need to gather few values which will be used to connect to sharepoint using Connect-PnPonline command. Below are the values required for this command.

Client ID = Copy Client ID of the App PnP Powershell from Azure Portal.
Certificate Path = Path of Certificate PFX File
CertificatePassword
= PFX File Password
Url =
Sharepoint site URL where you want to connect —- for example: https://jmittechpress.onmicrosoft.com
Tenant
= Azure Active Directory Tenant Name —— for example techpress.onmicrosoft.com

First connect to Sharepoint using Connect-PnPOnline command using the command shown below:

Connect-PnPOnline -ClientId <ClientID> -CertificatePath C:\SelfSignedCertificate\TechPress.pfx -CertificatePassword (ConvertTo-SecureString -AsPlainText "Welcome123" -Force) -Url https://<SharepointSite URL> -Tenant <Tenant Name>

Create one Microsoft 365 Group using New-PnPMicrosoft365Group without Team

$displayname = "London Finance"
$nickname = "LondonFinance"
$arrayOfOwners = "jmakhija@techpress.net", "tstark@techpress.net"
$arrayOfMembers = "jondoe@techpress.net"

New-PnPMicrosoft365Group -Displayname $displayName -Description "TechPress Finance Group" -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate

Owners and Members of the group as we defined in our command.

Create one Microsoft 365 Group using New-PnPMicrosoft365Group with Team

Create Microsoft 365 Group with Sharepoint site and with connected Team. I am using the same example as above, the only difference is a switch added to the end of New-PnPMicrosoft365Group Command CreateTeam.

$displayname = "London Finance"
$nickname = "LondonFinance"
$arrayOfOwners = "jmakhija@techpress.net", "tstark@techpress.net"
$arrayOfMembers = "jondoe@techpress.net"

New-PnPMicrosoft365Group -Displayname $displayName -Description "TechPress Finance Group" -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate -CreateTeam

Create Microsoft 365 Groups in bulk

For creating Microsoft365 groups in bulk, I have created a small script which you can use. You can copy the script from this blog post or download it from TechPress GitHub Page as well. Please find the link of Github page in the next section. Before you can use the script, there are some important points to note as given below:

Script requirements and Important Points
– Make sure to use -verbose switch when running the function (It’s also explained and show in later section with screenshots). If its not run with -verbose switch, script will still run but will not have full information about the progress displayed on the console.

– An CSV File is required as a source data for this script. A Sample CSV File is shown in the later section. Create a CSV File using the same headings and update the data. When this script / function is run, it will prompt for CSV File path, provide the path of the CSV File.

– The Script checks for Powershell module PnP.Powershell and Installs / Imports it for you. There is a confirmation message before it gets installed.

– Script creates Log files everytime its run and its stored at C:\Apps\Logs. You can change the value of the variables $Logfile and $Logfolder as per your requirement.

– After dot sourcing the script, you can check more information about the script using >get-help Create-M365GroupwithSPOSite

Only few variables required to be updated in the script before you can run the script.

Example:

$arrayOfOwners = “jmakhija@techpress.net”, “tstark@techpress.net”
$arrayOfMembers = “jondoe@techpress.net”

$ClientID = “<clientID>”
$CertPath = “<Path of the Certificate File>”
$SiteUrl = “<Sharepoint Site URL>”
$tenant = “<Azure AD tenant name>”
Sample M365Groups.csv File
If Teams Column is set to Y –> Microsoft 365 group + SPO Site + Team will be created
If Teams Column is set to N –> Microsoft 365 group + SPO Site will be created without Teams

Once you have a sample csv file created and variables populated in the powershell script. Lets run it to see how it goes. This is how my folder looks like:

Script Folder contains Powershell script and CSV File
Copy these two files in any folder and on powershell console dot source it like >. .\<script>.ps1
GitHub Script Download link
https://github.com/Techpress-net/Powershell-Scripts.git

– After dot sourcing the script, you can check more information about the script using get-help Create-M365GroupwithSPOSite

get-help Create-M365GroupwithSPOSite
After the groups are created, it will not be shown on the PS Console. The script is updated as per comment: https://techpress.net/how-to-create-microsoft-365-groups-in-bulk-with-sharepoint-site-and-teams-using-powershell/#comment-79
C:\Apps\Logs\M365GroupLog-08-13-2021_06-54-59.csv File
TipUse Excel -> Data -> Text to Colums and use the Delimeter as * to separate data it in two columns
Disclaimer
I have created below script and used it in the test enviornment as well as Production Envionments. Its recommeded to use this script to create couple of groups first or to use it in test enviornment first to see if you are successful before creating 100’s of groups using this script in Production.

This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the script or documentation. Neither this script/function, nor any part of it other than those parts that are explicitly copied from others, may be republished without author(s) express written permission. Author(s) retain the right to alter this disclaimer at any time.
Function Create-M365GroupwithSPOSite { 
<# 
.SYNOPSIS 
Create Microsoft 365 Groups in bulk along with Sharepoint Sites.If Teams Column value is Y
Teams Site will also be linked to the group else Teams Site will not be linked/created. 
 
.DESCRIPTION 
This is Create-M365GroupwithSPOSite Function which can be used to Create Microsoft 365 Groups
with Sharepoint Sites (with or without Teams Site). 
 
.NOTES     
        Name       : Create-M365GroupwithSPOSite  
        Author     : Jatin Makhija  
        Version    : 1.0.1  
        DateCreated: 13-08-2021 
        DateUpdated: 24-08-2021
        Blog       : https://www.techpress.net
         
.LINK 
https://www.techpress.net
 
.EXAMPLE 
PS> Create-M365GroupwithSPOSite -verbose
 
For Example 
 
Create-M365GroupwithSPOSite -verbose 
#> [cmdletBinding()] 
    param( 
    [parameter(mandatory = $true, Position =0, HelpMessage="Please Enter the Path to CSV File")] 
    [string]${CSVFilePath} 
         ) 
 
Try { 
 
        #Check for PNP Powershell module 
        $Module=Get-Module -Name pnp.powershell -ListAvailable  
        if($Module.count -eq 0) 
        { 
        Write-Host PNP Powershell module is not available  -ForegroundColor yellow  
        $Confirm= Read-Host Are you sure you want to install module? [Y] Yes [N] No 
        if($Confirm -match "[yY]") 
        { 
        Write-Host "Installing PnP.Powershell Module"
        Install-Module -Name PnP.PowerShell -Confirm:$False -Force
        Write-Host "Importing PnP.Powershell Module"
        Import-Module -Name PnP.PowerShell -Verbose:$false
        } 
        else 
        { 
        Write-Host PNP Powershell module is required for this script to work. 
        Exit
        }
        }         
 
    } 
 
Catch { 
Write-Warning "PNP Powershell module is required for this script to work." 
Write-Warning $_ 
break 
} 

$arrayOfOwners = "jmakhija@techpress.net", "tstark@techpress.net"
$arrayOfMembers = "jondoe@techpress.net"

$ClientID =  "<clientID>"
$CertPath =  "<PFX Certificate File Location>"
$CertPass =   Read-Host -Prompt 'Enter Password of the PFX File' -AsSecureString
$SiteUrl  =  "<Sharepoint Site URL>"
$tenant   =  "<Azure AD Tenant Name>"

$Params = @{
    ClientId            = $ClientID
    CertificatePath     = $CertPath
    CertificatePassword = $CertPass
    Url                 = $SiteUrl
    Tenant              = $tenant
}

Write-host "Connecting to PNPOnline" -ForegroundColor Blue -BackgroundColor White
Connect-PnPOnline @Params

$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$Logfile = "C:\Apps\Logs\M365GroupLog-$LogTime.csv"
$logfolder ="C:\Apps\Logs"
if(!(Test-Path -path $LogFolder)){
New-Item -ItemType Directory -path $logfolder
}
Else 
{
Write-Host "Great! log folder already exists, Please check C:\Apps\Log\ Folder for Log Files generated by this script"
}

Function LogWrite
{
    Param ([string]$logstring)

     Add-content $Logfile -value $logstring
}

Import-Csv ${CSVFilePath} -Header displayname, nickname, description, Teams | Select-Object -Skip 1 | ForEach-Object{ 
                                                    $displayname = $_.displayname 
                                                    $nickname = $_.nickname
                                                    $description = $_.description
                                                    $Teams = $_.Teams

if (Get-PnPMicrosoft365Group -identity $displayname) {
       Write-verbose "M365 Group $displayname already exists" 
       LogWrite "$displayname * Already Exists"
}

Elseif ($Teams -eq 'N') {
         Write-verbose "Teams Column Value set to $Teams for $displayname" 
         Write-verbose "Creating M365 Group + SPO Site without connected Teams for $displayname"
         try { 
         New-PnPMicrosoft365Group -DisplayName $displayname -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate | out-null
         } catch {
         LogWrite "$displayname *  could not be created"
         }
         LogWrite "$displayname *  created without Teams Site"
}

else {
    Write-verbose "Teams Column Value set to $Teams for $displayname"
    Write-verbose "Creating M365 Group + SPO Site with connected Teams for $displayname" 
    try{
    New-PnPMicrosoft365Group -DisplayName $displayname -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate -CreateTeam | out-null 
    } catch {
    LogWrite "$displayname *  could not be created"
    }
    LogWrite "$displayname * created with Teams Site"
     }
  }
}                                        

Subscribe to Stay Connected

Thank you for visiting TechPress 👍. When you subscribe to the blog, email notification ✉ will be sent to you when a new blog post is published. You can unsubscribe at any time.

guest
6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments