Files
IntunePolicies/Setup.ps1

275 lines
9.4 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function Get-OrCreateGroup {
param(
[string]$DisplayName,
[string]$MailNickname
)
$group = Get-MgGroup -Filter "displayName eq '$DisplayName'" -ConsistencyLevel eventual -CountVariable count
if ($group) {
Write-Host "🚫 Group '$DisplayName' already exists. Using existing GroupId: $($group.Id)"
return $group
}
else {
Write-Host "✅ Creating group '$DisplayName'..."
return New-MgGroup -BodyParameter @{
DisplayName = $DisplayName
MailEnabled = $false
MailNickname = $MailNickname
SecurityEnabled = $true
}
}
}
# Function to get or create CA policy
function Get-OrCreatePolicy {
param(
[string]$DisplayName,
[hashtable]$BodyParams
)
$policy = Get-MgIdentityConditionalAccessPolicy -Filter "displayName eq '$DisplayName'"
if ($policy) {
Write-Host "🚫 Policy '$DisplayName' already exists. Skipping creation."
return $policy
}
else {
Write-Host "✅ Creating policy '$DisplayName'..."
return New-MgIdentityConditionalAccessPolicy -BodyParameter $BodyParams
}
}
function Get-OrCreateCountryNamedLocations {
param(
[string[]]$Countries # ISO codes
)
$namedLocationIds = @()
foreach ($c in $Countries) {
$displayName = "Country - $c"
# Check if it exists
$existing = Get-MgIdentityConditionalAccessNamedLocation -Filter "displayName eq '$displayName'" -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "🚫 Named Location for $c already exists: $($existing.Id)"
$namedLocationIds += $existing.Id
}
else {
# Create new Named Location
$newLoc = New-MgIdentityConditionalAccessNamedLocation -BodyParameter @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
DisplayName = $displayName
CountriesAndRegions = @($c)
IncludeUnknownCountriesAndRegions = $false
}
Write-Host "✅ Created Named Location for $c $($newLoc.Id)"
$namedLocationIds += $newLoc.Id
}
}
return $namedLocationIds
}
# Ensure Microsoft Graph modules are installed
foreach ($module in @("Microsoft.Graph", "Microsoft.Graph.Beta", "ExchangeOnlineManagement")) {
if (-not (Get-Module -ListAvailable -Name $module)) {
Install-Module -Name $module -Scope CurrentUser -Force
}
}
Write-Host "🔐 Connecting to MS Graph Online..."
Connect-MgGraph -NoWelcome -Scopes `
"Policy.ReadWrite.SecurityDefaults", `
"Policy.ReadWrite.ConditionalAccess", `
"Policy.Read.All", `
"Group.ReadWrite.All", `
"Directory.ReadWrite.All", `
"UserAuthenticationMethod.ReadWrite.All", `
"Application.ReadWrite.All", `
"SecurityEvents.ReadWrite.All"
Write-Host "Connected to Microsoft Graph"
Write-Host "✅ Disabling Security Defaults..."
Update-MgPolicyIdentitySecurityDefaultEnforcementPolicy -BodyParameter @{ isEnabled = $false }
Write-Host " Checking/Creating Exclusion Groups..."
$teamsRoomsGroup = Get-OrCreateGroup -DisplayName "TeamsRoomsExclusions" -MailNickname "TeamsRoomsExcl"
$osTravelGroup = Get-OrCreateGroup -DisplayName "OSTravelExclusions" -MailNickname "OSTravelExcl"
Write-Host " Teams Rooms GroupId: $($teamsRoomsGroup.Id)"
Write-Host " OS Travel GroupId: $($osTravelGroup.Id)"
Write-Host " Checking/Creating Conditional Access Policy for Country Blocking..."
$AllowedCountries = @("AU","NZ","US","GB","DE","FR") # Add any ISO codes here
$allowedLocationIds = Get-OrCreateCountryNamedLocations -Countries $AllowedCountries
# 2. Wait for consistency
foreach ($locId in $allowedLocationIds) {
$retries = 0
do {
Start-Sleep -Seconds 2
$check = Get-MgIdentityConditionalAccessNamedLocation -Filter "id eq '$locId'" -ErrorAction SilentlyContinue
$retries++
} while (-not $check -and $retries -lt 10)
if (-not $check) { throw "⚠️ Named Location $locId not found in directory." }
}
$countryPolicyParams = @{
DisplayName = "Block countries except allowed"
State = "disabled"
Conditions = @{
Users = @{
IncludeUsers = @("All")
ExcludeGroups = @($osTravelGroup.Id)
}
Locations = @{
IncludeLocations = @("All")
ExcludeLocations = $allowedLocationIds
}
Applications = @{
IncludeApplications = @("All")
ExcludeApplications = @()
}
ClientAppTypes = @("all")
}
GrantControls = @{
Operator = "OR"
BuiltInControls = @("block")
}
}
$Policy = Get-OrCreatePolicy -DisplayName "Block countries except allowed" -BodyParams $countryPolicyParams
# Define the policy from your JSON
$policyParams = @{
DisplayName = "Require multifactor authentication for admins"
State = "enabled"
Conditions = @{
Users = @{
IncludeRoles = @(
"62e90394-69f5-4237-9190-012177145e10" # Global Administrator
"194ae4cb-b126-40b2-bd5b-6091b380977d" # Privileged Role Administrator
"f28a1f50-f6e7-4571-818b-6a12f2af6b6c" # Security Reader
"29232cdf-9323-42fd-ade2-1d097af3e4de" # Exchange Administrator
"b1be1c3e-b65d-4f19-8427-f6fa0d97feb9" # SharePoint Administrator
"729827e3-9c14-49f7-bb1b-9608f156bbb8" # Security Administrator
"b0f54661-2d74-4c50-afa3-1ec803f12efe" # Helpdesk Administrator
"fe930be7-5e62-47db-91af-98c3a49a38b1" # User Administrator
"c4e39bd9-1100-46d3-8c65-fb160da0071f" # Authentication Administrator
"9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3" # Conditional Access Administrator
"158c047a-c907-4556-b7ef-446551a6b5f7" # Security Operator
"966707d0-3269-4727-9be2-8c3a10f19b9d" # Reports Reader
"7be44c8a-adaf-4e2a-84d6-ab2649e08a13" # Billing Administrator
"e8611ab8-c189-46e8-94e1-60213ab1f814" # Cloud Application Administrator
)
ExcludeRoles = @(
"d29b2b05-8046-44ba-8758-1e26182fcf32" # Directory Synchronization Accounts
)
}
Applications = @{
IncludeApplications = @("All")
ExcludeApplications = @()
}
ClientAppTypes = @("all")
}
GrantControls = @{
Operator = "OR"
BuiltInControls = @("mfa")
}
}
# Create the Conditional Access policy
$policy = Get-OrCreatePolicy -DisplayName "Require multifactor authentication for admins" -BodyParams $policyParams
# Define the policy from your JSON
$policyParams = @{
DisplayName = "Require multifactor authentication for all users"
State = "enabled"
Conditions = @{
Users = @{
IncludeUsers = @("All")
ExcludeGroups = @($osTravelGroup.Id)
ExcludeRoles = @(
"d29b2b05-8046-44ba-8758-1e26182fcf32" # Directory Synchronization Accounts
)
}
Applications = @{
IncludeApplications = @("All")
ExcludeApplications = @()
}
ClientAppTypes = @("all")
}
GrantControls = @{
Operator = "OR"
BuiltInControls = @("mfa")
}
}
# Create the Conditional Access policy
$policy = Get-OrCreatePolicy -DisplayName "Require multifactor authentication for all users" -BodyParams $policyParams
# Define the policy from your JSON
$policyParams = @{
DisplayName = "Require multifactor authentication for Azure management"
State = "enabled"
Conditions = @{
Users = @{
IncludeUsers = @("All")
ExcludeRoles = @(
"d29b2b05-8046-44ba-8758-1e26182fcf32" # Directory Synchronization Accounts
)
}
Applications = @{
IncludeApplications = @(
"797f4846-ba00-4fd7-ba43-dac1f8f63013" # Azure Management
)
ExcludeApplications = @()
}
ClientAppTypes = @("all")
}
GrantControls = @{
Operator = "OR"
BuiltInControls = @("mfa")
}
}
# Create the Conditional Access policy
$policy = Get-OrCreatePolicy -DisplayName "Require multifactor authentication for Azure management" -BodyParams $policyParams
# Get Graph token for REST calls
$token = (Get-MgContext).AccessToken
$headers = @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" }
# Get all users
$users = Get-MgUser -All -Property "id,userPrincipalName,accountEnabled,strongAuthenticationRequirements"
foreach ($u in $users) {
# Skip disabled accounts
if (-not $u.AccountEnabled) {
Write-Host "🚫 Skipping disabled user $($u.UserPrincipalName)"
continue
}
# Skip if MFA already not set
if (-not $u.StrongAuthenticationRequirements -or $u.StrongAuthenticationRequirements.Count -eq 0) {
Write-Host " No per-user MFA set for $($u.UserPrincipalName) skipping"
continue
}
# Clear per-user MFA
$body = @{ strongAuthenticationRequirements = @() } | ConvertTo-Json -Depth 3
Invoke-RestMethod -Method PATCH `
-Headers $headers `
-Uri "https://graph.microsoft.com/v1.0/users/$($u.Id)" `
-Body $body
Write-Host "✅ Disabled per-user MFA for $($u.UserPrincipalName)"
}