├── All Office 365 customers’ global admins without multi-factor authentication.ps1 ├── Audit Log Enablement_SecureAppModel.ps1 ├── Block Admin-MFA.ps1 ├── Block Auto-FW.ps1 ├── Block Auto-FW_All Customers.ps1 ├── Bulk Update 365 User Passwords.ps1 ├── Bulk Update Primary SMTP.txt ├── Disable External User Access Teams.ps1 ├── Disable User Permission to Consent to App-Multitenant.txt ├── Disable User Permission to Consent to App.ps1 ├── Email Encryption Rule-All Customers.ps1 ├── Email Encryption Rule.ps1 ├── Enable MFA.ps1 ├── Enable Mailbox Auditing All Tenants.ps1 ├── Enable SSPR Multitenant.ps1 ├── Enable SSPR.ps1 ├── Enable Versioning SharePoint Sites.ps1 ├── Free_Busy Calendar Settings Multitenant.ps1 ├── MFAReport_AllCustomers.ps1 ├── Non-MFA Admins.ps1 ├── Only Free_Busy Calendar Single Tenant.ps1 ├── Security Notfications to Teams Channel.ps1 ├── Set Anonymous Links to Expire-SharePoint.ps1 ├── Set Outbound Spam Notifications.ps1 ├── Turn on Audit Log All Tenants.ps1 ├── Turn on Audit Log.ps1 ├── View All Global Admins in an Account.ps1 └── mailbox delegation /All Office 365 customers’ global admins without multi-factor authentication.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | 3 | $customers = Get-MsolPartnerContract 4 | $role = Get-MsolRole | Where-Object {$_.name -contains "Company Administrator"} 5 | foreach($customer in $customers){ 6 | 7 | $users = Get-MsolUser -TenantId $customer.tenantid 8 | $admins = Get-MsolRoleMember -TenantId $customer.tenantid -RoleObjectId $role.objectid 9 | 10 | foreach($admin in $admins){ 11 | $adminuser = $users | Where-Object {$_.userprincipalname -contains $admin.emailaddress} 12 | if($adminuser){ 13 | if($adminuser.strongauthenticationrequirements.state -notcontains "Enforced" -and $adminuser.strongauthenticationrequirements.state -notcontains "Enabled"){ 14 | Write-Host "No MFA enabled for $($adminuser.userprincipalname)" 15 | $adminuser | Add-Member TenantId $customer.tenantid 16 | $adminuser | Add-Member CustomerName $customer.name 17 | $adminuser | Select-Object TenantId,CustomerName,DisplayName,UserPrincipalName,islicensed,@{n="MFAStatus";e={$_.strongauthenticationrequirements.state}} | export-csv C:\temp\nonMFAAdmins.csv -NoTypeInformation -Append 18 | 19 | }else{ 20 | Write-Host "MFA enabled for $($adminuser.userprincipalname)" -ForegroundColor Green 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Audit Log Enablement_SecureAppModel.ps1: -------------------------------------------------------------------------------- 1 | Param 2 | ( 3 | [Parameter(Mandatory = $false)] 4 | [switch]$ConfigurePreconsent, 5 | [Parameter(Mandatory = $false)] 6 | [string]$TenantId 7 | ) 8 | 9 | $ErrorActionPreference = "Stop" 10 | 11 | # Check if the Azure AD PowerShell module is installed. 12 | if ( Get-Module -ListAvailable -Name AzureADPreview ) { 13 | # The Azure AD PowerShell module is not load and it is installed. This module 14 | # must be loaded for other operations performed by this script. 15 | Write-Host -ForegroundColor Green "Loading the Azure AD PowerShell module..." 16 | Import-Module AzureADPreview 17 | } else { 18 | Install-Module AzureADPreview 19 | } 20 | 21 | try { 22 | Write-Host -ForegroundColor Green "When prompted please enter the appropriate credentials... Warning: Window might have pop-under in VSCode" 23 | 24 | if([string]::IsNullOrEmpty($TenantId)) { 25 | Connect-AzureAD | Out-Null 26 | 27 | $TenantId = $(Get-AzureADTenantDetail).ObjectId 28 | } else { 29 | Connect-AzureAD -TenantId $TenantId | Out-Null 30 | } 31 | } catch [Microsoft.Azure.Common.Authentication.AadAuthenticationCanceledException] { 32 | # The authentication attempt was canceled by the end-user. Execution of the script should be halted. 33 | Write-Host -ForegroundColor Yellow "The authentication attempt was canceled. Execution of the script will be halted..." 34 | Exit 35 | } catch { 36 | # An unexpected error has occurred. The end-user should be notified so that the appropriate action can be taken. 37 | Write-Error "An unexpected error has occurred. Please review the following error message and try again." ` 38 | "$($Error[0].Exception)" 39 | } 40 | 41 | $adAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{ 42 | ResourceAppId = "00000002-0000-0000-c000-000000000000"; 43 | ResourceAccess = 44 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 45 | Id = "5778995a-e1bf-45b8-affa-663a9f3f4d04"; 46 | Type = "Role"}, 47 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 48 | Id = "a42657d6-7f20-40e3-b6f0-cee03008a62a"; 49 | Type = "Scope"}, 50 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 51 | Id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6"; 52 | Type = "Scope"} 53 | } 54 | 55 | $graphAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{ 56 | ResourceAppId = "00000003-0000-0000-c000-000000000000"; 57 | ResourceAccess = 58 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 59 | Id = "bf394140-e372-4bf9-a898-299cfc7564e5"; 60 | Type = "Role"}, 61 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 62 | Id = "7ab1d382-f21e-4acd-a863-ba3e13f7da61"; 63 | Type = "Role"} 64 | } 65 | 66 | $partnerCenterAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{ 67 | ResourceAppId = "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd"; 68 | ResourceAccess = 69 | [Microsoft.Open.AzureAD.Model.ResourceAccess]@{ 70 | Id = "1cebfa2a-fb4d-419e-b5f9-839b4383e05a"; 71 | Type = "Scope"} 72 | } 73 | 74 | $SessionInfo = Get-AzureADCurrentSessionInfo 75 | 76 | Write-Host -ForegroundColor Green "Creating the Azure AD application and related resources..." 77 | $DisplayName = "Delegated Access" 78 | $upn = Read-Host "enter in your UPN as a Global Admin in Partner Center" 79 | $app = New-AzureADApplication -AvailableToOtherTenants $true -DisplayName $DisplayName -IdentifierUris "https://$($SessionInfo.TenantDomain)/$((New-Guid).ToString())" -RequiredResourceAccess $adAppAccess, $graphAppAccess, $partnerCenterAppAccess -ReplyUrls @("urn:ietf:wg:oauth:2.0:oob","https://localhost","http://localhost","http://localhost:8400") 80 | $password = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId 81 | $spn = New-AzureADServicePrincipal -AppId $app.AppId -DisplayName $DisplayName 82 | 83 | 84 | $adminAgentsGroup = Get-AzureADGroup -Filter "DisplayName eq 'AdminAgents'" 85 | Add-AzureADGroupMember -ObjectId $adminAgentsGroup.ObjectId -RefObjectId $spn.ObjectId 86 | 87 | write-host "Installing PartnerCenter Module." -ForegroundColor Green 88 | install-module PartnerCenter -Force 89 | write-host "Sleeping for 30 seconds to allow app creation on O365" -foregroundcolor green 90 | start-sleep 30 91 | write-host "Please approve General consent form." -ForegroundColor Green 92 | $PasswordToSecureString = $password.value | ConvertTo-SecureString -asPlainText -Force 93 | $credential = New-Object System.Management.Automation.PSCredential($($app.AppId),$PasswordToSecureString) 94 | $token = New-PartnerAccessToken -ApplicationId "$($app.AppId)" -Scopes 'https://api.partnercenter.microsoft.com/user_impersonation' -ServicePrincipal -Credential $credential -Tenant $($spn.AppOwnerTenantID) -UseAuthorizationCode 95 | write-host "Please approve Exchange consent form." -ForegroundColor Green 96 | $Exchangetoken = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716' -Scopes 'https://outlook.office365.com/.default' -Tenant $($spn.AppOwnerTenantID) -UseDeviceAuthentication 97 | write-host "Press any key after auth. An error report about incorrect URIs is expected!" 98 | [void][System.Console]::ReadKey($true) 99 | Write-Host "######### Secrets #########" 100 | Write-Host "`$ApplicationId = '$($app.AppId)'" 101 | Write-Host "`$ApplicationSecret = '$($password.Value)'" 102 | Write-Host "`$TenantID = '$($spn.AppOwnerTenantID)'" 103 | write-host "`$RefreshToken = '$($token.refreshtoken)'" -ForegroundColor Blue 104 | write-host "`$ExchangeRefreshToken = '$($ExchangeToken.Refreshtoken)'" -ForegroundColor Green 105 | Write-Host "######### Secrets #########" 106 | Write-Host " SAVE THESE IN A SECURE LOCATION " 107 | 108 | 109 | $secPas = $ApplicationSecret| ConvertTo-SecureString -AsPlainText -Force 110 | $credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $secPas) 111 | 112 | 113 | $aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID 114 | $graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID 115 | 116 | 117 | Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken 118 | 119 | $customers = Get-MsolPartnerContract -All 120 | 121 | Write-Host "Found $($customers.Count) customers in Partner Center." -ForegroundColor DarkGreen 122 | 123 | 124 | foreach ($customer in $customers) { 125 | 126 | #Get ALL Licensed Users and Find Shared Mailboxes# 127 | Write-Host "Checking Audit Log for $($Customer.Name)" -ForegroundColor Green 128 | try{ 129 | $token = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716'-RefreshToken $ExchangeRefreshToken -Scopes 'https://outlook.office365.com/.default' -Tenant $customer.TenantId -ErrorAction SilentlyContinue 130 | $tokenValue = ConvertTo-SecureString "Bearer $($token.AccessToken)" -AsPlainText -Force 131 | $credential = New-Object System.Management.Automation.PSCredential($upn, $tokenValue) 132 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 133 | $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell-liveid?DelegatedOrg=$($InitialDomain)&BasicAuthToOAuthConversion=true" -Credential $credential -Authentication Basic -AllowRedirection -ErrorAction SilentlyContinue 134 | Import-PSSession $session -CommandName Get-AdminAuditLogConfig -AllowClobber 135 | $AuditLogConfig = Get-AdminAuditLogConfig 136 | Write-Host " " 137 | Write-Host "Audit Log Ingestion Enabled:" 138 | Write-Host $AuditLogConfig.UnifiedAuditLogIngestionEnabled 139 | Remove-PSSession $session 140 | }catch{("This tenant does not have exchange")} 141 | } 142 | -------------------------------------------------------------------------------- /Block Admin-MFA.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | $admins = Import-csv C:\temp\MFAEnabledAdmins.csv 3 | 4 | foreach($admin in $admins){ 5 | Write-Host "Blocking $($admin.userprincipalname)" 6 | Set-Msoluser -tenantid $admin.tenantid -userprincipalname $admin.userprincipalname -blockcredential $true 7 | } -------------------------------------------------------------------------------- /Block Auto-FW.ps1: -------------------------------------------------------------------------------- 1 | Install-Module PowershellGet -Force 2 | Update-Module PowershellGet 3 | Set-ExecutionPolicy RemoteSigned 4 | Install-Module -Name ExchangeOnlineManagement 5 | 6 | Connect-ExchangeOnline 7 | 8 | $externalTransportRuleName = "Block Auto-Forwarding" 9 | $rejectMessageText = "To improve security, auto-forwarding rules to external email addresses have been disabled. Please contanct your helpdesk if you want to create an exception." 10 | 11 | $externalForwardRule = Get-TransportRule | Where-Object {$_.Identity -contains $externalTransportRuleName} 12 | 13 | if (!$externalForwardRule) { 14 | Write-Output "Rule for Auto-forwarding not found, creating Rule" 15 | New-TransportRule -name "Block Auto-forwarding" -Priority 1 -SentToScope NotInOrganization -FromScope InOrganization -MessageTypeMatches AutoForward -RejectMessageEnhancedStatusCode 5.7.1 -RejectMessageReasonText $rejectMessageText 16 | } 17 | -------------------------------------------------------------------------------- /Block Auto-FW_All Customers.ps1: -------------------------------------------------------------------------------- 1 | $credential = Get-Credential 2 | Connect-MsolService -Credential $credential 3 | $customers = Get-MsolPartnerContract -All 4 | $TransportRuleName = "Block Auto-Forwarding" 5 | $rejectMessage = "To improve security, auto-forwarding rules to external email addresses have been disabled. Please contanct your helpdesk if you want to create an exception" 6 | 7 | Write-Output "Found $($customers.Count) customers for $((Get-MsolCompanyInformation).displayname)." 8 | 9 | foreach ($customer in $customers) { 10 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 11 | 12 | Write-Output "Checking transport rule for $($Customer.Name)" 13 | $DelegatedOrgURL = "https://outlook.office365.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name 14 | $session = New-PSSession -ConnectionUri $DelegatedOrgURL -Credential $credential -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection 15 | Import-PSSession $session -CommandName Get-TransportRule, New-TransportRule, Set-TransportRule -AllowClobber 16 | 17 | $externalForwardRule = Get-TransportRule | Where-Object {$_.Identity -contains $TransportRuleName} 18 | 19 | if (!$externalForwardRule) { 20 | Write-Output "Rule for Auto-forwarding not found, creating Rule" 21 | New-TransportRule -name "Block Auto-forwarding" -Priority 1 -SentToScope NotInOrganization -FromScope InOrganization -MessageTypeMatches AutoForward -RejectMessageEnhancedStatusCode 5.7.1 -RejectMessageReasonText $rejectMessage 22 | } 23 | Remove-PSSession $session 24 | } 25 | -------------------------------------------------------------------------------- /Bulk Update 365 User Passwords.ps1: -------------------------------------------------------------------------------- 1 | ##########Connect to Exchange Online########## 2 | 3 | Write-Host -Prompt "Connecting to Exchange Online" 4 | 5 | $credential = Get-Credential 6 | 7 | Install-module Msonline 8 | Import-Module MsOnline 9 | Connect-MsolService -Credential $credential 10 | $exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection 11 | Import-PSSession $exchangeSession -DisableNameChecking 12 | 13 | ############# Define CSV path of Users and Group ################## 14 | 15 | $UserPath = Read-Host -Prompt "Enter File Path For CSV list of users" 16 | 17 | 18 | #####Create CSV template with headers of Userprincipalname and Password####### 19 | 20 | 21 | Import-Csv -Path $UserPath |%{Set-MsolUserPassword -userPrincipalName $_.UserPrincipalName –NewPassword $_.Password -ForceChangePassword $True} -------------------------------------------------------------------------------- /Bulk Update Primary SMTP.txt: -------------------------------------------------------------------------------- 1 | Create CSV with Headers of 2 | 3 | Users 4 | 5 | AlaisEmailaddress 6 | 7 | Where 8 | 9 | Users=current primarty SMTP for User 10 | 11 | 12 | $csv = Import-Csv 'C:\Users\NickRoss\OneDrive - PAX8\Scripts'\Primarysmtpupdate.csv' 13 | foreach ($line in $csv) 14 | { 15 | $SMTP ="SMTP:"+$line.AliasEmailaddress 16 | Set-Mailbox -Identity $line.User -EmailAddresses $SMTP 17 | } -------------------------------------------------------------------------------- /Disable External User Access Teams.ps1: -------------------------------------------------------------------------------- 1 | Import-Module SkypeOnlineConnector 2 | $Cred = Get-Credential 3 | $CSSession = New-CsOnlineSession -Credential $Cred 4 | Import-PSSession -Session $CSSession 5 | 6 | Set-CsTeamsClientConfiguration -AllowGuestUser $False -------------------------------------------------------------------------------- /Disable User Permission to Consent to App-Multitenant.txt: -------------------------------------------------------------------------------- 1 | #Connect to Office365 Partner Tenancy 2 | $Cred = Get-Credential 3 | Connect-MsolService -Credential $Cred 4 | #Get list of Tennant ID's 5 | $Tenant = Get-MsolPartnerContract 6 | foreach ($ID in $Tenant) {Set-MsolCompanySettings -TenantId $ID.TenantID -UsersPermissionToUserConsentToAppEnabled $False 7 | Get-MsolCompanyInformation -TenantId $ID.TenantId | Select DisplayName, UsersPermissionToUserConsentToAppEnabled} -------------------------------------------------------------------------------- /Disable User Permission to Consent to App.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | 3 | Set-MsolCompanySettings -UsersPermissionToUserConsentToAppEnabled $false -------------------------------------------------------------------------------- /Email Encryption Rule-All Customers.ps1: -------------------------------------------------------------------------------- 1 | $credential = Get-Credential 2 | Connect-MsolService -Credential $credential 3 | $customers = Get-MsolPartnerContract -All 4 | $TransportRuleName = "Email Encryption" 5 | 6 | 7 | Write-Output "Found $($customers.Count) customers for $((Get-MsolCompanyInformation).displayname)." 8 | 9 | foreach ($customer in $customers) { 10 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 11 | 12 | Write-Output "Checking transport rule for $($Customer.Name)" 13 | $DelegatedOrgURL = "https://outlook.office365.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name 14 | $session = New-PSSession -ConnectionUri $DelegatedOrgURL -Credential $credential -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection 15 | Import-PSSession $session -CommandName Get-TransportRule, New-TransportRule, Set-TransportRule -AllowClobber 16 | 17 | $EmailEncryptRule = Get-TransportRule | Where-Object {$_.Identity -contains $TransportRuleName} 18 | 19 | if (!$EmailEncryptRule) { 20 | Write-Output "Rule for Encryption not found, creating Rule" 21 | New-TransportRule -Name "Encrypt Email" -SubjectContainsWords "Secure" -ApplyRightsProtectionTemplate "Encrypt" 22 | } 23 | Remove-PSSession $session 24 | } -------------------------------------------------------------------------------- /Email Encryption Rule.ps1: -------------------------------------------------------------------------------- 1 | Install-Module PowershellGet -Force 2 | Update-Module PowershellGet 3 | Set-ExecutionPolicy RemoteSigned 4 | Install-Module -Name ExchangeOnlineManagement 5 | 6 | Connect-ExchangeOnline 7 | 8 | New-TransportRule -Name "Encrypt Email" -SubjectContainsWords "Secure" -ApplyRightsProtectionTemplate "Encrypt" 9 | -------------------------------------------------------------------------------- /Enable MFA.ps1: -------------------------------------------------------------------------------- 1 | $UserCredential = Get-Credential 2 | 3 | Import-Module MSOnline 4 | 5 | Connect-MsolService –Credential $UserCredential 6 | 7 | $auth = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement 8 | 9 | $auth.RelyingParty = "*" 10 | 11 | $auth.State = "Enabled" 12 | 13 | $auth.RememberDevicesNotIssuedBefore = (Get-Date) 14 | 15 | Get-MsolUser –All | Foreach{ Set-MsolUser -UserPrincipalName $_.UserPrincipalName -StrongAuthenticationRequirements $auth} 16 | 17 | -------------------------------------------------------------------------------- /Enable Mailbox Auditing All Tenants.ps1: -------------------------------------------------------------------------------- 1 | $ScriptBlock = {Get-Mailbox -ResultSize Unlimited | Set-Mailbox -AuditEnabled $true -AuditOwner MailboxLogin, HardDelete, SoftDelete, Update, Move -AuditDelegate SendOnBehalf, MoveToDeletedItems, Move -AuditAdmin Copy, MessageBind} 2 | 3 | # Establish a PowerShell session with Office 365. You'll be prompted for your Delegated Admin credentials 4 | 5 | $Cred = Get-Credential 6 | Connect-MsolService -Credential $Cred 7 | $customers = Get-MsolPartnerContract -All 8 | Write-Host "Found $($customers.Count) customers for this Partner." 9 | 10 | foreach ($customer in $customers) { 11 | 12 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 13 | Write-Host "Enabling Mailbox Auditing for $($Customer.Name)" 14 | $DelegatedOrgURL = "https://ps.outlook.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name 15 | Invoke-Command -ConnectionUri $DelegatedOrgURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection -ScriptBlock $ScriptBlock -HideComputerName 16 | } -------------------------------------------------------------------------------- /Enable SSPR Multitenant.ps1: -------------------------------------------------------------------------------- 1 | #Connect to Office365 Partner Tenancy 2 | $Cred = Get-Credential 3 | Connect-MsolService -Credential $Cred 4 | #Get list of Tennant ID's 5 | $Tenant = Get-MsolPartnerContract 6 | foreach ($ID in $Tenant) {Set-MsolCompanySettings -TenantId $ID.TenantID -SelfServePasswordResetEnabled $true 7 | Get-MsolCompanyInformation -TenantId $ID.TenantId | Select DisplayName, SelfServePasswordResetEnabled} -------------------------------------------------------------------------------- /Enable SSPR.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | 3 | Set-MsolCompanySettings -SelfServePasswordResetEnabled $true -------------------------------------------------------------------------------- /Enable Versioning SharePoint Sites.ps1: -------------------------------------------------------------------------------- 1 | Install-Module -Name Microsoft.Online.SharePoint.PowerShell 2 | 3 | ##Variables for Processing 4 | $SiteUrl = Read-Host -Prompt "Enter the site url you want to enable versioning on." 5 | $UserName= Read-Host -Prompt "Enter your username." 6 | $Password =Read-Host -Prompt "Enter your password." 7 | 8 | try{ 9 | #Setup the context 10 | $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,(ConvertTo-SecureString $Password -AsPlainText -Force)) 11 | $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl) 12 | $Context.Credentials = $credentials 13 | 14 | #get the site and lists 15 | $web = $context.Web 16 | $context.Load($web) 17 | $context.load($web.lists) 18 | $Context.executeQuery() 19 | 20 | #Iterate through each list in the web 21 | foreach($list in $web.lists){ 22 | if ($list.hidden -eq $false) 23 | { 24 | #Enable versioning 25 | $list.EnableVersioning = $true 26 | $lIST.MajorVersionLimit = 50 27 | $list.Update() 28 | $Context.ExecuteQuery() 29 | Write-host "Versioning has been turned ON at :"$List.title 30 | } 31 | } 32 | } 33 | catch{ 34 | write-host "Completed Successfully" -foregroundcolor Green 35 | } 36 | -------------------------------------------------------------------------------- /Free_Busy Calendar Settings Multitenant.ps1: -------------------------------------------------------------------------------- 1 | $ScriptBlock = {Set-SharingPolicy -Identity "Default Sharing Policy" -Domains "Anonymous: CalendarSharingFreeBusySimple"} 2 | $ScriptBlock2 = {Enable-OrganizationCustomization} 3 | 4 | # Establish a PowerShell session with Office 365. You'll be prompted for your Delegated Admin credentials 5 | 6 | $Cred = Get-Credential 7 | Connect-MsolService -Credential $Cred 8 | $customers = Get-MsolPartnerContract -All 9 | Write-Host "Found $($customers.Count) customers for this Partner." 10 | 11 | foreach ($customer in $customers) { 12 | 13 | 14 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 15 | Write-Host "Enabling External Calendar Sharing Policy for $($Customer.Name)" 16 | $DelegatedOrgURL = "https://ps.outlook.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name 17 | Invoke-Command -ConnectionUri $DelegatedOrgURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection -Scriptblock $ScriptBlock2 -HideComputerName 18 | Invoke-Command -ConnectionUri $DelegatedOrgURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection -ScriptBlock $ScriptBlock -HideComputerName 19 | } -------------------------------------------------------------------------------- /MFAReport_AllCustomers.ps1: -------------------------------------------------------------------------------- 1 | ######### Secrets ######### 2 | $ApplicationId = 'ApplicationID' 3 | $ApplicationSecret = 'ApplicationSecret' | ConvertTo-SecureString -Force -AsPlainText 4 | $TenantID = 'Partner Center TenantID' 5 | $RefreshToken = 'LongRefreshToken' 6 | 7 | ######### Create Connection ######### 8 | $secPas = $ApplicationSecret| ConvertTo-SecureString -AsPlainText -Force 9 | $credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $secPas) 10 | 11 | $aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID 12 | $graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID 13 | 14 | Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken 15 | 16 | $customers = Get-MsolPartnerContract -All 17 | 18 | $Baseuri = "https://graph.microsoft.com/beta" 19 | $MFAState = foreach ($customer in $customers) { 20 | $users = Get-MSoluser -TenantId $customer.TenantId -All | Where {$_.UserPrincipalName -NotLike "*#EXT#*" -and $_.isLicensed -eq $true} 21 | $PerUserMFA = foreach ($user in $users) { 22 | $MFAStatus = if ($null -ne $user.StrongAuthenticationUserDetails) { ($user.StrongAuthenticationMethods | Where-Object { $_.IsDefault -eq $true }).methodType } else { "Disabled" } 23 | [PSCustomObject]@{ 24 | "Customer" = $customer.Name 25 | "DisplayName" = $user.DisplayName 26 | "UPN" = $user.UserPrincipalName 27 | "MFA Type" = $MFAStatus 28 | } 29 | } 30 | try { 31 | $CustGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes "https://graph.microsoft.com/.default" -ServicePrincipal -Tenant $customer.TenantId 32 | $Header = @{ Authorization = "Bearer $($CustGraphToken.AccessToken)" } 33 | $SecureDefaultsState = (Invoke-RestMethod -Uri "$baseuri/policies/identitySecurityDefaultsEnforcementPolicy" -Headers $Header -Method get -ContentType "application/json").IsEnabled 34 | $CAPolicies = (Invoke-RestMethod -Uri "$baseuri/identity/conditionalAccess/policies" -Headers $Header -Method get -ContentType "application/json").value 35 | } 36 | catch { 37 | $CAPolicies = $false 38 | } 39 | $EnforcedForUsers = foreach ($Policy in $CAPolicies) { 40 | if ($policy.grantControls.builtincontrols -ne 'mfa') { continue } 41 | if ($Policy.conditions.applications) { 42 | [PSCustomObject]@{ 43 | Name = $policy.displayName 44 | Target = 'Specific Applications' 45 | } 46 | continue 47 | } 48 | 49 | if ($Policy.conditions.users.includeUsers -eq "All") { 50 | [PSCustomObject]@{ 51 | Name = $policy.displayName 52 | Target = 'All Users' 53 | } 54 | } 55 | 56 | } 57 | 58 | $enforced = if ($EnforcedForUsers | Where-Object -Property Target -eq "All Users") { $True } else { $false } 59 | [PSCustomObject]@{ 60 | TenantName = $customer.DefaultDomainName 61 | UserList = $PerUserMFA 62 | 'Secure Defaults Enabled' = $SecureDefaultsState 63 | 'Conditional Access' = $CAPolicies 64 | 'Conditional Access Enforced MFA' = $Enforced 65 | } 66 | 67 | } 68 | 69 | $DisabledMFA = if ($MFAState.'Security Defaults Enabled' -eq $false -or $MFAState.'Conditional Access Enforced MFA') { 70 | $MFAState.userlist | Where-Object -Property "MFA Type" -eq "Disabled" 71 | } 72 | $DisabledMFA | Export-CSV C:\Temp\disabledMFAUsers.csv -------------------------------------------------------------------------------- /Non-MFA Admins.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | $admins = Import-csv C:\temp\nonMFAAdmins.csv 3 | 4 | $auth = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement 5 | $auth.RelyingParty = "*" 6 | $auth.State = "Enabled" 7 | $auth.RememberDevicesNotIssuedBefore = (Get-Date) 8 | 9 | foreach ($admin in $admins) { 10 | 11 | if ($admin.IsLicensed -eq "FALSE") { 12 | Write-Host "Enabling MFA for $($admin.userprincipalname)" -ForegroundColor Green 13 | Set-MsolUser -UserPrincipalName $admin.userprincipalname -StrongAuthenticationRequirements $auth -TenantId $admin.tenantid 14 | $state = (get-msoluser -TenantId $admin.tenantid -UserPrincipalName $admin.UserPrincipalName).StrongAuthenticationRequirements.state 15 | $admin.MFAStatus = $state 16 | $admin | export-csv C:\temp\adminMFAStatus.csv -NoTypeInformation -append 17 | } 18 | else { 19 | Write-Host "Not Enabling MFA for $($admin.userprincipalname)" -ForegroundColor Red 20 | $admin | export-csv C:\temp\MFAEnabledAdmins.csv -Append -NoTypeInformation 21 | } 22 | } -------------------------------------------------------------------------------- /Only Free_Busy Calendar Single Tenant.ps1: -------------------------------------------------------------------------------- 1 | Function Connect-EXOnline { 2 | $credentials = Get-Credential 3 | Write-Output "Getting the Exchange Online cmdlets" 4 | $session = New-PSSession -ConnectionUri https://outlook.office365.com/powershell-liveid/ ` 5 | -ConfigurationName Microsoft.Exchange -Credential $credentials ` 6 | -Authentication Basic -AllowRedirection 7 | Import-PSSession $session 8 | } 9 | Connect-EXOnline 10 | 11 | Set-SharingPolicy -Identity "Default Sharing Policy" -Domains "Anonymous: CalendarSharingFreeBusySimple" -------------------------------------------------------------------------------- /Security Notfications to Teams Channel.ps1: -------------------------------------------------------------------------------- 1 | function Get-AuthToken { 2 | 3 | <# 4 | .SYNOPSIS 5 | This function is used to authenticate with the Graph API REST interface 6 | .DESCRIPTION 7 | The function authenticate with the Graph API Interface with the tenant name 8 | .EXAMPLE 9 | Get-AuthToken 10 | Authenticates you with the Graph API interface 11 | .NOTES 12 | NAME: Get-AuthToken 13 | #> 14 | 15 | [cmdletbinding()] 16 | 17 | param 18 | ( 19 | [Parameter(Mandatory=$true)] 20 | $User 21 | ) 22 | 23 | $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User 24 | 25 | $tenant = $userUpn.Host 26 | 27 | 28 | Write-Host "Checking for AzureAD module..." 29 | 30 | $AadModule = Get-Module -Name "AzureAD" -ListAvailable 31 | 32 | if ($AadModule -eq $null) { 33 | Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" 34 | $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable 35 | } 36 | if ($AadModule -eq $null) { 37 | write-host 38 | write-host "AzureAD Powershell module not installed..." -f Red 39 | write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow 40 | write-host "Script can't continue..." -f Red 41 | write-host 42 | exit 43 | } 44 | 45 | # Getting path to ActiveDirectory Assemblies 46 | # If the module count is greater than 1 find the latest version 47 | if($AadModule.count -gt 1){ 48 | $Latest_Version = ($AadModule | select version | Sort-Object)[-1] 49 | $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } 50 | 51 | # Checking if there are multiple versions of the same module found 52 | if($AadModule.count -gt 1){ 53 | $aadModule = $AadModule | select -Unique 54 | } 55 | 56 | $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 57 | $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" 58 | } 59 | else { 60 | $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 61 | $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" 62 | } 63 | 64 | [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null 65 | 66 | [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null 67 | 68 | $clientId = " 129 | 130 | [cmdletbinding()] 131 | 132 | $graphApiVersion = "v1.0" 133 | $Resource = "security/alerts?`$top=1" 134 | 135 | try { 136 | $uri = "https://graph.microsoft.com/$graphApiVersion/$($resource)" 137 | (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).value 138 | } 139 | catch { 140 | $ex = $_.Exception 141 | $errorResponse = $ex.Response.GetResponseStream() 142 | $reader = New-Object System.IO.StreamReader($errorResponse) 143 | $reader.BaseStream.Position = 0 144 | $reader.DiscardBufferedData() 145 | $responseBody = $reader.ReadToEnd(); 146 | Write-Host "Response content:`n$responseBody" -f Red 147 | Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" 148 | write-host 149 | break 150 | } 151 | } 152 | 153 | #################################################### 154 | 155 | 156 | Function Get-Alert{ 157 | 158 | <# 159 | .SYNOPSIS 160 | This function is used to get the alert by ID from the Graph Security API REST interface 161 | .DESCRIPTION 162 | The function connects to the Graph API Interface and gets an alert by ID from the Microsoft Graph Security API 163 | .EXAMPLE 164 | Get-Alert 165 | Returns the alert from Security API with the provided ID 166 | .NOTES 167 | NAME: Get-Alert 168 | #> 169 | 170 | [cmdletbinding()] 171 | 172 | param 173 | ( 174 | [Parameter(Mandatory=$true)] 175 | $ID 176 | ) 177 | 178 | $graphApiVersion = "v1.0" 179 | $Resource = "security/alerts/$ID" 180 | try { 181 | $uri = "https://graph.microsoft.com/$graphApiVersion/$($resource)" 182 | (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get) 183 | } 184 | catch { 185 | $ex = $_.Exception 186 | $errorResponse = $ex.Response.GetResponseStream() 187 | $reader = New-Object System.IO.StreamReader($errorResponse) 188 | $reader.BaseStream.Position = 0 189 | $reader.DiscardBufferedData() 190 | $responseBody = $reader.ReadToEnd(); 191 | Write-Host "Response content:`n$responseBody" -f Red 192 | Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" 193 | write-host 194 | break 195 | } 196 | } 197 | 198 | #################################################### 199 | 200 | #region Authentication 201 | 202 | write-host 203 | 204 | # Checking if authToken exists before running authentication 205 | if($global:authToken){ 206 | 207 | # Setting DateTime to Universal time to work in all timezones 208 | $DateTime = (Get-Date).ToUniversalTime() 209 | 210 | # If the authToken exists checking when it expires 211 | $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes 212 | 213 | if($TokenExpires -le 0){ 214 | write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow 215 | write-host 216 | 217 | # Defining User Principal Name if not present 218 | if($User -eq $null -or $User -eq ""){ 219 | $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" 220 | Write-Host 221 | } 222 | $global:authToken = Get-AuthToken -User $User 223 | } 224 | } 225 | # Authentication doesn't exist, calling Get-AuthToken function 226 | else { 227 | if($User -eq $null -or $User -eq ""){ 228 | $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" 229 | Write-Host 230 | } 231 | 232 | # Getting the authorization token 233 | $global:authToken = Get-AuthToken -User $User 234 | } 235 | 236 | #endregion 237 | 238 | #################################################### 239 | 240 | 241 | #Teams webhook url 242 | $uri = "" 243 | #Image on the left hand side, here I have a regular user picture 244 | $ItemImage = 'https://img.icons8.com/color/1600/circled-user-male-skin-type-1-2.png' 245 | $SecurityGraph = New-Object 'System.Collections.Generic.List[System.Object]' 246 | $ArrayTable = New-Object 'System.Collections.Generic.List[System.Object]' 247 | 248 | Get-TopAlerts |Select-Object title, description, severity, eventdatetime, category, userstates, azureTenantId | ForEach-Object{ 249 | $obj = [PSCustomObject]@{ 250 | 'title' = $_.title 251 | 'Description' = $_.description 252 | 'severity' = $_.severity 253 | 'eventDateTime' = $_.eventDateTime 254 | 'category' = $_.category 255 | 'userstates' = $_.userstates.accountname 256 | 'azureTenantId' = $_.azureTenantId 257 | 258 | } 259 | $SecurityGraph.Add($obj) 260 | } 261 | 262 | 263 | $SecurityGraph | ForEach-Object { 264 | $Section = @{ 265 | activityTitle = "$($_.Title)" 266 | activityImage = $ItemImage 267 | facts = @( 268 | @{ 269 | name = 'TenantID:' 270 | value = $_.azureTenantId 271 | }, 272 | @{ 273 | name = 'Title:' 274 | value = $_.title 275 | }, 276 | @{ 277 | name = 'EventDatetime:' 278 | value = $_.eventDateTime 279 | }, 280 | @{ 281 | name = 'userStates:' 282 | value = $_.userStates 283 | }, 284 | @{ 285 | name = 'Description:' 286 | value = $_.Description 287 | }, 288 | @{ 289 | name = 'Category:' 290 | value = $_.Category 291 | }, 292 | @{ 293 | name = 'severity:' 294 | value = $_.severity 295 | } 296 | ) 297 | } 298 | $ArrayTable.add($section) 299 | } 300 | $body = ConvertTo-Json -Depth 8 @{ 301 | title = "Security Notifcations" 302 | text = "New Alert" 303 | sections = $ArrayTable 304 | } 305 | 306 | Invoke-RestMethod -uri $uri -Method Post -body $body -ContentType 'application/json' 307 | -------------------------------------------------------------------------------- /Set Anonymous Links to Expire-SharePoint.ps1: -------------------------------------------------------------------------------- 1 | Install-Module -Name Microsoft.Online.SharePoint.PowerShell 2 | 3 | $SharePointURL = Read-Host -Prompt "Enter your Tenants SharePoint Admin URL. This is typically in the format of https://domain-admin.sharepoint.com" 4 | 5 | Connect-SPOService -url $SharePointURL 6 | 7 | 8 | Set-SPOTenant -SharingCapability ExternalUserAndGuestSharing 9 | 10 | Set-SPOTenant -RequireAnonymousLinksExpireInDays 7 -------------------------------------------------------------------------------- /Set Outbound Spam Notifications.ps1: -------------------------------------------------------------------------------- 1 | Install-Module PowershellGet -Force 2 | Update-Module PowershellGet 3 | Set-ExecutionPolicy RemoteSigned 4 | Install-Module -Name ExchangeOnlineManagement 5 | 6 | Connect-ExchangeOnline 7 | 8 | $NotifcationEntity = Read-Host -Prompt "Enter the email of the recipient who will receive the spam notifications" 9 | 10 | Set-HostedOutboundSpamFilterPolicy Default -NotifyOutboundSpam $true -NotifyOutboundSpamRecipients $NotifcationEntity 11 | -------------------------------------------------------------------------------- /Turn on Audit Log All Tenants.ps1: -------------------------------------------------------------------------------- 1 | $ScriptBlock = {Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true} 2 | 3 | 4 | # Establish a PowerShell session with Office 365. You'll be prompted for your Delegated Admin credentials 5 | 6 | $Cred = Get-Credential 7 | Connect-MsolService -Credential $Cred 8 | $customers = Get-MsolPartnerContract -All 9 | Write-Host "Found $($customers.Count) customers for this Partner." 10 | 11 | foreach ($customer in $customers) { 12 | 13 | $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true} 14 | Write-Host "Enabling Audit Log for $($Customer.Name)" 15 | $DelegatedOrgURL = "https://ps.outlook.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name 16 | Invoke-Command -ConnectionUri $DelegatedOrgURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection -ScriptBlock $ScriptBlock -HideComputerName 17 | } 18 | -------------------------------------------------------------------------------- /Turn on Audit Log.ps1: -------------------------------------------------------------------------------- 1 | Function Connect-EXOnline { 2 | $credentials = Get-Credential 3 | Write-Output "Getting the Exchange Online cmdlets" 4 | $session = New-PSSession -ConnectionUri https://outlook.office365.com/powershell-liveid/ ` 5 | -ConfigurationName Microsoft.Exchange -Credential $credentials ` 6 | -Authentication Basic -AllowRedirection 7 | Import-PSSession $session 8 | } 9 | Connect-EXOnline 10 | 11 | Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true -------------------------------------------------------------------------------- /View All Global Admins in an Account.ps1: -------------------------------------------------------------------------------- 1 | Connect-MsolService 2 | 3 | $role = Get-MsolRole -RoleName "Company Administrator" 4 | 5 | 6 | Get-MsolRoleMember -RoleObjectId $role.ObjectId -------------------------------------------------------------------------------- /mailbox delegation: -------------------------------------------------------------------------------- 1 | Function Connect-EXOnline { 2 | $credentials = Get-Credential 3 | Write-Output "Getting the Exchange Online cmdlets" 4 | $session = New-PSSession -ConnectionUri https://outlook.office365.com/powershell-liveid/ ` 5 | -ConfigurationName Microsoft.Exchange -Credential $credentials ` 6 | -Authentication Basic -AllowRedirection 7 | Import-PSSession $session 8 | } 9 | Connect-EXOnline 10 | 11 | Get-Mailbox | Get-MailboxPermission | where {$_.user -ne "NT AUTHORITY\SELF" -and $_.IsInherited -eq $false} | Format-Table Identity, User, IsInherited, AccessRights 12 | --------------------------------------------------------------------------------