DeployPlaces.ps1

<#PSScriptInfo

.VERSION 1.3

.GUID b9e7fb23-a071-4441-97fe-a13c71e9975c

.AUTHOR syhaider

.COMPANYNAME

.COPYRIGHT

.TAGS

.LICENSEURI

.PROJECTURI

.ICONURI

.EXTERNALMODULEDEPENDENCIES

.REQUIREDSCRIPTS

.EXTERNALSCRIPTDEPENDENCIES

.RELEASENOTES


.PRIVATEDATA

#>


<#

.DESCRIPTION
 This script deploys Microsoft places and enable the selected features.

#>
 

param (
    [Alias("Places Advanced Features", "PlacesPremium")]
    [bool]$PlacesAdvancedFeatures = $true,
    [Alias("Places Mobile", "PlacesMobile")]
    [bool]$PlacesMobileApp = $true,
    [Alias("Places Analytics Users", "AnalyticsUsers")]
    [bool]$PlacesAnalytics = $true,
    [Alias("Places Finder Users", "PlacesFinderUsers")]
    [bool]$PlacesFinder = $true
)

$PlacesWebApp = $true

$modules = Get-InstalledModule
$exoInstalled = $false
foreach ($module in $modules)
{
    if ($module.Name -contains "ExchangeOnlineManagement")
    {
        $exoInstalled = $true
    }
}
if ($false -eq $exoInstalled)
{
    Write-Host "Adding the Exchange module"
    Install-Module -Name ExchangeOnlineManagement
}

Connect-ExchangeOnline

Write-Host "Do you want to use the default group display names for Places?"
$useDefault = Read-Host "Enter [Y] for Yes or [N] for No"
if ($useDefault -eq "Y") {
    Write-Host "Using the default group for Places"
    $displayNameCore = "Places Users [8C8BF34B-6BB8-4441-A911-3A990C9D838B]"
    $nameCore = "Places Users"
    $displayNamePrem = "Places Advanced Users [8C8BF34B-6BB8-4441-A911-3A990C9D838B]"
    $namePrem = "Places Advanced Users"
    $displayNameMobile = "Places Mobile Users [8C8BF34B-6BB8-4441-A911-3A990C9D838B]"
    $nameMobile = "Places Mobile Users"
    $displayNameAnalytics = "Places Analytics Users [8C8BF34B-6BB8-4441-A911-3A990C9D838B]"
    $nameAnalytics = "Places Analytics Users"
    $displayNamePlacesFinder = "Places Finder Users [8C8BF34B-6BB8-4441-A911-3A990C9D838B]"
    $namePlacesFinder = "Places Finder Users"
}
else {
    $displayNameCore = Read-Host "Please enter the display name of the group you want to use for Places Users"
    $nameCore = $displayNameCore
    $displayNamePrem = Read-Host "Please enter the display name of the group you want to use for Places Advanced Users"
    $namePrem = $displayNamePrem
    $displayNameMobile = Read-Host "Please enter the display name of the group you want to use for Places Mobile Users"
    $nameMobile = $displayNameMobile
    $displayNameAnalytics = Read-Host "Please enter the display name of the group you want to use for Places Analytics Users"
    $nameAnalytics = $displayNameAnalytics
    $displayNamePlacesFinder = Read-Host "Please enter the display name of the group you want to use for Places Finder Users"
    $namePlacesFinder = $displayNamePlacesFinder
}

$placesUsers = Get-distributionGroup $displayNameCore -ErrorAction 'silentlycontinue'
if (!$placesUsers)
{
    Write-Host "Creating a security group - Places Users"
    $placesUsers = New-DistributionGroup -Alias "placesUsers" -DisplayName $displayNameCore -Name $nameCore -Type Security
}

$mobileUsers = Get-distributionGroup $displayNameMobile -ErrorAction 'silentlycontinue'
if (!$mobileUsers)
{
    Write-Host "Creating a security group - Places Mobile Users"
    $mobileUsers = New-DistributionGroup -Alias "placesMobile" -DisplayName $displayNameMobile -Name $nameMobile -Type Security
}

$analyticsUsers = Get-distributionGroup $displayNameAnalytics -ErrorAction 'silentlycontinue'
if (!$analyticsUsers)
{
    Write-Host "Creating a security group - Places Analytics Users"
    $analyticsUsers = New-DistributionGroup -Alias "placesAnalytics" -DisplayName $displayNameAnalytics -Name $nameAnalytics -Type Security
}

$premGroup = Get-distributionGroup $displayNamePrem -ErrorAction 'silentlycontinue'
if (!$premGroup)
{
    Write-Host "Creating a security group - Places Advanced Features"
    $premGroup = New-DistributionGroup -Alias "placesAdvanced" -DisplayName $displayNamePrem -Name $namePrem -Type Security
}

$placesFinderUsers = Get-distributionGroup $displayNamePlacesFinder -ErrorAction 'silentlycontinue'
if (!$placesFinderUsers)
{
    Write-Host "Creating a security group - Places Finder Users"
    $placesFinderUsers = New-DistributionGroup -Alias "placesFinder" -DisplayName $displayNamePlacesFinder -Name $namePlacesFinder -Type Security
}

$placesUsersMembers = Get-DistributionGroupMember $placesUsers
$premGroupAdded = $false
foreach($placesUser in $placesUsersMembers)
{
    if ($placesUser.Id -eq $premGroup.Id)
    {
        $premGroupAdded = $true
    }
}

if ($false -eq $premGroupAdded)
{
    Write-Host "Adding Places Advanced Feature Users to the Places Users group"
    Add-DistributionGroupMember $placesUsers.Id -Member $premGroup
}

$dgMembers = Get-DistributionGroupMember $premGroup.Id
$addMobileToDG = $true
$addAnalyticsToDG = $true
$addPlacesFinderToDG = $true
foreach($dgMem in $dgMembers)
{
    if ($dgMem.Id -eq $mobileUsers.Id)
    {
        $addMobileToDG = $false
    }
    if ($dgMem.Id -eq $analyticsUsers.Id)
    {
        $addAnalyticsToDG = $false
    }
    if ($dgMem.Id -eq $placesFinderUsers.Id)
    {
        $addPlacesFinderToDG = $false
    }
}

if ($addMobileToDG)
{
    Write-Host "Adding Places Mobile Users to the Places Advanced Features group"
    Add-DistributionGroupMember $premGroup.Id -Member $mobileUsers
}
if ($addAnalyticsToDG)
{
    Write-Host "Adding Places Analytics Users to the Places Advanced Features group"
    Add-DistributionGroupMember $premGroup.Id -Member $analyticsUsers
}
if ($addPlacesFinderToDG)
{
    Write-Host "Adding Places Finder Users to the Places Advanced Features group"
    Add-DistributionGroupMember $premGroup.Id -Member $placesFinderUsers
}

Write-Host "Places Security Groups have been created."

$modules = Get-InstalledModule
$placesInstalled = $false
$azAccountInstalled = $false
$azResourcesInstalled = $false
$identityInstalled = $false
foreach ($module in $modules)
{
    if ($module.Name -contains "MicrosoftPlaces")
    {
        if ($module.Version -match "0\.4.*")
        {
            $placesInstalled = $true
        }
    }

    if ($module.Name -contains "Az.Accounts")
    {
        $azAccountInstalled = $true
    }

    if ($module.Name -contains "Az.Resources")
    {
        $azResourcesInstalled = $true
    }

    if ($module.Name -contains "Microsoft.Graph.Identity.DirectoryManagement")
    {
        $identityInstalled = $true
    }
}

if ($false -eq $placesInstalled)
{
    Write-Host "Installing Places Module"
    Install-Module -Name MicrosoftPlaces -AllowPrerelease -Force
}

Connect-MicrosoftPlaces

if ($false -eq $azAccountInstalled)
{
    Write-Host "Connecting to the Azure Accounts module"
    Install-Module -Name Az.Accounts -AllowClobber
}

Connect-AzAccount

if ($false -eq $azResourcesInstalled)
{
    Write-Host "Installing Azure Resources module"
    Install-Module -Name Az.Resources
}

if ($false -eq $identityInstalled)
{
    Write-Host "Installing Microsoft Graph Identity Directory Management module"
    Install-Module -Name Microsoft.Graph.Identity.DirectoryManagement
}

$tenants = Get-AzTenant
if ($tenants -is [array]) {
    $i = 0
    Write-Host "List of Tenants"
    Write-Host "---------------"
    foreach ($t in $tenants) {
        Write-Host "$($i+1) - $($t.TenantId) - $($t.Name)"
        $i++
    }
    Write-Host "------------------------------"
    $tenantNumber = Read-Host "Please enter the tenant number you want to use: "
    $tenant = $tenants[$tenantNumber-1]
}
else {
    $tenant = $tenants
}

function SetPlacesCore {
    Write-Host "Searching for group - $displayNameCore"

    $plCoreGroup = Get-AzADGroup -DisplayName $displayNameCore
    if ($null -eq $plCoreGroup) {
        Write-Error -Message "Please create a DL with Display Name - $displayNameCore" -ErrorAction Stop
    }

    if ('Unified' -eq $plCoreGroup.GroupType){
        Write-Error -Message "Please create a distribution or security group $displayNameCore is a M365 group which is not supported" -ErrorAction Stop
    }

    Write-Host "Found Group $displayNameCore"

    $oidtidCoreGroup=$plCoreGroup.Id + "@" + $tenant.TenantId
    $groupstring = "Default:false,OID:" + $oidtidCoreGroup + ":true"

    Write-Host "Enabling Places Web App"

    Set-PlacesSettings -Collection Places -EnablePlacesWebApp  $groupstring | Out-Null

    Set-PlacesSettings -Collection Places -EnableBuildings 'Default:true'
}

function SetPremiumFeatures {
    param([bool]$settingValue)
    Write-Host "Enabling Places Advanced Features for the tenant"
    
    Write-Host -Message "Looking for group - $displayNamePrem"

    $plGroup = Get-AzADGroup -DisplayName $displayNamePrem 
    if ($null -eq $plGroup) {
        Write-Error -Message "Unable to find a group with Display Name $displayNamePrem" -ErrorAction Stop        
    }

    Write-Host -Message "Tenant being used - $tenant.TenantId"
    $oidtidGroup=$plGroup.Id + "@" + $tenant.TenantId
    if ($settingValue)
    {
        $groupstring = "Default:false,OID:" + $oidtidGroup + ":true"
    }
    else
    {
        Write-Host "Setting Places Advanced to false"
        $groupstring = "Default:false,OID:" + $oidtidGroup + ":false"
        Write-Host $groupstring
    }
        
    Write-Host "Enabling Advanced Places features"

    Set-PlacesSettings -Collection Places -PlacesEnabled $groupstring -ErrorAction SilentlyContinue
}
function EnablePlacesMobileApp {
    Write-Host "Enabling the group that can use the Places iOS App"

    Write-Host "Looking for group - $displayNameMobile"
    $plGroup = Get-AzADGroup -DisplayName $displayNameMobile 
    if ($null -eq $plGroup) 
    {
        Write-Error -Message "Unable to find a group with Display Name $displayNameMobile" -ErrorAction Stop        
    }

    $oidtidGroup=$plGroup.Id + "@" + $tenant.TenantId
    $groupstring = "Default:false,OID:" + $oidtidGroup + ":true"

    Set-PlacesSettings -Collection Places -EnablePlacesMobileApp $groupstring
}

function EnablePlacesAnalytics {
    Write-Host "Enabling the group that can see Places Analytics"
    
    Write-Host "Looking for group - $displayNameAnalytics"
    $plGroup = Get-AzADGroup -DisplayName $displayNameAnalytics
    if ($null -eq $plGroup) {
        Write-Error -Message "Unable to find a group with Display Name $displayNameAnalytics" -ErrorAction Stop
    }

    $oidtidGroup=$plGroup.Id + "@" + $tenant.TenantId
    $groupstring = "Default:false,OID:" + $oidtidGroup + ":true"

    Set-PlacesSettings -Collection Places -SpaceAnalyticsEnabled $groupstring
}

function EnablePlacesFinder {
    Write-Host "Enabling the group that can see Places Finder"

    Write-Host "Looking for group - $displayNamePlacesFinder"
    $plGroup = Get-AzADGroup -DisplayName $displayNamePlacesFinder
    if ($null -eq $plGroup) {
        Write-Error -Message "Unable to find a group with Display Name $displayNamePlacesFinder" -ErrorAction Stop
    }

    $oidtidGroup=$plGroup.Id + "@" + $tenant.TenantId
    $groupstring = "Default:false,OID:" + $oidtidGroup + ":true"

    Set-PlacesSettings -Collection Places -PlacesFinderEnabled $groupstring
}


$settingEnabled = $false
function GetPlacesSetting {
    param([string]$placesSetting)
    $settings = Get-PlacesSettings -Collection Places -ReadFromPrimary

    Write-Information $placesSetting
    foreach ($setting in $settings)
    {
        if ($setting.Name -eq $placesSetting)
        {
            $scopedValues = $setting.ScopedValues;
            foreach($scope in $scopedValues)
            {
                if ($scope.ScopeValue.BoolValue)
                {
                    $settingEnabled = $true;
                    break;
                }
            }
        }

        if ($settingEnabled)
        {
            break;
        }
    }
    return $settingEnabled
}

Write-Host $

$coreRun = $false;
if ($PlacesWebApp)
{
    SetPlacesCore
    $coreRun = $true;
}
if ($PlacesAdvancedFeatures)
{
    Write-Host "PlacesAdvancedFeatures set to $PlacesAdvancedFeatures"
    if (!$coreRun)
    {
        SetPlacesCore
    }
    SetPremiumFeatures($PlacesAdvancedFeatures)
}

if ($PlacesMobileApp)
{
    $a = "Places.PlacesEnabled"
    $enabledSetting = GetPlacesSetting $a
    if (!$enabledSetting)
    {
        Write-Error -Message "To enable Places Mobile, please enable PlacesAdvancedFeatures first" -Exception ([System.IO.FileNotFoundException]::new()) -ErrorAction Stop
    }
    EnablePlacesMobileApp
}
if ($PlacesAnalytics)
{
    $a = "Places.PlacesEnabled"
    $enabledSetting = GetPlacesSetting $a
    if (!$enabledSetting)
    {
        Write-Error -Message "To enable Analytics, please enable PlacesAdvancedFeatures first" -Exception ([System.IO.FileNotFoundException]::new()) -ErrorAction Stop
    }
    EnablePlacesAnalytics
}
if ($PlacesFinder)
{
    $a = "Places.PlacesEnabled"
    $enabledSetting = GetPlacesSetting $a
    if (!$enabledSetting)
    {
        Write-Error -Message "To enable Places Finder, please enable PlacesAdvancedFeatures first" -Exception ([System.IO.FileNotFoundException]::new()) -ErrorAction Stop
    }
    EnablePlacesFinder
}

Write-Host "The DeployPlaces script version is 1.2"