├── Azure AD ├── Baseline-ConditionalAccessPolicies.ps1 ├── Disable-MfaForLicensedUsers.ps1 ├── Enable-GroupsCreationForAllUsers.ps1 ├── Enable-MfaForLicensedUsers.ps1 ├── Enable-SensitivityLabelsForGroups.ps1 ├── Install-BaselineCAPolicies.ps1 ├── Install-DataProtectionCAPolicies.ps1 ├── Install-GuestCAPolicies.ps1 ├── Install-ITPMBaselineCAPolicies.ps1 ├── Limit-GroupsCreation.ps1 ├── Readme.md └── Set-GroupExpirationPolicy.ps1 ├── Compliance ├── Enable-SensitivityLabelsForGroups.ps1 ├── Install-DataRetentionPolicies.ps1 ├── Install-EmailRetentionPolicy.ps1 ├── Install-SensitivityLabels.ps1 ├── Install-TeamsRetentionPolicies.ps1 ├── Limit-GroupsCreation.ps1 └── readme.md ├── DataProtectionScripts.zip ├── Exchange Online ├── Advanced-TenantConfig.ps1 ├── Block-ConsumerStorageOWA.ps1 ├── Block-UnmanagedDownload.ps1 ├── Configure-Auditing.ps1 ├── Customize-MessageEncryption.ps1 ├── Disable-Forwarding.ps1 ├── Disable-SharedMbxSignOn.ps1 ├── Install-EXOCustomProtection.ps1 ├── Install-EXOStandardProtection.ps1 ├── README.md ├── Set-DeletedItemsRetention.ps1 ├── Setup-ArchiveLegalHold.ps1 └── Setup-DKIM.ps1 ├── Incident Response ├── Export-ActivityByIPAddress.ps1 ├── Export-ActivityByUser.ps1 ├── Export-PrivilegedUserActions.ps1 ├── Export-PrivilegedUserSignIn.ps1 ├── Export-SignInByIPAddress.ps1 ├── Export-SignInByUser.ps1 ├── Install-AzureADProtectionAlerts.ps1 ├── ReadMe.md ├── Remediate-CompromisedUser.ps1 ├── Start-AzureADIRCollection.ps1 ├── Start-UnifiedAuditLogIRCollection.ps1 └── permissiontable.csv ├── LICENSE ├── Microsoft 365 Setup Guide.onepkg ├── README.md ├── Setup Intune ├── Export-ADMX.ps1 ├── Export-AppConfiguration.ps1 ├── Export-AppProtection.ps1 ├── Export-Applications.ps1 ├── Export-Compliance.ps1 ├── Export-DeviceConfiguration.ps1 ├── Export-EndpointSecurity.ps1 ├── Get-DeviceEnrollmentRestrictions.ps1 ├── Import-AppConfiguration.ps1 ├── Import-AppProtection.ps1 ├── Import-Applications.ps1 ├── Import-Compliance.ps1 ├── Import-DeviceConfiguration.ps1 ├── Import-EndpointSecurity.ps1 ├── Install-BYODMobileDeviceProfiles.ps1 ├── Install-MamAndMdmPolicies.ps1 ├── OLD_Import-MAMPolicy.ps1 ├── OLD_Setup-Intune.ps1 ├── README.md ├── Set-DeviceEnrollmentRestrictions.ps1 ├── Set-MDMAuthority.ps1 └── Setup-Intune.ps1 ├── ThreatDefenseScripts.zip ├── Windows 10 ├── Install-EndpointSecuritySample.ps1 ├── Install-LegacyProfiles.ps1 ├── Install-OneDriveProfile.ps1 ├── Install-Windows10SecurityProfiles.ps1 ├── Install-WindowsSecurityProfiles.ps1 ├── JSON │ ├── Export-AppConfiguration.ps1 │ ├── Export-AppProtection.ps1 │ ├── Export-Compliance.ps1 │ ├── Export-DeviceConfiguration.ps1 │ ├── Export-EndpointSecurity.ps1 │ ├── Export-SoftwareUpdates.ps1 │ ├── Import-AppConfiguration.ps1 │ ├── Import-AppProtection.ps1 │ ├── Import-Compliance.ps1 │ ├── Import-DeviceConfiguration.ps1 │ ├── Import-EndpointSecurity.ps1 │ ├── Win10-ADMX │ │ └── OneDriveClientConfig.json │ ├── Win10-Apps │ │ ├── ChromiumEdge.json │ │ ├── Office32.json │ │ └── Office64.json │ ├── Win10-Compliance │ │ ├── [ITPM Baseline] Windows 10_ Delayed.json │ │ └── [ITPM Baseline] Windows 10_ Immediate.json │ ├── Win10-DeviceConfig │ │ ├── [ITPM Corporate] Windows 10_ Allow Autopilot Reset.json │ │ ├── [ITPM Corporate] Windows 10_ Disable first sign-in animation.json │ │ ├── [ITPM Corporate] Windows 10_ MDMWinsOverGP.json │ │ ├── [ITPM Legacy] Windows 10_ Baseline Device Restrictions.json │ │ └── [ITPM Legacy] Windows 10_ Baseline Endpoint Protection.json │ ├── Win10-EndpointSecurity │ │ ├── [ITPM Corporate] ASR Rules Audit.json │ │ ├── [ITPM Corporate] ASR Rules Enable.json │ │ ├── [ITPM Corporate] BitLocker silent enablement.json │ │ ├── [ITPM Corporate] BitLocker with removable drive protection.json │ │ ├── [ITPM Corporate] Defender Antivirus.json │ │ ├── [ITPM Corporate] Optional_ Block removable storage.json │ │ ├── [ITPM Corporate] Windows Firewall.json │ │ ├── [ITPM Corporate] Windows Hello for Business.json │ │ ├── [ITPM Corporate] Windows Security Center.json │ │ ├── [ITPM Enterprise] SmartLocker Audit.json │ │ ├── [ITPM Enterprise] SmartLocker Enable.json │ │ └── [ITPM Enterprise] Windows Credential Guard.json │ ├── Win10-SecurityBaselines │ │ ├── [ITPM Corporate] Edge Chromium baseline.json │ │ └── [ITPM Corporate] Modified security baseline.json │ ├── Win10-Update │ │ ├── [ITPM Corporate] Default Update Ring.json │ │ └── [ITPM Corporate] Delayed Update Ring.json │ ├── Win10-WIP │ │ ├── [ITPM Optional] WIP-MAM without enrollment.json │ │ └── [ITPM Optional] WIP-MDM with enrollment.json │ └── readme.md └── readme.md ├── ZeroTrustScripts.zip └── mggraph-samples ├── Install-SmbAdmxConfigs.ps1 ├── Install-SmbAppProtectionPolicies.ps1 ├── Install-SmbCompliancePolicies.ps1 ├── Install-SmbConditionalAccessPolicies.ps1 ├── Install-SmbDeviceConfigs.ps1 ├── Install-SmbDeviceFilters.ps1 ├── Install-SmbSecurityProfile.ps1 └── Install-SmbSettingsCatalogBaselines.ps1 /Azure AD/Disable-MfaForLicensedUsers.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | Disable MFA on all licensed user accounts (per-user MFA) 6 | Use this when you want to switch from per-user MFA to Conditional Access for MFA 7 | Conditional Access requires Azure AD Premium P1/P2, EM+S E3/E5 or M365B/E3/35 8 | 9 | You have to connect to Azure AD using Connect-MsolService before running this script: 10 | https://docs.microsoft.com/en-us/powershell/module/msonline/connect-msolservice?view=azureadps-1.0 11 | 12 | Source of script: https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-userstates 13 | 14 | .NOTES 15 | FileName: Disable-MfaForLicensedUsers.ps1 16 | Author: Alex Fields, ITProMentor.com 17 | Created: 02-01-2020 18 | Revised: 02-01-2020 19 | Version: 1.0 20 | 21 | #> 22 | ################################################################################################### 23 | 24 | 25 | 26 | ## To disable only for a specific user: 27 | ## Set-MsolUser -UserPrincipalName user@domain.com -StrongAuthenticationRequirements @() 28 | ## To disable for all users: 29 | ## Get-Msoluser -all | Where-Object {$_.IsLicensed -eq $true} | Set-MsolUser -StrongAuthenticationRequirements @() 30 | 31 | ## Find out who is registered for MFA: 32 | ## Get-Msoluser -all | Where-Object {$_.StrongAuthenticationMethods -like "*"}  # Sets the MFA requirement state 33 | function Set-MfaState { 34 | 35 | [CmdletBinding()] 36 | param( 37 | [Parameter(ValueFromPipelineByPropertyName=$True)] 38 | $ObjectId, 39 | [Parameter(ValueFromPipelineByPropertyName=$True)] 40 | $UserPrincipalName, 41 | [ValidateSet("Disabled","Enabled","Enforced")] 42 | $State 43 | ) 44 | 45 | Process { 46 | Write-Verbose ("Setting MFA state for user '{0}' to '{1}'." -f $ObjectId, $State) 47 | $Requirements = @() 48 | if ($State -ne "Disabled") { 49 | $Requirement = 50 | [Microsoft.Online.Administration.StrongAuthenticationRequirement]::new() 51 | $Requirement.RelyingParty = "*" 52 | $Requirement.State = $State 53 | $Requirements += $Requirement 54 | } 55 | 56 | Set-MsolUser -ObjectId $ObjectId -UserPrincipalName $UserPrincipalName ` 57 | -StrongAuthenticationRequirements $Requirements 58 | } 59 | } 60 | 61 | # Disable MFA for all users 62 | Get-MsolUser -All | Set-MfaState -State Disabled # After this has been run, create a Conditional Access policy to replace per-user MFA: # Azure AD > Security > Conditional Access > New policy # Name it GRANT - MFA for users # Select Users and groups > All users (and Exclude any emergency access accounts, other exceptions) # Select Cloud apps and actions > All cloud apps # Do NOT select any Conditions (e.g. unless you want to exclude trusted locations) # Select Access Controls > Grant > Require Multi-factor authentication # Save and enable the policy -------------------------------------------------------------------------------- /Azure AD/Enable-GroupsCreationForAllUsers.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | This will re-enable creating Microsoft 365 Groups for all users 6 | 7 | You must have the Preview version of the Azure AD PowerShell module: 8 | Uninstall-Module AzureAD 9 | Install-Module AzureADPreview 10 | 11 | Source of script: 12 | https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/manage-creation-of-groups?view=o365-worldwide 13 | 14 | .NOTES 15 | FileName: Enable-GroupsCreationForAllUsers.ps1 16 | Author: Alex Fields, ITProMentor.com 17 | Created: February 2020 18 | Revised: April 2021 19 | 20 | #> 21 | ################################################################################################### 22 | 23 | Import-Module AzureADPreview -Force 24 | 25 | $GroupName = "" 26 | $AllowGroupCreation = "True" 27 | 28 | 29 | $CheckForGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $GroupName 30 | 31 | if ($CheckForGroup -eq $null -or $CheckForGroup -eq "") { 32 | New-AzureADGroup -DisplayName $GroupName -SecurityEnabled $true -MailEnabled $false -MailNickName sg-GroupCreators 33 | 34 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 35 | if(!$settingsObjectID) 36 | { 37 | $template = Get-AzureADDirectorySettingTemplate | Where-object {$_.displayname -eq "group.unified"} 38 | $settingsCopy = $template.CreateDirectorySetting() 39 | New-AzureADDirectorySetting -DirectorySetting $settingsCopy 40 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 41 | } 42 | 43 | $settingsCopy = Get-AzureADDirectorySetting -Id $settingsObjectID 44 | $settingsCopy["EnableGroupCreation"] = $AllowGroupCreation 45 | 46 | if($GroupName) 47 | { 48 | $settingsCopy["GroupCreationAllowedGroupId"] = (Get-AzureADGroup -SearchString $GroupName).objectid 49 | } else { 50 | $settingsCopy["GroupCreationAllowedGroupId"] = $GroupName 51 | } 52 | Set-AzureADDirectorySetting -Id $settingsObjectID -DirectorySetting $settingsCopy 53 | 54 | (Get-AzureADDirectorySetting -Id $settingsObjectID).Values 55 | 56 | Write-Host 57 | Write-Host "Please add users to the new Security group to enable Groups creation." -ForegroundColor Yellow 58 | Write-Host 59 | Write-Host "Script completed." -ForegroundColor Green 60 | 61 | 62 | } else { 63 | 64 | Write-Host "Security group for Group Creators already exists; no changes will be made." -ForegroundColor Red 65 | Write-Host 66 | Write-Host "Exiting script." -ForegroundColor Red 67 | Write-Host 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /Azure AD/Enable-MfaForLicensedUsers.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | Enable MFA on all licensed user accounts (per-user MFA) 6 | This method works on all versions of Azure AD / Office 365 7 | If you want to switch from per-user MFA to Conditional Access, see: Disable-MfaForLicensedUsers.ps1 8 | 9 | You have to connect to Azure AD using Connect-MsolService before running this script: 10 | https://docs.microsoft.com/en-us/powershell/module/msonline/connect-msolservice?view=azureadps-1.0 11 | 12 | Source of script: https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-userstates 13 | 14 | .NOTES 15 | FileName: Enable-MfaForLicensedUsers.ps1 16 | Author: Alex Fields, ITProMentor.com 17 | Created: 02-01-2020 18 | Revised: 02-01-2020 19 | Version: 1.0 20 | 21 | #> 22 | ################################################################################################### 23 | 24 | 25 | 26 | $st = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement 27 | $st.RelyingParty = "*" 28 | $st.State = "Enabled" 29 | $sta = @($st) 30 | 31 | Get-Msoluser -all | Where-Object {$_.IsLicensed -eq $true} | Set-MsolUser -StrongAuthenticationRequirements $sta 32 | 33 | ## To disable for a specific user: 34 | ## Set-MsolUser -UserPrincipalName user@domain.com -StrongAuthenticationRequirements @() 35 | ## To disable for all users: 36 | ## Get-Msoluser -all | Where-Object {$_.IsLicensed -eq $true} | Set-MsolUser -StrongAuthenticationRequirements @() 37 | 38 | ## Find out who is registered for MFA: 39 | ## Get-Msoluser -all | Where-Object {$_.StrongAuthenticationMethods -like "*"}  -------------------------------------------------------------------------------- /Azure AD/Enable-SensitivityLabelsForGroups.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script will enable Sensitivity labels for Groups and Sites: 5 | 6 | .PREREQUISITES 7 | 1. You must install the AzureADPreview PowerShell module (Install-AzureADPreview) 8 | 2. You will also require the Exchange Online V2 module (Install-Module -Name ExchangeOnlineManagement) 9 | 10 | .DETAILS 11 | FileName: Enable-SensitivityLabelsForGroups.ps1 12 | Author: Alex Fields, ITProMentor.com 13 | Created: November 2020 14 | Updated: April 2021 15 | 16 | .NOTES 17 | You will be prompted twice since you must authenticate against both Azure AD and Exchange Online 18 | 19 | #> 20 | ################################################################################################### 21 | 22 | 23 | ## Import the AzureADPreview module 24 | Import-Module AzureADPreview 25 | 26 | ## Connect to Azure AD 27 | Connect-AzureAD 28 | 29 | ## Import the Exchange Online V2 module 30 | Import-Module ExchangeOnlineManagement 31 | 32 | ## Connect to the Security & Compliance center with the EXO V2 module 33 | Connect-IPPSSession 34 | 35 | ## Get the Template ID for Group.Unified 36 | $TemplateId = (Get-AzureADDirectorySettingTemplate | where { $_.DisplayName -eq "Group.Unified" }).Id 37 | $Template = Get-AzureADDirectorySettingTemplate | where -Property Id -Value $TemplateId -EQ 38 | 39 | 40 | ## Create a new settings object based on the template 41 | $Setting = $Template.CreateDirectorySetting() 42 | 43 | ## Enable the unified lables feature for groups 44 | $Setting["EnableMIPLabels"] = "True" 45 | 46 | ## Apply the setting 47 | New-AzureADDirectorySetting -DirectorySetting $Setting 48 | 49 | ## Note: Read the settings for this new object out with the following: 50 | $Setting.Values 51 | 52 | ## Run the following to allow Sensitivity labels to be used with Groups: 53 | Execute-AzureAdLabelSync 54 | 55 | 56 | ## End of script -------------------------------------------------------------------------------- /Azure AD/Install-DataProtectionCAPolicies.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script will create the following Data Protection Conditional Access policies in your tenant: 5 | 6 | 1. CA201: Office 365: Require managed apps on iOS & Android (MAM) 7 | 2. CA202: Office 365: Require compliant device for iOS & Android (MDM) 8 | 3. CA203: Office 365: Require compliant device for desktop apps on Windows & macOS 9 | 4. CA204: Office 365: Prevent web downloads on unmanaged devices 10 | 11 | .NOTES 12 | 1. You may need to disable the 'Security defaults' first. See https://aka.ms/securitydefaults 13 | 2. None of the policies created by this script will be enabled by default. 14 | 3. Before enabling policies, you should notify end users about the expected impacts 15 | 4. Be sure to populate the security group 'sg-Exclude from CA' with at least one admin account for emergency access 16 | 5. To install the Azure AD Preview PowerShell module use: Install-Module AzureADPreview -AllowClobber 17 | 18 | .DETAILS 19 | FileName: Install-DataProtectionCAPolicies.ps1 20 | Author: Alex Fields, ITProMentor.com 21 | Created: June 2021 22 | Updated: January 2022 23 | 24 | #> 25 | ################################################################################################### 26 | 27 | Import-Module AzureADPreview 28 | Connect-AzureAD 29 | 30 | ## Check for the existence of the "Exclude from CA" security group, and create the group if it does not exist 31 | 32 | $ExcludeCAGroupName = "sgu-Exclude From CA" 33 | $ExcludeCAGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $ExcludeCAGroupName 34 | 35 | if ($ExcludeCAGroup -eq $null -or $ExcludeCAGroup -eq "") { 36 | New-AzureADGroup -DisplayName $ExcludeCAGroupName -SecurityEnabled $true -MailEnabled $false -MailNickName sgu-ExcludeFromCA 37 | $ExcludeCAGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $ExcludeCAGroupName 38 | } 39 | else { 40 | Write-Host "Exclude from CA group already exists" 41 | } 42 | 43 | 44 | ######################################################## 45 | ## 1. 46 | ## CA201: Require managed apps on iOS & Android (MAM) 47 | 48 | ## This policy enables MAM enforcement for iOS and Android devices 49 | ## MAM NOTES: 50 | ## 1. End-users will not be able to access company data from built-in browser or mail apps for iOS or Android; they must use approved apps (e.g. Outlook, Edge) 51 | ## 2. You must also deploy App protection policies in Microsoft Endpoint Manager for this policy to be most effective 52 | ## 2. Android and iOS users must have the Authenticator app configured, and Android users must also download the Company Portal app 53 | 54 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 55 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 56 | $conditions.Applications.IncludeApplications = "Office365" 57 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 58 | $conditions.Users.IncludeUsers = "All" 59 | $conditions.Users.ExcludeUsers = "GuestsOrExternalUsers" 60 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 61 | $conditions.Platforms = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessPlatformCondition 62 | $conditions.Platforms.IncludePlatforms = @('Android', 'IOS') 63 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls 64 | $controls._Operator = "OR" 65 | $controls.BuiltInControls = @('ApprovedApplication', 'CompliantApplication') 66 | 67 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA201: O365: Require managed apps on iOS & Android (MAM)" -State "Disabled" -Conditions $conditions -GrantControls $controls 68 | 69 | ######################################################## 70 | ## 2. 71 | ## CA202: Require compliant device for mobile apps on iOS & Android (MDM) 72 | 73 | ## [OPTIONAL POLICY] Enforces MDM compliance for client app access on iOS and Android devices (i.e. Company-owned devices) 74 | ## MDM NOTES: 75 | ## 1. For iOS: Configure Apple enrollment certificate, and optionally connect Apple Business Manager (company-owned) 76 | ## 2. For Android: Link your Managed Google Play account, and optionally configure corporate-owned dedicated or fully managed devices 77 | ## 3. Personal devices: Both iOS and Android users should download the Authenticator app, and the Company Portal app to sign-in 78 | 79 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 80 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 81 | $conditions.Applications.IncludeApplications = "Office365" 82 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 83 | $conditions.Users.IncludeUsers = "All" 84 | $conditions.Users.ExcludeUsers = "GuestsOrExternalUsers" 85 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 86 | $conditions.Platforms = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessPlatformCondition 87 | $conditions.Platforms.IncludePlatforms = @('Android', 'IOS') 88 | $conditions.ClientAppTypes = @('MobileAppsAndDesktopClients') 89 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls 90 | $controls._Operator = "OR" 91 | $controls.BuiltInControls = @('CompliantDevice') 92 | 93 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA202: O365: Require compliant device for mobile apps on iOS & Android (MDM)" -State "Disabled" -Conditions $conditions -GrantControls $controls 94 | 95 | ######################################################## 96 | ## 3. 97 | ## CA203: Require compliant device for desktop clients on Windows & macOS 98 | 99 | ## This policy enforces device compliance (or Hybrid Azure AD join) for these platforms: Windows, macOS 100 | ## NOTES: 101 | ## 1. End-users must enroll their devices with Intune before enabling this policy 102 | ## 2. Azure AD joined or Hybrid Joined devices will be managed without taking additional action 103 | ## 3. Users with personal devices should use the Company Portal app to enroll 104 | ## 4. This policy blocks unmanaged device access from desktop client apps (e.g. Outlook, OneDrive, etc.) 105 | ## 5. Optionally, you may add 'Browser' to the ClientAppTypes condition in lieu of the block web downloads policy (SESSION policy) 106 | 107 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 108 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 109 | $conditions.Applications.IncludeApplications = "Office365" 110 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 111 | $conditions.Users.IncludeUsers = "All" 112 | $conditions.Users.ExcludeUsers = "GuestsOrExternalUsers" 113 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 114 | $conditions.Platforms = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessPlatformCondition 115 | $conditions.Platforms.IncludePlatforms = @('Windows', 'macOS') 116 | $conditions.ClientAppTypes = @('MobileAppsAndDesktopClients') 117 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls 118 | $controls._Operator = "OR" 119 | $controls.BuiltInControls = @('DomainJoinedDevice', 'CompliantDevice') 120 | 121 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA203: O365: Require compliant device for desktop clients on Windows and macOS" -State "Disabled" -Conditions $conditions -GrantControls $controls 122 | 123 | ######################################################## 124 | ## 4. 125 | ## CA204: Prevent web downloads on unmanaged devices 126 | 127 | ## [OPTIONAL POLICY] This policy prevents web downloads from unmanaged devices and unmanaged web browsers 128 | ## Policy NOTES: 129 | ## 1. You must take additional action in Exchange Online and SharePoint Online to complete the set up for this policy to take effect 130 | ## 2. See my Conditional Access Best Practices guide for more details on those additional steps 131 | ## 3. Unmanaged browsers (e.g. Firefox) will also be impacted by this policy, even on managed devices 132 | ## 4. End users should be advised to use Edge (Chromium version) with Office 365 133 | 134 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 135 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 136 | $conditions.Applications.IncludeApplications = "Office365" 137 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 138 | $conditions.Users.IncludeUsers = "All" 139 | $conditions.Users.ExcludeUsers = "GuestsOrExternalUsers" 140 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 141 | $conditions.ClientAppTypes = @('Browser') 142 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessSessionControls 143 | $controls.ApplicationEnforcedRestrictions = $true 144 | 145 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA204: O365: Prevent web downloads on unmanaged devices" -State "Disabled" -Conditions $conditions -SessionControls $controls 146 | 147 | ######################################################## 148 | 149 | Write-Host "Script completed" -ForegroundColor Cyan 150 | 151 | -------------------------------------------------------------------------------- /Azure AD/Install-GuestCAPolicies.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | #NOTE: This script is legacy, the latest complete baseline is Install-ITPMBaselineCAPolicies.ps1 3 | .SYNOPSIS 4 | This script will create the following optional Conditional Access policies in your tenant: 5 | 6 | 1. CA301: Block guest access to unsupported apps 7 | 2. CA302: Require MFA for guests and external users 8 | 9 | .NOTES 10 | 1. You may need to disable the 'Security defaults' first. See https://aka.ms/securitydefaults 11 | 2. None of the policies created by this script will be enabled by default. 12 | 3. Before enabling policies, you should notify end users about the expected impacts 13 | 4. Be sure to populate the security group 'sg-Exclude from CA' with at least one admin account for emergency access 14 | 15 | .HOW-TO 16 | 1. To install the Azure AD Preview PowerShell module use: Install-Module AzureADPreview -AllowClobber 17 | 2. Run .\Install-GuestCAPolicies.ps1 18 | 19 | .DETAILS 20 | FileName: Install-GuestCAPolicies.ps1 21 | Author: Alex Fields, ITProMentor.com 22 | Created: June 2021 23 | Updated: January 2022 24 | 25 | #> 26 | ################################################################################################### 27 | 28 | 29 | 30 | ## Check for the existence of the "Exclude from CA" security group, and create the group if it does not exist 31 | 32 | $ExcludeCAGroupName = "sgu-Exclude From CA" 33 | $ExcludeCAGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $ExcludeCAGroupName 34 | 35 | if ($ExcludeCAGroup -eq $null -or $ExcludeCAGroup -eq "") { 36 | New-AzureADGroup -DisplayName $ExcludeCAGroupName -SecurityEnabled $true -MailEnabled $false -MailNickName sg-ExcludeFromCA 37 | $ExcludeCAGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $ExcludeCAGroupName 38 | } 39 | else { 40 | Write-Host "Exclude from CA group already exists" 41 | } 42 | 43 | 44 | ######################################################## 45 | ## 1. 46 | ## CA301: Block guest access to unsupported apps 47 | ## This policy blocks guest access to all cloud apps except Office 365 48 | 49 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 50 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 51 | $conditions.Applications.IncludeApplications = "All" 52 | $conditions.Applications.ExcludeApplications = "Office365" 53 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 54 | $conditions.Users.IncludeUsers = "GuestsOrExternalUsers" 55 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 56 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls 57 | $controls._Operator = "OR" 58 | $controls.BuiltInControls = "Block" 59 | 60 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA301: Block guest access to unsupported apps" -State "Disabled" -Conditions $conditions -GrantControls $controls 61 | 62 | ######################################################## 63 | ## 2. 64 | ## CA302: Require MFA for guests and external users 65 | ## This policy requires Multi-factor Authentication for guests 66 | 67 | $conditions = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet 68 | $conditions.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition 69 | $conditions.Applications.IncludeApplications = "All" 70 | $conditions.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition 71 | $conditions.Users.IncludeUsers = "GuestsOrExternalUsers" 72 | $conditions.Users.ExcludeGroups = $ExcludeCAGroup.ObjectId 73 | $conditions.ClientAppTypes = @('Browser', 'MobileAppsAndDesktopClients') 74 | $controls = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls 75 | $controls._Operator = "OR" 76 | $controls.BuiltInControls = "MFA" 77 | 78 | New-AzureADMSConditionalAccessPolicy -DisplayName "CA302: Require MFA for guests and external users" -State "Disabled" -Conditions $conditions -GrantControls $controls 79 | 80 | 81 | ######################################################## 82 | 83 | Write-Host "Script completed" -ForegroundColor Cyan 84 | -------------------------------------------------------------------------------- /Azure AD/Limit-GroupsCreation.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | Define a security group using the variable $GroupName 6 | This will limit the privilege for creating Office 365 Groups to the specified security group 7 | 8 | You must have the Preview version of the Azure AD PowerShell module: 9 | Uninstall-Module AzureAD 10 | Install-Module AzureADPreview 11 | 12 | Source of script: 13 | https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/manage-creation-of-groups?view=o365-worldwide 14 | 15 | .NOTES 16 | FileName: Limit-GroupsCreation.ps1 17 | Author: Alex Fields, ITProMentor.com 18 | Created: February 2020 19 | Revised: April 2021 20 | 21 | #> 22 | ################################################################################################### 23 | 24 | Import-Module AzureADPreview -Force 25 | 26 | $GroupName = "sg-Group Creators" 27 | $AllowGroupCreation = "False" 28 | 29 | 30 | $CheckForGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $GroupName 31 | 32 | if ($CheckForGroup -eq $null -or $CheckForGroup -eq "") { 33 | New-AzureADGroup -DisplayName $GroupName -SecurityEnabled $true -MailEnabled $false -MailNickName sg-GroupCreators 34 | 35 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 36 | if(!$settingsObjectID) 37 | { 38 | $template = Get-AzureADDirectorySettingTemplate | Where-object {$_.displayname -eq "group.unified"} 39 | $settingsCopy = $template.CreateDirectorySetting() 40 | New-AzureADDirectorySetting -DirectorySetting $settingsCopy 41 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 42 | } 43 | 44 | $settingsCopy = Get-AzureADDirectorySetting -Id $settingsObjectID 45 | $settingsCopy["EnableGroupCreation"] = $AllowGroupCreation 46 | 47 | if($GroupName) 48 | { 49 | $settingsCopy["GroupCreationAllowedGroupId"] = (Get-AzureADGroup -SearchString $GroupName).objectid 50 | } else { 51 | $settingsCopy["GroupCreationAllowedGroupId"] = $GroupName 52 | } 53 | Set-AzureADDirectorySetting -Id $settingsObjectID -DirectorySetting $settingsCopy 54 | 55 | (Get-AzureADDirectorySetting -Id $settingsObjectID).Values 56 | 57 | Write-Host 58 | Write-Host "Please add users to the new Security group to enable Groups creation." -ForegroundColor Yellow 59 | Write-Host 60 | Write-Host "Script completed." -ForegroundColor Green 61 | 62 | 63 | } else { 64 | 65 | Write-Host "Security group for Group Creators already exists; no changes will be made." -ForegroundColor Red 66 | Write-Host 67 | Write-Host "Exiting script." -ForegroundColor Red 68 | Write-Host 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /Azure AD/Readme.md: -------------------------------------------------------------------------------- 1 | ## Azure AD scripts 2 | 3 | NOTE: ALL SCRIPTS IN THIS DIRECTORY ARE OBSOLETE AND NO LONGER UPDATED. 4 | FOR THE LATEST, PLEASE SEE: https://github.com/vanvfields/Microsoft-365/tree/master/mggraph-samples 5 | -------------------------------------------------------------------------------- /Azure AD/Set-GroupExpirationPolicy.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | This script checks for and sets the Microsoft 365 Groups expiration policy. 6 | If the policy already exists the script will exit without making changes. 7 | 8 | You have to connect to Azure AD using Connect-AzureAD before running this script: 9 | https://docs.microsoft.com/en-us/powershell/azure/active-directory/install-adv2?view=azureadps-2.0 10 | 11 | Source of script: 12 | https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/groups-lifecycle#powershell-examples 13 | 14 | .NOTES 15 | FileName: Set-GroupExpirationPolicy.ps1 16 | Author: Alex Fields, ITProMentor.com 17 | Created: April 2021 18 | Revised: April 2021 19 | 20 | #> 21 | ################################################################################################### 22 | 23 | 24 | ## Check for Group expiration policy 25 | $CheckPolicy = Get-AzureADMSGroupLifecyclePolicy 26 | 27 | if ($CheckPolicy -eq $null -or $CheckPolicy -eq "") { 28 | 29 | Write-Host 30 | Write-Host "No expiration policy found." -ForegroundColor Yellow 31 | Write-Host 32 | $EmailNotification = Read-Host "Enter the email address for orphaned Group notifications" 33 | Write-Host 34 | $GroupLifetime = Read-Host "Enter the desired lifetime for inactive Groups (in days)" 35 | Write-Host 36 | New-AzureADMSGroupLifecyclePolicy -GroupLifetimeInDays $GroupLifetime -ManagedGroupTypes All -AlternateNotificationEmails $EmailNotification 37 | Write-Host 38 | Write-Host "Script complete" -ForegroundColor Green 39 | Write-Host 40 | } 41 | 42 | else { 43 | 44 | Write-Host 45 | Write-Host "Group expiration policy already exists; no changes will be made." -ForegroundColor Red 46 | Write-Host 47 | $CheckPolicy 48 | Write-Host 49 | Write-Host "Script complete" -ForegroundColor Green 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Compliance/Enable-SensitivityLabelsForGroups.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script will enable Sensitivity labels for Groups and Sites: 5 | 6 | .PREREQUISITES 7 | 1. You must install the AzureADPreview PowerShell module (Install-AzureADPreview) 8 | 2. You will also require the Exchange Online V2 module (Install-Module -Name ExchangeOnlineManagement) 9 | 10 | .DETAILS 11 | FileName: Enable-SensitivityLabelsForGroups.ps1 12 | Author: Alex Fields, ITProMentor.com 13 | Created: November 2020 14 | Updated: April 2021 15 | 16 | .NOTES 17 | You will be prompted twice since you must authenticate against both Azure AD and Exchange Online 18 | 19 | #> 20 | ################################################################################################### 21 | 22 | 23 | ## Import the AzureADPreview module 24 | Import-Module AzureADPreview 25 | 26 | ## Connect to Azure AD 27 | Connect-AzureAD 28 | 29 | ## Import the Exchange Online V2 module 30 | Import-Module ExchangeOnlineManagement 31 | 32 | ## Connect to the Security & Compliance center with the EXO V2 module 33 | Connect-IPPSSession 34 | 35 | ## Get the Template ID for Group.Unified 36 | $TemplateId = (Get-AzureADDirectorySettingTemplate | where { $_.DisplayName -eq "Group.Unified" }).Id 37 | $Template = Get-AzureADDirectorySettingTemplate | where -Property Id -Value $TemplateId -EQ 38 | 39 | 40 | ## Create a new settings object based on the template 41 | $Setting = $Template.CreateDirectorySetting() 42 | 43 | ## Enable the unified lables feature for groups 44 | $Setting["EnableMIPLabels"] = "True" 45 | 46 | ## Apply the setting 47 | New-AzureADDirectorySetting -DirectorySetting $Setting 48 | 49 | ## Note: Read the settings for this new object out with the following: 50 | $Setting.Values 51 | 52 | ## Run the following to allow Sensitivity labels to be used with Groups: 53 | Execute-AzureAdLabelSync 54 | 55 | 56 | ## End of script -------------------------------------------------------------------------------- /Compliance/Install-DataRetentionPolicies.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Use this script to deploy a blanket retention policy as described in the Data Protection Starter Kit. 4 | You should be familiar with the regulations and policies applicable to your organization before running this script. 5 | Script provided as-is, use at your own risk. 6 | 7 | .NOTES 8 | 1. You must have the ExchangeOnlineManagement PowerShell module installed in order to run this script. 9 | 2. Connect to the Security & Compliance center using Connect-IPPSSession 10 | 11 | .DETAILS 12 | FileName: Install-DataRetentionPolicies.ps1 13 | Author: Alex Fields, ITProMentor.com 14 | Created: September 2021 15 | Updated: September 2021 16 | 17 | #> 18 | 19 | 20 | #Connect-IPPSSession 21 | 22 | Write-Host 23 | $AskDate = Read-Host "Will your retention policies be based on (1) Date created or (2) Date last modified? Type 1 or 2 and press Enter" 24 | 25 | if ($AskDate -eq "1") { 26 | $ExpirationDateOption = "CreationAgeInDays" 27 | Write-Host 28 | Write-Host "Warning: Retention policies created by this script will be based on date created!" -ForegroundColor Yellow 29 | } elseif ($AskDate -eq "2") { 30 | $ExpirationDateOption = "ModificationAgeInDays" 31 | Write-Host 32 | Write-Host "Warning: Retention policies created by this script will be based on date last modified!" -ForegroundColor Yellow 33 | } else { 34 | Write-Host 35 | Write-Host "Input not recognized. Defaulting to date last modified." -ForegroundColor Yellow 36 | $ExpirationDateOption = "ModificationAgeInDays" 37 | Write-Host 38 | Write-Host "Warning: Retention policies created by this script will be based on date last modified!" -ForegroundColor Yellow 39 | } 40 | 41 | Write-Host 42 | $AskEnable = Read-Host "Do you want the policies to be enabled upon creation? Type Y or N and press Enter" 43 | 44 | if ($AskEnable -eq "y") { 45 | $Enabled = $true 46 | Write-Host 47 | Write-Host "Warning: The policies you create next will be enabled and enforced." -ForegroundColor Yellow 48 | } else { 49 | $Enabled = $false 50 | Write-Host 51 | Write-Host "Warning: The policies you create next will be disabled and will not take effect until you enable them." -ForegroundColor Yellow 52 | } 53 | 54 | Write-Host 55 | $Answer = Read-Host "Do you want to deploy the default User retention policy for Email and OneDrive data? Type Y or N and press Enter" 56 | 57 | if ($Answer -eq "y") { 58 | Write-Host 59 | $Years = Read-Host "Retain Email and OneDrive data for how many years? Enter a value between 1 and 10 and press Enter" 60 | $Duration = 365*$Years 61 | 62 | Write-Host 63 | $AskAction = Read-Host "Do you want to (1) Keep, (2) Keep and Delete, or (3) just Delete? Enter 1, 2, or 3 and press Enter" 64 | if ($AskAction -eq "1") { 65 | 66 | New-RetentionCompliancePolicy -Name "User data retention policy" -ExchangeLocation All -OneDriveLocation All -Enabled $Enabled 67 | New-RetentionComplianceRule -Name "User data retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Keep -Policy "User data retention policy" 68 | Write-Host 69 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 70 | 71 | } elseif ($AskAction -eq "2") { 72 | 73 | New-RetentionCompliancePolicy -Name "User data retention policy" -ExchangeLocation All -OneDriveLocation All -Enabled $Enabled 74 | New-RetentionComplianceRule -Name "User data retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction KeepAndDelete -Policy "User data retention policy" 75 | Write-Host 76 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 77 | 78 | } elseif ($AskAction -eq "3") { 79 | 80 | New-RetentionCompliancePolicy -Name "User data deletion policy" -ExchangeLocation All -OneDriveLocation All -Enabled $Enabled 81 | New-RetentionComplianceRule -Name "User data deletion rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Delete -Policy "User data deletion policy" 82 | Write-Host 83 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 84 | 85 | } else { 86 | Write-Host 87 | Write-Host "Invalid input, no policy will be created." -ForegroundColor Yellow 88 | } 89 | 90 | 91 | } else { 92 | Write-Host 93 | Write-Host "The default User data retention policy will not be deployed." -ForegroundColor Yellow 94 | 95 | } 96 | 97 | Write-Host 98 | $Answer = Read-Host "Do you want to deploy the default Company data retention policy? Type Y or N and press Enter" 99 | 100 | if ($Answer -eq "y") { 101 | Write-Host 102 | $Years = Read-Host "Retain SharePoint and Groups data for how many years? Enter a value between 1 and 10 and press Enter" 103 | 104 | $Duration = 365*$Years 105 | 106 | Write-Host 107 | $AskAction = Read-Host "Do you want to (1) Keep, (2) Keep and Delete, or (3) just Delete? Enter 1, 2, or 3 and press Enter" 108 | 109 | if ($AskAction -eq "1") { 110 | 111 | New-RetentionCompliancePolicy -Name "Company data retention policy" -SharePointLocation All -ModernGroupLocation All -Enabled $Enabled 112 | New-RetentionComplianceRule -Name "Company data retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Keep -Policy "Company data retention policy" 113 | Write-Host 114 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 115 | 116 | } elseif ($AskAction -eq "2") { 117 | 118 | New-RetentionCompliancePolicy -Name "Company data retention policy" -SharePointLocation All -ModernGroupLocation All -Enabled $Enabled 119 | New-RetentionComplianceRule -Name "Company data retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction KeepAndDelete -Policy "Company data retention policy" 120 | Write-Host 121 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 122 | 123 | } elseif ($AskAction -eq "3") { 124 | 125 | New-RetentionCompliancePolicy -Name "Company data deletion policy" -SharePointLocation All -ModernGroupLocation All -Enabled $Enabled 126 | New-RetentionComplianceRule -Name "Company data deletion rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Delete -Policy "Company data deletion policy" 127 | Write-Host 128 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 129 | 130 | } else { 131 | Write-Host 132 | Write-Host "Invalid input, no policy will be created." -ForegroundColor Yellow 133 | 134 | } 135 | 136 | 137 | } else { 138 | Write-Host 139 | Write-Host "The default Company data retention policy will not be deployed." -ForegroundColor Yellow 140 | 141 | } 142 | 143 | Write-Host 144 | Write-Host "Script completed" -ForegroundColor Cyan -------------------------------------------------------------------------------- /Compliance/Install-EmailRetentionPolicy.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Use this script to deploy a blanket retention policy as described in the Data Protection Starter Kit. 4 | You should be familiar with the regulations and policies applicable to your organization before running this script. 5 | Script provided as-is, use at your own risk. 6 | 7 | .NOTES 8 | 1. You must have the ExchangeOnlineManagement PowerShell module installed in order to run this script. 9 | 2. Connect to the Security & Compliance center using Connect-IPPSSession 10 | 11 | .DETAILS 12 | FileName: Install-EmailRetentionPolicy.ps1 13 | Author: Alex Fields, ITProMentor.com 14 | Created: September 2021 15 | Updated: February 2022 16 | 17 | #> 18 | 19 | #Import-Module ExchangeOnlineManagement 20 | #Connect-IPPSSession 21 | 22 | Write-Host 23 | $AskDate = Read-Host "Will your retention policy be based on (1) Date created or (2) Date last modified? Type 1 or 2 and press Enter" 24 | 25 | if ($AskDate -eq "1") { 26 | $ExpirationDateOption = "CreationAgeInDays" 27 | Write-Host 28 | Write-Host "Warning: Retention policies created by this script will be based on date created!" -ForegroundColor Yellow 29 | } elseif ($AskDate -eq "2") { 30 | $ExpirationDateOption = "ModificationAgeInDays" 31 | Write-Host 32 | Write-Host "Warning: Retention policies created by this script will be based on date last modified!" -ForegroundColor Yellow 33 | } else { 34 | Write-Host 35 | Write-Host "Input not recognized. Defaulting to date last modified." -ForegroundColor Yellow 36 | $ExpirationDateOption = "ModificationAgeInDays" 37 | Write-Host 38 | Write-Host "Warning: Retention policies created by this script will be based on date last modified!" -ForegroundColor Yellow 39 | } 40 | 41 | Write-Host 42 | $AskEnable = Read-Host "Do you want the policy to be enabled upon creation? Type Y or N and press Enter" 43 | 44 | if ($AskEnable -eq "y") { 45 | $Enabled = $true 46 | Write-Host 47 | Write-Host "Warning: The policy you create next will be enabled and enforced." -ForegroundColor Yellow 48 | } else { 49 | $Enabled = $false 50 | Write-Host 51 | Write-Host "Warning: The policy you create next will be disabled and will not take effect until you enable them." -ForegroundColor Yellow 52 | } 53 | 54 | 55 | Write-Host 56 | $Years = Read-Host "Retain Email data for how many years? Enter a value between 1 and 10 and press Enter" 57 | $Duration = 365*$Years 58 | 59 | Write-Host 60 | $AskAction = Read-Host "Do you want to (1) Keep, (2) Keep and Delete, or (3) just Delete? Enter 1, 2, or 3 and press Enter" 61 | if ($AskAction -eq "1") { 62 | 63 | New-RetentionCompliancePolicy -Name "Email retention policy" -ExchangeLocation All -Enabled $Enabled 64 | New-RetentionComplianceRule -Name "Email retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Keep -Policy "Email retention policy" 65 | Write-Host 66 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 67 | 68 | } elseif ($AskAction -eq "2") { 69 | 70 | New-RetentionCompliancePolicy -Name "Email retention policy" -ExchangeLocation All -Enabled $Enabled 71 | New-RetentionComplianceRule -Name "Email retention rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction KeepAndDelete -Policy "Email retention policy" 72 | Write-Host 73 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 74 | 75 | } elseif ($AskAction -eq "3") { 76 | 77 | New-RetentionCompliancePolicy -Name "Email deletion policy" -ExchangeLocation All -Enabled $Enabled 78 | New-RetentionComplianceRule -Name "Email deletion rule" -RetentionDuration $Duration -RetentionDurationDisplayHint Years -ExpirationDateOption $ExpirationDateOption -RetentionComplianceAction Delete -Policy "Email deletion policy" 79 | Write-Host 80 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 81 | 82 | } -------------------------------------------------------------------------------- /Compliance/Install-SensitivityLabels.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Use this script to deploy Sensitivity Labels from the Data Protection Starter Kit: 4 | - Non-Business: Use to identify personal data 5 | - Public: Use to identify data explicitly approved for public consumption 6 | - General: Use to identify data that can be shared as needed for business purposes. 7 | - Confidential: Category of labels to identify sensitive data 8 | -Anyone (Not Protected): Use to identify sensitive data which can be shared with approved external parties 9 | -External (Protected): Use to identify and protect sensitive data which can be shared with approved external parties 10 | -Internal (Protected): Use to identify and protect sensitive data which can only be shared internally 11 | -Recipients Only (Protected): Use to encrypt email messges in Outlook with Do Not Forward permissions (recipients cannot forward, copy, or print) 12 | 13 | .NOTES 14 | 1. You must have the AzureADPreview PowerShell module installed in order to run this script. 15 | 2. You must have the ExchangeOnlineManagement PowerShell module installed in order to run this script. 16 | 3. You must enable Sensitivity labels for Groups and Sites in order to run this script. 17 | 4. Reference: https://docs.microsoft.com/en-us/microsoft-365/compliance/sensitivity-labels-teams-groups-sites 18 | 19 | .DETAILS 20 | FileName: Install-SensitivityLabels.ps1 21 | Author: Alex Fields, ITProMentor.com 22 | Created: May 2021 23 | Updated: May 2021 24 | 25 | #> 26 | 27 | 28 | Import-Module AzureADPreview 29 | Connect-AzureAD 30 | 31 | Import-Module ExchangeOnlineManagement 32 | Connect-IPPSSession 33 | 34 | 35 | $CheckLabels = Get-LabelPolicy 36 | 37 | if (!$CheckLabels) { 38 | 39 | ## Install the Non-Business label 40 | $NonBusinessParam=@{ 41 | 'Name' = 'Non-Business'; 42 | 'DisplayName' = 'Non-Business'; 43 | 'Tooltip' = 'Use this classification to identify personal, non-corporate data. This label does not imply privacy.' 44 | } 45 | 46 | New-Label @NonBusinessParam 47 | 48 | ## Install the Public label 49 | $PublicParam=@{ 50 | 'Name' = 'Public'; 51 | 'DisplayName' = 'Public'; 52 | 'Tooltip' = 'Use this classification to identify data that is explicitly approved for general public consumption.'; 53 | 'SiteAndGroupProtectionEnabled' = $true; 54 | 'SiteAndGroupProtectionPrivacy' = 'Public'; 55 | 'SiteAndGroupProtectionAllowAccessToGuestUsers' = $true; 56 | 'SiteAndGroupProtectionAllowEmailFromGuestUsers' = $true; 57 | #'SiteExternalSharingControlType' = "ExternalUserAndGuestSharing"; 58 | 'Comment' = ' ' 59 | } 60 | 61 | New-Label @PublicParam 62 | 63 | ## Install the General label 64 | $GeneralParam=@{ 65 | 'Name' = 'General'; 66 | 'DisplayName' = 'General'; 67 | 'Tooltip' = 'Use this label to identify data that belongs to the Organization, but which may be shared as needed.'; 68 | 'SiteAndGroupProtectionEnabled' = $true; 69 | 'SiteAndGroupProtectionAllowAccessToGuestUsers' = $true; 70 | 'SiteAndGroupProtectionAllowEmailFromGuestUsers' = $true; 71 | #'SiteExternalSharingControlType' = "ExternalUserSharingOnly"; 72 | 'Comment' = ' ' 73 | } 74 | 75 | New-Label @GeneralParam 76 | 77 | ## Install the Confidential label 78 | $ConfidentialParam=@{ 79 | 'Name' = 'Confidential'; 80 | 'DisplayName' = 'Confidential'; 81 | 'Tooltip' = 'Use this classification to identify and protect data which is sensitive, and which should be shared more carefully.'; 82 | 'SiteAndGroupProtectionEnabled' = $true; 83 | 'SiteAndGroupProtectionPrivacy' = 'Private'; 84 | 'SiteAndGroupProtectionAllowAccessToGuestUsers' = $false; 85 | 'SiteAndGroupProtectionAllowEmailFromGuestUsers' = $false; 86 | #'SiteExternalSharingControlType' = "Disabled"; 87 | 'Comment' = ' ' 88 | } 89 | 90 | New-Label @ConfidentialParam 91 | 92 | ## Install sub-labels for Confidential 93 | 94 | ## Install the Anyone (Not Protected) label (No encryption is applied) 95 | 96 | $AnyoneParam=@{ 97 | 'Name' = 'Anyone'; 98 | 'DisplayName' = 'Anyone (Not Protected)'; 99 | 'Tooltip' = 'Use this classification to identify Confidential data that can be shared with approved parties outside the Organization; no encryption is applied.'; 100 | 'ParentID' = 'Confidential'; 101 | 'EncryptionEnabled' = $false; 102 | 'EncryptionProtectionType' = 'RemoveProtection'; 103 | 'ApplyContentMarkingHeaderEnabled' = $true; 104 | 'ApplyContentMarkingHeaderAlignment' = 'Left'; 105 | 'ApplyContentMarkingHeaderText' = 'Confidential (Not Protected)' 106 | } 107 | 108 | New-Label @AnyoneParam 109 | 110 | 111 | ## Install the External (Protected) label 112 | 113 | $RightsDefinition = "VIEW,VIEWRIGHTSDATA,DOCEDIT,EDIT,PRINT,EXTRACT,REPLY,REPLYALL,FORWARD,OBJMODEL" 114 | 115 | $ExternalParam=@{ 116 | 'Name' = 'External'; 117 | 'DisplayName' = 'External (Protected)'; 118 | 'Tooltip' = 'Use this classification to identify and protect Confidential data that can be shared with approved parties outside the Organization.'; 119 | 'ParentID' = 'Confidential'; 120 | 'EncryptionEnabled' = $true; 121 | 'EncryptionProtectionType' = 'Template'; 122 | 'EncryptionRightsDefinitions' = "AuthenticatedUsers"+":"+$RightsDefinition; 123 | 'EncryptionContentExpiredOnDateInDaysOrNever' = 'Never'; 124 | 'EncryptionOfflineAccessDays' = '30'; 125 | 'ApplyContentMarkingHeaderEnabled' = $true; 126 | 'ApplyContentMarkingHeaderAlignment' = 'Left'; 127 | 'ApplyContentMarkingHeaderText' = 'Confidential (External)' 128 | } 129 | 130 | New-Label @ExternalParam 131 | 132 | ## Install the Internal label (Encryption with Co-author permissions for all users in the domain) 133 | 134 | $TenantDomain = (Get-AzureADDomain | Where-Object {$_.isInitial}).name 135 | $RightsDefinition = "VIEW,VIEWRIGHTSDATA,DOCEDIT,EDIT,PRINT,EXTRACT,REPLY,REPLYALL,FORWARD,OBJMODEL" 136 | 137 | $InternalParam=@{ 138 | 'Name' = 'Internal'; 139 | 'DisplayName' = 'Internal (Protected)'; 140 | 'Tooltip' = 'Use this classification to identify and protect Confidential data that should not be shared outside the Organization.'; 141 | 'ParentID' = 'Confidential'; 142 | 'EncryptionEnabled' = $true; 143 | 'EncryptionProtectionType' = 'Template'; 144 | 'EncryptionRightsDefinitions' = $TenantDomain+":"+$RightsDefinition; 145 | 'EncryptionContentExpiredOnDateInDaysOrNever' = 'Never'; 146 | 'EncryptionOfflineAccessDays' = '30'; 147 | 'ApplyContentMarkingHeaderEnabled' = $true; 148 | 'ApplyContentMarkingHeaderAlignment' = 'Left'; 149 | 'ApplyContentMarkingHeaderText' = 'Confidential (Internal)' 150 | 151 | } 152 | 153 | New-Label @InternalParam 154 | 155 | 156 | ## Install the Recipients Only label (Applies Do Not Forward template in Outlook) 157 | $DNFParam=@{ 158 | 'Name' = 'Recipients Only'; 159 | 'DisplayName' = 'Recipients Only (Protected)'; 160 | 'Tooltip' = 'Use this classification to protect Confidential messages in Outlook. Recipients cannot forward, copy, or print the message.'; 161 | 'ParentID' = 'Confidential'; 162 | 'EncryptionEnabled' = $true; 163 | 'EncryptionProtectionType' = 'UserDefined'; 164 | 'EncryptionDoNotForward' = $true 165 | } 166 | 167 | New-Label @DNFParam 168 | 169 | 170 | Write-Host 171 | Write-Host "The default labels have been installed." -ForegroundColor Cyan 172 | Write-Host 173 | $Publish = Read-Host "Do you want to publish the labels to all users? Type Y or N and press Enter" 174 | 175 | if ($Publish = 'y') { 176 | 177 | 178 | ## Install a label policy to publish the labels 179 | 180 | 181 | $PolicyJSON = @" 182 | 183 | { 184 | "requiredowngradejustification": true, 185 | "mandatory": false, 186 | "siteandgroupmandatory": false, 187 | "siteandgroupdefaultlabelid": "" 188 | } 189 | 190 | "@ 191 | 192 | 193 | New-LabelPolicy -Name "Default classification labels" -Labels "Non-Business","Public","General","Confidential","Anyone","External","Internal","Recipients Only" -ExchangeLocation All -Settings $PolicyJSON 194 | Write-Host 195 | Write-Host 'Default labels have been added and published to all users in the tenant.' -ForegroundColor Cyan 196 | Write-Host 197 | Write-Host 'Script completed' -ForegroundColor Cyan 198 | Write-Host 199 | } 200 | 201 | else { 202 | 203 | Write-Host 204 | Write-Host "Labels will not be published at this time. You must publish labels before they can be applied to content." -ForegroundColor Yellow 205 | 206 | } 207 | 208 | } 209 | 210 | else { 211 | Write-Host 212 | Write-Host 'Labels are already deployed in this organization. No changes have been made.' -ForegroundColor Yellow 213 | Write-Host 214 | Write-Host 'Script completed' -ForegroundColor Cyan 215 | Write-Host 216 | } 217 | 218 | 219 | <# 220 | .NOTES 221 | At the time of writing this script, the external sharing settings for sites are not functioning correctly when deployed via PowerShell. 222 | 223 | Therefore I have commented out the parameters for now, until Microsoft fixes it. 224 | 225 | It should be as follows: 226 | 227 | SiteExternalSharingControlType: 228 | Anonymous/Anyone links = ExternalUserAndGuestSharing 229 | New and existing guests = ExternalUserSharingOnly 230 | Existing guests only = ExistingExternalUserSharingOnly 231 | Only in the organization = Disabled 232 | 233 | 234 | #> -------------------------------------------------------------------------------- /Compliance/Install-TeamsRetentionPolicies.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Use this script to deploy a blanket retention policy as described in the Data Protection Starter Kit. 4 | You should be familiar with the regulations and policies applicable to your organization before running this script. 5 | Script provided as-is, use at your own risk. 6 | 7 | .NOTES 8 | 1. You must have the ExchangeOnlineManagement PowerShell module installed in order to run this script. 9 | 2. Connect to the Security & Compliance center using Connect-IPPSSession 10 | 11 | .DETAILS 12 | FileName: Install-TeamsRetentionPolicies.ps1 13 | Author: Alex Fields, ITProMentor.com 14 | Created: September 2021 15 | Updated: September 2021 16 | 17 | #> 18 | 19 | 20 | #Connect-IPPSSession 21 | 22 | Write-Host 23 | $AskEnable = Read-Host "Do you want the policies to be enabled upon creation? Type Y or N and press Enter" 24 | 25 | if ($AskEnable -eq "y") { 26 | $Enabled = $true 27 | Write-Host 28 | Write-Host "Warning: The policies you create next will be enabled and enforced." -ForegroundColor Yellow 29 | } else { 30 | $Enabled = $false 31 | Write-Host 32 | Write-Host "Warning: The policies you create next will be disabled and will not take effect until you enable them." -ForegroundColor Yellow 33 | } 34 | 35 | Write-Host 36 | $Answer = Read-Host "Do you want to deploy the default retention policy for Teams chats? Type Y or N and press Enter" 37 | 38 | if ($Answer -eq "y") { 39 | Write-Host 40 | $Days = Read-Host "Retain Teams chat messages for how many days? Enter a value up to 3650 and press Enter" 41 | 42 | Write-Host 43 | $AskAction = Read-Host "Do you want to (1) Keep, (2) Keep and Delete, or (3) just Delete? Enter 1, 2, or 3 and press Enter" 44 | if ($AskAction -eq "1") { 45 | 46 | New-RetentionCompliancePolicy -Name "Teams chats retention policy" -TeamsChatLocation All -Enabled $Enabled 47 | New-RetentionComplianceRule -Name "Teams chats retention rule" -RetentionDuration $Days -RetentionComplianceAction Keep -Policy "Teams chats retention policy" 48 | Write-Host 49 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 50 | 51 | } elseif ($AskAction -eq "2") { 52 | 53 | New-RetentionCompliancePolicy -Name "Teams chats retention policy" -TeamsChatLocation All -Enabled $Enabled 54 | New-RetentionComplianceRule -Name "Teams chats retention rule" -RetentionDuration $Days -RetentionComplianceAction KeepAndDelete -Policy "Teams chats retention policy" 55 | Write-Host 56 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 57 | 58 | } elseif ($AskAction -eq "3") { 59 | 60 | New-RetentionCompliancePolicy -Name "Teams chats deletion policy" -TeamsChatLocation All -Enabled $Enabled 61 | New-RetentionComplianceRule -Name "Teams chats deletion rule" -RetentionDuration $Days -RetentionComplianceAction Delete -Policy "Teams chats deletion policy" 62 | Write-Host 63 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 64 | 65 | } else { 66 | Write-Host 67 | Write-Host "Invalid input, no policy will be created." -ForegroundColor Yellow 68 | } 69 | 70 | 71 | } else { 72 | Write-Host 73 | Write-Host "The default Teams chats policy will not be deployed." -ForegroundColor Yellow 74 | 75 | } 76 | 77 | Write-Host 78 | $Answer = Read-Host "Do you want to deploy the default Teams channels retention policy? Type Y or N and press Enter" 79 | 80 | if ($Answer -eq "y") { 81 | Write-Host 82 | $Days = Read-Host "Retain Teams channel messages for how many days? Enter a value up to 3650 and press Enter" 83 | 84 | Write-Host 85 | $AskAction = Read-Host "Do you want to (1) Keep, (2) Keep and Delete, or (3) just Delete? Enter 1, 2, or 3 and press Enter" 86 | 87 | if ($AskAction -eq "1") { 88 | 89 | New-RetentionCompliancePolicy -Name "Teams channels retention policy" -TeamsChannelLocation All -Enabled $Enabled 90 | New-RetentionComplianceRule -Name "Teams channels retention rule" -RetentionDuration $Days -RetentionComplianceAction Keep -Policy "Teams channels retention policy" 91 | Write-Host 92 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 93 | 94 | } elseif ($AskAction -eq "2") { 95 | 96 | New-RetentionCompliancePolicy -Name "Teams channels retention policy" -TeamsChannelLocation All -Enabled $Enabled 97 | New-RetentionComplianceRule -Name "Teams channels retention rule" -RetentionDuration $Days -RetentionComplianceAction KeepAndDelete -Policy "Teams channels retention policy" 98 | Write-Host 99 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 100 | 101 | } elseif ($AskAction -eq "3") { 102 | 103 | New-RetentionCompliancePolicy -Name "Teams channels deletion policy" -TeamsChannelLocation All -Enabled $Enabled 104 | New-RetentionComplianceRule -Name "Teams channels deletion rule" -RetentionDuration $Days -RetentionComplianceAction Delete -Policy "Teams channels deletion policy" 105 | Write-Host 106 | Write-Host "The policy has been created. Once enabled, it can take up to 24 hours to take effect." -ForegroundColor Green 107 | 108 | } else { 109 | Write-Host 110 | Write-Host "Invalid input, no policy will be created." -ForegroundColor Yellow 111 | 112 | } 113 | 114 | 115 | } else { 116 | Write-Host 117 | Write-Host "The default Teams channels policy will not be deployed." -ForegroundColor Yellow 118 | 119 | } 120 | 121 | Write-Host 122 | Write-Host "Script completed" -ForegroundColor Cyan -------------------------------------------------------------------------------- /Compliance/Limit-GroupsCreation.ps1: -------------------------------------------------------------------------------- 1 |  2 | <################################################################################################## 3 | # 4 | .SYNOPSIS 5 | Define a security group using the variable $GroupName 6 | This will limit the privilege for creating Microsoft 365 Groups to the specified security group 7 | 8 | You must have the Preview version of the Azure AD PowerShell module: 9 | Uninstall-Module AzureAD 10 | Install-Module AzureADPreview 11 | 12 | Source of script: 13 | https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/manage-creation-of-groups?view=o365-worldwide 14 | 15 | .NOTES 16 | FileName: Limit-GroupsCreation.ps1 17 | Author: Alex Fields, ITProMentor.com 18 | Created: February 2020 19 | Revised: April 2021 20 | 21 | #> 22 | ################################################################################################### 23 | 24 | Import-Module AzureADPreview -Force 25 | 26 | $GroupName = "sg-Group Creators" 27 | $AllowGroupCreation = "False" 28 | 29 | 30 | $CheckForGroup = Get-AzureADGroup -All $true | Where-Object DisplayName -eq $GroupName 31 | 32 | if ($CheckForGroup -eq $null -or $CheckForGroup -eq "") { 33 | New-AzureADGroup -DisplayName $GroupName -SecurityEnabled $true -MailEnabled $false -MailNickName sg-GroupCreators 34 | 35 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 36 | if(!$settingsObjectID) 37 | { 38 | $template = Get-AzureADDirectorySettingTemplate | Where-object {$_.displayname -eq "group.unified"} 39 | $settingsCopy = $template.CreateDirectorySetting() 40 | New-AzureADDirectorySetting -DirectorySetting $settingsCopy 41 | $settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id 42 | } 43 | 44 | $settingsCopy = Get-AzureADDirectorySetting -Id $settingsObjectID 45 | $settingsCopy["EnableGroupCreation"] = $AllowGroupCreation 46 | 47 | if($GroupName) 48 | { 49 | $settingsCopy["GroupCreationAllowedGroupId"] = (Get-AzureADGroup -SearchString $GroupName).objectid 50 | } else { 51 | $settingsCopy["GroupCreationAllowedGroupId"] = $GroupName 52 | } 53 | Set-AzureADDirectorySetting -Id $settingsObjectID -DirectorySetting $settingsCopy 54 | 55 | (Get-AzureADDirectorySetting -Id $settingsObjectID).Values 56 | 57 | Write-Host 58 | Write-Host "Please add users to the new Security group to enable Groups creation." -ForegroundColor Yellow 59 | Write-Host 60 | Write-Host "Script completed." -ForegroundColor Green 61 | 62 | 63 | } else { 64 | 65 | Write-Host "Security group for Group Creators already exists; no changes will be made." -ForegroundColor Red 66 | Write-Host 67 | Write-Host "Exiting script." -ForegroundColor Red 68 | Write-Host 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /Compliance/readme.md: -------------------------------------------------------------------------------- 1 | ## Compliance 2 | 3 | These scripts help organizations govern their data using features like Sensitivity labels and Retention policies. 4 |

Enable-SensitivityLabelsForGroups.ps1 - This script will turn on the Groups features for Sensitivity labels 5 |

Install-SensitivityLabels.ps1 - Run this script to import the default sensitivity labels covered in my Data Protection Toolkit 6 |

Install-DataRetentionPolicies.ps1 - Create policies to retain user data (Email and OneDrive) as well as Company data (SharePoint and Groups) 7 |

Install-TeamsRetentionPolicies.ps1 - Create policies for Teams chat and channel messages 8 | -------------------------------------------------------------------------------- /DataProtectionScripts.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanvfields/Microsoft-365/6be47eaa43899b34594c9c02c3dfd46d765c4d6f/DataProtectionScripts.zip -------------------------------------------------------------------------------- /Exchange Online/Block-ConsumerStorageOWA.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script will block the ability for users to connect to Consumer cloud storage locations via OWA 4 | ## Prerequisites: 5 | ## The tenant will require any Exchange Online plan 6 | ## Connect to Exchange Online via PowerShell using MFA: 7 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | $OwaPolicy = Get-OwaMailboxPolicy -Identity OwaMailboxPolicy-Default 14 | if ($OwaPolicy.AdditionalStorageProvidersAvailable) { 15 | Write-Host 16 | Write-Host -ForegroundColor $AssessmentColor "Connecting consumer storage locations like GoogleDrive and OneDrive (personal) are currently enabled by the default OWA policy" 17 | Write-Host 18 | $Answer = Read-Host "Do you want to block outside storage locations like GoogleDrive or consumer OneDrive in the default OWA policy? Type Y or N and press Enter to continue" 19 | if ($Answer -eq 'y'-or $Answer -eq 'yes') { 20 | Get-OwaMailboxPolicy | Set-OwaMailboxPolicy -AdditionalStorageProvidersAvailable $False 21 | Write-Host 22 | Write-Host -ForegroundColor $MessageColor "Consumer storage locations like GoogleDrive and OneDrive (personal) are now disabled" 23 | } Else { 24 | Write-Host 25 | Write-Host -ForegroundColor $AssessmentColor "Consumer storage locations like GoogleDrive and OneDrive (personal) have not been disabled" 26 | } 27 | } Else { 28 | Write-Host 29 | Write-Host -ForegroundColor $MessageColor "Consumer storage locations like GoogleDrive and OneDrive (personal) are already disabled" 30 | } 31 | -------------------------------------------------------------------------------- /Exchange Online/Block-UnmanagedDownload.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script will block attachment downloads on unmanaged devices 4 | ## Prerequisites: 5 | ## The tenant will require any Exchange Online plan and Azure AD Premium P1 or Microsoft 365 Business 6 | ## Connect to Exchange Online via PowerShell using MFA: 7 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | $OwaPolicy = Get-OwaMailboxPolicy -Identity OwaMailboxPolicy-Default 14 | if ($OwaPolicy.ConditionalAccessPolicy -eq 'Off') { 15 | Write-Host 16 | Write-Host -ForegroundColor $AssessmentColor "Attachment download is currently enabled for unmanaged devices by the default OWA policy" 17 | Write-Host 18 | $Answer = Read-Host "Do you want to disable attachment download on unmanaged devices? Type Y or N and press Enter to continue" 19 | if ($Answer -eq 'y'-or $Answer -eq 'yes') { 20 | Get-OwaMailboxPolicy | Set-OwaMailboxPolicy -ConditionalAccessPolicy ReadOnly 21 | Write-Host 22 | Write-Host -ForegroundColor $MessageColor "Attachment download on unmanaged devices is now disabled; please be sure to create a corresponding Conditional Access policy in Azure AD" 23 | } Else { 24 | Write-Host 25 | Write-Host -ForegroundColor $AssessmentColor "Attachment download on unamanged devices has not been disabled" 26 | } 27 | } Else { 28 | Write-Host 29 | Write-Host -ForegroundColor $MessageColor "Attachment download on unmanaged devices is already disabled; please be sure there is a corresponding Conditional Access policy present in Azure AD" 30 | } 31 | 32 | 33 | ## NOTE: You must implement this policy in conjunction with a corresponding Conditional access policy in Azure AD 34 | ## As of today this process cannot be scripted (in a supported way) as Conditional Access is not exposed via the Graph API 35 | ## To create the policy from Azure AD > Conditional Access: 36 | ## Name the policy "Block attachment download in OWA on unmanaged devices" 37 | ## Target the appropriate user groups (or All users) 38 | ## Target Exchange Online 39 | ## Use the Session Control called "Enforce app restricitons" 40 | ## Save and enable the policy 41 | 42 | -------------------------------------------------------------------------------- /Exchange Online/Configure-Auditing.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script configures auditing for Exchange Online 4 | ## Reference: https://docs.microsoft.com/en-us/exchange/policy-and-compliance/mailbox-audit-logging/enable-or-disable?view=exchserver-2019 5 | ## Prerequisites: 6 | ## The tenant will need any Exchange Online plan 7 | ## Connect to Exchange Online via PowerShell using MFA: https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/clconnect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | ## Enable Unified Audit Log Search: 14 | $AuditLogConfig = Get-AdminAuditLogConfig 15 | if ($AuditLogConfig.UnifiedAuditLogIngestionEnabled) { 16 | Write-Host 17 | Write-Host -ForegroundColor $MessageColor "Unified Audit Log Search is already enabled" 18 | } else { 19 | Write-Host 20 | Write-Host -ForegroundColor $AssessmentColor "Unified Audit Log is not enabled" 21 | Write-Host 22 | $Answer = Read-Host "Do you want to enable the Unified Audit Log now? Type Y or N and press Enter to continue" 23 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 24 | Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true 25 | Write-Host 26 | Write-Host -ForegroundColor $MessageColor "Unified Audit Log Search is now enabled" 27 | } else { 28 | Write-Host 29 | Write-Host -ForegroundColor $AssessmentColor "Unified Audit Log will not be enabled" 30 | } 31 | } 32 | 33 | ## Prompt for the audit log age limit on all mailboxes: 34 | Write-Host 35 | $Answer = Read-Host "Do you want to set the audit log age limit and enable all auditing actions on all mailboxes? Type Y or N and press Enter to continue" 36 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 37 | Write-Host 38 | $AuditLogAgeLimit = Read-Host "Enter the new audit log age limit in days (or press Enter to continue without making changes)" 39 | if ($AuditLogAgeLimit -eq $null -or $AuditLogAgeLimit -eq "" -or $AuditLogAgeLimit -eq 'n' -or $AuditLogAgeLimit -eq 'no'){ 40 | Write-Host 41 | Write-Host -ForegroundColor $AssessmentColor "The audit log age limit and audit actions will not be modified" 42 | } else { 43 | Get-Mailbox -ResultSize Unlimited | Set-Mailbox -AuditEnabled $true -AuditLogAgeLimit $AuditLogAgeLimit 44 | Write-Host 45 | Write-Host -ForegroundColor $MessageColor "The new audit log age limit has been set for all mailboxes" 46 | ## Enable all mailbox auditing actions 47 | Get-Mailbox -ResultSize Unlimited | Set-Mailbox -AuditAdmin @{Add="Copy","Create","FolderBind","HardDelete","MessageBind","Move","MoveToDeletedItems","SendAs","SendOnBehalf","SoftDelete","Update","UpdateFolderPermissions","UpdateInboxRules","UpdateCalendarDelegation"} 48 | Get-Mailbox -ResultSize Unlimited | Set-Mailbox –AuditDelegate @{Add="Create","FolderBind","HardDelete","Move","MoveToDeletedItems","SendAs","SendOnBehalf","SoftDelete","Update","UpdateFolderPermissions","UpdateInboxRules"} 49 | Get-Mailbox -ResultSize Unlimited | Set-Mailbox –AuditOwner @{Add="Create","HardDelete","Move","Mailboxlogin","MoveToDeletedItems","SoftDelete","Update","UpdateFolderPermissions","UpdateInboxRules","UpdateCalendarDelegation"} 50 | Write-Host 51 | Write-host -ForegroundColor $MessageColor "All auditing actions are now enabled on all mailboxes" 52 | } 53 | 54 | } else { 55 | Write-Host 56 | Write-Host -ForegroundColor $AssessmentColor "The audit log age limit and audit actions will not be modified" 57 | } 58 | 59 | -------------------------------------------------------------------------------- /Exchange Online/Customize-MessageEncryption.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | Customize aspects of the OME encryption experience. 5 | 6 | Connect to Exchange Online via PowerShell using MFA: 7 | https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | 9 | .NOTES 10 | FileName: Customize-MessageEncryption.ps1 11 | Author: Alex Fields, ITProMentor.com 12 | Created: April 2021 13 | Revised: February 2023 14 | 15 | 16 | #> 17 | ################################################################################################### 18 | ## NOTE: If the script errors out, you may need to set your execution policy. 19 | ## You may also need to run: Enable-OrganizationCustomization 20 | ## Please define these variables before running this script: 21 | $MessageColor = "Green" 22 | $AssessmentColor = "Yellow" 23 | ################################################################################################### 24 | 25 | 26 | ################################################# 27 | ## ENABLE ENCRYPT IN OWA 28 | ## SUBSCRIPTIONS: O365E3/E5, M365B/E3/E5, EM+SE3/E5 29 | ################################################# 30 | 31 | $IRMConfig = Get-IRMConfiguration 32 | if (!$IRMConfig.SimplifiedClientAccessEnabled) { 33 | Write-Host 34 | Write-Host -ForegroundColor $AssessmentColor "The 'Encrypt' option is not available in OWA" 35 | Write-Host 36 | $Answer = Read-Host "Enable the 'Encrypt' option in Outlook Web Access now? Type Y or N and press Enter to continue" 37 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 38 | Set-IRMConfiguration -SimplifiedClientAccessEnabled $true 39 | Write-Host 40 | Write-Host -ForegroundColor $MessageColor "The 'Encrypt' option for Outlook on the web has been enabled" 41 | } else { 42 | Write-Host 43 | Write-Host -ForegroundColor $AssessmentColor "The 'Encrypt' option for Outlook on the Web will not be enabled" 44 | } 45 | } else { 46 | Write-Host 47 | Write-Host -ForegroundColor $MessageColor "The 'Encrypt' option for Outlook on the web is already enabled" 48 | } 49 | 50 | 51 | ################################################# 52 | ## ENCRYPT PDF ATTACHMENTS 53 | ## SUBSCRIPTIONS: O365E3/E5, M365B/E3/E5, EM+SE3/E5 54 | ################################################# 55 | if (!$IRMConfig.EnablePdfEncryption) { 56 | Write-Host 57 | Write-Host -ForegroundColor $AssessmentColor "PDF attachments are not encrypted by OME" 58 | Write-Host 59 | $Answer = Read-Host "Do you want to enable encryption of PDF attachments in OME protected messages? Type Y or N and press Enter to continue" 60 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 61 | Set-IRMConfiguration -EnablePdfEncryption $true 62 | Write-Host 63 | Write-Host -ForegroundColor $MessageColor "PDF attachments will now be encrypted by OME" 64 | } else { 65 | Write-Host 66 | Write-Host -ForegroundColor $AssessmentColor "PDF attachments will not be encrypted by OME" 67 | } 68 | } else { 69 | Write-Host 70 | Write-Host -ForegroundColor $MessageColor "PDF attachments are already being encrypted by OME" 71 | } 72 | 73 | 74 | ################################################# 75 | ## AUTO-DECRYPT ENCRYPTED ATTACHMENTS 76 | ## SUBSCRIPTIONS: O365E3/E5, M365B/E3/E5, EM+SE3/E5 77 | ################################################# 78 | Write-Host 79 | if (!$IRMConfig.DecryptAttachmentForEncryptOnly) { 80 | Write-Host 81 | Write-Host -ForegroundColor $AssessmentColor "Attachments are encrypted by default upon download" 82 | Write-Host 83 | $Answer = Read-Host "Do you want to enable attachments to be decrypted on download? Type Y or N and press Enter to continue" 84 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 85 | Set-IRMConfiguration -DecryptAttachmentForEncryptOnly $true 86 | Write-Host 87 | Write-Host -ForegroundColor $MessageColor "Attachments will now be automatically decrypted on download" 88 | } else { 89 | Write-Host 90 | Write-Host -ForegroundColor $AssessmentColor "Attachments will remain encrypted on download" 91 | } 92 | } else { 93 | Write-Host 94 | Write-Host -ForegroundColor $MessageColor "Attachments are automatically decrypted on download" 95 | } 96 | 97 | 98 | ################################################# 99 | ## JOURNAL REPORT DECRYPTION 100 | ## SUBSCRIPTIONS: O365E3/E5, M365B/E3/E5, EM+SE3/E5 101 | ################################################# 102 | Write-Host 103 | if (!$IRMConfig.JournalReportDecryptionEnabled) { 104 | Write-Host 105 | Write-Host -ForegroundColor $AssessmentColor "Journal reports of OME protected messages are currently not decrypted" 106 | Write-Host 107 | $Answer = Read-Host "Do you want to enable decrypted journal reports for OME protected messages? Type Y or N and press Enter to continue" 108 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 109 | Set-IRMConfiguration -JournalReportDecryptionEnabled $true 110 | Write-Host 111 | Write-Host -ForegroundColor $MessageColor "Journal reports will now be decrypted" 112 | } else { 113 | Write-Host 114 | Write-Host -ForegroundColor $AssessmentColor "Journal reports will remain encrypted" 115 | } 116 | } else { 117 | Write-Host 118 | Write-Host -ForegroundColor $MessageColor "Journal reports of OME messages are already being decrypted, no changes have been made" 119 | } 120 | 121 | 122 | -------------------------------------------------------------------------------- /Exchange Online/Disable-Forwarding.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script disables auto-forwarding 4 | ## Prerequisites: 5 | ## The tenant will need to include licensing for any Exchange Online Plan 6 | ## Connect to Exchange Online via PowerShell using MFA: 7 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | ## Disable external domain forwarding (globally disable auto-forwarding on the default remote domain): 14 | 15 | $RemoteDomainDefault = Get-RemoteDomain Default 16 | 17 | if ($RemoteDomainDefault.AutoForwardEnabled) { 18 | Write-Host 19 | Write-Host -ForegroundColor $AssessmentColor "Auto-forwarding to remote domains is currently allowed." 20 | Write-Host 21 | $Answer = Read-Host "Do you want to block auto-forwarding to remote domains? Type Y or N and press Enter to continue" 22 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 23 | Set-RemoteDomain Default -AutoForwardEnabled $false 24 | Write-Host 25 | Write-Host -ForegroundColor $MessageColor "Auto-forwarding to remote domains is now disabled" 26 | } else { 27 | Write-Host 28 | Write-Host -ForegroundColor $AssessmentColor "Auto-forwarding to remote domains will not be disabled"} 29 | } else { 30 | Write-Host 31 | Write-Host -ForegroundColor $MessageColor "Auto-forwarding to remote domains is already disabled" 32 | } 33 | 34 | Write-Host 35 | $Answer = Read-Host "Do you want to export to CSV a list of mailboxes that might be impacted by disabling auto-forward to remote domains? Type Y or N and press Enter to continue" 36 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 37 | ## Collect existing mailbox forwarding into CSV files at C:\temp\DomainName-MailboxForwarding.csv and DomainName-InboxRules.csv 38 | Write-Host 39 | Write-Host -ForegroundColor $AssessmentColor "Exporting known mailbox forwarders and inbox rules that auto-forward" 40 | $DefaultDomainName = Get-AcceptedDomain | Where-Object Default -EQ True 41 | Get-Mailbox -ResultSize Unlimited -Filter {(RecipientTypeDetails -ne "DiscoveryMailbox") -and ((ForwardingSmtpAddress -ne $null) -or (ForwardingAddress -ne $null))} | Select Identity,ForwardingSmtpAddress,ForwardingAddress | Export-Csv c:\temp\$DefaultDomainName-MailboxForwarding.csv -append 42 | foreach ($a in (Get-Mailbox -ResultSize Unlimited |select PrimarySMTPAddress)) {Get-InboxRule -Mailbox $a.PrimarySMTPAddress | ?{($_.ForwardTo -ne $null) -or ($_.ForwardAsAttachmentTo -ne $null) -or ($_.DeleteMessage -eq $true) -or ($_.RedirectTo -ne $null)} |select Name,Identity,ForwardTo,ForwardAsAttachmentTo, RedirectTo, DeleteMessage | Export-Csv c:\temp\$DefaultDomainName-InboxRules.csv -append } 43 | Write-Host 44 | Write-Host -ForegroundColor $AssessmentColor "After running this script, check the CSV files under C:\temp for a list of mail users who may be affected by disabling the ability to auto-forward messages to external domains" 45 | Write-Host 46 | } else { 47 | Write-Host 48 | Write-Host -ForegroundColor $MessageColor "Run the script again if you wish to export auto-forwarding mailboxes and inbox rules" 49 | Write-Host 50 | } 51 | 52 | 53 | ## End of script 54 | 55 | 56 | ## The rest of this script is optional, and commented out (use if you deem appropriate) 57 | ## Remove any existing mailbox forwarding rules that are in place: 58 | ## Get-Mailbox | Set-Mailbox -ForwardingAddress $null -ForwardingSmtpAddress $null 59 | 60 | ## DENY AUTO-FORWARDING FROM MAILBOX RULES VIA TRANSPORT RULE 61 | ## Creates a transport rule which will deny auto forwarding rules to external domains and reject the message with a notification to end-users 62 | ## $TransportRuleName = "External Forward Block" 63 | ## $rejectMessageText = "Mail forwarding to external domains is not permitted. If you have questions, please contact support." 64 | ## $ExternalForwardRule = Get-TransportRule | Where-Object {$_.Identity -contains $TransportRuleName} 65 | ## if (!$ExternalForwardRule) { 66 | ## Write-Output "External Forward Block rule not found, creating rule..." 67 | ## New-TransportRule -name $TransportRuleName -Priority 1 -SentToScope NotInOrganization -FromScope InOrganization -MessageTypeMatches AutoForward -RejectMessageEnhancedStatusCode 5.7.1 -RejectMessageReasonText $rejectMessageText 68 | ## } else {Write-Output "External forward block rule already exists."} 69 | 70 | ## Remove the ability for users to setup forwarding via the OWA portal 71 | ## Creates a new RBAC Role Assignment Policy 72 | ## $RoleName = "DenyForwarding" 73 | ## $DenyForwardRole = Get-ManagementRole | Where-Object {$_.Name -contains $RoleName} 74 | ## if (!$DenyForwardRole) { 75 | ## Write-Output "DenyForwarding role not found, creating role..." 76 | ## New-ManagementRole -Parent MyBaseOptions -Name $RoleName 77 | ## Set-ManagementRoleEntry DenyForwarding\Set-Mailbox -RemoveParameter -Parameters DeliverToMailboxAndForward,ForwardingAddress,ForwardingSmtpAddress 78 | ## New-RoleAssignmentPolicy -Name DenyForwardingRoleAssignmentPolicy -Roles DenyForwarding,MyContactInformation,MyRetentionPolicies,MyMailSubscriptions,MyTextMessaging,MyVoiceMail,MyDistributionGroupMembership,MyDistributionGroups,MyProfileInformation,MyTeamMailboxes,"My ReadWriteMailbox Apps","My Marketplace Apps","My Custom Apps" 79 | ## Set-RoleAssignmentPolicy -Identity DenyForwardingRoleAssignmentPolicy -IsDefault -Confirm:$false 80 | ## } else {Write-Output "DenyForwarding role already exists."} 81 | -------------------------------------------------------------------------------- /Exchange Online/Disable-SharedMbxSignOn.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Use this script to block sign-in for shared mailboxes 3 | ## You must connect to Exchange Online and Azure AD using Connect-EXOPSSession and Connect-MsolService before running this script 4 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 5 | ## https://docs.microsoft.com/en-us/powershell/module/msonline/connect-msolservice?view=azureadps-1.0 6 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 7 | 8 | 9 | $SharedMailboxes = Get-Mailbox -ResultSize Unlimited -Filter {RecipientTypeDetails -Eq "SharedMailbox"} 10 | 11 | Foreach ($user in $SharedMailboxes) { 12 | 13 | Set-MsolUser -UserPrincipalName $user.UserPrincipalName -BlockCredential $true 14 | 15 | } 16 | 17 | 18 | ## End of script 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Exchange Online/README.md: -------------------------------------------------------------------------------- 1 |

The Office 365 Email Security Checklist scripts

2 | 3 |

Description of the scripts:

4 | 5 |

Install-EXOStandardProtection.ps1: This script will configure your default EOP and MDO settings to match the Standard protection template 6 |

Advanced-TenantConfig.ps1: For customization of Exchange Online including many of the settings featured in other scripts: 7 |

Block-UnmanagedDownload.ps1 : This script configures the "Read-Only" Conditonal Access policy (additional config required) 8 |

Block-ConsumerStorageOWA.ps1 : This script disables 3rd party consumer storage locations in OWA 9 |

Configure-Auditing.ps1 : This script enables and helps you configure audit log age, etc. 10 |

Disable-Forwarding.ps1: This script will disable auto-forwarding and also output csv of existing forwarders to C:\temp 11 |

Disable-SharedMbxSignOn.ps1 : This script disables sign-in for shared mailboxes 12 |

Set-DeletedItemsRetention.ps1 : This script sets the deleted items retention value to max = 30 days (instead of default = 14) 13 |

Setup-DKIM.ps1 : This script helps with configuring DKIM; use: .\Setup-DKIM.ps1 -Domain "yourdomainhere.com" 14 | 15 | 16 |

Be sure to read the comments and review each script. You are responsible for your own implementation, use at your own risk. 17 |

These scripts follow the guide published at: https://www.itpromentor.com/email-security-checklist/ 18 |

19 | -------------------------------------------------------------------------------- /Exchange Online/Set-DeletedItemsRetention.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script will max out the retention period for deleted items in all Exchange Online mailboxes (the maximum configurable value is 30 days) 4 | ## Prerequisites: 5 | ## The tenant will require any Exchange Online plan 6 | ## Connect to Exchange Online via PowerShell using MFA: 7 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | Write-Host 14 | $CurrentRetention = (Get-Mailbox -ResultSize Unlimited).RetainDeletedItemsFor 15 | Write-Host -ForegroundColor $AssessmentColor "Current retention limit (in days and number of mailboxes):" 16 | $CurrentRetention | group | select name, count | ft 17 | Write-Host 18 | $Answer = Read-Host "By default Exchange Online retains deleted items for 14 days; would you like to enforce the maximum allowed value of 30 days for all mailboxes? Type Y or N and press Enter to continue" 19 | if ($Answer -eq 'y' -or $Answer -eq 'yes') { 20 | Get-Mailbox -ResultSize Unlimited | Set-Mailbox -RetainDeletedItemsFor 30 21 | Get-MailboxPlan | Set-MailboxPlan -RetainDeletedItemsFor 30 22 | Write-Host 23 | Write-Host -ForegroundColor $MessageColor "Deleted items will be retained for the maximum of 30 days for all mailboxes" 24 | } else { 25 | Write-Host 26 | Write-Host -ForegroundColor $AssessmentColor "The deleted items retention value has not been modified on any mailboxes" 27 | } 28 | 29 | 30 | ## End of script 31 | -------------------------------------------------------------------------------- /Exchange Online/Setup-ArchiveLegalHold.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script can be used to enable the archive mailbox, and/or litigation hold 4 | ## Prerequisites: 5 | ## Exchange Online plan 2 or the Exchange Online Archiving add-on 6 | ## Connect to Exchange Online via PowerShell using MFA: 7 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 8 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 9 | 10 | $MessageColor = "cyan" 11 | $AssessmentColor = "magenta" 12 | 13 | 14 | Write-Host 15 | $Answer = Read-Host "Do you want to configure Archiving and Litigation Hold features? NOTE: Requires Exchange Online Plan 2 or Exchange Online Archiving add-on; type Y or N and press Enter to Continue" 16 | if($Answer -eq 'y' -or $Answer -eq 'yes') { 17 | 18 | ## Check whether the auto-expanding archive feature is enabled, and if not, enable it 19 | $OrgConfig = Get-OrganizationConfig 20 | if ($OrgConfig.AutoExpandingArchiveEnabled) { 21 | Write-Host 22 | Write-Host -ForegroundColor $MessageColor "The Auto Expanding Archive feature is already enabled" 23 | } else { 24 | Set-OrganizationConfig -AutoExpandingArchive 25 | Write-Host 26 | Write-Host -ForegroundColor $MessageColor "The Auto Expanding Archive feature is now enabled" 27 | } 28 | 29 | ## Prompt whether or not to enable the Archive mailbox for all users 30 | Write-Host 31 | $ArchiveAnswer = Read-Host "Do you want to enable the Archive mailbox for all user mailboxes? NOTE: Works against cloud-only accounts; does not work against AD synchronized accounts. Type Y or N and press Enter to continue" 32 | if ($ArchiveAnswer -eq 'y'-or $ArchiveAnswer -eq 'yes') { 33 | Get-Mailbox -ResultSize Unlimited -Filter {ArchiveStatus -Eq "None" -AND RecipientTypeDetails -eq "UserMailbox"} | Enable-Mailbox -Archive 34 | Write-Host 35 | Write-Host -ForegroundColor $MessageColor "The Archive mailbox has been enabled for all user mailboxes" 36 | } Else { 37 | Write-Host 38 | Write-Host -ForegroundColor $AssessmentColor "The Archive mailbox will not be enabled for all user mailboxes" 39 | } 40 | 41 | ## Prompt whether or not to enable Litigation Hold for all mailboxes 42 | Write-Host 43 | $LegalHoldAnswer = Read-Host "Do you want to enable Litigation Hold for all mailboxes? Type Y or N and press Enter to continue" 44 | if ($LegalHoldAnswer -eq 'y' -or $LegalHoldAnswer -eq 'yes') { 45 | Get-Mailbox -ResultSize Unlimited -Filter {LitigationHoldEnabled -Eq "False" -AND RecipientTypeDetails -ne "DiscoveryMailbox"} | Set-Mailbox -LitigationHoldEnabled $True 46 | Write-Host 47 | Write-Host -ForegroundColor $MessageColor "Litigation Hold has been enabled for all mailboxes" 48 | } Else { 49 | Write-Host 50 | Write-Host -ForegroundColor $AssessmentColor "Litigation Hold will not be enabled for all mailboxes" 51 | } 52 | 53 | } Else { 54 | Write-Host 55 | Write-Host -ForegroundColor $AssessmentColor "Archiving and Litigation Hold will not be configured" 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Exchange Online/Setup-DKIM.ps1: -------------------------------------------------------------------------------- 1 | ## Script by Alex Fields, ITProMentor.com 2 | ## Description: 3 | ## This script can be used to help configure DKIM for Office 365 4 | ## Use: .\Setup-DKIM.ps1 -DomainName "yourdomainhere.com" 5 | ## If you do not specify the DomainName variable, the script will prompt you for it 6 | ## Prerequisites: 7 | ## The tenant will require any Exchange Online plan 8 | ## Connect to Exchange Online via PowerShell using MFA: 9 | ## https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps 10 | ## WARNING: Script provided as-is. Author is not responsible for its use and application. Use at your own risk. 11 | 12 | 13 | $MessageColor = "cyan" 14 | $AssessmentColor = "magenta" 15 | 16 | Param( 17 | $DomainName 18 | ) 19 | 20 | if($DomainName -eq $null -or $DomainName -eq ""){ 21 | Write-Host 22 | $DomainName = Read-Host -Prompt "Please specify the domain name" 23 | Write-Host 24 | } 25 | 26 | 27 | ## This line will return the CNAME record values for the specified domain name (Points to): 28 | Write-Host -ForegroundColor $MessageColor "Enter the (Points to) CNAME values in DNS for selector1._domainkey and selector2._domainkey:" 29 | Write-Host 30 | 31 | Get-DkimSigningConfig $DomainName | fl Domain,*cname 32 | 33 | ## Pause the script to allow time for entering DKIM records 34 | Write-Host 35 | Read-Host -Prompt "Enter the DKIM records, have a coffee and wait for several minutes while DNS propogates, and then press Enter to continue..." 36 | Write-Host 37 | ## This line will attempt to activate the DKIM service (CNAME records must be already be populated in DNS) 38 | 39 | ##If DKIM exists but not already enabled, enable it 40 | if (((get-dkimsigningconfig -identity $domainname -ErrorAction silent).enabled) -eq $False) {set-dkimsigningconfig -identity $domainname -enabled $true} 41 | ##If it doesn't exist - create new config 42 | if (!(get-dkimsigningconfig -identity $domainname -erroraction silent)) {New-DkimSigningConfig -DomainName $DomainName -Enabled $true} 43 | Write-Host 44 | 45 | ## End of script 46 | 47 | -------------------------------------------------------------------------------- /Incident Response/Export-ActivityByIPAddress.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports data from the Unified Audit Log for a specified IP address 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. You must have the ExchangeOnlineManagement PowerShell module installed in order to use this script, i.e.: 7 | 8 | Install-Module ExchangeOnlineManagement 9 | Connect-ExchangeOnline 10 | 11 | .NOTES 12 | FileName: Export-ActivitybyIPAddress.ps1 13 | Author: Alex Fields 14 | Created: June 2021 15 | Revised: June 2021 16 | 17 | #> 18 | ################################################################################################### 19 | <# 20 | ## Import module and Connect to Exchange Online 21 | Import-Module ExchangeOnlineManagement 22 | Connect-ExchangeOnline 23 | #> 24 | 25 | ## Define variables 26 | $OutputPath = "" 27 | $DaysAgo = "90" 28 | 29 | $CheckLog= (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled 30 | 31 | if (!$CheckLog) { 32 | Write-Host "The Unified Audit Log is not enabled in this tenant. You cannot export activities." -ForegroundColor Cyan 33 | 34 | } else { 35 | 36 | ## If OutputPath variable is not defined, prompt for it 37 | if (!$OutputPath) { 38 | Write-Host 39 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 40 | } 41 | 42 | ## If OutputPath does not exist, create it 43 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 44 | if (!$CheckOutputPath) { 45 | Write-Host 46 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 47 | mkdir $OutputPath 48 | } 49 | 50 | ## Set Start and End Dates 51 | $StartDate = (Get-Date).AddDays(-$DaysAgo) 52 | $EndDate = Get-Date 53 | 54 | ## Get Primary Domain Name (used in naming output files) 55 | $PrimaryDomain = Get-AcceptedDomain | Where-Object Default -eq $true 56 | $DomainName = $PrimaryDomain.DomainName 57 | 58 | 59 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 60 | if (!$CheckSubDir) { 61 | Write-Host 62 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 63 | mkdir $OutputPath\$DomainName 64 | } 65 | 66 | $IPAddress = Read-Host "Enter the IP address of interest" 67 | $History = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -IPAddresses $IPAddress -SessionCommand ReturnLargeSet 68 | 69 | if (!$History) { 70 | Write-Host 71 | Write-Host "There are no activities in the audit log for the time period specified" -ForegroundColor Cyan 72 | Write-Host 73 | } else { 74 | 75 | ## Output the events to CSV 76 | $History | Out-GridView 77 | $History | Export-Csv -Path $OutputPath\$DomainName\$IPAddress-AuditLogDetail.csv 78 | Write-Host 79 | Write-Host "See IP address activities in the OutputPath" -ForegroundColor Yellow 80 | Write-Host 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /Incident Response/Export-ActivityByUser.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports data from the Unified Audit Log for a specified user 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. You must have the ExchangeOnlineManagement PowerShell module installed in order to use this script, i.e.: 7 | 8 | Install-Module ExchangeOnlineManagement 9 | Connect-ExchangeOnline 10 | 11 | .NOTES 12 | FileName: Export-ActivityByUser.ps1 13 | Author: Alex Fields 14 | Created: June 2021 15 | Revised: June 2021 16 | 17 | #> 18 | ################################################################################################### 19 | <# 20 | ## Import module and Connect to Exchange Online 21 | Import-Module ExchangeOnlineManagement 22 | Connect-ExchangeOnline 23 | #> 24 | ############################################################# 25 | ## Gather the parameters 26 | ## You may set the parameters in the script or enter by prompt 27 | 28 | ## Define variables 29 | $OutputPath = "" 30 | $DaysAgo = "90" 31 | 32 | $CheckLog= (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled 33 | 34 | if (!$CheckLog) { 35 | Write-Host "The Unified Audit Log is not enabled in this tenant. You cannot export activities." -ForegroundColor Cyan 36 | Write-Host 37 | } else { 38 | 39 | 40 | ## If OutputPath variable is not defined, prompt for it 41 | if (!$OutputPath) { 42 | Write-Host 43 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 44 | } 45 | 46 | ## If OutputPath does not exist, create it 47 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 48 | if (!$CheckOutputPath) { 49 | Write-Host 50 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 51 | mkdir $OutputPath 52 | } 53 | 54 | ## Set Start and End Dates 55 | $StartDate = (Get-Date).AddDays(-$DaysAgo) 56 | $EndDate = Get-Date 57 | 58 | ## Get Primary Domain Name (used in naming output files) 59 | $PrimaryDomain = Get-AcceptedDomain | Where-Object Default -eq $true 60 | $DomainName = $PrimaryDomain.DomainName 61 | 62 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 63 | if (!$CheckSubDir) { 64 | Write-Host 65 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 66 | mkdir $OutputPath\$DomainName 67 | } 68 | 69 | $User = Read-Host "Enter the user's primary email address (UPN)" 70 | $History = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -UserIds $User -SessionCommand ReturnLargeSet 71 | 72 | if (!$History) { 73 | Write-Host 74 | Write-Host "There are no activities in the audit log for the time period specified" -ForegroundColor Cyan 75 | Write-Host 76 | } else { 77 | 78 | ## Output the events to CSV 79 | $History | Out-GridView 80 | $History | Export-Csv -Path $OutputPath\$DomainName\$User-AuditLogActivities.csv 81 | Write-Host 82 | Write-Host "See user activities in the OutputPath" -ForegroundColor Yellow 83 | Write-Host 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /Incident Response/Export-PrivilegedUserActions.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports several data points from the Azure AD Incident Response PowerShell module 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. Specify the primary $DomainName associated with the tenant in order to run the script, or it will prompt 7 | 4. You must have the AzureADIncidentResponse PowerShell module installed in order to use this script, i.e.: 8 | 9 | Install-Module AzureADIncidentResponse 10 | 11 | 12 | .NOTES 13 | FileName: Export-PrivilegedUserActions.ps1 14 | Author: Alex Fields 15 | Created: June 2021 16 | Revised: June 2021 17 | 18 | #> 19 | ################################################################################################### 20 | <# 21 | Import-Module AzureAD 22 | Import-Module AzureADIncidentResponse 23 | #> 24 | ############################################################# 25 | ## Gather the parameters 26 | ## You may set the parameters in the script or enter by prompt 27 | 28 | $DomainName = "" 29 | $OutputPath = "" 30 | 31 | ## If the OutputPath variable is undefined, prompt for input 32 | if (!$OutputPath) { 33 | Write-Host 34 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 35 | } 36 | 37 | ## If the output path does not exist, then create it 38 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 39 | if (!$CheckOutputPath) { 40 | Write-Host 41 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 42 | mkdir $OutputPath 43 | } 44 | 45 | ## If the DomainName variable is undefined, prompt for input 46 | if ($DomainName -eq "") { 47 | Write-Host 48 | $DomainName = Read-Host 'Enter the primary domain name associated with the tenant' 49 | } 50 | 51 | 52 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 53 | if (!$CheckSubDir) { 54 | Write-Host 55 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 56 | mkdir $OutputPath\$DomainName 57 | } 58 | 59 | 60 | ############################################################# 61 | ## Get the tenant ID and connect to Azure AD 62 | $TenantID = Get-AzureADIRTenantId -DomainName $DomainName 63 | Connect-AzureADIR -TenantId $TenantID 64 | ############################################################# 65 | 66 | $PrivUsers = Get-AzureADIRPrivilegedRoleAssignment -TenantId $TenantID | Where-Object RoleMemberObjectType -EQ User 67 | 68 | foreach ($User in $PrivUsers) { 69 | 70 | $DisplayToID = Get-AzureADIRDisplayNameToObjectId -DisplayName $User.RoleMemberName -ObjectType User 71 | 72 | $RoleMemberEmail = $User.RoleMemberMail 73 | 74 | $AuditDetail = Get-AzureADIRAuditActivity -TenantId $TenantID -InitiatedByUser $DisplayToID.ObjectId 75 | 76 | if (!$AuditDetail) { 77 | Write-Host 78 | } else { 79 | 80 | $AuditDetail | Export-Csv $OutputPath\$DomainName\$RoleMemberEmail-AADActivityDetail.csv 81 | 82 | } 83 | 84 | } 85 | 86 | Write-Host 87 | Write-Host "See the output in the domain subdirectory." -ForegroundColor Cyan 88 | Write-Host -------------------------------------------------------------------------------- /Incident Response/Export-PrivilegedUserSignIn.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports several data points from the Azure AD Incident Response PowerShell module 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. Specify the primary $DomainName associated with the tenant in order to run the script, or it will prompt 7 | 4. You must have the AzureADIncidentResponse PowerShell module installed in order to use this script, i.e.: 8 | 9 | Install-Module AzureADIncidentResponse 10 | 11 | 12 | .NOTES 13 | FileName: Export-PrivilegedUserSignIn.ps1 14 | Author: Alex Fields 15 | Created: June 2021 16 | Revised: June 2021 17 | 18 | #> 19 | ################################################################################################### 20 | <# 21 | Import-Module AzureAD 22 | Import-Module AzureADIncidentResponse 23 | #> 24 | ############################################################# 25 | ## Gather the parameters 26 | ## You may set the parameters in the script or enter by prompt 27 | 28 | $DomainName = "" 29 | $OutputPath = "" 30 | 31 | ## If the OutputPath variable is undefined, prompt for input 32 | if (!$OutputPath) { 33 | Write-Host 34 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 35 | } 36 | 37 | ## If the output path does not exist, then create it 38 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 39 | if (!$CheckOutputPath) { 40 | Write-Host 41 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 42 | mkdir $OutputPath 43 | } 44 | 45 | ## If the DomainName variable is undefined, prompt for input 46 | if ($DomainName -eq "") { 47 | Write-Host 48 | $DomainName = Read-Host 'Enter the primary domain name associated with the tenant' 49 | } 50 | 51 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 52 | if (!$CheckSubDir) { 53 | Write-Host 54 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 55 | mkdir $OutputPath\$DomainName 56 | } 57 | 58 | ############################################################# 59 | ## Get the tenant ID and connect to Azure AD 60 | $TenantID = Get-AzureADIRTenantId -DomainName $DomainName 61 | Connect-AzureADIR -TenantId $TenantID 62 | ############################################################# 63 | 64 | $PrivUsers = Get-AzureADIRPrivilegedRoleAssignment -TenantId $TenantID | Where-Object RoleMemberObjectType -EQ User 65 | 66 | foreach ($User in $PrivUsers) { 67 | 68 | $DisplayToID = Get-AzureADIRDisplayNameToObjectId -DisplayName $User.RoleMemberName -ObjectType User 69 | 70 | $RoleMemberEmail = $User.RoleMemberMail 71 | 72 | $SignInDetail = Get-AzureADIRSignInDetail -TenantId $TenantID -UserId $DisplayToID.ObjectId 73 | 74 | if (!$SignInDetail) { 75 | Write-Host 76 | } else { 77 | 78 | $SignInDetail | Export-Csv $OutputPath\$DomainName\$RoleMemberEmail-SignInDetail.csv 79 | 80 | } 81 | 82 | } 83 | 84 | Write-Host 85 | Write-Host "See the output in the domain subdirectory." -ForegroundColor Cyan 86 | Write-Host -------------------------------------------------------------------------------- /Incident Response/Export-SignInByIPAddress.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports several data points from the Azure AD Incident Response PowerShell module 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. Specify the primary $DomainName associated with the tenant in order to run the script, or it will prompt 7 | 4. You must have the AzureADIncidentResponse PowerShell module installed in order to use this script, i.e.: 8 | 9 | Install-Module AzureADIncidentResponse 10 | 11 | 12 | .NOTES 13 | FileName: Export-SignInByIPAddress.ps1 14 | Author: Alex Fields 15 | Created: June 2021 16 | Revised: June 2021 17 | 18 | #> 19 | ################################################################################################### 20 | <# 21 | Import-Module AzureAD 22 | Import-Module AzureADIncidentResponse 23 | #> 24 | ############################################################# 25 | ## Gather the parameters 26 | ## You may set the parameters in the script or enter by prompt 27 | 28 | $DomainName = "" 29 | $OutputPath = "" 30 | 31 | ## If the OutputPath variable is undefined, prompt for input 32 | if (!$OutputPath) { 33 | Write-Host 34 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 35 | } 36 | 37 | ## If the output path does not exist, then create it 38 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 39 | if (!$CheckOutputPath) { 40 | Write-Host 41 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 42 | mkdir $OutputPath 43 | } 44 | 45 | ## If the DomainName variable is undefined, prompt for input 46 | if ($DomainName -eq "") { 47 | Write-Host 48 | $DomainName = Read-Host 'Enter the primary domain name associated with the tenant' 49 | } 50 | 51 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 52 | if (!$CheckSubDir) { 53 | Write-Host 54 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 55 | mkdir $OutputPath\$DomainName 56 | } 57 | 58 | ############################################################# 59 | ## Get tenant ID and connect to Azure AD 60 | $TenantID = Get-AzureADIRTenantId -DomainName $DomainName 61 | Connect-AzureADIR -TenantId $TenantID 62 | ############################################################# 63 | 64 | $IPAddress = Read-Host "Enter the interesting IP Address" 65 | 66 | $SignInDetail = Get-AzureADIRSignInDetail -TenantId $TenantID -IpAddress $IPAddress 67 | 68 | if (!$SignInDetail) { 69 | Write-Host 70 | } else { 71 | 72 | $SignInDetail | Out-GridView 73 | $SignInDetail | Export-Csv $OutputPath\$DomainName\$IPAddress-SignInDetail.csv 74 | 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /Incident Response/Export-SignInByUser.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports several data points from the Azure AD Incident Response PowerShell module 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. Specify the primary $DomainName associated with the tenant in order to run the script, or it will prompt 7 | 4. You must have the AzureADIncidentResponse PowerShell module installed in order to use this script, i.e.: 8 | 9 | Install-Module AzureADIncidentResponse 10 | 11 | 12 | .NOTES 13 | FileName: Export-SignInByUser.ps1 14 | Author: Alex Fields 15 | Created: June 2021 16 | Revised: June 2021 17 | 18 | #> 19 | ################################################################################################### 20 | <# 21 | Import-Module AzureAD 22 | Import-Module AzureADIncidentResponse 23 | #> 24 | ############################################################# 25 | ## Gather the parameters and set the working directory 26 | ## You may set the parameters in the script or enter by prompt 27 | 28 | $DomainName = "" 29 | $OutputPath = "" 30 | 31 | ## If the OutputPath variable is undefined, prompt for input 32 | if (!$OutputPath) { 33 | Write-Host 34 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 35 | } 36 | 37 | ## If the output path does not exist, then create it 38 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 39 | if (!$CheckOutputPath) { 40 | Write-Host 41 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 42 | mkdir $OutputPath 43 | } 44 | 45 | ## If the DomainName variable is undefined, prompt for input 46 | if ($DomainName -eq "") { 47 | Write-Host 48 | $DomainName = Read-Host 'Enter the primary domain name associated with the tenant' 49 | } 50 | 51 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 52 | if (!$CheckSubDir) { 53 | Write-Host 54 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 55 | mkdir $OutputPath\$DomainName 56 | } 57 | 58 | ############################################################# 59 | ## Get the tenant ID and connect to Azure AD 60 | $TenantID = Get-AzureADIRTenantId -DomainName $DomainName 61 | Connect-AzureADIR -TenantId $TenantID 62 | 63 | ############################################################# 64 | 65 | $User = Read-Host "Enter the user's primary email address (UPN)" 66 | 67 | $DisplayName = (Get-AzureADUser -ObjectId $User).DisplayName 68 | 69 | $DisplayToID = Get-AzureADIRDisplayNameToObjectId -DisplayName $DisplayName -ObjectType User 70 | 71 | $SignInDetail = Get-AzureADIRSignInDetail -TenantId $TenantID -UserId $DisplayToID.ObjectId 72 | 73 | if (!$SignInDetail) { 74 | Write-Host 75 | } else { 76 | 77 | $SignInDetail | Out-GridView 78 | $SignInDetail | Export-Csv $OutputPath\$DomainName\$User-SignInDetail.csv 79 | 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /Incident Response/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## Incident Response Scripts 2 | 3 | I have found these scripts to be useful during Incident Response in Microsoft 365. 4 | 5 | 1) Start-AzureADIRCollection.ps1: Use this script to begin a collection of data against a tenant. You must have the AzureADIncidentResponse module installed. 6 | 7 | 2) Start-UnifiedAuditLogIRCollection.ps1: Use this script to get interesting events exported from the Unified Audit Log. You must have the ExchangeOnlineManagement module installed. 8 | 9 | 3) Export-PrivilegedUserSignIn.ps1: Use this script to investigate the sign-in activities from privileged user accounts. You must have the AzureADIncidentResponse module installed. 10 | 11 | 4) Export-PrivilegedUserActions.ps1: Use this script to investigate the Azure AD audit log for activities performed by privileged users. You must have the AzureADIncidentResponse module installed. 12 | 13 | 5) Export-SignInByUser.ps1: Use this script to get available sign-in data for the specified username. You must have the AzureADIncidentResponse module installed. 14 | 15 | 6) Export-SignInByIpAddress.ps1: Use this script to get available sign-in data for the specified IP address. You must have the AzureADIncidentResponse module installed. 16 | 17 | 7) Export-ActivityByUser.ps1: Use this script to get activities from the Unified audit log for the specified username. You must have the ExchangeOnlineManagement module installed. 18 | 19 | 8) Export-ActivityByIpAddress.ps1: Use this script to get available sign-in data for the specified IP address. You must have the ExchangeOnlineManagement module installed. 20 | 21 | 9) Install-AzureADProtectionAlerts.ps1: Use this script to import alert policies for Azure AD monitoring. You must have the ExchangeOnlineManagement module installed. 22 | 23 | 10) Remediate-CompromisedUser.ps1: Use this script to disable and revoke access, and/or reset a user's password and re-enable access. You must have the AzureAD module installed. There is also an option to reset all admin passwords at once, excluding breakglass and current user account (this option requires the AzureADIncidentResponse module). 24 | 25 | -------------------------------------------------------------------------------- /Incident Response/Remediate-CompromisedUser.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 5 | WARNING: Make sure you understand what you're doing before running this script! 6 | 7 | 1. This script will disable and revoke all refresh tokens for the specified user account 8 | 2. You will also reset the password and optionally re-enable the account 9 | 3. There is also an option to reset all admin passwords to random complex GUIDs (this requires the AzureADIncidentResponse module) 10 | 4. You must connect to Azure AD before running this script, i.e.: 11 | 12 | Connect-AzureAD 13 | 14 | .NOTES 15 | FileName: Remediate-CompromisedUser.ps1 16 | Author: Alex Fields 17 | Created: June 2021 18 | Revised: June 2021 19 | 20 | #> 21 | ################################################################################################### 22 | 23 | Import-Module AzureAD 24 | 25 | Write-Host "Do you want to disable an account or reset and re-enable an account?" -ForegroundColor Cyan 26 | Write-Host " 1. Disable an account" -ForegroundColor Cyan 27 | Write-Host " 2. Reset password and re-enable an account" -ForegroundColor Cyan 28 | Write-Host " 3. Panic button: Reset all my admin accounts NOW!" -ForegroundColor Cyan 29 | 30 | $Choice = Read-Host "Type your selection: 1, 2, or 3 and press Enter" 31 | 32 | if ($Choice -eq "1") { 33 | #Get the Username and ObjectID 34 | $UserEmail = Read-Host "Enter the user's primary email address (UPN)" 35 | $User = Get-AzureADUser -ObjectId $UserEmail 36 | 37 | #Disable the user's account and revoke all refresh tokens 38 | Write-Host 39 | Write-Host "Disabling the user's account and revoking all refresh tokens..." -ForegroundColor Yellow 40 | Set-AzureADUser -ObjectId $UserEmail -AccountEnabled $false 41 | Revoke-AzureADUserAllRefreshToken -ObjectId $UserEmail 42 | 43 | #Disable the user's registered devices 44 | Write-Host 45 | Write-Host "Optional: Do you want to disable the user's registered devices?" -ForegroundColor Cyan 46 | Write-Host 47 | $Answer = Read-Host "Type Y or N and press Enter." 48 | 49 | if ($Answer -eq "y") { 50 | Write-Host 51 | Write-Host "Disabling the user's registered devices..." -ForegroundColor Yellow 52 | Get-AzureADUserRegisteredDevice -ObjectId $UserEmail | Set-AzureADDevice -AccountEnabled $false 53 | } else { 54 | Write-Host 55 | Write-Host "The user's registered devices will not be disabled." -ForegroundColor Cyan 56 | } 57 | } 58 | 59 | if ($Choice -eq "2") { 60 | #Get the Username and ObjectID 61 | $UserEmail = Read-Host "Enter the user's primary email address (UPN)" 62 | $User = Get-AzureADUser -ObjectId $UserEmail 63 | 64 | #Change the password quickly to a random string (guid) 65 | Write-Host 66 | Write-Host "Changing the user's password to a random string..." -ForegroundColor Yellow 67 | Write-Host 68 | Set-AzureADUserPassword -ObjectId $User.ObjectId -Password (ConvertTo-SecureString (New-Guid).Guid -AsPlainText -Force) 69 | 70 | #Change the password a second time to a string of your choosing: 71 | Write-Host "You may now change the user's password to a value of your choosing." -ForegroundColor Yellow 72 | Write-Host 73 | $GetPassword = Read-Host "Enter the new password" 74 | $Password = ConvertTo-SecureString $GetPassword -AsPlainText -Force 75 | Set-AzureADUserPassword -ObjectId $User.ObjectId -Password $Password -ForceChangePasswordNextLogin $true 76 | Write-Host 77 | 78 | $Answer = Read-Host "Do you want to re-enable the user's account now? Type Y or N and press ENTER" 79 | Write-Host 80 | 81 | if ($Answer -eq "y") { 82 | Set-AzureADUser -ObjectId $UserEmail -AccountEnabled $true 83 | Write-Host "User's account has been re-enabled. User must change password on next login." -ForegroundColor Yellow 84 | Write-Host 85 | } else 86 | { 87 | Write-Host "No further action will be taken. Account is still disabled." -ForegroundColor Yellow 88 | Write-Host 89 | } 90 | 91 | #Enable the user's registered devices 92 | Write-Host "Optional: Do you want to re-enable the user's registered devices?" -ForegroundColor Cyan 93 | Write-Host 94 | $Answer = Read-Host "Type Y or N and press Enter." 95 | 96 | if ($Answer -eq "y") { 97 | Write-Host 98 | Write-Host "Re-enabling the user's registered devices..." -ForegroundColor Yellow 99 | Get-AzureADUserRegisteredDevice -ObjectId $UserEmail | Set-AzureADDevice -AccountEnabled $true 100 | } else { 101 | Write-Host 102 | Write-Host "The user's registered devices will not be re-enabled." -ForegroundColor Cyan 103 | } 104 | 105 | 106 | } 107 | 108 | if ($Choice -eq "3") { 109 | ## Credit for this section goes to Daniel Chronlund's DCToolBox PowerShell module. 110 | Write-Host 111 | Write-Host "You must have the Azure AD Incident Response module installed to use this option." -ForegroundColor Cyan 112 | Import-Module AzureADIncidentResponse -ErrorAction Stop 113 | Write-Host 114 | Write-Host "Warning: You are about to reset all of your admin passwords to randomly generated GUIDs." -ForegroundColor Yellow 115 | Write-Host "You may specify one other 'breakglass' account besides the current account to exclude from this process." -ForegroundColor Yellow 116 | Write-Host "Are you sure you want to continue?" -ForegroundColor Yellow 117 | $Answer = Read-Host "Type Y or N and press Enter to continue" 118 | 119 | if ($Answer -eq "y") { 120 | ############################################################# 121 | ## Get the tenant ID and connect to Azure AD 122 | $Domain = Get-AzureADDomain | where-object IsDefault -eq $true 123 | $TenantID = Get-AzureADIRTenantId -DomainName $Domain.Name 124 | Connect-AzureADIR -TenantId $TenantID 125 | ############################################################# 126 | 127 | ## Get the current user running PowerShell against Azure AD. 128 | Write-Host 129 | Write-Host "Getting the current Azure AD user to exclude from the reset process." -ForegroundColor Cyan 130 | $CurrentUser = (Get-AzureADCurrentSessionInfo).Account.Id 131 | 132 | ## Get the additional breakglass user: 133 | Write-Host "Specify one additional Azure AD breakglass account below." -ForegroundColor Cyan 134 | $BreakGlassUser = Read-Host "Enter the UPN of your breakglass account and press Enter to continue" 135 | 136 | Write-Host 137 | Write-Host "Getting Azure AD privileged users" -ForegroundColor Cyan 138 | $PrivUsers = Get-AzureADIRPrivilegedRoleAssignment -TenantId $TenantID | Where-Object RoleMemberObjectType -EQ User 139 | 140 | ## Loop through admins and set new complex passwords (using generated GUIDs). 141 | foreach ($User in $PrivUsers) { 142 | if ($User.RoleMemberUPN -notin $BreakGlassUser -and $User.RoleMemberUPN -ne $CurrentUser) { 143 | Write-Host "Setting new password and revoking current tokens for $($User.RoleMemberUPN)..." -ForegroundColor Yellow 144 | Revoke-AzureADUserAllRefreshToken -ObjectId $User.RoleMemberUPN 145 | Set-AzureADUserPassword -ObjectId $User.RoleMemberUPN -Password (ConvertTo-SecureString (New-Guid).Guid -AsPlainText -Force) 146 | Set-AzureADUserPassword -ObjectId $User.RoleMemberUPN -Password (ConvertTo-SecureString (New-Guid).Guid -AsPlainText -Force) 147 | } else { 148 | Write-Host "Skipping $($User.RoleMemberUPN)!" -ForegroundColor Cyan 149 | } 150 | } 151 | Write-Host 152 | Write-Host "Admin passwords have been changed." -ForegroundColor Cyan 153 | Write-Host "Note: You must manually reset the passwords again and help the users get back into their accounts." -ForegroundColor Yellow 154 | Write-Host "All admin users are advised to check their MFA methods at https://aka.ms/mysecurityinfo after regaining access." -ForegroundColor Yellow 155 | } else { 156 | Write-Host 157 | Write-Host "Exiting script. No changes have been made." -ForegroundColor Cyan 158 | } 159 | } 160 | 161 | Write-Host 162 | Write-Host "Script complete" -ForegroundColor Cyan 163 | Write-Host -------------------------------------------------------------------------------- /Incident Response/Start-AzureADIRCollection.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | 1. This script exports several data points from the Azure AD Incident Response PowerShell module 5 | 2. You can set the Output Path using the variable $OutputPath, or just run the script and it will prompt 6 | 3. Specify the primary $DomainName associated with the tenant in order to run the script, or it will prompt 7 | 4. See additional examples of the AzureADIR functions in the comments at the end of the script 8 | 5. You must have the AzureADIncidentResponse PowerShell module installed in order to use this script, i.e.: 9 | 10 | Install-Module AzureADIncidentResponse 11 | 12 | 13 | .NOTES 14 | FileName: Start-AzureADIRCollection.ps1 15 | Author: Alex Fields 16 | Created: June 2021 17 | Revised: June 2021 18 | 19 | #> 20 | ################################################################################################### 21 | 22 | Import-Module AzureAD 23 | Import-Module AzureADIncidentResponse 24 | 25 | ############################################################# 26 | ## Gather the parameters 27 | ## You may set the parameters in the script or enter by prompt 28 | 29 | $DomainName = "" 30 | $OutputPath = "" 31 | 32 | 33 | ## If the OutputPath variable is undefined, prompt for input 34 | if (!$OutputPath) { 35 | Write-Host 36 | $OutputPath = Read-Host 'Enter the output path, e.g. C:\IROutput' 37 | } 38 | 39 | ## If the output path does not exist, then create it 40 | $CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue 41 | if (!$CheckOutputPath) { 42 | Write-Host 43 | Write-Host "Output path does not exist, so the directory will be created." -ForegroundColor Yellow 44 | mkdir $OutputPath 45 | } 46 | 47 | ## If the DomainName variable is undefined, prompt for input 48 | if ($DomainName -eq "") { 49 | Write-Host 50 | $DomainName = Read-Host 'Enter the primary domain name associated with the tenant' 51 | } 52 | 53 | $CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue 54 | if (!$CheckSubDir) { 55 | Write-Host 56 | Write-Host "Domain sub-directory does not exist, so the sub-directory will be created." -ForegroundColor Yellow 57 | mkdir $OutputPath\$DomainName 58 | } 59 | 60 | ## Change directory to the OutputPath 61 | cd $OutputPath\$DomainName 62 | 63 | ############################################################# 64 | ## Get the tenant ID and connect to Azure AD 65 | $TenantID = Get-AzureADIRTenantId -DomainName $DomainName 66 | Connect-AzureADIR -TenantId $TenantID 67 | ############################################################# 68 | 69 | ## Get a current list of Azure AD Privileged role assignments 70 | Get-AzureADIRPrivilegedRoleAssignment -TenantId $TenantID -CsvOutput 71 | 72 | ## Gets two lists of applications with assigned permissions: delegated (user) permissions and application permissions 73 | Get-AzureADIRPermission -TenantId $TenantID -CsvOutput 74 | 75 | ## Get a current list of Azure AD users and make recommendations on how to improve their MFA stance 76 | Get-AzureADIRMfaAuthMethodAnalysis -TenantId $TenantID -LocationInfo -CsvOutput 77 | 78 | ## Gets the last interactive sign-in activity for all users in the tenant 79 | Get-AzureADIRUserLastSignInActivity -TenantId $TenantID -All -GuestInfo -CsvOutput 80 | 81 | 82 | ## Get a list of Azure AD users with MFA usage location and phone number 83 | $PhoneToLocationCheck = Get-AzureADIRMfaPhoneToLocationCheck -TenantId $TenantID 84 | if (!$PhoneToLocationCheck) { 85 | Write-Host "There is no data returned for the function Get-AzureADIRMfaPhoneToLocationCheck" -ForegroundColor Cyan 86 | } else { 87 | Get-AzureADIRMfaPhoneToLocationCheck -TenantId $TenantID -CsvOutput 88 | } 89 | 90 | ## Gets user risk dismissals for the target tenant 91 | $UserRiskDismissCheck = Get-AzureADIRDismissedUserRisk -TenantId $TenantID 92 | if (!$UserRiskDismissCheck) { 93 | Write-Host "There is no data returned for the function Get-AzureADIRDismissedUserRisk" -ForegroundColor Cyan 94 | } else { 95 | Get-AzureADIRDismissedUserRisk -TenantId $TenantID -CsvOutput 96 | } 97 | 98 | ## Gets Self-service password reset usage history for the target tenant 99 | $SsprHistoryCheck = Get-AzureADIRSsprUsageHistory -TenantId $TenantID 100 | if (!$SsprHistoryCheck) { 101 | Write-Host "There is no data returned for the function Get-AzureADIRSsprUsageHistory" -ForegroundColor Cyan 102 | } else { 103 | Get-AzureADIRSsprUsageHistory -TenantId $TenantID -CsvOutput 104 | } 105 | 106 | ## Get Azure AD Conditional Access policies 107 | $CAPolicy = Get-AzureADIRConditionalAccessPolicy -TenantId $TenantID 108 | if (!$CAPolicy) { 109 | Write-Host "There is no data returned for the function Get-AzureADIRConditionalAccessPolicy" -ForegroundColor Cyan 110 | } else { 111 | Get-AzureADIRConditionalAccessPolicy -TenantId $TenantID -All -XmlOutput 112 | } 113 | 114 | ###################################################################### 115 | Write-Host "Please review the files in your output directory" -ForegroundColor Cyan 116 | Write-Host 117 | Write-Host "Script completed." -ForegroundColor Cyan 118 | Write-Host 119 | 120 | <# 121 | ############################################################# 122 | ## More Examples; I encourage you to use and explore the various AzureADIR functions 123 | 124 | ############################################################# 125 | ## Collect Azure AD Audit logs by category 126 | 127 | Get-AzureADIRAuditActivity -TenantId $TenantID -Category "DirectoryManagement" | Out-GridView 128 | 129 | Get-AzureADIRAuditActivity -TenantId $TenantID -Category "UserManagement" | Out-GridView 130 | 131 | Get-AzureADIRAuditActivity -TenantId $TenantID -Category "RoleManagement" | Out-GridView 132 | 133 | Get-AzureADIRAuditActivity -TenantId $TenantID -Category "ApplicationManagement" | Out-GridView 134 | 135 | 136 | ############################################################# 137 | ## Collect Azure AD Audit logs for specific activities 138 | 139 | ## Gets new MFA method registrations 140 | Get-AzureADIRAuditActivity -TenantId $TenantID -ActivityDisplayName "User registered security info" | Out-GridView 141 | 142 | ## Gets newly added applications 143 | Get-AzureADIRAuditActivity -TenantId $TenantID -ActivityDisplayName ("Add application") | Out-GridView 144 | 145 | ## Gets a list of newly added application permissions 146 | Get-AzureADIRAuditActivity -TenantId $TenantID -ActivityDisplayName ("Add app role assignment to service principal") | Out-GridView 147 | 148 | ## Gets a list of newly added delegated user permissions 149 | Get-AzureADIRAuditActivity -TenantId $TenantID -ActivityDisplayName ("Add delegated permission grant") | Out-GridView 150 | 151 | ## Gets a list of newly consented application permissions 152 | Get-AzureADIRAuditActivity -TenantId $TenantID -ActivityDisplayName ("Consent to application") | Out-GridView 153 | 154 | ############################################################# 155 | ## Gets stale user accounts not signed in within last 30 days (including guests) 156 | Get-AzureADIRUserLastSignInActivity -TenantId $TenantID -StaleThreshold 30 -GuestInfo | Export-Csv -Path $OutputPath\$DomainName\AADLog_StaleAccountsLastSignIn.csv 157 | 158 | ############################################################# 159 | 160 | 161 | 162 | #> -------------------------------------------------------------------------------- /Incident Response/permissiontable.csv: -------------------------------------------------------------------------------- 1 | Type,Permission,Risk,Reason 2 | Delegated,Mail.ReadBasic,Medium,DataExfiltration 3 | Delegated,Mail,High,Phishing 4 | Delegated,Contacts,High,Phishing 5 | Delegated,MailboxSettings,High,Phishing 6 | Delegated,People,High,Phishing 7 | Delegated,Files,High,Phishing 8 | Delegated,Notes,High,Phishing 9 | Delegated,Directory.AccessAsUser.All,High,Phishing 10 | Delegated,user_impersonation,High,Phishing 11 | Delegated,Application.ReadWrite.All,High,BroadImpact 12 | Delegated,Directory.ReadWrite.All,High,BroadImpact 13 | Delegated,Domain.ReadWrite.All,High,BroadImpact 14 | Delegated,EduRoster.ReadWrite.All,High,BroadImpact 15 | Delegated,Group.ReadWrite.All,High,BroadImpact 16 | Delegated,Member.Read.Hidden,High,BroadImpact 17 | Delegated,RoleManagement.ReadWrite.Directory,High,BroadImpact 18 | Delegated,User.ReadWrite.All,High,BroadImpact 19 | Delegated,User.ManageCreds.All,High,BroadImpact 20 | Application,Mail,High,Phishing 21 | Application,Contacts,High,Phishing 22 | Application,MailboxSettings,High,Phishing 23 | Application,People,High,Phishing 24 | Application,Files,High,Phishing 25 | Application,Notes,High,Phishing 26 | Application,Directory.AccessAsUser.All,High,Phishing 27 | Application,user_impersonation,High,Phishing 28 | Application,Application.ReadWrite.All,High,BroadImpact 29 | Application,Directory.ReadWrite.All,High,BroadImpact 30 | Application,Domain.ReadWrite.All,High,BroadImpact 31 | Application,EduRoster.ReadWrite.All,High,BroadImpact 32 | Application,Group.ReadWrite.All,High,BroadImpact 33 | Application,Member.Read.Hidden,High,BroadImpact 34 | Application,RoleManagement.ReadWrite.Directory,High,BroadImpact 35 | Application,User.ReadWrite.All,High,BroadImpact 36 | Application,User.ManageCreds.All,High,BroadImpact 37 | Delegated,User.Read,Low,Common pattern 38 | Delegated,User.ReadBasic.All,Low,Common pattern 39 | Delegated,open_id,Low,Common pattern 40 | Delegated,email,Low,Common pattern 41 | Delegated,profile,Low,Common pattern 42 | Delegated,offline_access,Low,Common pattern when used with other low permissions -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Microsoft 365 Setup Guide.onepkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanvfields/Microsoft-365/6be47eaa43899b34594c9c02c3dfd46d765c4d6f/Microsoft 365 Setup Guide.onepkg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft-365 2 | Scripts and other resources to help configure Microsoft 365. Latest and greatest scripts are located in the zip files in this directory: 3 | - ZeroTrustScripts.zip: Corresponds to the scripts described in my Zero Trust Guide for the SMB, including Conditional Access baselines. 4 | - ThreatDefenseScripts.zip: Corresponds to the scripts described in my Threat Defense Guide for the SMB, including Protection alerts, Exchange Online, Microsoft Defender for Office 365, and more. 5 | - DataProtectionScripts.zip: Corresponds to the scripts described in my Data Protection Guide for the SMB. 6 | 7 | ## Azure AD 8 | Legacy; no longer updating this directory. 9 | 10 | ## Exchange Online 11 | Legacy; see ThreatDefenseScripts.zip for latest and greatest versions of these. The Office 365 Email Security Checklist: For anyone with an Exchange Online subscription for Email hosted in Office 365, start here. Scripts from this guide are located in the Exchange Online folder. 12 | 13 | ## Incident Response 14 | These scripts I have found to to be useful during Incident Response. 15 | 16 | ## mggraph-samples 17 | These scripts utilize the newer Graph SDK PowerShell module, and replace the scripts I had previously maintained in this repo. 18 | 19 | ## Setup Intune 20 | Legacy; no longer updating this directory. 21 | 22 | ## Windows 10 23 | Legacy; no longer updating this directory. 24 | 25 | -------------------------------------------------------------------------------- /Setup Intune/Get-DeviceEnrollmentRestrictions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | # Returns all device enrollment configurations configured in Intune and then filters on Default Platform Restrictions 4 | $DeviceEnrollmentConfigurations = Get-DeviceEnrollmentConfigurations 5 | 6 | $PlatformRestrictions = ($DeviceEnrollmentConfigurations | Where-Object { ($_.id).contains("DefaultPlatformRestrictions") }).id 7 | 8 | or 9 | 10 | $PlatformRestrictions = ($DeviceEnrollmentConfigurations | Where-Object { ($_.id).contains("StandardRestrictions") }).id 11 | 12 | 13 | #> 14 | 15 | 16 | <# 17 | 18 | .COPYRIGHT 19 | Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 20 | See LICENSE in the project root for license information. 21 | 22 | #> 23 | 24 | #################################################### 25 | 26 | function Get-AuthToken { 27 | 28 | <# 29 | .SYNOPSIS 30 | This function is used to authenticate with the Graph API REST interface 31 | .DESCRIPTION 32 | The function authenticate with the Graph API Interface with the tenant name 33 | .EXAMPLE 34 | Get-AuthToken 35 | Authenticates you with the Graph API interface 36 | .NOTES 37 | NAME: Get-AuthToken 38 | #> 39 | 40 | [cmdletbinding()] 41 | 42 | param 43 | ( 44 | [Parameter(Mandatory=$true)] 45 | $User 46 | ) 47 | 48 | $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User 49 | 50 | $tenant = $userUpn.Host 51 | 52 | Write-Host "Checking for AzureAD module..." 53 | 54 | $AadModule = Get-Module -Name "AzureAD" -ListAvailable 55 | 56 | if ($AadModule -eq $null) { 57 | 58 | Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" 59 | $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable 60 | 61 | } 62 | 63 | if ($AadModule -eq $null) { 64 | write-host 65 | write-host "AzureAD Powershell module not installed..." -f Red 66 | write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow 67 | write-host "Script can't continue..." -f Red 68 | write-host 69 | exit 70 | } 71 | 72 | # Getting path to ActiveDirectory Assemblies 73 | # If the module count is greater than 1 find the latest version 74 | 75 | if($AadModule.count -gt 1){ 76 | 77 | $Latest_Version = ($AadModule | select version | Sort-Object)[-1] 78 | 79 | $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } 80 | 81 | # Checking if there are multiple versions of the same module found 82 | 83 | if($AadModule.count -gt 1){ 84 | 85 | $aadModule = $AadModule | select -Unique 86 | 87 | } 88 | 89 | $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 90 | $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" 91 | 92 | } 93 | 94 | else { 95 | 96 | $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 97 | $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" 98 | 99 | } 100 | 101 | [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null 102 | 103 | [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null 104 | 105 | $clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" 106 | 107 | $redirectUri = "urn:ietf:wg:oauth:2.0:oob" 108 | 109 | $resourceAppIdURI = "https://graph.microsoft.com" 110 | 111 | $authority = "https://login.microsoftonline.com/$Tenant" 112 | 113 | try { 114 | 115 | $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority 116 | 117 | # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx 118 | # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession 119 | 120 | $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" 121 | 122 | $userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($User, "OptionalDisplayableId") 123 | 124 | $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result 125 | 126 | # If the accesstoken is valid then create the authentication header 127 | 128 | if($authResult.AccessToken){ 129 | 130 | # Creating header for Authorization token 131 | 132 | $authHeader = @{ 133 | 'Content-Type'='application/json' 134 | 'Authorization'="Bearer " + $authResult.AccessToken 135 | 'ExpiresOn'=$authResult.ExpiresOn 136 | } 137 | 138 | return $authHeader 139 | 140 | } 141 | 142 | else { 143 | 144 | Write-Host 145 | Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red 146 | Write-Host 147 | break 148 | 149 | } 150 | 151 | } 152 | 153 | catch { 154 | 155 | write-host $_.Exception.Message -f Red 156 | write-host $_.Exception.ItemName -f Red 157 | write-host 158 | break 159 | 160 | } 161 | 162 | } 163 | 164 | #################################################### 165 | 166 | Function Get-DeviceEnrollmentConfigurations(){ 167 | 168 | <# 169 | .SYNOPSIS 170 | This function is used to get Deivce Enrollment Configurations from the Graph API REST interface 171 | .DESCRIPTION 172 | The function connects to the Graph API Interface and gets Device Enrollment Configurations 173 | .EXAMPLE 174 | Get-DeviceEnrollmentConfigurations 175 | Returns Device Enrollment Configurations configured in Intune 176 | .NOTES 177 | NAME: Get-DeviceEnrollmentConfigurations 178 | #> 179 | 180 | [cmdletbinding()] 181 | 182 | $graphApiVersion = "Beta" 183 | $Resource = "deviceManagement/deviceEnrollmentConfigurations" 184 | 185 | try { 186 | 187 | $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" 188 | (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value 189 | 190 | } 191 | 192 | catch { 193 | 194 | $ex = $_.Exception 195 | $errorResponse = $ex.Response.GetResponseStream() 196 | $reader = New-Object System.IO.StreamReader($errorResponse) 197 | $reader.BaseStream.Position = 0 198 | $reader.DiscardBufferedData() 199 | $responseBody = $reader.ReadToEnd(); 200 | Write-Host "Response content:`n$responseBody" -f Red 201 | Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" 202 | write-host 203 | break 204 | 205 | } 206 | 207 | } 208 | 209 | #################################################### 210 | 211 | #region Authentication 212 | 213 | write-host 214 | 215 | # Checking if authToken exists before running authentication 216 | if($global:authToken){ 217 | 218 | # Setting DateTime to Universal time to work in all timezones 219 | $DateTime = (Get-Date).ToUniversalTime() 220 | 221 | # If the authToken exists checking when it expires 222 | $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes 223 | 224 | if($TokenExpires -le 0){ 225 | 226 | write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow 227 | write-host 228 | 229 | # Defining User Principal Name if not present 230 | 231 | if($User -eq $null -or $User -eq ""){ 232 | 233 | $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" 234 | Write-Host 235 | 236 | } 237 | 238 | $global:authToken = Get-AuthToken -User $User 239 | 240 | } 241 | } 242 | 243 | # Authentication doesn't exist, calling Get-AuthToken function 244 | 245 | else { 246 | 247 | if($User -eq $null -or $User -eq ""){ 248 | 249 | $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" 250 | Write-Host 251 | 252 | } 253 | 254 | # Getting the authorization token 255 | $global:authToken = Get-AuthToken -User $User 256 | 257 | } 258 | 259 | #endregion 260 | 261 | #################################################### 262 | 263 | $DeviceEnrollmentConfigurations = Get-DeviceEnrollmentConfigurations 264 | 265 | $DeviceEnrollmentConfigurations | Where-Object { ($_.id).contains("DefaultPlatformRestrictions") } -------------------------------------------------------------------------------- /Setup Intune/README.md: -------------------------------------------------------------------------------- 1 | # Scripts to setup Intune: 2 | 3 | NOTE: ALL SCRIPTS IN THIS DIRECTORY ARE OBSOLETE AND NO LONGER UPDATED. 4 | FOR THE LATEST, PLEASE SEE: https://github.com/vanvfields/Microsoft-365/tree/master/mggraph-samples 5 | 6 | 7 | -------------------------------------------------------------------------------- /Setup Intune/Set-MDMAuthority.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script will set the default MDM authority to Intune if it is not already 5 | 6 | 7 | .HOW-TO 8 | 1. To install the module use: Install-Module Microsoft.Graph.Intune 9 | 10 | .DETAILS 11 | FileName: Set-MDMAuthority.ps1 12 | Author: Alex Fields, ITProMentor.com 13 | Created: September 2019 14 | Updated: January 2021 15 | 16 | #> 17 | ################################################################################################### 18 | 19 | 20 | #Connect to MS Graph API 21 | Connect-MSGraph 22 | #Check if Intune already is MDM Authority 23 | $mdmAuth = (Invoke-MSGraphRequest -Url "https://graph.microsoft.com/beta/organization('$OrgId')?`$select=mobiledevicemanagementauthority" -HttpMethod Get -ErrorAction Stop).mobileDeviceManagementAuthority 24 | #Sets Intune as MDM Authority if not already set 25 | if($mdmAuth -notlike "intune") { Write-Progress -Activity "Set Intune as the MDM Authority" -Status "..." $OrgID = (Invoke-MSGraphRequest -Url "https://graph.microsoft.com/v1.0/organization" -HttpMethod Get -ErrorAction Stop).value.id Invoke-MSGraphRequest -Url "https://graph.microsoft.com/v1.0/organization/$OrgID/setMobileDeviceManagementAuthority" -HttpMethod Post -ErrorAction Stop } 26 | -------------------------------------------------------------------------------- /ThreatDefenseScripts.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanvfields/Microsoft-365/6be47eaa43899b34594c9c02c3dfd46d765c4d6f/ThreatDefenseScripts.zip -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-ADMX/OneDriveClientConfig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "definition@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('81c07ba0-7512-402d-b1f6-00856975cfab')", 4 | "enabled": "true" 5 | }, 6 | { 7 | "definition@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('61b07a01-7e60-4127-b086-f6b32458a5c5')", 8 | "enabled": "true" 9 | }, 10 | { 11 | "definition@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('2ce2f507-aae8-49a1-98ce-dc3faafcd331')", 12 | "enabled": "true" 13 | }, 14 | { 15 | "definition@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('24bec81e-a596-4fc1-867b-0256114a19a4')", 16 | "enabled": "true", 17 | "presentationValues": [ 18 | { 19 | "@odata.type": "#microsoft.graph.groupPolicyPresentationValueText", 20 | "value": "$TenantID", 21 | "presentation@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('24bec81e-a596-4fc1-867b-0256114a19a4')/presentations('4640c3f7-b89a-41be-948b-e86a2a97cae4')" 22 | } 23 | ] 24 | }, 25 | { 26 | "definition@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('39147fa2-6c5e-437b-8264-19b50b891709')", 27 | "enabled": "true", 28 | "presentationValues": [ 29 | { 30 | "@odata.type": "#microsoft.graph.groupPolicyPresentationValueText", 31 | "value": "$TenantID", 32 | "presentation@odata.bind": "https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('39147fa2-6c5e-437b-8264-19b50b891709')/presentations('fbefbbdf-5382-477c-8b6c-71f4a06e2805')" 33 | } 34 | ] 35 | } 36 | ] -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Apps/ChromiumEdge.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.context": "https://graph.microsoft.com/Beta/$metadata#deviceAppManagement/mobileApps/$entity", 3 | "@odata.type": "#microsoft.graph.windowsMicrosoftEdgeApp", 4 | "displayName": "[ITPM Baseline] Chromium Edge for Windows 10", 5 | "description": "Microsoft Edge is the browser for business with modern and legacy web compatibility, new privacy features such as Tracking prevention, and built-in productivity tools such as enterprise-grade PDF support and access to Office and corporate search right from a new tab.", 6 | "publisher": "Microsoft", 7 | "isFeatured": false, 8 | "privacyInformationUrl": "https://privacy.microsoft.com/en-US/privacystatement", 9 | "informationUrl": "https://www.microsoft.com/en-us/windows/microsoft-edge", 10 | "developer": "Microsoft", 11 | "isAssigned": false, 12 | "dependentAppCount": 0, 13 | "channel": "stable", 14 | "displayLanguageLocale": null 15 | } 16 | 17 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Apps/Office32.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "@odata.type": "#microsoft.graph.officeSuiteApp", 4 | 5 | "autoAcceptEula": true, 6 | 7 | "description": "[ITPM Baseline] 64-bit Microsoft 365 Desktop apps", 8 | 9 | "developer": "Microsoft", 10 | 11 | "displayName": "[ITPM Baseline] 64-bit Microsoft 365 Desktop apps", 12 | 13 | "excludedApps": { 14 | 15 | "groove": true, 16 | 17 | "infoPath": true, 18 | 19 | "sharePointDesigner": true, 20 | 21 | "lync": true 22 | 23 | }, 24 | 25 | "informationUrl": "", 26 | 27 | "isFeatured": false, 28 | 29 | "largeIcon": { 30 | 31 | "type": "image/png", 32 | 33 | "value": "iVBORw0KGgoAAAANSUhEUgAAAF0AAAAeCAMAAAEOZNKlAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJhUExURf////7z7/i9qfF1S/KCW/i+qv3q5P/9/PrQwfOMae1RG+s8AOxGDfBtQPWhhPvUx/759/zg1vWgg+9fLu5WIvKFX/rSxP728/nCr/FyR+tBBvOMaO1UH+1RHOs+AvSScP3u6f/+/v3s5vzg1+xFDO9kNPOOa/i7pvzj2/vWyes9Af76+Pzh2PrTxf/6+f7y7vOGYexHDv3t5+1SHfi8qPOIZPvb0O1NFuxDCe9hMPSVdPnFs/3q4/vaz/STcu5VIe5YJPWcfv718v/9/e1MFfF4T/F4TvF2TP3o4exECvF0SexIEPONavzn3/vZze1QGvF3Te5dK+5cKvrPwPrQwvKAWe1OGPexmexKEveulfezm/BxRfamiuxLE/apj/zf1e5YJfSXd/OHYv3r5feznPakiPze1P7x7f739f3w6+xJEfnEsvWdf/Wfge1LFPe1nu9iMvnDsfBqPOs/BPOIY/WZevJ/V/zl3fnIt/vTxuxHD+xEC+9mN+5ZJv749vBpO/KBWvBwRP/8+/SUc/etlPjArP/7+vOLZ/F7UvWae/708e1OF/aihvSWdvi8p+tABfSZefvVyPWihfSVde9lNvami+9jM/zi2fKEXvBuQvOKZvalifF5UPJ/WPSPbe9eLfrKuvvd0uxBB/7w7Pzj2vrRw/rOv+1PGfi/q/eymu5bKf3n4PnJuPBrPf3t6PWfgvWegOxCCO9nOO9oOfaskvSYePi5pPi2oPnGtO5eLPevlvKDXfrNvv739Pzd0/708O9gL+9lNfJ9VfrLu/OPbPnDsPBrPus+A/nArfarkQAAAGr5HKgAAADLdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AvuakogAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAz5JREFUOE+tVTtu4zAQHQjppmWzwIJbEVCzpTpjbxD3grQHSOXKRXgCAT6EC7UBVAmp3KwBnmvfzNCyZTmxgeTZJsXx43B+HBHRE34ZkXgkerXFTheeiCkRrbB4UXmp4wSWz5raaQEMTM5TZwuiXoaKgV+6FsmkZQcSy0kA71yMTMGHanX+AzMMGLAQCxU1F/ZwjULPugazl82GM0NEKm/U8EqFwEkO3/EAT4grgl0nucwlk9pcpTTJ4VPA4g/Rb3yIRhhp507e9nTQmZ1OS5RO4sS7nIRPEeHXCHdkw9ZEW2yVE5oIS7peD58Avs7CN+PVCmHh21oOqBdjDzIs+FldPJ74TFESUSJEfVzy9U/dhu+AuOT6eBp6gGKyXEx8euO450ZE4CMfstMFT44broWw/itkYErWXRx+fFArt9Ca9os78TFed0LVIUsmIHrwbwaw3BEOnOk94qVpQ6Ka2HjxewJnfyd6jUtGDQLdWlzmYNYLeKbbGOucJsNabCq1Yub0o92rtR+i30V2dapxYVEePXcOjeCKPnYyit7BtKeNlZqHbr+gt7i+AChWA9RsRs03pxTQc67ouWpxyESvjK5Vs3DVSy3IpkxPm5X+wZoBi+MFHWW69/w8FRhc7VBe6HAhMB2b8Q0XqDzTNZtXUMnKMjwKVaCrB/CSUL7WSx/HsdJC86lFGXwnioTeOMPjV+szlFvrZLA5VMVK4y+41l4e1xfx7Z88o4hkilRUH/qKqwNVlgDgpvYCpH3XwAy5eMCRnezIUxffVXoDql2rTHFDO+pjWnTWzAfrYXn6BFECblUpWGrvPZvBipETjS5ydM7tdXpH41ZCEbBNy/+wFZu71QO2t9pgT+iZEf657Q1vpN94PQNDxUHeKR103LV9nPVOtDikcNKO+2naCw7yKBhOe9Hm79pe8C4/CfC2wDjXnqC94kEeBU3WwN7dt/2UScXas7zDl5GpkY+M8WKv2J7fd4Ib2rGTk+jsC2cleEM7jI9veF7B0MBJrsZqfKd/81q9pR2NZfwJK2JzsmIT1Ns8jUH0UusQBpU8d2JzsHiXg1zXGLqxfitUNTDT/nUUeqDBp2HZVr+Ocqi/Ty3Rf4Jn82xxfSNtAAAAAElFTkSuQmCC" 34 | 35 | }, 36 | 37 | "localesToInstall": [ 38 | 39 | "en-us" 40 | 41 | ], 42 | 43 | "notes": "", 44 | 45 | "officePlatformArchitecture": "x86", 46 | 47 | "owner": "Microsoft", 48 | 49 | "privacyInformationUrl": "", 50 | 51 | "productIds": [ 52 | 53 | "o365ProPlusRetail" 54 | 55 | ], 56 | 57 | "publisher": "Microsoft", 58 | 59 | "updateChannel": "current", 60 | 61 | "useSharedComputerActivation": true 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Apps/Office64.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "@odata.type": "#microsoft.graph.officeSuiteApp", 4 | 5 | "autoAcceptEula": true, 6 | 7 | "description": "[ITPM Baseline] 64-bit Microsoft 365 Desktop apps", 8 | 9 | "developer": "Microsoft", 10 | 11 | "displayName": "[ITPM Baseline] 64-bit Microsoft 365 Desktop apps", 12 | 13 | "excludedApps": { 14 | 15 | "groove": true, 16 | 17 | "infoPath": true, 18 | 19 | "lync": true, 20 | 21 | "sharePointDesigner": true 22 | 23 | }, 24 | 25 | "informationUrl": "", 26 | 27 | "isFeatured": false, 28 | 29 | "largeIcon": { 30 | 31 | "type": "image/png", 32 | 33 | "value": "iVBORw0KGgoAAAANSUhEUgAAAF0AAAAeCAMAAAEOZNKlAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJhUExURf////7z7/i9qfF1S/KCW/i+qv3q5P/9/PrQwfOMae1RG+s8AOxGDfBtQPWhhPvUx/759/zg1vWgg+9fLu5WIvKFX/rSxP728/nCr/FyR+tBBvOMaO1UH+1RHOs+AvSScP3u6f/+/v3s5vzg1+xFDO9kNPOOa/i7pvzj2/vWyes9Af76+Pzh2PrTxf/6+f7y7vOGYexHDv3t5+1SHfi8qPOIZPvb0O1NFuxDCe9hMPSVdPnFs/3q4/vaz/STcu5VIe5YJPWcfv718v/9/e1MFfF4T/F4TvF2TP3o4exECvF0SexIEPONavzn3/vZze1QGvF3Te5dK+5cKvrPwPrQwvKAWe1OGPexmexKEveulfezm/BxRfamiuxLE/apj/zf1e5YJfSXd/OHYv3r5feznPakiPze1P7x7f739f3w6+xJEfnEsvWdf/Wfge1LFPe1nu9iMvnDsfBqPOs/BPOIY/WZevJ/V/zl3fnIt/vTxuxHD+xEC+9mN+5ZJv749vBpO/KBWvBwRP/8+/SUc/etlPjArP/7+vOLZ/F7UvWae/708e1OF/aihvSWdvi8p+tABfSZefvVyPWihfSVde9lNvami+9jM/zi2fKEXvBuQvOKZvalifF5UPJ/WPSPbe9eLfrKuvvd0uxBB/7w7Pzj2vrRw/rOv+1PGfi/q/eymu5bKf3n4PnJuPBrPf3t6PWfgvWegOxCCO9nOO9oOfaskvSYePi5pPi2oPnGtO5eLPevlvKDXfrNvv739Pzd0/708O9gL+9lNfJ9VfrLu/OPbPnDsPBrPus+A/nArfarkQAAAGr5HKgAAADLdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AvuakogAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAz5JREFUOE+tVTtu4zAQHQjppmWzwIJbEVCzpTpjbxD3grQHSOXKRXgCAT6EC7UBVAmp3KwBnmvfzNCyZTmxgeTZJsXx43B+HBHRE34ZkXgkerXFTheeiCkRrbB4UXmp4wSWz5raaQEMTM5TZwuiXoaKgV+6FsmkZQcSy0kA71yMTMGHanX+AzMMGLAQCxU1F/ZwjULPugazl82GM0NEKm/U8EqFwEkO3/EAT4grgl0nucwlk9pcpTTJ4VPA4g/Rb3yIRhhp507e9nTQmZ1OS5RO4sS7nIRPEeHXCHdkw9ZEW2yVE5oIS7peD58Avs7CN+PVCmHh21oOqBdjDzIs+FldPJ74TFESUSJEfVzy9U/dhu+AuOT6eBp6gGKyXEx8euO450ZE4CMfstMFT44broWw/itkYErWXRx+fFArt9Ca9os78TFed0LVIUsmIHrwbwaw3BEOnOk94qVpQ6Ka2HjxewJnfyd6jUtGDQLdWlzmYNYLeKbbGOucJsNabCq1Yub0o92rtR+i30V2dapxYVEePXcOjeCKPnYyit7BtKeNlZqHbr+gt7i+AChWA9RsRs03pxTQc67ouWpxyESvjK5Vs3DVSy3IpkxPm5X+wZoBi+MFHWW69/w8FRhc7VBe6HAhMB2b8Q0XqDzTNZtXUMnKMjwKVaCrB/CSUL7WSx/HsdJC86lFGXwnioTeOMPjV+szlFvrZLA5VMVK4y+41l4e1xfx7Z88o4hkilRUH/qKqwNVlgDgpvYCpH3XwAy5eMCRnezIUxffVXoDql2rTHFDO+pjWnTWzAfrYXn6BFECblUpWGrvPZvBipETjS5ydM7tdXpH41ZCEbBNy/+wFZu71QO2t9pgT+iZEf657Q1vpN94PQNDxUHeKR103LV9nPVOtDikcNKO+2naCw7yKBhOe9Hm79pe8C4/CfC2wDjXnqC94kEeBU3WwN7dt/2UScXas7zDl5GpkY+M8WKv2J7fd4Ib2rGTk+jsC2cleEM7jI9veF7B0MBJrsZqfKd/81q9pR2NZfwJK2JzsmIT1Ns8jUH0UusQBpU8d2JzsHiXg1zXGLqxfitUNTDT/nUUeqDBp2HZVr+Ocqi/Ty3Rf4Jn82xxfSNtAAAAAElFTkSuQmCC" 34 | 35 | }, 36 | 37 | "localesToInstall": [ 38 | 39 | "en-us" 40 | 41 | ], 42 | 43 | "notes": "", 44 | 45 | "officePlatformArchitecture": "x64", 46 | 47 | "owner": "Microsoft", 48 | 49 | "privacyInformationUrl": "", 50 | 51 | "productIds": [ 52 | 53 | "o365ProPlusRetail" 54 | 55 | ], 56 | 57 | "publisher": "Microsoft", 58 | 59 | "updateChannel": "current", 60 | 61 | "useSharedComputerActivation": true 62 | 63 | } 64 | 65 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Compliance/[ITPM Baseline] Windows 10_ Delayed.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windows10CompliancePolicy", 3 | "description": "Assign this policy to all users including BYOD users. Windows 10 compliance settings to apply with 24 hour grace period.", 4 | "displayName": "[ITPM Baseline] Windows 10: Delayed", 5 | "passwordRequired": false, 6 | "passwordBlockSimple": false, 7 | "passwordRequiredToUnlockFromIdle": false, 8 | "passwordMinutesOfInactivityBeforeLock": null, 9 | "passwordExpirationDays": null, 10 | "passwordMinimumLength": null, 11 | "passwordMinimumCharacterSetCount": null, 12 | "passwordRequiredType": "deviceDefault", 13 | "passwordPreviousPasswordBlockCount": null, 14 | "requireHealthyDeviceReport": false, 15 | "osMinimumVersion": "10.0.18363.476", 16 | "osMaximumVersion": null, 17 | "mobileOsMinimumVersion": null, 18 | "mobileOsMaximumVersion": null, 19 | "earlyLaunchAntiMalwareDriverEnabled": false, 20 | "bitLockerEnabled": true, 21 | "secureBootEnabled": true, 22 | "codeIntegrityEnabled": true, 23 | "storageRequireEncryption": false, 24 | "activeFirewallRequired": true, 25 | "defenderEnabled": true, 26 | "defenderVersion": null, 27 | "signatureOutOfDate": true, 28 | "rtpEnabled": true, 29 | "antivirusRequired": true, 30 | "antiSpywareRequired": true, 31 | "deviceThreatProtectionEnabled": false, 32 | "deviceThreatProtectionRequiredSecurityLevel": "unavailable", 33 | "configurationManagerComplianceRequired": false, 34 | "tpmRequired": true, 35 | "deviceCompliancePolicyScript": null, 36 | "validOperatingSystemBuildRanges": [ 37 | 38 | ], 39 | "scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":24,"notificationTemplateId":"","notificationMessageCCList":[]}]}] 40 | } 41 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Compliance/[ITPM Baseline] Windows 10_ Immediate.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windows10CompliancePolicy", 3 | "description": "Assign this policy to all users, including BYOD users. Windows 10 compliance settings to apply immediately. \n", 4 | "displayName": "[ITPM Baseline] Windows 10: Immediate", 5 | "passwordRequired": false, 6 | "passwordBlockSimple": false, 7 | "passwordRequiredToUnlockFromIdle": false, 8 | "passwordMinutesOfInactivityBeforeLock": null, 9 | "passwordExpirationDays": null, 10 | "passwordMinimumLength": null, 11 | "passwordMinimumCharacterSetCount": null, 12 | "passwordRequiredType": "deviceDefault", 13 | "passwordPreviousPasswordBlockCount": null, 14 | "requireHealthyDeviceReport": false, 15 | "osMinimumVersion": "10.0.18363", 16 | "osMaximumVersion": null, 17 | "mobileOsMinimumVersion": null, 18 | "mobileOsMaximumVersion": null, 19 | "earlyLaunchAntiMalwareDriverEnabled": false, 20 | "bitLockerEnabled": false, 21 | "secureBootEnabled": false, 22 | "codeIntegrityEnabled": false, 23 | "storageRequireEncryption": false, 24 | "activeFirewallRequired": false, 25 | "defenderEnabled": true, 26 | "defenderVersion": null, 27 | "signatureOutOfDate": false, 28 | "rtpEnabled": true, 29 | "antivirusRequired": true, 30 | "antiSpywareRequired": false, 31 | "deviceThreatProtectionEnabled": false, 32 | "deviceThreatProtectionRequiredSecurityLevel": "unavailable", 33 | "configurationManagerComplianceRequired": false, 34 | "tpmRequired": false, 35 | "deviceCompliancePolicyScript": null, 36 | "validOperatingSystemBuildRanges": [ 37 | 38 | ], 39 | "scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}] 40 | } 41 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-DeviceConfig/[ITPM Corporate] Windows 10_ Disable first sign-in animation.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windows10CustomConfiguration", 3 | "deviceManagementApplicabilityRuleOsEdition": null, 4 | "deviceManagementApplicabilityRuleOsVersion": null, 5 | "deviceManagementApplicabilityRuleDeviceMode": null, 6 | "description": "Assign this profile to Company owned Windows 10 devices. Prevents the sign-in animation sequence for users signing into the device for the first time.", 7 | "displayName": "[ITPM Corporate] Windows 10: Disable first sign-in animation", 8 | "omaSettings": [ 9 | { 10 | "@odata.type": "#microsoft.graph.omaSettingInteger", 11 | "displayName": "EnableFirstLogonAnimation", 12 | "description": "Disable first sign-in animation", 13 | "omaUri": "./Device/Vendor/MSFT/Policy/Config/WindowsLogon/EnableFirstLogonAnimation", 14 | "isEncrypted": false, 15 | "value": 0, 16 | "isReadOnly": false 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-DeviceConfig/[ITPM Corporate] Windows 10_ MDMWinsOverGP.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windows10CustomConfiguration", 3 | "deviceManagementApplicabilityRuleOsEdition": null, 4 | "deviceManagementApplicabilityRuleOsVersion": null, 5 | "deviceManagementApplicabilityRuleDeviceMode": null, 6 | "description": "Assign this profile to Hybrid Azure AD Joined Windows 10 devices. Allows MDM settings to override conflicts with Group Policy.", 7 | "displayName": "[ITPM Corporate] Windows 10: MDM wins over Group Policy", 8 | "omaSettings": [ 9 | { 10 | "@odata.type": "#microsoft.graph.omaSettingInteger", 11 | "displayName": "ControlPolicyConflict/MDMWinsOverGP", 12 | "description": "MDMWinsOverGP", 13 | "omaUri": "./Device/Vendor/MSFT/Policy/Config/ControlPolicyConflict/MDMWinsOverGP", 14 | "isEncrypted": false, 15 | "value": 1, 16 | "isReadOnly": false 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-EndpointSecurity/[ITPM Corporate] Optional_ Block removable storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Corporate] Optional: Block removable storage", 3 | "description": "Assign this policy to Company-owned Windows 10 devices. This policy will block removable storage devices.", 4 | "TemplateDisplayName": "Device control", 5 | "TemplateId": "4648b50e-d3ef-4ba0-848e-b0ef561b3aa5", 6 | "settingsDelta": [ 7 | { 8 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 9 | "id": "d6b80913-f6d6-4ed5-8e10-4d39350d3162", 10 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_allowHardwareDeviceInstallationByDeviceIdentifiers", 11 | "valueJson": "null", 12 | "implementationId": null 13 | }, 14 | { 15 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 16 | "id": "8aaf2cf8-991d-44b2-bb65-df3188da0aff", 17 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_hardwareDeviceInstallationByDeviceIdentifiers", 18 | "valueJson": "null", 19 | "implementationId": null 20 | }, 21 | { 22 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 23 | "id": "952670b6-88ed-4e67-9e74-65c1c24a7549", 24 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_allowHardwareDeviceInstallationBySetupClasses", 25 | "valueJson": "null", 26 | "implementationId": null 27 | }, 28 | { 29 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 30 | "id": "c49f9c88-d94c-4425-b58e-36e95e1131a7", 31 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_hardwareDeviceInstallationBySetupClasses", 32 | "valueJson": "null", 33 | "implementationId": null 34 | }, 35 | { 36 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 37 | "id": "ee6d8ed7-942a-4ba3-a204-51078064371d", 38 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_allowHardwareDeviceInstallationByDeviceInstanceIdentifiers", 39 | "valueJson": "null", 40 | "implementationId": null 41 | }, 42 | { 43 | "@odata.type": "#microsoft.graph.deviceManagementAbstractComplexSettingInstance", 44 | "id": "6aa7a8f8-c62d-4225-8727-ab30498ca609", 45 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_preventHardwareDeviceInstallationByDeviceInstanceIdentifiers", 46 | "valueJson": "null", 47 | "implementationId": null 48 | }, 49 | { 50 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 51 | "id": "f8f41cd7-43a4-4b67-a8a8-aa9a302c1a36", 52 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_defenderScanRemovableDrivesDuringFullScan", 53 | "valueJson": "null", 54 | "value": null 55 | }, 56 | { 57 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 58 | "id": "384ca184-09d7-4f4d-a848-2464545f8339", 59 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_dataProtectionBlockDirectMemoryAccess", 60 | "valueJson": "null", 61 | "value": null 62 | }, 63 | { 64 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 65 | "id": "676c1472-b18e-4f57-ba60-461735f5611a", 66 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_dmaGuardDeviceEnumerationPolicy", 67 | "valueJson": "null", 68 | "value": null 69 | }, 70 | { 71 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 72 | "id": "55fcf7fc-b959-442c-9e20-101635129443", 73 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_storageBlockRemovableStorage", 74 | "valueJson": "true", 75 | "value": true 76 | }, 77 | { 78 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 79 | "id": "8ebd96c0-6d7b-400c-a0f1-ae4d82b2ede0", 80 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_usbBlocked", 81 | "valueJson": "null", 82 | "value": null 83 | }, 84 | { 85 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 86 | "id": "877a254e-a5b4-4d86-b4a3-ee9cdc07c6dc", 87 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_storageBlockRemovableStorageWrite", 88 | "valueJson": "null", 89 | "value": null 90 | }, 91 | { 92 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 93 | "id": "9c2d0165-5029-4e52-8acd-d32378bcd72a", 94 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothBlocked", 95 | "valueJson": "null", 96 | "value": null 97 | }, 98 | { 99 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 100 | "id": "d051bb57-2f4a-4aa1-b7db-417c3ec0adcd", 101 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothBlockDiscoverableMode", 102 | "valueJson": "null", 103 | "value": null 104 | }, 105 | { 106 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 107 | "id": "aa8ca4c8-ff45-4f66-bc07-d24db4957989", 108 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothBlockPrePairing", 109 | "valueJson": "null", 110 | "value": null 111 | }, 112 | { 113 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 114 | "id": "ea2f58a7-88f4-462d-81ce-9fa53f2bd3f2", 115 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothBlockAdvertising", 116 | "valueJson": "null", 117 | "value": null 118 | }, 119 | { 120 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 121 | "id": "3950efa9-b504-4fb9-9f3a-04890af6abd6", 122 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothBlockPromptedProximalConnections", 123 | "valueJson": "null", 124 | "value": null 125 | }, 126 | { 127 | "@odata.type": "#microsoft.graph.deviceManagementCollectionSettingInstance", 128 | "id": "6b1c8efd-e000-4355-bcb0-c7a00bcb9ae2", 129 | "definitionId": "deviceConfiguration--windows10GeneralConfiguration_bluetoothAllowedServices", 130 | "valueJson": "null" 131 | } 132 | ] 133 | } 134 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-EndpointSecurity/[ITPM Corporate] Windows Hello for Business.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Corporate] Windows Hello for Business", 3 | "description": "Assign this profile to Company-owned Windows 10 devices that are Azure AD Joined. Do not assign this profile to Hybrid Azure AD Joined devices.", 4 | "TemplateDisplayName": "Account protection (Preview)", 5 | "TemplateId": "0f2b5d70-d4e9-4156-8c16-1397eb6c54a5", 6 | "settingsDelta": [ 7 | { 8 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 9 | "id": "cd95785f-6ff4-4f4e-a24e-d109213074ae", 10 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_windowsHelloForBusinessBlocked", 11 | "valueJson": "false", 12 | "value": false 13 | }, 14 | { 15 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 16 | "id": "3ed2b206-e91d-4689-a932-1d018cd47b42", 17 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinMinimumLength", 18 | "valueJson": "6", 19 | "value": 6 20 | }, 21 | { 22 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 23 | "id": "38083c1c-cef8-4b83-95a0-de16602f5bfa", 24 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinMaximumLength", 25 | "valueJson": "null", 26 | "value": null 27 | }, 28 | { 29 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 30 | "id": "4480fd2e-fca3-47db-a5dd-eeea2d139df6", 31 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinLowercaseCharactersUsage", 32 | "valueJson": "\"notConfigured\"", 33 | "value": "notConfigured" 34 | }, 35 | { 36 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 37 | "id": "ee78ed01-1324-4a8e-acdd-9643e617e083", 38 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinUppercaseCharactersUsage", 39 | "valueJson": "\"notConfigured\"", 40 | "value": "notConfigured" 41 | }, 42 | { 43 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 44 | "id": "60ebb8d8-7307-4620-9241-f629631a3162", 45 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinSpecialCharactersUsage", 46 | "valueJson": "\"notConfigured\"", 47 | "value": "notConfigured" 48 | }, 49 | { 50 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 51 | "id": "e95e446e-2f6e-4608-a5bf-21a5fa144092", 52 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinExpirationInDays", 53 | "valueJson": "null", 54 | "value": null 55 | }, 56 | { 57 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 58 | "id": "12d7704e-7321-4954-9bde-43ed396b3ef7", 59 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinPreviousBlockCount", 60 | "valueJson": "null", 61 | "value": null 62 | }, 63 | { 64 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 65 | "id": "49acd01f-162e-4b7c-ac0a-7c624a25f3f2", 66 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinRecoveryEnabled", 67 | "valueJson": "true", 68 | "value": true 69 | }, 70 | { 71 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 72 | "id": "0446ee25-ace2-4ec7-8aa6-2e9c2348208e", 73 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_securityDeviceRequired", 74 | "valueJson": "true", 75 | "value": true 76 | }, 77 | { 78 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 79 | "id": "52edebb1-69f9-4bfa-9d62-6a86f6ece2ac", 80 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_unlockWithBiometricsEnabled", 81 | "valueJson": "true", 82 | "value": true 83 | }, 84 | { 85 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 86 | "id": "e943ec65-d992-4f0f-88e6-4b528eee4956", 87 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_enhancedAntiSpoofingForFacialFeaturesEnabled", 88 | "valueJson": "true", 89 | "value": true 90 | }, 91 | { 92 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 93 | "id": "ad0fa863-5fbc-4def-af64-792319b54c57", 94 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_useCertificatesForOnPremisesAuthEnabled", 95 | "valueJson": "false", 96 | "value": false 97 | }, 98 | { 99 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 100 | "id": "b90734da-6b11-409e-a322-6e1d6ffb2b50", 101 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_useSecurityKeyForSignin", 102 | "valueJson": "true", 103 | "value": true 104 | }, 105 | { 106 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 107 | "id": "53a4c135-6e3b-46ba-bd0e-ac5500e4c66b", 108 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_deviceGuardLocalSystemAuthorityCredentialGuardSettings", 109 | "valueJson": "\"notConfigured\"", 110 | "value": "notConfigured" 111 | } 112 | ] 113 | } 114 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-EndpointSecurity/[ITPM Enterprise] SmartLocker Audit.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Enterprise] Audit SmartLocker", 3 | "description": "Assign this policy to Company-owned Windows 10 devices. You must have proper licensing to use this profile: Microsoft 365 Business Premium, E3, or E5. Use either the Audit policy or the Enable policy, but not both at the same time. ", 4 | "TemplateDisplayName": "Application control", 5 | "TemplateId": "63be6324-e3c9-4c97-948a-e7f4b96f0f20", 6 | "settingsDelta": [ 7 | { 8 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 9 | "id": "d0ff1ed6-327f-4432-8ed6-132906e14a5b", 10 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_appLockerApplicationControl", 11 | "valueJson": "\"auditComponentsStoreAppsAndSmartlocker\"", 12 | "value": "auditComponentsStoreAppsAndSmartlocker" 13 | }, 14 | { 15 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 16 | "id": "b3a22ebd-fdb3-4c7b-b1d7-f62477f1098b", 17 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_smartScreenBlockOverrideForFiles", 18 | "valueJson": "false", 19 | "value": false 20 | }, 21 | { 22 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 23 | "id": "d6e99022-8be2-493d-a5a3-37b6b3d5b080", 24 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_smartScreenEnableInShell", 25 | "valueJson": "false", 26 | "value": false 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-EndpointSecurity/[ITPM Enterprise] SmartLocker Enable.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Enterprise] Enable SmartLocker", 3 | "description": "Assign this policy to Company-owned Windows 10 devices. You must have proper licensing to use this profile: Microsoft 365 Business Premium, E3, or E5. Use either the Audit policy or the Enable policy, but not both at the same time. ", 4 | "TemplateDisplayName": "Application control", 5 | "TemplateId": "63be6324-e3c9-4c97-948a-e7f4b96f0f20", 6 | "settingsDelta": [ 7 | { 8 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 9 | "id": "a7210811-f78c-42de-89a4-e1e67182ba54", 10 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_appLockerApplicationControl", 11 | "valueJson": "\"enforceComponentsStoreAppsAndSmartlocker\"", 12 | "value": "enforceComponentsStoreAppsAndSmartlocker" 13 | }, 14 | { 15 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 16 | "id": "f6217e90-ddce-449c-8035-6b3ebd2fe71a", 17 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_smartScreenBlockOverrideForFiles", 18 | "valueJson": "true", 19 | "value": true 20 | }, 21 | { 22 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 23 | "id": "c839aa8a-eed0-4d9a-93a1-3d39d556fcc2", 24 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_smartScreenEnableInShell", 25 | "valueJson": "true", 26 | "value": true 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-EndpointSecurity/[ITPM Enterprise] Windows Credential Guard.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Enterprise] Windows Credential Guard", 3 | "description": "Assign this profile to Company-owned Windows 10 devices. You must have the proper licensing to use this profile: Windows 10 E3, Windows 10 E5, Microsoft 365 E3, or Microsoft 365 E5. Reboot required after assigning this policy.", 4 | "TemplateDisplayName": "Account protection (Preview)", 5 | "TemplateId": "0f2b5d70-d4e9-4156-8c16-1397eb6c54a5", 6 | "settingsDelta": [ 7 | { 8 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 9 | "id": "10e3cec5-7ad8-4893-b18a-2192712e5c32", 10 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_windowsHelloForBusinessBlocked", 11 | "valueJson": "null", 12 | "value": null 13 | }, 14 | { 15 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 16 | "id": "01b9e719-44fa-42c2-bf31-1ebf251e671f", 17 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinMinimumLength", 18 | "valueJson": "null", 19 | "value": null 20 | }, 21 | { 22 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 23 | "id": "d540ddcb-7362-41d9-aa04-f3d91d00e3a9", 24 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinMaximumLength", 25 | "valueJson": "null", 26 | "value": null 27 | }, 28 | { 29 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 30 | "id": "7ab6bb3c-8b71-4eef-9977-d860768b2ae0", 31 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinLowercaseCharactersUsage", 32 | "valueJson": "\"notConfigured\"", 33 | "value": "notConfigured" 34 | }, 35 | { 36 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 37 | "id": "13810d4d-0b1c-4296-ad2c-0f74208f3935", 38 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinUppercaseCharactersUsage", 39 | "valueJson": "\"notConfigured\"", 40 | "value": "notConfigured" 41 | }, 42 | { 43 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 44 | "id": "48afc500-bde2-48f2-bbe6-0688fc6e5a7e", 45 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinSpecialCharactersUsage", 46 | "valueJson": "\"notConfigured\"", 47 | "value": "notConfigured" 48 | }, 49 | { 50 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 51 | "id": "4fa67f28-8368-4843-97f5-7bdd5e2679a8", 52 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinExpirationInDays", 53 | "valueJson": "null", 54 | "value": null 55 | }, 56 | { 57 | "@odata.type": "#microsoft.graph.deviceManagementIntegerSettingInstance", 58 | "id": "f0aa3a2c-bcfc-4712-9839-6e8c59338961", 59 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinPreviousBlockCount", 60 | "valueJson": "null", 61 | "value": null 62 | }, 63 | { 64 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 65 | "id": "2c1b17bc-eecd-4c0e-a897-274acaff1fc3", 66 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_pinRecoveryEnabled", 67 | "valueJson": "false", 68 | "value": false 69 | }, 70 | { 71 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 72 | "id": "bc506189-8231-4479-97f2-fe4e2ae6a394", 73 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_securityDeviceRequired", 74 | "valueJson": "false", 75 | "value": false 76 | }, 77 | { 78 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 79 | "id": "719e4b80-932d-4362-a6eb-7f77ecc64601", 80 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_unlockWithBiometricsEnabled", 81 | "valueJson": "false", 82 | "value": false 83 | }, 84 | { 85 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 86 | "id": "a5479a08-baae-46f7-b706-1d4841a2382d", 87 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_enhancedAntiSpoofingForFacialFeaturesEnabled", 88 | "valueJson": "false", 89 | "value": false 90 | }, 91 | { 92 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 93 | "id": "a258ef47-73a2-4d10-bd90-a9cf9079e1ae", 94 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_useCertificatesForOnPremisesAuthEnabled", 95 | "valueJson": "false", 96 | "value": false 97 | }, 98 | { 99 | "@odata.type": "#microsoft.graph.deviceManagementBooleanSettingInstance", 100 | "id": "eff025ac-84b6-4d7b-a898-5ce5f23ad22f", 101 | "definitionId": "deviceConfiguration--windowsIdentityProtectionConfiguration_useSecurityKeyForSignin", 102 | "valueJson": "false", 103 | "value": false 104 | }, 105 | { 106 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 107 | "id": "24a7e66c-3ba0-49ce-b647-35a579af9ffb", 108 | "definitionId": "deviceConfiguration--windows10EndpointProtectionConfiguration_deviceGuardLocalSystemAuthorityCredentialGuardSettings", 109 | "valueJson": "\"enableWithUEFILock\"", 110 | "value": "enableWithUEFILock" 111 | } 112 | ] 113 | } 114 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-SecurityBaselines/[ITPM Corporate] Edge Chromium baseline.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Corporate] Edge Chromium baseline", 3 | "description": "This policy will disable all browser extensions by default. Create a Device configuration profile to allow specific extensions to be installed from the Edge add-ons store.", 4 | "roleScopeTagIds": [ 5 | "0" 6 | ], 7 | "TemplateDisplayName": "Microsoft Edge baseline", 8 | "TemplateId": "a8d6fa0e-1e66-455b-bb51-8ce0dde1559e", 9 | "versionInfo": "September 2020 (Edge version 85 and later)", 10 | "settingsDelta": [ 11 | { 12 | "@odata.type": "#microsoft.graph.deviceManagementCollectionSettingInstance", 13 | "id": "cc3e5d9b-e76e-47b7-b6ae-79f55f7e1a76", 14 | "definitionId": "admx--microsoftedgeAuthSchemes_AuthSchemes", 15 | "valueJson": "[\"ntlm\",\"negotiate\"]" 16 | }, 17 | { 18 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 19 | "id": "7fa472aa-3cc9-40c9-818e-c5e914215e77", 20 | "definitionId": "admx--microsoftedge_AuthSchemes", 21 | "valueJson": "\"enabled\"", 22 | "value": "enabled" 23 | }, 24 | { 25 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 26 | "id": "cd316e16-f5f6-4253-8652-4e9ec9e3fd8d", 27 | "definitionId": "admx--microsoftedge_DefaultPluginsSetting", 28 | "valueJson": "\"enabled\"", 29 | "value": "enabled" 30 | }, 31 | { 32 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 33 | "id": "38c8b1b1-d6e7-4471-9a0a-d6c0577dfde8", 34 | "definitionId": "admx--microsoftedgeDefaultPluginsSetting_DefaultPluginsSetting", 35 | "valueJson": "\"2\"", 36 | "value": "2" 37 | }, 38 | { 39 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 40 | "id": "70f60848-cb70-4fc7-99d6-92189843566a", 41 | "definitionId": "admx--microsoftedge_ExtensionInstallBlocklist", 42 | "valueJson": "\"enabled\"", 43 | "value": "enabled" 44 | }, 45 | { 46 | "@odata.type": "#microsoft.graph.deviceManagementCollectionSettingInstance", 47 | "id": "a640b71e-8cf4-4805-88e9-eb596bbd272c", 48 | "definitionId": "admx--microsoftedgeExtensionInstallBlocklist_ExtensionInstallBlocklistDesc", 49 | "valueJson": "[\"*\"]" 50 | }, 51 | { 52 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 53 | "id": "0a12320a-4702-4dfb-8b61-f4f1fcbd3efc", 54 | "definitionId": "admx--microsoftedge_NativeMessagingUserLevelHosts", 55 | "valueJson": "\"disabled\"", 56 | "value": "disabled" 57 | }, 58 | { 59 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 60 | "id": "9f63f0ae-f25e-44d8-8618-b56566fc5800", 61 | "definitionId": "admx--microsoftedge_PasswordManagerEnabled", 62 | "valueJson": "\"disabled\"", 63 | "value": "disabled" 64 | }, 65 | { 66 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 67 | "id": "5f4d089f-6bab-4e19-848f-bf10cc94af9a", 68 | "definitionId": "admx--microsoftedge_PreventSmartScreenPromptOverride", 69 | "valueJson": "\"enabled\"", 70 | "value": "enabled" 71 | }, 72 | { 73 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 74 | "id": "5999e27c-ddde-4176-95fe-0decaa2119f8", 75 | "definitionId": "admx--microsoftedge_PreventSmartScreenPromptOverrideForFiles", 76 | "valueJson": "\"enabled\"", 77 | "value": "enabled" 78 | }, 79 | { 80 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 81 | "id": "958e2890-d23c-4428-9a4b-6961fb492ffb", 82 | "definitionId": "admx--microsoftedge_SitePerProcess", 83 | "valueJson": "\"enabled\"", 84 | "value": "enabled" 85 | }, 86 | { 87 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 88 | "id": "58dce6dc-16cc-4d7d-b151-92a5d2bae90d", 89 | "definitionId": "admx--microsoftedge_SmartScreenEnabled", 90 | "valueJson": "\"enabled\"", 91 | "value": "enabled" 92 | }, 93 | { 94 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 95 | "id": "82cac80b-13f4-4272-8598-0662fb684698", 96 | "definitionId": "admx--microsoftedgev80diff_SmartScreenPuaEnabled", 97 | "valueJson": "\"enabled\"", 98 | "value": "enabled" 99 | }, 100 | { 101 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 102 | "id": "f128307a-3e2a-4a40-934e-5147f31d845b", 103 | "definitionId": "admx--microsoftedge_SSLErrorOverrideAllowed", 104 | "valueJson": "\"disabled\"", 105 | "value": "disabled" 106 | }, 107 | { 108 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 109 | "id": "fd4c09bc-d143-4688-aa2c-2edaa149d77d", 110 | "definitionId": "admx--microsoftedge_SSLVersionMin", 111 | "valueJson": "\"enabled\"", 112 | "value": "enabled" 113 | }, 114 | { 115 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 116 | "id": "28bd2c9e-e5c3-4aaf-bed5-d82c7006bb92", 117 | "definitionId": "admx--microsoftedgeSSLVersionMin_SSLVersionMin", 118 | "valueJson": "\"tls1.2\"", 119 | "value": "tls1.2" 120 | }, 121 | { 122 | "@odata.type": "#microsoft.graph.deviceManagementStringSettingInstance", 123 | "id": "e7941c35-cf0c-4220-ad37-872dbb65d396", 124 | "definitionId": "admx--microsoftedgev85diff_EnableSha1ForLocalAnchors", 125 | "valueJson": "\"disabled\"", 126 | "value": "disabled" 127 | } 128 | ] 129 | } 130 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Update/[ITPM Corporate] Default Update Ring.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windowsUpdateForBusinessConfiguration", 3 | "deviceManagementApplicabilityRuleOsEdition": null, 4 | "deviceManagementApplicabilityRuleOsVersion": null, 5 | "deviceManagementApplicabilityRuleDeviceMode": null, 6 | "description": "Applies updates via the Semi-annual channel without delay.", 7 | "displayName": "[ITPM Corporate] Default Update Ring", 8 | "deliveryOptimizationMode": "userDefined", 9 | "prereleaseFeatures": "userDefined", 10 | "automaticUpdateMode": "autoInstallAtMaintenanceTime", 11 | "microsoftUpdateServiceAllowed": true, 12 | "driversExcluded": false, 13 | "qualityUpdatesDeferralPeriodInDays": 0, 14 | "featureUpdatesDeferralPeriodInDays": 0, 15 | "qualityUpdatesPaused": false, 16 | "featureUpdatesPaused": false, 17 | "qualityUpdatesPauseExpiryDateTime": "0001-01-01T00:00:00Z", 18 | "featureUpdatesPauseExpiryDateTime": "0001-01-01T00:00:00Z", 19 | "businessReadyUpdatesOnly": "businessReadyOnly", 20 | "skipChecksBeforeRestart": false, 21 | "updateWeeks": null, 22 | "qualityUpdatesPauseStartDate": null, 23 | "featureUpdatesPauseStartDate": null, 24 | "featureUpdatesRollbackWindowInDays": 21, 25 | "qualityUpdatesWillBeRolledBack": false, 26 | "featureUpdatesWillBeRolledBack": false, 27 | "qualityUpdatesRollbackStartDateTime": "0001-01-01T00:00:00Z", 28 | "featureUpdatesRollbackStartDateTime": "0001-01-01T00:00:00Z", 29 | "engagedRestartDeadlineInDays": null, 30 | "engagedRestartSnoozeScheduleInDays": null, 31 | "engagedRestartTransitionScheduleInDays": null, 32 | "deadlineForFeatureUpdatesInDays": null, 33 | "deadlineForQualityUpdatesInDays": null, 34 | "deadlineGracePeriodInDays": null, 35 | "postponeRebootUntilAfterDeadline": null, 36 | "autoRestartNotificationDismissal": "notConfigured", 37 | "scheduleRestartWarningInHours": 4, 38 | "scheduleImminentRestartWarningInMinutes": 15, 39 | "userPauseAccess": "enabled", 40 | "userWindowsUpdateScanAccess": "enabled", 41 | "updateNotificationLevel": "restartWarningsOnly", 42 | "installationSchedule": { 43 | "@odata.type": "#microsoft.graph.windowsUpdateActiveHoursInstall", 44 | "activeHoursStart": "08:00:00.0000000", 45 | "activeHoursEnd": "18:00:00.0000000" 46 | }, 47 | "groupAssignments@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/deviceConfigurations(\u0027d968b611-a9b7-4adf-8c3b-2d3361be93a9\u0027)/microsoft.graph.windowsUpdateForBusinessConfiguration/groupAssignments", 48 | "groupAssignments": [ 49 | { 50 | "id": "d968b611-a9b7-4adf-8c3b-2d3361be93a9_0fc81c18-92f0-4a95-bf84-6662c8be3f41", 51 | "targetGroupId": "0fc81c18-92f0-4a95-bf84-6662c8be3f41", 52 | "excludeGroup": false 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-Update/[ITPM Corporate] Delayed Update Ring.json: -------------------------------------------------------------------------------- 1 | { 2 | "@odata.type": "#microsoft.graph.windowsUpdateForBusinessConfiguration", 3 | "deviceManagementApplicabilityRuleOsEdition": null, 4 | "deviceManagementApplicabilityRuleOsVersion": null, 5 | "deviceManagementApplicabilityRuleDeviceMode": null, 6 | "description": "This update ring delays quality updates by one week and feature updates by two weeks. Optionally, you may apply this ring to a broad population of users and use the default ring against pilot users in your organization.", 7 | "displayName": "[ITPM Corporate] Delayed Update Ring", 8 | "deliveryOptimizationMode": "userDefined", 9 | "prereleaseFeatures": "userDefined", 10 | "automaticUpdateMode": "autoInstallAtMaintenanceTime", 11 | "microsoftUpdateServiceAllowed": true, 12 | "driversExcluded": false, 13 | "qualityUpdatesDeferralPeriodInDays": 7, 14 | "featureUpdatesDeferralPeriodInDays": 14, 15 | "qualityUpdatesPaused": false, 16 | "featureUpdatesPaused": false, 17 | "qualityUpdatesPauseExpiryDateTime": "0001-01-01T00:00:00Z", 18 | "featureUpdatesPauseExpiryDateTime": "0001-01-01T00:00:00Z", 19 | "businessReadyUpdatesOnly": "businessReadyOnly", 20 | "skipChecksBeforeRestart": false, 21 | "updateWeeks": null, 22 | "qualityUpdatesPauseStartDate": null, 23 | "featureUpdatesPauseStartDate": null, 24 | "featureUpdatesRollbackWindowInDays": 21, 25 | "qualityUpdatesWillBeRolledBack": false, 26 | "featureUpdatesWillBeRolledBack": false, 27 | "qualityUpdatesRollbackStartDateTime": "0001-01-01T00:00:00Z", 28 | "featureUpdatesRollbackStartDateTime": "0001-01-01T00:00:00Z", 29 | "engagedRestartDeadlineInDays": null, 30 | "engagedRestartSnoozeScheduleInDays": null, 31 | "engagedRestartTransitionScheduleInDays": null, 32 | "deadlineForFeatureUpdatesInDays": null, 33 | "deadlineForQualityUpdatesInDays": null, 34 | "deadlineGracePeriodInDays": null, 35 | "postponeRebootUntilAfterDeadline": null, 36 | "autoRestartNotificationDismissal": "notConfigured", 37 | "scheduleRestartWarningInHours": 4, 38 | "scheduleImminentRestartWarningInMinutes": 15, 39 | "userPauseAccess": "enabled", 40 | "userWindowsUpdateScanAccess": "enabled", 41 | "updateNotificationLevel": "restartWarningsOnly", 42 | "installationSchedule": { 43 | "@odata.type": "#microsoft.graph.windowsUpdateActiveHoursInstall", 44 | "activeHoursStart": "08:00:00.0000000", 45 | "activeHoursEnd": "18:00:00.0000000" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-WIP/[ITPM Optional] WIP-MAM without enrollment.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "[ITPM Baseline] Windows MAM/without enrollment", 3 | "description": "Use this policy only if you plan to allow unmanaged Windows 10 devices to connect to your corporate data using Microsoft 365 desktop applications. Do not assign this policy until you have added your approved apps and network locations.", 4 | "enforcementLevel": "noProtection", 5 | "enterpriseDomain": "$EnterpriseDomain", 6 | "protectionUnderLockConfigRequired": false, 7 | "dataRecoveryCertificate": null, 8 | "revokeOnUnenrollDisabled": false, 9 | "rightsManagementServicesTemplateId": null, 10 | "azureRightsManagementServicesAllowed": false, 11 | "iconsVisible": true, 12 | "enterpriseIPRangesAreAuthoritative": false, 13 | "enterpriseProxyServersAreAuthoritative": false, 14 | "indexingEncryptedStoresOrItemsBlocked": false, 15 | "isAssigned": false, 16 | "revokeOnMdmHandoffDisabled": true, 17 | "mdmEnrollmentUrl": "https://enrollment.manage.microsoft.com/enrollmentserver/discovery.svc", 18 | "windowsHelloForBusinessBlocked": false, 19 | "pinMinimumLength": 6, 20 | "pinUppercaseLetters": "notAllow", 21 | "pinLowercaseLetters": "notAllow", 22 | "pinSpecialCharacters": "notAllow", 23 | "pinExpirationDays": 0, 24 | "numberOfPastPinsRemembered": 0, 25 | "passwordMaximumAttemptCount": 0, 26 | "minutesOfInactivityBeforeDeviceLock": 0, 27 | "daysWithoutContactBeforeUnenroll": 90, 28 | "enterpriseProtectedDomainNames": [ 29 | 30 | ], 31 | "protectedApps": [ 32 | 33 | ], 34 | "exemptApps": [ 35 | 36 | ], 37 | "enterpriseNetworkDomainNames": [ 38 | 39 | ], 40 | "enterpriseProxiedDomains": [ 41 | { 42 | "displayName": "OneDrive and SharePoint", 43 | "proxiedDomains": [ 44 | { 45 | "ipAddressOrFQDN": "$Sharepoint.sharepoint.com", 46 | "proxy": null 47 | }, 48 | { 49 | "ipAddressOrFQDN": "$Sharepoint-my.sharepoint.com", 50 | "proxy": null 51 | }, 52 | { 53 | "ipAddressOrFQDN": "/*AppCompat*/", 54 | "proxy": null 55 | } 56 | ] 57 | } 58 | ], 59 | "enterpriseIPRanges": [ 60 | 61 | ], 62 | "enterpriseProxyServers": [ 63 | 64 | ], 65 | "enterpriseInternalProxyServers": [ 66 | 67 | ], 68 | "neutralDomainResources": [ 69 | 70 | ], 71 | "smbAutoEncryptedFileExtensions": [ 72 | 73 | ], 74 | "protectedAppLockerFiles": [ 75 | 76 | ], 77 | "exemptAppLockerFiles": [ 78 | 79 | ], 80 | "assignments": [ 81 | 82 | ], 83 | "@odata.type": "#microsoft.graph.windowsInformationProtectionPolicy" 84 | } 85 | -------------------------------------------------------------------------------- /Windows 10/JSON/Win10-WIP/[ITPM Optional] WIP-MDM with enrollment.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "displayName": "[ITPM Baseline] Windows MDM/with enrollment)", 4 | "description": "Use this policy to protect corporate data on MDM enrolled devices. Do not assign this policy until you have added your approved apps and network locations.", 5 | "enforcementLevel": "noProtection", 6 | "enterpriseDomain": "$EnterpriseDomain", 7 | "protectionUnderLockConfigRequired": false, 8 | "dataRecoveryCertificate": null, 9 | "revokeOnUnenrollDisabled": false, 10 | "rightsManagementServicesTemplateId": null, 11 | "azureRightsManagementServicesAllowed": false, 12 | "iconsVisible": true, 13 | "enterpriseIPRangesAreAuthoritative": false, 14 | "enterpriseProxyServersAreAuthoritative": false, 15 | "indexingEncryptedStoresOrItemsBlocked": false, 16 | "isAssigned": false, 17 | "enterpriseProtectedDomainNames": [ 18 | 19 | ], 20 | "protectedApps": [ 21 | 22 | ], 23 | "exemptApps": [ 24 | 25 | ], 26 | "enterpriseNetworkDomainNames": [ 27 | 28 | ], 29 | "enterpriseProxiedDomains": [ 30 | { 31 | "displayName": "OneDrive and SharePoint", 32 | "proxiedDomains": [ 33 | { 34 | "ipAddressOrFQDN": "$Sharepoint.sharepoint.com", 35 | "proxy": "" 36 | }, 37 | { 38 | "ipAddressOrFQDN": "$Sharepoint-my.sharepoint.com", 39 | "proxy": "" 40 | }, 41 | { 42 | "ipAddressOrFQDN": "/*AppCompat*/", 43 | "proxy": "" 44 | } 45 | ] 46 | } 47 | ], 48 | "enterpriseIPRanges": [ 49 | 50 | ], 51 | "enterpriseProxyServers": [ 52 | 53 | ], 54 | "enterpriseInternalProxyServers": [ 55 | 56 | ], 57 | "neutralDomainResources": [ 58 | 59 | ], 60 | "smbAutoEncryptedFileExtensions": [ 61 | 62 | ], 63 | "protectedAppLockerFiles": [ 64 | 65 | ], 66 | "exemptAppLockerFiles": [ 67 | 68 | ], 69 | "assignments": [ 70 | 71 | ], 72 | "@odata.type": "#microsoft.graph.mdmWindowsInformationProtectionPolicy" 73 | } 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Windows 10/JSON/readme.md: -------------------------------------------------------------------------------- 1 | This folder contains export/import scripts that you can use in lieu of my **Install-Windows10SecurityProfiles.ps1** script. 2 | 3 | As well, I have included the individual JSON files that I use in my **Windows 10 Business Secure Configuration Guide**. 4 | -------------------------------------------------------------------------------- /Windows 10/readme.md: -------------------------------------------------------------------------------- 1 | NOTE: ALL SCRIPTS IN THIS DIRECTORY ARE OBSOLETE AND NO LONGER UPDATED. 2 | FOR THE LATEST, PLEASE SEE: https://github.com/vanvfields/Microsoft-365/tree/master/mggraph-samples 3 | 4 | -------------------------------------------------------------------------------- /ZeroTrustScripts.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanvfields/Microsoft-365/6be47eaa43899b34594c9c02c3dfd46d765c4d6f/ZeroTrustScripts.zip -------------------------------------------------------------------------------- /mggraph-samples/Install-SmbCompliancePolicies.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script installs device compliance policies from JSON: 5 | 1. [SMB] Windows - Immediate compliance 6 | 2. [SMB] Windows - Delayed compliance 7 | 3. [SMB] Windows - Defender compliance 8 | 9 | .NOTES 10 | FileName: Install-SmbCompliancePolicies.ps1 11 | Author: Alex Fields 12 | Based on: https://github.com/microsoft/mggraph-intune-samples & https://github.com/Azure/securedworkstation 13 | Created: May 2024 14 | Revised: May 2024 15 | Version: 1.0 16 | 17 | #> 18 | ################################################################################################### 19 | 20 | #region connect 21 | 22 | # Function to connect to Microsoft Graph 23 | function Connect-ToGraph { 24 | param ( 25 | [string[]]$RequiredScopes, 26 | [string[]]$RequiredModules 27 | ) 28 | 29 | # Import required modules 30 | foreach ($module in $RequiredModules) { 31 | try { 32 | #Import the module 33 | Import-Module -Name $module -ErrorAction Stop 34 | } 35 | catch { 36 | Write-Host "Failed to import $module module. Please install the module first." 37 | return 38 | } 39 | 40 | } 41 | 42 | try { 43 | # Connect to Microsoft Graph using Connect-MgGraph 44 | Connect-MgGraph -Scopes $RequiredScopes -ErrorAction Stop 45 | Write-Host "Successfully connected to Microsoft Graph with scopes: $($RequiredScopes -join ', ')" 46 | } 47 | catch { 48 | Write-Host "Failed to connect to Microsoft Graph. Please check your credentials and try again." 49 | Write-Host "Error: $($_.Exception.Message)" 50 | } 51 | } 52 | 53 | #Define the required scopes 54 | $RequiredScopes = @("DeviceManagementConfiguration.ReadWrite.All") 55 | 56 | #Define the required modules 57 | $RequiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.DeviceManagement") 58 | 59 | #Connect to the graph with required modules and scopes 60 | Connect-ToGraph -RequiredScopes $RequiredScopes -RequiredModules $RequiredModules 61 | 62 | #endregion 63 | 64 | #region functions 65 | 66 | #Function to create a compliance policy 67 | function New-CompliancePolicy { 68 | param ( 69 | [Parameter(Mandatory = $true)] 70 | [string]$JsonData 71 | ) 72 | 73 | try { 74 | # Define the Graph API URI for creating compliance policies 75 | $graphUri = "https://graph.microsoft.com/beta/deviceManagement/deviceCompliancePolicies" 76 | 77 | # Create the compliance policy in Microsoft Graph using Invoke-MgGraphRequest 78 | $response = Invoke-MgGraphRequest -Method POST -Uri $graphUri -Body $JsonData -ContentType "application/json" 79 | 80 | Write-Output "Compliance policy created successfully." 81 | } 82 | catch { 83 | Write-Error "Failed to create compliance policy: $($_.Exception.Message)" 84 | } 85 | } 86 | 87 | #endregion 88 | 89 | #region json 90 | 91 | $smbImmediate = @' 92 | { 93 | "@odata.type": "#microsoft.graph.windows10CompliancePolicy", 94 | "description": "Intune compliance settings to apply immediately\n", 95 | "displayName": "[SMB] Windows - Immediate compliance", 96 | "osMinimumVersion": "10.0.19045.0", 97 | "bitLockerEnabled": false, 98 | "secureBootEnabled": false, 99 | "codeIntegrityEnabled": false, 100 | "storageRequireEncryption": false, 101 | "activeFirewallRequired": false, 102 | "defenderEnabled": true, 103 | "defenderVersion": null, 104 | "signatureOutOfDate": false, 105 | "rtpEnabled": true, 106 | "antivirusRequired": false, 107 | "antiSpywareRequired": false, 108 | "deviceThreatProtectionEnabled": false, 109 | "deviceThreatProtectionRequiredSecurityLevel": "unavailable", 110 | "tpmRequired": false, 111 | "scheduledActionsForRule": [ 112 | { 113 | "ruleName": null, 114 | "@odata.type": "#microsoft.graph.deviceComplianceScheduledActionForRule", 115 | "scheduledActionConfigurations": [ 116 | { 117 | "gracePeriodHours": 0, 118 | "actionType": "block", 119 | "notificationTemplateId": "" 120 | } 121 | ] 122 | } 123 | ] 124 | } 125 | '@ 126 | 127 | $smbDelayed = @' 128 | { 129 | "@odata.type": "#microsoft.graph.windows10CompliancePolicy", 130 | "description": "Intune compliance settings to apply after a 24 hour grace period\n", 131 | "displayName": "[SMB] Windows - Delayed compliance", 132 | "osMinimumVersion": "10.0.19045.0", 133 | "bitLockerEnabled": true, 134 | "secureBootEnabled": true, 135 | "codeIntegrityEnabled": true, 136 | "storageRequireEncryption": false, 137 | "activeFirewallRequired": true, 138 | "defenderEnabled": true, 139 | "defenderVersion": null, 140 | "signatureOutOfDate": true, 141 | "rtpEnabled": true, 142 | "antivirusRequired": true, 143 | "antiSpywareRequired": true, 144 | "deviceThreatProtectionEnabled": false, 145 | "deviceThreatProtectionRequiredSecurityLevel": "unavailable", 146 | "tpmRequired": true, 147 | "scheduledActionsForRule": [ 148 | { 149 | "ruleName": null, 150 | "@odata.type": "#microsoft.graph.deviceComplianceScheduledActionForRule", 151 | "scheduledActionConfigurations": [ 152 | { 153 | "gracePeriodHours": 24, 154 | "actionType": "block", 155 | "notificationTemplateId": "" 156 | } 157 | ] 158 | } 159 | ] 160 | } 161 | '@ 162 | 163 | $smbDefender = @' 164 | { 165 | "@odata.type": "#microsoft.graph.windows10CompliancePolicy", 166 | "description": "Defender for Business compliance settings to apply after 24 hour grace period\n", 167 | "displayName": "[SMB] Windows - Defender for Business compliance", 168 | "deviceThreatProtectionEnabled": true, 169 | "deviceThreatProtectionRequiredSecurityLevel": "low", 170 | "scheduledActionsForRule": [ 171 | { 172 | "ruleName": null, 173 | "@odata.type": "#microsoft.graph.deviceComplianceScheduledActionForRule", 174 | "scheduledActionConfigurations": [ 175 | { 176 | "gracePeriodHours": 24, 177 | "actionType": "block", 178 | "notificationTemplateId": "" 179 | } 180 | ] 181 | } 182 | ] 183 | } 184 | '@ 185 | 186 | #endregion 187 | 188 | #region create policies 189 | 190 | New-CompliancePolicy -JsonData $smbImmediate 191 | New-CompliancePolicy -JsonData $smbDelayed 192 | New-CompliancePolicy -JsonData $smbDefender 193 | 194 | #endregion 195 | 196 | #Disconnect from Microsoft Graph 197 | Disconnect-MgGraph 198 | -------------------------------------------------------------------------------- /mggraph-samples/Install-SmbDeviceFilters.ps1: -------------------------------------------------------------------------------- 1 | <################################################################################################## 2 | # 3 | .SYNOPSIS 4 | This script installs device filters: 5 | 1. Windows-Corporate-Joined 6 | 2. Windows-Personal-Registered 7 | 3. Windows-Unknown 8 | 9 | .NOTES 10 | FileName: Install-SmbAdmxConfigs.ps1 11 | Author: Alex Fields 12 | Based on: https://github.com/microsoft/mggraph-intune-samples & https://github.com/Azure/securedworkstation 13 | Created: May 2024 14 | Revised: May 2024 15 | Version: 1.0 16 | 17 | #> 18 | ################################################################################################### 19 | 20 | #region connect 21 | 22 | function Connect-ToGraph { 23 | param ( 24 | [string[]]$RequiredScopes, 25 | [string[]]$RequiredModules 26 | ) 27 | 28 | # Import required modules 29 | foreach ($module in $RequiredModules) { 30 | try { 31 | #Import the module 32 | Import-Module -Name $module -ErrorAction Stop 33 | } 34 | catch { 35 | Write-Host "Failed to import $module module. Please install the module first." 36 | return 37 | } 38 | 39 | } 40 | 41 | try { 42 | # Connect to Microsoft Graph using Connect-MgGraph 43 | Connect-MgGraph -Scopes $RequiredScopes -ErrorAction Stop 44 | 45 | Write-Host "Successfully connected to Microsoft Graph with scopes: $($RequiredScopes -join ', ')" 46 | } 47 | catch { 48 | Write-Host "Failed to connect to Microsoft Graph. Please check your credentials and try again." 49 | Write-Host "Error: $($_.Exception.Message)" 50 | } 51 | } 52 | 53 | $RequiredScopes = @("DeviceManagementConfiguration.ReadWrite.All") 54 | $RequiredModules = @("Microsoft.Graph.Authentication") 55 | 56 | Connect-ToGraph -RequiredScopes $RequiredScopes -RequiredModules $RequiredModules 57 | 58 | #endregion 59 | 60 | #region functions 61 | 62 | function New-DeviceFilter { 63 | param ( 64 | [string]$jsonData 65 | ) 66 | 67 | $url = "https://graph.microsoft.com/beta/deviceManagement/assignmentFilters" 68 | 69 | try { 70 | $response = Invoke-MgGraphRequest -Method POST -Uri $url -Body $jsonData -ContentType "application/json" 71 | return $response 72 | } 73 | catch { 74 | Write-Error "An error occurred: $_" 75 | } 76 | } 77 | 78 | #endregion 79 | 80 | #region json 81 | 82 | $WinCorporate = @" 83 | { 84 | "displayName": "Windows-Corporate-Joined", 85 | "platform": "windows10AndLater", 86 | "assignmentFilterManagementType": "devices", 87 | "rule": "(device.deviceOwnership -eq \"Corporate\") or (device.deviceTrustType -eq \"Azure AD joined\") or (device.deviceTrustType -eq \"Hybrid Azure AD joined\")" 88 | } 89 | "@ 90 | 91 | $WinPersonal = @" 92 | { 93 | "displayName": "Windows-Personal-Registered", 94 | "platform": "windows10AndLater", 95 | "assignmentFilterManagementType": "devices", 96 | "rule": "(device.deviceOwnership -eq \"Personal\") or (device.deviceTrustType -eq \"Azure AD registered\")" 97 | } 98 | "@ 99 | 100 | $WinUnknown = @" 101 | { 102 | "displayName": "Windows-Unknown", 103 | "platform": "windows10AndLater", 104 | "assignmentFilterManagementType": "devices", 105 | "rule": "(device.deviceOwnership -eq \"Unknown\") or (device.deviceTrustType -eq \"Unknown\")" 106 | } 107 | "@ 108 | 109 | #endregion 110 | 111 | #region create filters 112 | 113 | New-DeviceFilter -jsonData $WinCorporate 114 | 115 | New-DeviceFilter -jsonData $WinPersonal 116 | 117 | New-DeviceFilter -jsonData $WinUnknown 118 | 119 | #endregion 120 | 121 | # Disconnect from Microsoft Graph 122 | Disconnect-MgGraph --------------------------------------------------------------------------------