Added Files

This commit is contained in:
DistractADD
2021-07-06 13:16:46 +10:00
parent f2475a3bdd
commit cfddd4fad2
393 changed files with 65842 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# Script to add user to an AzureAD role
<#
You can find a list of available roles in the following Microsoft article
https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal
Double check using Get-AzureADDirectoryRole as they don't always have the same name in PowerShell as the GUI
Built from the code example on the following Mircosoft page
https://docs.microsoft.com/en-us/powershell/module/azuread/add-azureaddirectoryrolemember?view=azureadps-2.0
#>
# User UPN to assign role to
$roleUser = ''
# Role Name to Assign
$roleName = ''
# Import AzureAD module and Connect
Import-Module AzureAD
Connect-AzureAD
# Fetch user to assign to role
$roleMember = Get-AzureADUser -ObjectId $roleUser
# Fetch role instance
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
# If role instance does not exist, instantiate it based on the role template
if (!($role)) {
# Instantiate an instance of the role template
$roleTemplate = Get-AzureADDirectoryRoleTemplate | Where-Object {$_.displayName -eq $roleName}
Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId
# Fetch role instance again
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
}
# Add user to role
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $roleMember.ObjectId
# Fetch role membership for role to confirm
Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Get-AzureADUser

View File

@@ -0,0 +1,45 @@
# Bulk add a new licence to users on the basis of what licence they currently have.
#
# An updated version of my previous MSOL script, now using AzureAD.
# This is useful for something like adding Office 365 ATP to everyone who currently has E3, for example.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# What licence do the users currently have?
$existingLicence = 'ENTERPRISEPACK'
# What licence are we adding?
$licenceToAdd = 'ATP_ENTERPRISE'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence skus
$allSkus = Get-AzureADSubscribedSku
# Get sku ID for existing licence
$existingSkuID = ($allSkus | Where-Object {$_.SkuPartNumber -eq $existingLicence}).SkuId
# Get sku ID for new licence
$newSkuID = ($allSkus | Where-Object {$_.SkuPartNumber -eq $licenceToAdd}).SkuId
# Find everyone who has the existing licence but not the licence we're adding
$users = Get-AzureADUser -All $true | Where-Object {$_.AssignedLicenses.SkuId -match $existingSkuID -and !($_.AssignedLicenses.SkuId -match $newSkuID)}
# Create a new licence object for the licence we're adding
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
# Create a new assigned licenses object and add the licence we're adding to add licenses
$newLicenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$newLicenses.AddLicenses = $newLicense
# Add the new licence to each user in the list
foreach ($user in $users) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $newLicenses
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,53 @@
# Bulk add additional licences to a list of users.
#
# An updated version of my previous MSOL script, now using AzureAD.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
$licencesToAdd = @('ENTERPRISEPACK','ATP_ENTERPRISE','EMSPREMIUM')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Get all available licence skus
$newSkuIDs = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToAdd}).SkuId
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Add the licences to add to the licences object
foreach ($newSkuID in $newSkuIDs) {
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
$licenses.AddLicenses += $newLicense
}
# Add the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses -ErrorAction Stop
Write-Output -InputObject ('Licence(s) added for user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,58 @@
# Script to add multiple users to multiple AzureAD roles
<#
You can find a list of available roles in the following Microsoft article
https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal
Double check using Get-AzureADDirectoryRole as they don't always have the same name in PowerShell as the GUI
Built from the code example on the following Mircosoft page
https://docs.microsoft.com/en-us/powershell/module/azuread/add-azureaddirectoryrolemember?view=azureadps-2.0
#>
# User UPNs to assign roles to
$roleUsers = @('')
# Role Names to Assign
$roleNames = @('')
# Import AzureAD module and Connect
Import-Module AzureAD
Connect-AzureAD
# Run through the list of users
foreach ($roleUser in $roleUsers) {
# Fetch user to assign to role
$roleMember = Get-AzureADUser -ObjectId $roleUser
# Run through the list of roles
foreach ($roleName in $roleNames) {
# Fetch User Account Administrator role instance
$role = Get-AzureADDirectoryRole | Where-Object { $_.displayName -eq $roleName }
# If role instance does not exist, instantiate it based on the role template
if (!($role)) {
# Instantiate an instance of the role template
$roleTemplate = Get-AzureADDirectoryRoleTemplate | Where-Object { $_.displayName -eq $roleName }
Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId
# Fetch User Account Administrator role instance again
$role = Get-AzureADDirectoryRole | Where-Object { $_.displayName -eq $roleName }
}
# Get existing users with the role assigned
$existingRoleUsers = (Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId).UserPrincipalName
# Assign role to new user if not already in the list
if ($roleMember.UserPrincipalName -notin $existingRoleUsers) {
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $roleMember.ObjectId -ErrorAction Stop
}
}
}
# Uncomment to fetch role membership for each role to confirm
#foreach ($roleName in $roleNames) {
# Write-Output -InputObject ('Members for role: ' + $roleName)
# Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Get-AzureADUser | Where-Object {$_.UserPrincipalName -in $roleUsers} | Format-List -Property DisplayName,UserPrincipalName
#}

View File

@@ -0,0 +1,29 @@
# Script to bulk disable guest accounts in Azure AD, either all or for a specific domain
#
# Are we disabling for a specific guest domain? Leave blank for all guests.
$guestDomain = ''
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get a list of all guests from Azure AD either matching the domain or all guests
if ($guestDomain -ne '') {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $true -and $_.UserType -eq 'Guest' -and $_.Mail -like ('*' + $guestDomain) }
}
else {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $true -and $_.UserType -eq 'Guest' }
}
# Disable the guest accounts
try {
$guestAccounts | Set-AzureADUser -AccountEnabled $false -ErrorAction Stop
Write-Output -InputObject ('The specified guest accounts have been disabled.')
}
catch {
Write-Output -InputObject ('Failed - The specified guest accounts have not been disabled.')
}

View File

@@ -0,0 +1,24 @@
# Script to bulk enable guest accounts in Azure AD, either all or for a specific domain
#
# Are we disabling for a specific guest domain? Leave blank for all guests.
$guestDomain = ''
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get a list of all guests from Azure AD either matching the domain or all guests
if ($guestDomain -ne '') {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $false -and $_.UserType -eq 'Guest' -and $_.Mail -like ('*' + $guestDomain) }
}
else {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $false -and $_.UserType -eq 'Guest' }
}
# Enable the guest accounts
$guestAccounts | Set-AzureADUser -AccountEnabled $true
Write-Output -InputObject ('The specified guest accounts have been disabled.')

View File

@@ -0,0 +1,21 @@
# Find all guests with unaccepted invites over a specific time period and remove them
#
# How many days are we allowing for invites to be accepted? (This can be 0 for all)
$cutOffDays = 30
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get the cut off date
$cutOffDate = (Get-Date).AddDays(-$cutOffDays)
# Get a list of all guests with unaccepted invites older than the specificed timeframe
$unacceptedGuests = Get-AzureADUser -All $true | Where-Object { $_.UserType -eq 'Guest' -and $_.UserState -eq 'PendingAcceptance' -and $_.RefreshTokensValidFromDateTime -lt $cutOffDate }
# Remove the guest accounts
$unacceptedGuests | Remove-AzureADUser

View File

@@ -0,0 +1,44 @@
# Bulk remove licences to a list of users.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we removing?
$licencesToRemove = @('ENTERPRISEPACK','ATP_ENTERPRISE','EMSPREMIUM')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Get SkuIDs for licence(s) to be removed
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToRemove}).SkuId
# Remove the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('Licence(s) removed from user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,59 @@
# Bulk replace licences to a list of users.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
$licencesToAdd = @('EMSPREMIUM')
# What licences are we removing?
$licencesToRemove = @('EMS','AAD_PREMIUM_P2')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
$userList = @('OAndrewsAdmin@sis.tv')
# Get all available licence skus
$newSkuIDs = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToAdd}).SkuId
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Add the licences to add to the licences object
foreach ($newSkuID in $newSkuIDs) {
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
$licenses.AddLicenses += $newLicense
}
# Add the licences we want to remove to the $licenses object
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToRemove}).SkuID
# Replace the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('Licences updated for user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,14 @@
# Update Online User UPN - when AD sync doesn't do it.
# Import the Azure AD module and connect
Import-Module AzureAD
Connect-AzureAD
# Whose UPN are we changing?
$oldUPN = Read-Host -Prompt 'Enter user''s old UPN in the format username@domain'
# What are we changing it to?
$newUPN = Read-Host -Prompt 'Enter user''s new UPN in the format username@domain'
# Update the UPN in AzureAD
Set-AzureADUser -ObjectId $oldUPN -UserPrincipalName $newUPN

View File

@@ -0,0 +1,10 @@
# Import the Azure AD module and connect
Import-Module AzureAD
Connect-AzureAD
# Whose ID are we getting?
$userUPN = Read-Host -Prompt 'Enter user''s UPN in the format username@domain'
# Convert 365 ImmutableID to AD GUID
$immutableID = (Get-AzureADUser -ObjectId $userUPN).ImmutableID
[GUID][System.Convert]::FromBase64String($immutableID)

View File

@@ -0,0 +1,29 @@
# Retrieve licences for all users and export to CSV.
#
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence details
$allSkus = Get-AzureADSubscribedSku
# Import list of users from file
$users = Get-AzureADUser -All $true
# Get Licences for each user and find out what they are from the list
$allUserLicences = @()
foreach ($user in $users) {
$assignedLicences = @()
foreach ($license in $user.AssignedLicenses.SkuID) {
$assignedLicences += ($allSkus | Where-Object { $_.SkuID -eq $license }).SkuPartNumber
}
$userLicences = [PSCustomObject]@{
'UserName' = $user.UserPrincipalName
'AssignedLicences' = (($assignedLicences | Sort-Object) -join ';')
}
$allUserLicences += $userLicences
}
# Export list to CSV file
$allUserLicences | Export-Csv -Path 'C:\Temp\AllUserLicences.csv' -NoTypeInformation

View File

@@ -0,0 +1,38 @@
# Retrieve licences for a list of users and export them to a CSV file.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence details
$allSkus = Get-AzureADSubscribedSku
# Import list of users from file
$users = Get-Content -Path $userListPath | Sort-Object
# Get Licences for user and find out what they are from the list
$allUserLicences = @()
foreach ($user in $users) {
$assignedLicences = @()
try {
$userDetails = Get-AzureADUser -ObjectId $user -ErrorAction Stop
foreach ($license in $userDetails.AssignedLicenses.SkuID) {
$assignedLicences += ($allSkus | Where-Object { $_.SkuID -eq $license }).SkuPartNumber
}
}
catch {
$assignedLicences = 'User not found.'
}
$userLicences = [PSCustomObject]@{
'UserName' = $user
'AssignedLicences' = (($assignedLicences | Sort-Object) -join ';')
}
$allUserLicences += $userLicences
}
# Export list to CSV file
$allUserLicences | Export-Csv -Path 'C:\Temp\UserLicences.csv' -NoTypeInformation

View File

@@ -0,0 +1,84 @@
# Some example scripts for finding users with specific plans assigned
#
# A full list of subscription and plan ID's is available from:
# https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-service-plan-reference
#
# Here I'm using the following plan IDs.
#
# OFFICESUBSCRIPTION (43de0ff5-c92c-492b-9116-175376d08c38)
# PROJECT_CLIENT_SUBSCRIPTION (fafd7243-e5c1-4a3a-9e40-495efcb1d3c3)
# VISIO_CLIENT_SUBSCRIPTION (663a804f-1c30-4ff0-9915-9db84f0d1cea)
#
# Plan ID's to check for
$planID1 = '43de0ff5-c92c-492b-9116-175376d08c38'
$planID2 = 'fafd7243-e5c1-4a3a-9e40-495efcb1d3c3'
$planID3 = '663a804f-1c30-4ff0-9915-9db84f0d1cea'
# Import the AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all users from AzureAD
$allUsers = Get-AzureADUser -All $true
# Create variables to put the users in to
$planID1Users = @()
$planID2Users = @()
$planID3Users = @()
# Check through the users and check what plans are assigned and enabled
foreach ($user in $allUsers) {
foreach ($assignedPlan in $user.AssignedPlans) {
# Find all users of plan 1 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID1 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID1Users += $user
}
# Find all users of plan 2 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID2 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID2Users += $user
}
# Find all users of plan 3 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID3 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID3Users += $user
}
}
}
# Create variables to put the users in to
$plan1OnlyUsers = @()
$planID1and2Users = @()
$planID1and3Users = @()
$planID12and3Users = @()
# Using plan 1 as the master list, check which other licences are assigned
foreach ($planID1User in $planID1Users) {
# Find users who are only in the plan 1 list
if ($planID1User -notin $planID2Users -and $planID1User -notin $planID3Users) {
$plan1OnlyUsers += $planID1User
}
# Find users who are the plan 1 and plan 2 list
if ($planID1User -in $planID2Users) {
$planID1and2Users += $planID1User
}
# Find users who are in the plan 1 and plan 3 list
if ($planID1User -in $planID3Users) {
$planID1and3Users += $planID1User
}
# Find users who are in all three lists
if ($planID1User -in $planID2Users -and $planID1User -in $planID3Users) {
$planID12and3Users += $planID1User
}
}
# How many people in each list?
$plan1OnlyUsers.Count
$planID1and2Users.Count
$planID1and3Users.Count
$planID12and3Users.Count
# Who are those people?
$plan1OnlyUsers
$planID1and2Users
$planID1and3Users
$planID12and3Users

View File

@@ -0,0 +1,36 @@
# Script to invite a list of guest users to AzureAD and add them to a group
#
# Useful for bulk adding guests to a SharePoint or Teams group
#
# Uses a CSV file containing columns for FirstName,LastName,DisplayName,ExternalEmailAddress
#
# Where is our list of people?
$contactsFile = 'C:\Temp\ExternalContacts.csv'
# What group are we added them to?
$groupName = 'Test Group'
# Import the AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import the list of people
$contactsList = Import-Csv -Path $contactsFile
# Find the group ID for our group
$groupID = (Get-AzureADGroup -All $true | Where-Object {$_.DisplayName -eq $groupName}).ObjectId
# Run through the list sending the guest invite and adding them to the group, unless their email address is already used somewhere
foreach ($externalUser in $contactsList) {
$getExisting = Get-AzureADUser -SearchString $externalUser.ExternalEmailAddress
if ($getExisting.Count -eq 0) {
$newUser = New-AzureADMSInvitation -InvitedUserDisplayName $externalUser.DisplayName -InvitedUserEmailAddress $externalUser.ExternalEmailAddress -SendInvitationMessage $true -InviteRedirectUrl "https://myapps.microsoft.com"
Add-AzureADGroupMember -ObjectId $groupID -RefObjectId $newUser.InvitedUser.Id
Write-Output -InputObject ('Guest ' + $externalUser.ExternalEmailAddress + ' created and added to group.')
}
else {
Write-Output -InputObject ('Object already exists with email address ' + $externalUser.ExternalEmailAddress + '.')
}
}

View File

@@ -0,0 +1,42 @@
# Remove all licences from a list of users
#
# Removing licences with this module doesn't work in the way that Microsoft's documentation states.
# I'm assuming this is a bug, so the code below works at time of creation but may stop working in the future.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Remove all the licences
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
if(($user.AssignedLicenses.SkuId).Count -ge 1) {
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuId -in $user.AssignedLicenses.SkuId}).SkuId
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('All licences removed from user account ' + $username + '.')
}
else {
Write-Output -InputObject ('User account ' + $username + ' has no licences assigned.')
}
}
else {
Write-Output -InputObject ('User account ' + $username + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('User account ' + $username + ' does not exist.')
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,63 @@
# Script to get details for a list of mailboxes and save that out to a CSV file
#
# File containing the list of mailboxes
$inputFile = 'C:\Temp\MailboxList.txt'
# File to save the results to
$outputFile = 'C:\Temp\SharedMailboxes.csv'
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Check output folder exists and create it if it doesn't
$outputPath = (Split-Path -Path $outputFile)
if (!(Test-Path -Path $outputPath)) {New-Item -Path $outputFolder -ItemType Directory}
# If output file already exists, delete it.
if (Test-Path -Path $outputFile) {Remove-Item -Path $outputFile}
# Get the list of mailboxes from the file
$mailboxes = Get-Content -Path $inputFile
# Initialise the results table
$mailboxesTable = @()
# Iterate through the mailboxes from the file and show a progress bar as we go.
foreach ($mailbox in $mailboxes) {
Write-Progress -Activity 'Checking..' -status $mailbox -percentComplete ($mailboxes.IndexOf($mailbox) / $mailboxes.Count * 100)
# Get the statistics for the mailbox.
$mailboxStats = ''
$mailboxStats = Get-MailboxStatistics -Identity $mailbox -ErrorAction SilentlyContinue -
# If mailboxStats is blank then mailbox doesn't exist, so that entry can be skipped. For all others get the mailbox permissions and build the output table.
if ($mailboxStats -ne $null) {
# Get permit permissions for users where the username has an @ in it, this filters out all the system permissions.
$usersWithAccess = (Get-MailboxPermission -Identity $mailbox | Where-Object -Property {($_.User -like '*@*') -and ($_.Deny -ne 'False')}).User -join '; '
$tableRow = New-Object System.Object
$tableRow | Add-Member -MemberType NoteProperty -Name 'MailboxUPN' -Value $mailbox
$tableRow | Add-Member -MemberType NoteProperty -Name 'MailboxType' -Value $mailboxStats.MailboxTypeDetail
$tableRow | Add-Member -MemberType NoteProperty -Name 'ItemCount' -Value $mailboxStats.ItemCount
$tableRow | Add-Member -MemberType NoteProperty -Name 'TotalItemSize' -Value $mailboxStats.TotalItemSize
$tableRow | Add-Member -MemberType NoteProperty -Name 'LastLogonTime' -Value $mailboxStats.LastLogonTime
$tableRow | Add-Member -MemberType NoteProperty -Name 'UsersWithAccess' -Value $usersWithAccess
$mailboxesTable += $tableRow
}
}
# Output the final table of results to a file.
$mailboxesTable | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Online session
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,20 @@
# Find mailboxes where UPN domain doesn't match email domain
#
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Get list of mailboxes with a different mail domain to UPN domain
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.UserPrincipalName.Split('@')[1] -ne $_.PrimarySmtpAddress.Split('@')[1]} | Format-Table Name,UserPrincipalName,PrimarySmtpAddress,RecipientTypeDetails
# Disconnect from Exchange Online
Remove-PSSession $exchangeSession

View File

@@ -0,0 +1,38 @@
# Script to get all client forwarding rules, smtp forwarding rules and delegates on mailboxes
#
# This builds on top of a script from https://github.com/OfficeDev/O365-InvestigationTooling
#
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
$allUsers = @()
$allUsers = Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,UserPrincipalName,ForwardingAddress,ForwardingSMTPAddress,DeliverToMailboxandForward
$userInboxRules = @()
$userDelegates = @()
foreach ($user in $allUsers) {
Write-Progress -Activity "Checking inbox rules for..." -status $user.UserPrincipalName -percentComplete ($allUsers.IndexOf($user) / $allUsers.Count * 100)
$userInboxRules += Get-InboxRule -Mailbox $user.UserPrincipalName | `
Select-Object MailboxOwnerId,Name,Description,Enabled,Priority,ForwardTo,ForwardAsAttachmentTo,RedirectTo,DeleteMessage | `
Where-Object {($_.ForwardTo -ne $null) -or ($_.ForwardAsAttachmentTo -ne $null) -or ($_.RedirectsTo -ne $null)}
$userDelegates += Get-MailboxPermission -Identity $user.UserPrincipalName | Where-Object {($_.IsInherited -ne "True") -and ($_.User -notlike "*SELF*")}
}
$smtpForwarding = $allUsers | Select-Object DisplayName,ForwardingAddress,ForwardingSMTPAddress,DeliverToMailboxandForward | Where-Object {$_.ForwardingSMTPAddress -ne $null}
$userInboxRules | Export-Csv MailForwardingRulesToExternalDomains.csv -NoTypeInformation
$smtpForwarding | Export-Csv Mailboxsmtpforwarding.csv -NoTypeInformation
$userDelegates | Export-Csv MailboxDelegatePermissions.csv -NoTypeInformation
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,41 @@
# Script to grant access rights on mailboxes
#
# Mailboxes to grant rights on
$grantRightsOnMailboxes = @('','')
# Users to grant rights to
$grantRightsToUsers = @('','')
# Rights to grant
$accessRights = 'Editor'
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Apply the permissions
foreach ($grantRightsToUser in $grantRightsToUsers ) {
foreach ($grantRightsOnMailbox in $grantRightsOnMailboxes) {
$calendarIdentity = $grantRightsOnMailbox + ':\Calendar'
$existingPermissions = Get-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -ErrorAction SilentlyContinue
if (!($existingPermissions)) {
Add-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -AccessRights $accessRights
}
else {
Set-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -AccessRights $accessRights
}
Set-Mailbox -Identity $upn GrantSendOnBehalfTo @{add=$editor}
}
}
# End the PowerShell session
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,45 @@
# Enable mailbox auditing and disable PowerShell remoting on individual mailboxes
#
# Working on this as a one stop for hardening Exchange Online accounts
#
# UPN of New User
$newUPN = ''
# Is the user an administrator?
$isAnAdmin = $false
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Set Auditing parameters
$params = @{
'AuditEnabled' = $true
'AuditLogAgeLimit' = '180'
'AuditAdmin' = @('Update','MoveToDeletedItems','SoftDelete','HardDelete','SendAs','SendOnBehalf','Create','UpdateFolderPermission')
'AuditDelegate' = @('Update','SoftDelete','HardDelete','SendAs','Create','UpdateFolderPermissions','MoveToDeletedItems','SendOnBehalf')
'AuditOwner' = @('UpdateFolderPermission','MailboxLogin','Create','SoftDelete','HardDelete','Update','MoveToDeletedItems')
}
# Enable Auditing
Get-Mailbox -Identity $newUPN | Set-Mailbox @params
# Disable PowerShell Remoting for non-Admin staff
if ($isAnAdmin) {
Set-User -Identity $newUPN -RemotePowerShellEnabled $true
}
else {
Set-User -Identity $newUPN -RemotePowerShellEnabled $false
}
# Disconnect from Exchange Online
Remove-PSSession $exchangeSession

View File

@@ -0,0 +1,111 @@
# Script to bulk remove email proxy addresses from Exchange users in a synced environment using an on-prem Exchange management server
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# Which domains are we removing?
$domainsToRemove = @('','')
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking
### Check if address policies are using this domain ###
# Initialise a hastable to store our results in
$addressPolicies = @()
# Get all address policies from Exchange
$allAddressPolicies = Get-EmailAddressPolicy
# Run through the domains checking if the domain to be removed is in the address policies
foreach ($domainToRemove in $domainsToRemove) {
$emailAddressTemplate = 'SMTP:@' + $domainToRemove
$addressPolicies += $allAddressPolicies | Where-Object {$_.EnabledEmailAddressTemplates -contains $emailAddressTemplate}
}
# If domain found in address policies then list them and ask if we want to contiue removing the proxy domain
if ($addressPolicies.Count -gt 0) {
Write-Output -InputObject ('The following address policies are using the domain to be removed:')
$addressPolicies | Format-Table
$continue = ''
while ($continue -notmatch '[YyNn]') {
$continue = Read-Host -Prompt 'Do you want to continue running the script? (Y/N)'
}
if ($continue -match '[Nn]') {
Write-Output -InputObject ('Terminating script.')
break
}
else {
Write-Output -InputObject ('Continuing with script.')
}
}
###
### Remove the domain from mailboxes ###
# Get All Mailboxes
$allMailboxes = Get-RemoteMailbox -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each mailbox
foreach ($mailbox in $allMailboxes) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($mailbox.EmailAddresses -split ',' | Where-Object {$_ -match $domainToRemove}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from maibox ' + $mailbox.Name)
Set-RemoteMailbox -Identity $mailbox.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from contacts ###
# Get all the contacts
$allContacts = Get-MailContact -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each contact
foreach ($contact in $allContacts) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($contact.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from contact ' + $contact.Name)
Set-MailContact -Identity $contact.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false -ForceUpgrade:$true
}
}
###
### Remove the domain from groups ###
# Get all the groups (this includes email enabled security groups)
$allGroups = Get-DistributionGroup -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each group
foreach ($group in $allGroups) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($group.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from group ' + $group.Name)
Set-DistributionGroup -Identity $group.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Public folders don't feature here because in this scenario they're cloud only ###
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,62 @@
# Find mailboxes for synced accounts, where the mailbox exists in Exchange Online but doesn't exist on-prem as a remote mailbox.
#
# Like the other stuff in this folder, it's a bit of a niche scenario.
# We're looking for mailboxes which were created in on-prem AD and then licenced in the cloud without a remote mailbox being created on the on-prem Exchange server, so that we can remote mail enable them correctly.
#
# This is a bit complicated as it requires connected to two Exchange environments at once, so uses command prefixes for one of them.
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# What is your remote routing address? E.g.: @domain.mail.onmicrosoft.com
$remoteRoutingSuffix = '@domain.mail.onmicrosoft.com'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Create Exchange on-prem connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange on-prem and add the OnPrem prefix to all commands
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking -Prefix OnPrem
# Get list of mailboxes from Exchange online for synced users
$allOnlineMailboxes = Get-Mailbox -ResultSize Unlimited | Where-Object {$_.IsDirSynced -eq $true -and $_.Name -notlike 'DiscoverySearchMailbox*'}
# Get list of remote mailboxes from on-prem server
$allOnPremMailboxes = Get-OnPremRemoteMailbox -ResultSize Unlimited
# Compare the two lists and add those missing from the on-prem list to the $syncedMailboxMismatch hashtable
$syncedMailboxMismatch = $allOnlineMailboxes | Where-Object {$allOnPremMailboxes.PrimarySmtpAddress -notcontains $_.PrimarySmtpAddress}
# Find mailboxes where alias and username match
$matchedUPNAliases = $syncedMailboxMismatch | Where-Object {$_.Alias -eq $_.UserPrincipalName.Split('@')[0]}
# Find mailboxes where alias and username don't match
$mismatchedUPNAliases = $syncedMailboxMismatch | Where-Object {$_.Alias -ne $_.UserPrincipalName.Split('@')[0]}
# Fix the mailboxes where username and alias matched.
foreach ($mailboxToRemoteEnable in $matchedUPNAliases) {
$mailboxUsername = $mailboxToRemoteEnable.UserPrincipalName.Split('@')[0]
$mailboxToFix = $mailboxToRemoteEnable.UserPrincipalName
$remoteRoutingAddress = $mailboxUsername + $remoteRoutingSuffix
Enable-OnPremRemoteMailbox -Identity $mailboxToFix -RemoteRoutingAddress $remoteRoutingAddress
}
# Write out the mailboxes that have been updated
Write-Output -InputObject ('The following mailboxes have been remote mail enabled.')
$matchedUPNAliases | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress
# Write out the mailboxes that have been left due to a mismatch between username and alias
Write-Output -InputObject ('The following mailboxes have not been changed because they have a mismatch between email alias and username.')
$mismatchedUPNAliases | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,24 @@
# Disable a list of mail users
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# What accounts are we disabling?
$usersToDisable = @('','')
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking -AllowClobber
# Get list of mailboxes
foreach ($userToDisable in $usersToDisable) {
Disable-RemoteMailbox -Identity $userToDisable -Confirm:$false
}
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,28 @@
# Find mailboxes using a specific email domain and export list to CSV file
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# Primary SMTP domain to search for
$primarySMTP = ''
# Where are we saving the output file?
$outputFile = 'C:\Temp\Mailboxes.csv'
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking
# Get list of mailboxes
$allMailboxes = Get-RemoteMailbox -ResultSize Unlimited | Where-Object {($_.PrimarySmtpAddress.Split('@')[1] -eq $primarySMTP)}
# Export results to CSV file
$allMailboxes | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress,EmailAddresses | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,15 @@
# Exchange Online with AzureAD Connect
## What is this?
The scripts in this folder are for managing mailboxes in a synced environment, where you have an Exchange server on-prem purely for management purposes. This means all mailboxes are seen as "remote" mailboxes, so all the scripts use commands to that effect. These can easily be updated to a normal environment like on-prem only or cloud only just by removing the work "remote" from the commands. For example, Get-RemoteMailbox to just Get-Mailbox.
## Pre-requisites
These scripts require you to have on-prem Active Directory with an on-prem Exchange server for management, and using AzureAD Connect to sync to AzureAD.
It's pretty niche.
## Disclaimer
All scripts are provided as is without warranty of any kind, use them at your own risk.

View File

@@ -0,0 +1,20 @@
# Bulk change guest accounts from a certain domain so that they show in the Global Address List
#
# Uses the new PowerShell "module" that support MFA.
#
# What domain are the guests email addresses from?
$guestDomain = ''
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Find all the relevant users and enable them to show in the address list
Get-MailUser -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -eq 'GuestMailUser' -and $_.EmailAddresses -match $guestDomain} | Set-MailUser -HiddenFromAddressListsEnabled $false
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,42 @@
# Create a group and add it to all room mailboxes as an editor
#
# Uses the new PowerShell "module" that support MFA.
#
# What do you want the editors group to be called?
$editorsGroup = 'Calendar Editors'
# Who do you want to be in the group? This can be 1 or more people.
$editorsMembers = @('','')
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all room mailboxes in the organisation
$roomMailboxes = (Get-Mailbox -RecipientTypeDetails RoomMailbox).Alias
# If the editors group doesn't exist, create it.
if (!(Get-DistributionGroup -Identity $editorsGroup -ErrorAction SilentlyContinue)) {
New-DistributionGroup -Name $editorsGroup -Type Security
}
# Add members to the group
$existingMembers = Get-DistributionGroupMember -Identity $editorsGroup
foreach ($editorsMember in $editorsMembers) {
if ($editorsMember -notin $existingMembers.Name) {
Add-DistributionGroupMember -Identity $editorsGroup -Member $editorsMember
}
}
# Add the permissions to the mailboxes
foreach ($roomMailbox in $roomMailboxes) {
$calendarFolder = $mailboxAlias + ':\calendar'
Add-MailboxFolderPermission -Identity $calendarFolder -User $editorsGroup -AccessRights Editor
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,41 @@
# Create a rule to block email forwarding to specific domains.
#
# Uses the new PowerShell "module" that support MFA.
#
# What domains are we blocking?
$domainListFile = 'C:\Temp\DomainList.txt'
# What do we want to call the rule?
$ruleName = 'Block Auto Forwarding to Specific Domains 4'
# What reason do we want end users to see for the rejection?
$rejectionReason = 'Auto forwarding messages to this email provider is not permitted.'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get the domain list from the file
$domainList = Get-Content -Path $domainListFile
# Create a new rule
$parameters = @{
'Name' = $ruleName;
'FromScope' = 'InOrganization';
'SenderAddressLocation' = 'Header'
'RecipientDomainIs' = $domainList;
'MessageTypeMatches' = 'AutoForward';
'RejectMessageEnhancedStatusCode' = '5.7.1'
'RejectMessageReasonText' = $rejectionReason;
'Priority' = 0;
'Mode' = 'Enforce'
'Enabled' = $true
}
New-TransportRule @parameters
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,91 @@
# Script to bulk remove email proxy addresses from Exchange Online users
#
# Which domains are we removing?
$domainsToRemove = @('','')
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
### Remove the domain from mailboxes ###
# Get All Mailboxes
$allMailboxes = Get-Mailbox -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each mailbox
foreach ($mailbox in $allMailboxes) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($mailbox.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from maibox ' + $mailbox.Name)
Set-Mailbox -Identity $mailbox.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from contacts ###
# Get all the contacts
$allContacts = Get-MailContact -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each contact
foreach ($contact in $allContacts) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($contact.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from contact ' + $contact.Name)
Set-MailContact -Identity $contact.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false -ForceUpgrade:$true
}
}
###
### Remove the domain from groups ###
# Get all the groups (this includes email enabled security groups)
$allGroups = Get-DistributionGroup -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each group
foreach ($group in $allGroups) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($group.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from group ' + $group.Name)
Set-DistributionGroup -Identity $group.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from public folders ###
# Get all the groups (this includes email enabled security groups)
$allPublicFolders = Get-MailPublicFolder -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each public folder
foreach ($publicFolder in $allPublicFolders) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($publicFolder.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from public folder ' + $publicFolder.Name)
Set-MailPublicFolder -Identity $publicFolder.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,20 @@
# Enable Modern Authentication in Exchange Online
#
# Uses the new PowerShell "module" that support MFA.
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Enable modern authentication
Set-OrganizationConfig -OAuth2ClientProfileEnabled $true
# Verify the setting has changed
Get-OrganizationConfig | Format-Table -AutoSize Name,OAuth2ClientProfileEnabled
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,29 @@
# Enable mailbox auditing on mailboxes where auditing is not already enabled
#
# This is a rewrite of a script from https://github.com/OfficeDev/O365-InvestigationTooling
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Set Auditing parameters
$params = @{
'AuditEnabled' = $true
'AuditLogAgeLimit' = '180'
'AuditAdmin' = @('Update','MoveToDeletedItems','SoftDelete','HardDelete','SendAs','SendOnBehalf','Create','UpdateFolderPermission')
'AuditDelegate' = @('Update','SoftDelete','HardDelete','SendAs','Create','UpdateFolderPermissions','MoveToDeletedItems','SendOnBehalf')
'AuditOwner' = @('UpdateFolderPermission','MailboxLogin','Create','SoftDelete','HardDelete','Update','MoveToDeletedItems')
}
# Enable Auditing
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -match '(User|Shared|Room|Discovery)Mailbox' -and $_.AuditEnabled -eq $false} | Set-Mailbox @params
# Check Auditing
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -match '(User|Shared|Room|Discovery)Mailbox'} | Format-Table -AutoSize UserPrincipalName,RecipientTypeDetails,AuditEnabled,AuditLogAgeLimit
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,15 @@
# Find mailboxes where UPN domain doesn't match email domain
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get list of mailboxes with a different mail domain to UPN domain
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.UserPrincipalName.Split('@')[1] -ne $_.PrimarySmtpAddress.Split('@')[1]} | Format-Table Name,UserPrincipalName,PrimarySmtpAddress,RecipientTypeDetails
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,40 @@
# Find shared mailboxes on the basis of their email domain and lists of who has access to them
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputFile = 'C:\Temp\GroupDetails.csv'
# Wildcard for groups to find
$searchWildcard = '*@example.domain'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all the groups we're looking for
$allGroups = Get-DistributionGroup | Where-Object {$_.PrimarySmtpAddress -like $searchWildcard}
# Initialise the hash table to store results in
$groupDetails = @()
# Run through the groups getting the members and adding
foreach ($group in $allGroups) {
$groupMembers = (Get-DistributionGroupMember -Identity $group.Name).Alias -join '; '
$groupDetails += [PSCustomObject]@{
'GroupName' = $group.Name;
'GroupEmail' = $group.PrimarySmtpAddress;
'GroupType' = $group.GroupType;
'GroupMembers' = $groupMembers
}
}
# Export results to CSV file
$groupDetails | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,40 @@
# Get the permissions and sendas rights for a list of mailboxes and output them to CSV
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputPath = 'C:\Temp\MailboxPermissions\'
# What mailboxes are we checking?
$mailboxes = Get-Content -Path 'C:\Temp\Mailboxes.txt'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all non-inherited mailbox permissions excluding self and output to a CSV file named for each mailbox
foreach ($mailbox in $mailboxes) {
Write-Output -InputObject ('Getting permissions for mailbox ' + $mailbox)
$mailboxPermissions = Get-MailboxPermission -Identity $mailbox | Where-Object {$_.IsInherited -eq $false -and $_.User -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,User,AccessRights,Deny
if ($mailboxPermissions.Count -gt 0) {
$outputFile = $outputPath + 'MailboxPermissions_' + ($mailbox -replace '@','_') + '.csv'
$mailboxPermissions | Export-CSV -Path $outputFile -NoTypeInformation
}
}
# Get all non-inherited recipient permissions (sendas) excluding self and output to a CSV file named for each mailbox
foreach ($mailbox in $mailboxes) {
Write-Output -InputObject ('Getting permissions for recipient ' + $mailbox)
$recipientPermissions = Get-RecipientPermission -Identity $mailbox | Where-Object {$_.IsInherited -eq $false -and $_.Trustee -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,Trustee,AccessRights,AccessControlType
if ($recipientPermissions.Count -gt 0) {
$outputFile = $outputPath + 'RecipientPermissions_' + ($mailbox -replace '@','_') + '.csv'
$recipientPermissions | Export-CSV -Path $outputFile -NoTypeInformation
}
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,32 @@
# Find shared mailboxes on the basis of their email domain and lists of who has access to them
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputPath = 'C:\Temp\'
# Wildcard for mailboxes to find
$searchWildcard = '*'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all the mailboxes we're looking for
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited | Where-Object {$_.PrimarySmtpAddress -like $searchWildcard} | Select-Object Name,Alias,PrimarySmtpAddress,ProhibitSendQuota
# Export list of mailboxes to CSV File
$sharedMailboxes | Export-CSV -Path ($outputPath + 'Shared Mailboxes.csv') -NoTypeInformation
# Get all non-inherited permissions excluding self and output to a CSV file named for each group
foreach ($sharedMailbox in $sharedMailboxes) {
$mailboxPermissions = Get-MailboxPermission -Identity $sharedMailbox.alias | Where-Object {$_.IsInherited -eq $false -and $_.User -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,User,AccessRights,Deny
$mailboxPermissions | Export-CSV -Path ($outputPath + $sharedMailbox.Name + '.csv') -NoTypeInformation
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,27 @@
# Exchange Online with MFA Support
## What is this?
Connecting to Exchange Online through a remote PowerShell session doesn't work when using multi factor authentication. You can (apparrently) get round that by creating an application password, but I've never got it to work and in my mind creating a password to bypass MFA somewhat defeates the point of enabling MFA in the first place.
There now is a new "module" available which does support MFA, so this folder is where I'll be putting new scripts that support MFA or old scripts as I update them.
## Pre-requisites
To connect using MFA you have to locally install a new module from Microsoft. Which for whatever reason isn't available from PSGallery, nor can it be simply downloaded. Instead it has to be installed from within the Exchange Online admin centre using one of those annoying ClickOnce installers that only work in MS's own web browsers.
Microsoft have a document explaining the unnecessarily convulted install process here:
[Connect to Exchange Online PowerShell using multi-factor authentication](https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps)
In addition, because this will be using a remote session it will require the script execution policy within PowerShell to be changed to RemoteSigned. This is done either globally with:
`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned`
Or for the current user with:
`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
## Disclaimer
All scripts are provided as is without warranty of any kind, use them at your own risk.

View File

@@ -0,0 +1,32 @@
# Reset default calendar permissions to availability for a list of users.
#
# Uses the new PowerShell "module" that support MFA.
#
# File with list of users
$userlistPath = 'C:\Temp\Userlist.txt'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get list of users
$userlist = Get-Content -Path $userlistPath
# Get mailboxes for users in list
$mailboxes = Get-Mailbox -ResultSize Unlimited | Where-Object {$_.Name -in $userlist} | Sort-Object -Property Name
# Check the mailboxes and reset any which have default permissions of None to AvailabilityOnly
foreach ($mailbox in $mailboxes) {
$calendarPath = $mailbox.UserPrincipalName + ':\Calendar'
$defaultPermissions = Get-MailboxFolderPermission -Identity $calendarPath -User 'Default'
if ($defaultPermissions.AccessRights -eq 'None') {
Set-MailboxFolderPermission -Identity $calendarPath -User 'Default' -AccessRights AvailabilityOnly
}
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,28 @@
# A simple script to enable forwarding for a list of users from a CSV file
#
# The script is expecting the CSV file to have two columns called SourceAddress and DestinationAddress
#
# Get the list of users from a CSV file
$userList = Import-Csv -Path 'C:\Temp\UserList.csv'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all non-inherited permissions excluding self and output to a CSV file named for each group
foreach ($user in $userList) {
Write-Output -InputObject ('Forwarding ' + $user.SourceAddress + ' to ' + $user.DestinationAddress)
Set-Mailbox -Identity $user.SourceAddress -ForwardingSmtpAddress $user.DestinationAddress
}
# Pull back a list to check everything has worked correctly
foreach ($user in $userList) {
Get-Mailbox -Identity $user.SourceAddress | Select-Object UserPrincipalName,ForwardingSmtpAddress,DeliverToMailboxAndForward
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,52 @@
# Create and set up a room mailbox.
#
# Uses the new PowerShell "module" that support MFA.
#
# New room name and alias
$displayName = ''
$mailboxAlias = ''
# How many people can the room take?
$roomCapacity = ''
# Do you want meeting requests to be auto accepted?
$requestAutoAccept = $true
# Do we want to add the room to a room list?
$addToRoomList = $true
# What is the room list called? (Will be created if it doesn't exist)
$roomList = ''
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Create the new room mailbox
New-Mailbox -Room -Alias $mailboxAlias -Name $displayName -DisplayName $displayName -ResourceCapacity $roomCapacity
# Wait for the meeting room mailbox to process
Start-Sleep -Seconds 30
# Set the mailbox calendar to auto accept meeting requests (assuming policies are met)
if ($requestAutoAccept) {
Set-CalendarProcessing $mailboxAlias -AutomateProcessing AutoAccept
}
# If we're adding the room to a room list, then do that.
if ($addToRoomList) {
# If the room list doesn't exist, create it.
if (!(Get-DistributionGroup -Identity $roomList -ErrorAction SilentlyContinue)) {
New-DistributionGroup -Name $roomList -RoomList
}
# Add the room to the list
Add-DistributionGroupMember -Identity $roomList -Member $mailboxAlias
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,76 @@
# ScheduledBitLockerKeyBackup.ps1
<#
Script intended for deployment through Intune:
Creates a locally saved PS script to get the bitlocker key and save it to Azure.
Then creates a scheduled task to run that script at every logon.
#>
# Name and description for the schedulled task to be created
$taskName = 'Bitlocker Key Backup to AzureAD'
$taskDescription = 'Retrieve Bitlocker key for system drive and store it in AzureAD'
# Day, time and randomised delay for the task to be created
$taskDay = 'Monday'
$taskTime = '12:00:00'
$taskDelay = '00:20:00'
# Path to the folder for the files to be created
$scriptFolder = 'C:\ProgramData\Intune\Scripts\'
# Names of the files to be created
$scriptFilename = 'BitlockerKeyBackup.ps1'
$scriptLogFilename = 'BitlockerKeyBackup-LastRun.log'
$deployLogFilename = 'BitlockerKeyBackup-Deployed.log'
# Establish full paths to the files
$scriptPath = $scriptFolder + $scriptFilename
$logPath = $scriptFolder + $scriptLogFilename
$deployLogPath = $scriptFolder + $deployLogFilename
# If folder doesn't exist create it, else clean up files from last run
if (!(Test-Path -Path $scriptFolder)) {
New-Item -Path $scriptFolder -ItemType Directory
}
else {
foreach ($filePath in @($scriptPath, $logPath, $deployLogPath)) {
if (Test-Path -Path $filePath) {
Remove-Item -Path $filePath
}
}
}
# Contents of the PS script file to be created on the target machine
$scriptContents = @(
'$logPath = ''' + $logPath + ''''
'try {'
' $recoveryPassword = ((Get-BitlockerVolume -MountPoint $env:SystemDrive -ErrorAction Stop).KeyProtector | Where-Object {$_.KeyProtectorType -eq "RecoveryPassword"})'
' $result = BackupToAAD-BitLockerKeyProtector $env:systemdrive -KeyProtectorId $recoveryPassword.KeyProtectorId -ErrorAction Stop'
' Out-File -InputObject $result -FilePath $logPath'
'}'
'catch {'
' Out-File -InputObject $Error[0].Exception.Message -FilePath $logPath'
'}'
)
# Create the script file
Out-File -InputObject $scriptContents -FilePath $scriptPath
# Set up the various parts of the scheduled task
$taskArgument = '-ExecutionPolicy Bypass -Command ". ' + $scriptPath + '"'
$taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $taskArgument -WorkingDirectory $scriptFolder
$taskTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $taskDay -At $taskTime -RandomDelay $taskDelay
$taskPrincipal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType 'ServiceAccount' -RunLevel 'Highest'
$taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Compatibility 'Win8' -Hidden -StartWhenAvailable
# If the scheduled task already exists then remove it
if (Get-ScheduledTask | Where-Object { $_.TaskName -eq $taskName }) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
}
# Create the scheduled task and run it immediately
$taskCreated = Register-ScheduledTask -Action $taskAction -Trigger $taskTrigger -TaskName $taskName -Description $taskDescription -Principal $taskPrincipal -Settings $taskSettings
Start-ScheduledTask -TaskName $taskName
# Create a log file for the deployment of the scheduled task
Out-File -InputObject $taskCreated -FilePath $deployLogPath

View File

@@ -0,0 +1,4 @@
# Convert AD GUID to 365 ImmutableID
$adGuid = Read-Host -Prompt 'Enter Active Directory GUID to convert to ImmutableID'
[System.Convert]::ToBase64String($adGuid.tobytearray())

View File

@@ -0,0 +1,22 @@
# Bulk add a new licence to users on the basis of what licence they currently have
#
# This is useful for something like adding Office 365 ATP to everyone who currently has E3, for example.
#
# What licence do the users currently have?
$existingLicence = ''
# What licence are we adding?
$licenceToAdd = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the existing
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $existingLicence -and !(($_.licenses).AccountSkuId -match $licenceToAdd)}
# Add the new licence
foreach ($user in $users) {
Set-MSOLUserLicense -UserPrincipalName $user.UserPrincipalName AddLicenses $licenceToAdd
}

View File

@@ -0,0 +1,37 @@
# Bulk add additional licences to a list of users where they already have a licence assigned.
#
# Only works where the user already has a licence assigned as assigning a licence to an unlicenced user is a different process.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
# List of available SKUs can be obtained with (Get-MsolAccountSku).AccountSkuId
$licencesToAdd = @('','')
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Import list of users from file
$users = Get-Content -Path $userListPath | Sort-Object
# Add the new licence
foreach ($user in $users) {
$userDetails = Get-MSOLUser -UserPrincipalName $user
foreach ($licenceToAdd in $licencesToAdd) {
if ($userDetails.IsLicensed -eq $true) {
if (!(($userDetails.licenses).AccountSkuId -match $licenceToAdd)) {
Write-Output -InputObject ('Adding Licence ' + $licenceToAdd + ' to ' + $user + '.')
Set-MSOLUserLicense -UserPrincipalName $user AddLicenses $licenceToAdd
}
else {
Write-Output -InputObject ('User ' + $user + ' already has ' + $licenceToAdd + ' licence assigned.')
}
}
else {
Write-Output -InputObject ('User ' + $user + ' has no existing licence assigned.')
}
}
}

View File

@@ -0,0 +1,42 @@
# Bulk enable or disable MFA for all users in a tenant
#
# Enable or disable MFA?
$enableMFA = $true
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Enable or disable MFA
if ($enableMFA) {
# Create an object containing the authentication requirements
$authReq = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
# Include all relying parties
$authReq.RelyingParty = '*'
# Set MFA state to enabled
# Enabled allows connected apps to keep working until the user completes MFA set up.
# This can also be set to enforced which would disconnect everything immediately.
$authReq.State = 'Enabled'
# Set the cut off date before which registered devices should require re-connecting with MFA.
# Using the current date is recommended so that all previously connected devices have to be reconnected.
$authReq.RememberDevicesNotIssuedBefore = (Get-Date)
# Find all licenced users who do not currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -notmatch 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Enable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements $authReq
}
else {
# Find all licenced users who currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -match 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Disable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements @()
}

View File

@@ -0,0 +1,22 @@
# Bulk update Online User UPNs
#
# What domain are we replacing?
$oldDomain = ''
# What are we replacing it with?
$newDomain = ''
# Import the MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Get all users using that domain as their UPN
$users = Get-MsolUser -All | Where-Object {$_.UserPrincipalName -match $oldDomain}
# Run through the users replacing their UPN and keeping us updated on what's going on
foreach ($user in $users) {
$newUPN = $user.UserPrincipalName.Split('@')[0] + '@' + $newDomain
Write-Output -InputObject ('Setting UPN for user ' + $user.UserPrincipalName + ' to ' + $newUPN)
Set-MsolUserPrincipalName -UserPrincipalName $user.UserPrincipalName -NewUserPrincipalName $newUPN
}

View File

@@ -0,0 +1,12 @@
# Disable MFA for all licenced users who currently have it enabled
#
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find all licenced users who currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -match 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Disable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements @()

View File

@@ -0,0 +1,26 @@
# Enable MFA for all licenced users who don't currently have it enabled
#
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Create an object containing the authentication requirements
$authReq = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
# Include all relying parties
$authReq.RelyingParty = '*'
# Set MFA state to enabled
# Enabled allows connected apps to keep working until the user completes MFA set up.
# This can also be set to enforced which would disconnect everything immediately.
$authReq.State = 'Enabled'
# Set the cut off date before which registered devices should require re-connecting with MFA
$authReq.RememberDevicesNotIssuedBefore = (Get-Date)
# Find all licenced users who do not currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -notmatch 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Enable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements $authReq

View File

@@ -0,0 +1,17 @@
# Bulk remove a licence from users
#
# What licence are we removing?
$licenceToRemove = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the licence to be removed
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $licenceToRemove}
# Remove the licence
foreach ($user in $users) {
Set-MSOLUserLicense user $user.UserPrincipalName RemoveLicenses $licenceToRemove
}

View File

@@ -0,0 +1,21 @@
# Bulk replace a licence for all users who have the one being replaced.
#
# What licence are we removing?
$licenceToRemove = ''
# What licence are we adding?
$licenceToAdd = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the licence being replaced
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $licenceToRemove}
# Remove the old licence and add the new one
foreach ($user in $users) {
Set-MSOLUserLicense user $user.UserPrincipalName RemoveLicenses $licenceToRemove
Set-MSOLUserLicense user $user.UserPrincipalName -AddLicenses $licenceToAdd
}

View File

@@ -0,0 +1,16 @@
# Update Online User UPN - when AD sync doesn't do it.
# Import the MSOL module and connect
Import-Module MSOnline
Connect-MsolService
# Whose UPN are we changing?
$oldUPN = Read-Host -Prompt 'Enter user''s old UPN in the format username@domain'
# What are we changing it to?
$newUPN = Read-Host -Prompt 'Enter user''s new UPN in the format username@domain'
# Change the UPN
if (Get-ADUser -Identity $newUPN.Split('@')[0]) {
Set-MsolUserPrincipalName -UserPrincipalName $oldUPN -NewUserPrincipalName $newUPN
}

View File

@@ -0,0 +1,9 @@
# Delete a user and then delete the deleted user
Import-Module MSOnline
Connect-MsolService
$upnToDelete = Read-Host -Prompt 'Enter UPN of user to delete in the format username@domain'
Remove-MsolUser -UserPrincipalName $upnToDelete
Remove-MsolUser -UserPrincipalName $upnToDelete -RemoveFromRecycleBin

View File

@@ -0,0 +1,33 @@
# Remove a duplicate 365 account created by a faulty sync and reconnect
# the orphaned 365 user to the AD account.
#
# Get correct and incorrect account details
$adUsername = Read-Host -Prompt 'Enter username for AD account'
$msolIncorrectUPN = Read-Host -Prompt 'Enter UPN for the duplicate object in MSOL'
# Connect to MS Online
Import-Module MSOnline
Connect-MsolService
# Get AD user account
$adObject = Get-ADUser -Identity $adUsername
# Get correct UPN from AD account
$msolCorrectUPN = $adObject.UserPrincipalName
#
try {
Get-MsolUser -UserPrincipalName $msolCorrectUPN -ErrorAction Stop
Remove-MSOLuser -UserPrincipalName $msolIncorrectUPN
Remove-MSOLuser -UserPrincipalName $msolIncorrectUPN -RemoveFromRecycleBin
$adGuid = $adObject.ObjectGuid
$immutableID = [System.Convert]::ToBase64String($adGuid.ToByteArray())
Set-MSOLuser -UserPrincipalName $msolCorrectUPN -ImmutableID $immutableID
}
catch {
Write-Host 'No account found in Azure AD matching the UPN for that AD account.'
}

View File

@@ -0,0 +1,4 @@
# Convert 365 ImmutableID to AD GUID
$immutableID = Read-Host -Prompt 'Enter ImmutableID to convert to Active Directory GUID'
[GUID][System.Convert]::FromBase64String($immutableID)

View File

@@ -0,0 +1,18 @@
# Retrive a list of all OneDrive for Business sites within the organisation
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the common base URL for OneDrive for Business
$spoBaseWildcard = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/*'
# Get a list of all 'personal' sites (e.g.: OneDrive for Business sites) within the tenant
Get-SPOSite -Limit all -IncludePersonalSite $true | Where-Object {$_.Url -like $spoBaseWildcard} | Select-Object Owner,URL,StorageQuota | Format-Table -AutoSize

View File

@@ -0,0 +1,47 @@
# Increase the size of specific users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The size you want to increase to in TB.
$newSize = 1
# The list of UPNs for the accounts you wich to add the secondary admin to (list can contain a single item if required)
$userList = @('','')
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the base URL for OneDrive for Business
$spoBaseURL = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/'
# Convert new size to bytes
$newBytes = $newSize * 1048576
# Increase size for each user in list
foreach ($userUPN in $userList) {
$spoURL = $spoBaseURL + ($userUPN.ToLower() -replace "[@.]", "_")
try {
$currentBytes = (Get-SPOSite -Identity $spoURL -ErrorAction:Stop).StorageQuota
if ($currentBytes -gt $newBytes) {
try {
Set-SPOSite -Identity $spoURL -StorageQuota $newBytes -ErrorAction:Stop
Write-Output -InputObject ('Updated OneDrive account limit for ' + $userUPN + ' to ' + $newSize + 'TB.')
}
catch {
Write-Output -InputObject ('Failed to update OneDrive account limit for ' + $userUPN + '.')
}
}
else {
Write-Output -InputObject ('OneDrive account limit for ' + $userUPN + ' already equal to or higher than ' + $newSize + 'TB.')
}
}
catch {
Write-Output -InputObject ('No OneDrive account found for ' + $userUPN + '.')
}
}

View File

@@ -0,0 +1,44 @@
# Increase the size of all users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The size you want to increase to in TB.
$newSize = 1
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the common base URL for OneDrive for Business
$spoBaseWildcard = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/*'
# Convert new size to bytes
$newBytes = $newSize * 1048576
# Get a list of all personal sites within the tenant.
$personalSites = Get-SPOSite -Limit all -IncludePersonalSite $true | Where-Object {$_.Url -like $spoBaseWildcard}
# Increase size for each user in turn.
foreach ($personalSite in $personalSites) {
$spoURL = $personalSite.Url
$userUPN = $personalSite.Owner
$currentBytes = $personalSite.StorageQuota
if ($currentBytes -lt $newBytes) {
try {
Set-SPOSite -Identity $spoURL -StorageQuota $newBytes -ErrorAction:Stop
Write-Output -InputObject ('Updated OneDrive account limit for ' + $userUPN + ' to ' + $newSize + 'TB.')
}
catch {
Write-Output -InputObject ('Failed to update OneDrive account limit for ' + $userUPN + '.')
}
}
else {
Write-Output -InputObject ('OneDrive account limit for ' + $userUPN + ' already equal to or higher than ' + $newSize + 'TB.')
}
}

View File

@@ -0,0 +1,27 @@
# Add a collection administrator to your users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The UPN of the account you wish to add as a secondary admin
$secondaryAdminUPN = ''
# The list of UPNs for the accounts you wich to add the secondary admin to
$userList = @('','')
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the base URL for OneDrive for Business
$spoBaseURL = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/'
# Add secondary admin to each user in the list
foreach ($userUPN in $userList) {
$spoURL = $spoBaseURL + ($userUPN.ToLower() -replace "[@.]", "_")
Set-SPOUser -Site $spoURL -LoginName $secondaryAdminUPN -IsSiteCollectionAdmin $true -ErrorAction:Continue
}

View File

@@ -0,0 +1,28 @@
# Remove a collection administrator from your users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The UPN of the account you wish to add as a secondary admin
$secondaryAdminUPN = ''
# The list of UPNs for the accounts you wich to add the secondary admin to
$userList = @('','')
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the base URL for OneDrive for Business
$spoBaseURL = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/'
# Add secondary admin to each user in the list
foreach ($userUPN in $userList) {
$spoURL = $spoBaseURL + ($userUPN.ToLower() -replace "[@.]", "_")
Set-SPOUser -Site $spoURL -LoginName $secondaryAdminUPN -IsSiteCollectionAdmin $false -ErrorAction:Continue
Remove-SPOUser -Site $spoURL -LoginName $secondaryAdminUPN
}

View File

@@ -0,0 +1,27 @@
# Retrive a list of all OneDrive for Business sites, check their size and reset it if it is less than the default
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the common base URL for OneDrive for Business
$spoBaseWildcard = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/*'
# Get the default quota for the tenant
$defaultQuota = (Get-SPOTenant).OneDriveStorageQuota
# Get a list of all 'personal' sites (e.g.: OneDrive for Business sites) within the tenant
$usersToReset = Get-SPOSite -Limit all -IncludePersonalSite $true | Where-Object {$_.Url -like $spoBaseWildcard -and $_.StorageQuota -lt $defaultQuota}
# Get a list of all 'personal' sites (e.g.: OneDrive for Business sites) within the tenant
foreach ($userToReset in $usersToReset) {
Write-Output -InputObject ('Resetting user ' + $userToReset.Owner)
Set-SPOSite -Identity $userToReset.Url -StorageQuotaReset
}

View File

@@ -0,0 +1,49 @@
# Script to go through all SPO sites and check if a user is assigned to them
#
# This is the name of your tenant, as shown in the URL when accessing SharePoint online
# E.g.: https://<tenant-name>.sharepoint.com/
$spoTenantName = ''
# Who are we looking for? (uses a wildcard like comparison)
$loginNameLike = ''
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Get all SharePoint Online sites
$allSpoSites = Get-SPOSite -Limit All
# Run through the sites...
foreach ($spoSite in $allSpoSites) {
# Try to get a list of users for the current site - requires owner access to the site.
try {
$spoUsers = Get-SPOUser -Site $spoSite.Url -Limit All -ErrorAction:Stop | Where-Object {$_.LoginName -like $loginNameLike}
$usersRetrived = $true
}
catch {
$spoUsers = ''
$usersRetrived = $false
}
# If the previous try didn't fail then work on the retrived list
if ($usersRetrived) {
# If the list isn't empty, then set the output message to the userlogin name and site URL.
if ([string]$spoUsers.Count -gt 0) {
foreach ($spoUser in $spoUsers) {
$outputMessage = 'User ' + $spoUser.LoginName + ' found in site ' + $spoSite.Url
}
}
# Else (if the list is empty) set the output message to reflect that the user wasn't found in that group.
else {
$outputMessage = 'User not found in site ' + $spoSite.Url
}
}
# If users weren't retrived then set the output message to reflect that.
else {
$outputMessage = 'Unable to get users from site: ' + $spoSite.Url
}
# Finally write out the output message.
Write-Output -InputObject $outputMessage
}

View File

@@ -0,0 +1,33 @@
# Script to go through all SPO sites and check if a user is assigned to them
#
# This is the name of your tenant, as shown in the URL when accessing SharePoint online
# E.g.: https://<tenant-name>.sharepoint.com/
$spoTenantName = ''
# Who are we looking for? (uses a wildcard like comparison)
$siteNameLike = '*'
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Get all SharePoint Online sites
$allSpoSites = Get-SPOSite -Limit All | Where-Object {$_.Title -like $siteNameLike}
Get-SpoSiteGroup
# Run through the sites...
foreach ($spoSite in $allSpoSites) {
# Try to get a list of users for the current site - requires owner access to the site.
$allSiteGroups = Get-SpoSiteGroup -Site $spoSite.Url
foreach ($siteGroup in $allSiteGroups) {
Write-Host
$siteGroup | Select-Object -ExpandProperty Users
}
}
$spoUsers | Export-Csv C:\Temp\SISLive-Sharepoint-Site.csv -NoTypeInformation
$allSpoSites

View File

@@ -0,0 +1,37 @@
# Enable all licenced users for Microsoft audio conferencing
#
# In addition to the SfB module this requires the MSOnline module so it can check who is licenced.
#
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Load the Skype Online Connector module and connect
Import-Module SkypeOnlineConnector
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession
# This can be just one licence, or several, eg. MCOMEETADV (audio conferencing), ENTERPRISEPREMIUM (E5) and MEETING_ROOM all include audio conferencing.
# List of available SKUs can be obtained with (Get-MsolAccountSku).AccountSkuId
$audioConferencingLicences = @('MCOMEETADV','ENTERPRISEPREMIUM','MEETING_ROOM')
# Find everyone who has the audio conferencing licence(s) assigned
$users = @()
foreach ($audioConferencingLicence in $audioConferencingLicences) {
$users += (Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $audioConferencingLicence}).UserPrincipalName
}
# Get the default service number from your tenant
$defaultServiceNumber = (Get-CsOnlineDialInConferencingBridge -Name 'Conference Bridge').DefaultServiceNumber
# Enable conferencing for everyone on that list who doesn't already have it enabled
foreach ($user in $users) {
$currentProvider = (Get-CsOnlineDialInConferencingUserInfo -Identity $user).Provider
if ($currentProvider -ne 'Microsoft') {
Enable-CsOnlineDialInConferencingUser -ServiceNumber $defaultServiceNumber -ReplaceProvider -SendEmail
}
}
# Disconnect
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,44 @@
# Enable Microsoft audio conferencing for a list of users
#
# Expects a CSV file with two columns, one containing the UserPrincipalName and the other containing the ServiceNumber.
#
# A list of dedicated conference numbers can be retrieved with:
# (Get-CsOnlineDialInConferencingBridge -Name 'Conference Bridge').ServiceNumbers | Where-Object {$_.IsShared -eq $false}
#
# If the service number entry for a user in the CSV file is blank then the default will be used.
#
# Where is the list of users?
$userListPath = 'C:\Temp\UserList.csv'
# Load the Skype Online Connector module and connect
Import-Module SkypeOnlineConnector
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession
# Get list of users from file
$users = Import-Csv -Path $userListPath
# Get the conference bridge details
$conferenceBridge = Get-CsOnlineDialInConferencingBridge -Name 'Conference Bridge'
# Enable conferencing for everyone on that list who doesn't already have it enabled
foreach ($user in $users) {
if (($user.ServiceNumber).Length -gt 0) {
$serviceNumber = $conferenceBridge.ServiceNumbers | Where-Object {$_.Number -eq $user.ServiceNumber}
}
else {
$serviceNumber = $conferenceBridge.DefaultServiceNumber
}
$currentProvider = (Get-CsOnlineDialInConferencingUserInfo -Identity $user.UserPrincipalName).Provider
if ($currentProvider -ne 'Microsoft') {
Enable-CsOnlineDialInConferencingUser -Identity $user.UserPrincipalName -ServiceNumber $serviceNumber.Number -ReplaceProvider -SendEmail
Write-Output -InputObject ('Audio conferencing enabled for ' + $user.UserPrincipalName + ' with number ' + $serviceNumber.Number + '.')
}
else {
Write-Output -InputObject ('Audio conferencing already enabled for ' + $user.UserPrincipalName + '.')
}
}
# Disconnect
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,18 @@
# Enable Modern Authentication in Skype for Business Online
#
# Load the Skype Online Connector module
Import-Module SkypeOnlineConnector
# Establish a session to Exchange Online
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession
# Enable modern authentication
Set-CsOAuthConfiguration -ClientAdalAuthOverride Allowed
# Verify the setting has changed
Get-CsOAuthConfiguration | Format-Table -AutoSize Identity,ClientAdalAuthOverride
# End the PS Session
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,74 @@
# Script to extract conferencing details for users from the AcpInfo setting
#
# Load the Skype Online Connector module
Import-Module SkypeOnlineConnector
# Establish a session to Exchange Online
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession
# Company Wildcard
$companyWildcard = '*'
# AcpInfo Wildcard
$acpInfoWildcard = '*BT*'
# Output file
$outputFile = 'C:\Temp\ConferencingUsers.csv'
# Get all conferencing users matching the above wildcarded info
$conferencingUsers = Get-CsOnlineUser -WarningAction:SilentlyContinue -ErrorAction:SilentlyContinue | Where-Object {($_.Company -like $companyWildcard) -and ($_.AcpInfo -like $acpInfoWildcard) -and ($_.Enabled -eq $true)} | Select-Object DisplayName,UserPrincipalName,AcpInfo
# Set up user details hash table
$userDetails = @()
# Run through the users, check if they're in the exclusions list and if not then pull the details out of the AcpInfo code
foreach ($conferencingUser in $conferencingUsers) {
$tollNumber = ''
if ([string]$conferencingUser.AcpInfo -match '<tollNumber>(?<tollNumber>.*)</tollNumber>') {
$tollNumber = $Matches.tollNumber
}
$tollFreeNumber = ''
if ([string]$conferencingUser.AcpInfo -match '<tollFreeNumber>(?<tollFreeNumber>.*)</tollFreeNumber>') {
$tollFreeNumber = $Matches.tollFreeNumber
}
$participantPassCode = ''
if ([string]$conferencingUser.AcpInfo -match '<participantPassCode>(?<participantPassCode>.*)</participantPassCode>') {
$participantPassCode = $Matches.participantPassCode
}
$domain = ''
if ([string]$conferencingUser.AcpInfo -match '<domain>(?<domain>.*)</domain>') {
$domain = $Matches.domain
}
$name = ''
if ([string]$conferencingUser.AcpInfo -match '<name>(?<name>.*)</name>') {
$name = $Matches.name
}
$url = ''
if ([string]$conferencingUser.AcpInfo -match '<url>(?<url>.*)</url>') {
$url = $Matches.url
}
$userDetails += [PSCustomObject]@{
'DisplayName' = [string]$conferencingUser.DisplayName
'UserPrincipalName' = [string]$conferencingUser.UserPrincipalName
'TollNumber' = [string]$tollNumber
'TollFreeNumber' = [string]$tollFreeNumber
'ParticipantPassCode' = [string]$participantPassCode
'Domain' = [string]$domain
'Name' = [string]$name
'Url' = [string]$url
}
}
# Output to CSV file
$userDetails | Export-Csv -Path $outputFile -NoTypeInformation
# End the PS Session
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,27 @@
# Script to bulk remove 3rd party conferencing details for all users
#
# Load the Skype Online Connector module
Import-Module SkypeOnlineConnector
# Establish a session to Exchange Online
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession -AllowClobber
# Company Wildcard
$companyWildcard = '*'
# AcpInfo to match (doesn't need to be the full name)
$acpInfoWildcard = '*BT*'
# Get all conferencing users matching the above info
$thirdPartyAcpUsers = Get-CsOnlineUser -WarningAction:SilentlyContinue -ErrorAction:SilentlyContinue | Where-Object {($_.Company -like $companyWildcard) -and ($_.AcpInfo -like $acpInfoWildcard) -and ($_.Enabled -eq $true)}
# Run through the users and remove their ACP info
foreach ($thirdPartyAcpUser in $thirdPartyAcpUsers) {
$acpInfoName = ([xml]$thirdPartyAcpUser.AcpInfo).acpInformation.name
Remove-CsUserAcp -Identity $thirdPartyAcpUser.Identity -Name $acpInfoName
}
# End the PS Session
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,26 @@
# Script to bulk remove conferencing details for a list of users
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# Load the Skype Online Connector module
Import-Module SkypeOnlineConnector
# Establish a session to Exchange Online
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession -AllowClobber
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Get CS Online user identities for all the users in the list
$csOnlineUsers = (Get-CsOnlineUser -WarningAction SilentlyContinue | Where-Object {$_.UserPrincipalName -in $userList}).Identity
# Run through the users and remove their ACP info
foreach ($csOnlineUser in $csOnlineUsers) {
Remove-CsUserAcp -Identity $csOnlineUser
}
# End the PS Session
Remove-PSSession -Session $sfbSession

View File

@@ -0,0 +1,41 @@
# Update Microsoft audio conferencing for a list of users
#
# Expects a CSV file with two columns, one containing the UserPrincipalName and the other containing the ServiceNumber.
#
# A list of dedicated conference numbers can be retrieved with:
# (Get-CsOnlineDialInConferencingBridge -Name 'Conference Bridge').ServiceNumbers | Where-Object {$_.IsShared -eq $false}
#
# If the service number entry for a user in the CSV file is blank then the default will be used.
#
# Where is the list of users?
$userListPath = 'C:\Temp\UsersToUpdate.csv'
# Load the Skype Online Connector module and connect
Import-Module SkypeOnlineConnector
$sfbSession = New-CsOnlineSession
Import-PSSession -Session $sfbSession
# Get list of users from file
$users = Import-Csv -Path $userListPath
# Get the conference bridge details
$conferenceBridge = Get-CsOnlineDialInConferencingBridge -Name 'Conference Bridge'
# Enable conferencing for everyone on that list who doesn't already have it enabled
foreach ($user in $users) {
if (($user.ServiceNumber).Length -gt 0) {
$serviceNumber = $conferenceBridge.ServiceNumbers | Where-Object {$_.Number -eq $user.ServiceNumber}
}
else {
$serviceNumber = $conferenceBridge.DefaultServiceNumber
}
$currentTollNumber = (Get-CsOnlineDialInConferencingUserInfo -Identity $user.UserPrincipalName).DefaultTollNumber
if ($currentTollNumber -ne $user.ServiceNumber) {
Set-CsOnlineDialInConferencingUser -Identity $user.UserPrincipalName -ServiceNumber $serviceNumber.Number -SendEmail
Write-Output -InputObject ('Audio conferencing updated for ' + $user.UserPrincipalName + ' with number ' + $serviceNumber.Number + '.')
}
}
# Disconnect
Remove-PSSession -Session $sfbSession