Added Files
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
#}
|
||||
@@ -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.')
|
||||
}
|
||||
@@ -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.')
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 + '.')
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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())
|
||||
@@ -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
|
||||
}
|
||||
@@ -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.')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 @()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 @()
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.'
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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 + '.')
|
||||
}
|
||||
}
|
||||
@@ -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.')
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user