# Check if the Microsoft Graph PowerShell SDK is installed if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) { Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force } # Check if the Microsoft Graph PowerShell SDK is installed if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Beta)) { Install-Module -Name Microsoft.Graph.Beta -Scope CurrentUser -Force } # Connect to Microsoft Graph Connect-MgGraph -Scopes "DeviceManagementConfiguration.ReadWrite.All", "Organization.Read.All", "Group.ReadWrite.All", "Directory.ReadWrite.All" -NoWelcome # Get Tenant ID $tenant = Get-MgOrganization $tenantId = $tenant.Id # Create the security group with static membership $groupBody = @{ displayName = "Intune - Test Machine Group" mailEnabled = $false mailNickname = "IntuneTestMachineGroup" securityEnabled = $true # No need for groupTypes or membershipRule for static groups } $group = $groupBody.displayName # Convert the body to JSON $groupBodyJson = $groupBody | ConvertTo-Json -Depth 100 # Create the static group using Invoke-MgGraphRequest $response = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/groups" -Body $groupBodyJson -ContentType "application/json" $groupId = $response.id Write-Host "✅ Successfully created static group '$group - $groupid'" # Define the dynamic membership rule $dynamicRule = '(device.deviceOSType -eq "Windows") and (device.accountEnabled -eq true) and (device.managementType -eq "MDM")' #(device.devicePhysicalIDs -any (_ -startsWith "[ZTDid]")) # Create the security group with dynamic membership $groupBody = @{ displayName = "Intune - All Windows Workstations MDM" mailEnabled = $false mailNickname = "IntuneWindowsDevices" securityEnabled = $true groupTypes = @("DynamicMembership") membershipRule = $dynamicRule membershipRuleProcessingState = "On" } $group = $groupBody.displayname # Convert the body to JSON $groupBodyJson = $groupBody | ConvertTo-Json -Depth 100 # Create the group using Invoke-MgGraphRequest $null = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/groups" -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $group" # Define the dynamic membership rule $dynamicRule = '(device.devicePhysicalIDs -any (_ -startsWith "[ZTDid]"))' # Create the security group with dynamic membership $groupBody = @{ displayName = "Intune - AutoPilot Devices" mailEnabled = $false mailNickname = "IntuneWindowsDevices" securityEnabled = $true groupTypes = @("DynamicMembership") membershipRule = $dynamicRule membershipRuleProcessingState = "On" } $group = $groupBody.displayname # Convert the body to JSON $groupBodyJson = $groupBody | ConvertTo-Json -Depth 100 # Create the group using Invoke-MgGraphRequest $null = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/groups" -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $group" # Define the dynamic membership rule $dynamicRule = '(device.deviceOSVersion -startsWith "10") and (device.deviceOSType -eq "Windows")' # Create the security group with dynamic membership $groupBody = @{ displayName = "Intune - All Windows Computers" mailEnabled = $false mailNickname = "IntuneWindowsDevices" securityEnabled = $true groupTypes = @("DynamicMembership") membershipRule = $dynamicRule membershipRuleProcessingState = "On" } $group = $groupBody.displayname # Convert the body to JSON $groupBodyJson = $groupBody | ConvertTo-Json -Depth 100 # Create the group using Invoke-MgGraphRequest $null = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/groups" -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $group" $policies = Get-ChildItem ./policies/settingscatalog ForEach ($policy in $policies) { $PolicyName = $policy.name $JsonData = Get-Content -Path ./policies/settingscatalog/$PolicyName -Raw $JsonDataUpdated = $JsonData -replace '\$tenantId', $tenantId $PolicyObject = $JsonDataUpdated | ConvertFrom-Json try { # Add assignment to the created group $uri = "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies" # Using the beta version $response = Invoke-MgGraphRequest -Method POST -Uri $uri -Body ($PolicyObject | ConvertTo-Json -Depth 100) Write-Host "✅ $PolicyName - successfully imported!" $policyid = $response.id $assignmentUri = "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies/$PolicyId/assign" $assignmentBody = @{ assignments = @( @{ target = @{ "@odata.type" = "#microsoft.graph.groupAssignmentTarget" groupId = $groupId } } ) } Invoke-MgGraphRequest -Method POST -Uri $assignmentUri -Body ($assignmentBody | ConvertTo-Json -Depth 100) Write-Host "✅ Group assigned to the policy!" } catch { Write-Error "❌ An error occurred while importing the policy: $_" } } $policies = Get-ChildItem ./policies/compliance ForEach ($policy in $policies) { $PolicyName = $policy.name $JsonData = Get-Content -Path ./policies/compliance/$PolicyName -Raw $JsonDataUpdated = $JsonData -replace '\$tenantId', $tenantId $PolicyObject = $JsonDataUpdated | ConvertFrom-Json try { $uri = "https://graph.microsoft.com/beta/deviceManagement/deviceCompliancePolicies" # Using the beta version $null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body ($PolicyObject | ConvertTo-Json -Depth 100) Write-Host "✅ $PolicyName - successfully imported!" } catch { Write-Error "❌ An error occurred while importing the policy: $_" } } # Create Windows Update Ring Policies # Create a baseline policy using web interface # Extract the JSON Data to build paramters # - Get-MgDeviceManagementDeviceConfiguration | Select-Object displayName, id, @{Name="JSON"; Expression={ $_ | ConvertTo-Json -Depth 10 }} # Get the ID of the policy you created and get the JSON structure # - Get-MgDeviceManagementDeviceConfiguration -DeviceConfigurationId "" | ConvertTo-Json -Depth 10 # Define the update ring configuration with Microsoft product updates enabled $params = @{ "@odata.type"= "#microsoft.graph.windowsUpdateForBusinessConfiguration" "displayName"= "Win - Windows Updates - Ring 1 - Pilot" "description"= "Devices in this ring receive updates immediately after release with 1 day grace period before a forced reboot." "automaticUpdateMode"= "windowsDefault" "deliveryOptimizationMode"= "userDefined" "prereleaseFeatures"= "userDefined" "microsoftUpdateServiceAllowed"= $true # Enables updates for Microsoft products "driversExcluded"= $false "qualityUpdatesDeferralPeriodInDays"= 0 "featureUpdatesDeferralPeriodInDays"= 0 "qualityUpdatesPaused"= $false "featureUpdatesPaused"= $false "businessReadyUpdatesOnly"= "userDefined" "skipChecksBeforeRestart"= $false "featureUpdatesRollbackWindowInDays"= 30 "qualityUpdatesWillBeRolledBack"= $false "featureUpdatesWillBeRolledBack"= $false "deadlineForFeatureUpdatesInDays"= 0 "deadlineForQualityUpdatesInDays"= 0 "deadlineGracePeriodInDays"= 1 "postponeRebootUntilAfterDeadline"= $true "autoRestartNotificationDismissal"= "notConfigured" "userPauseAccess"= "disabled" "userWindowsUpdateScanAccess"= "enabled" "updateNotificationLevel"= "defaultNotifications" "allowWindows11Upgrade"= $false "roleScopeTagIds"= @("0") # Scope tags (use appropriate scope tags as needed) "supportsScopeTags"= $true } $ring = $params.displayName # Create the update ring policy in Intune $null = New-MgDeviceManagementDeviceConfiguration -BodyParameter $params Write-Host "✅ Successfully created $ring" $params = @{ "@odata.type"= "#microsoft.graph.windowsUpdateForBusinessConfiguration" "displayName"= "Win - Windows Updates - Ring 2 - UAT" "description"= "Devices in this ring receive updates 3 days after release and have a 0-day deadline on install with 2 day grace period before a forced reboot." "version"= 1 "deliveryOptimizationMode"= "userDefined" "prereleaseFeatures"= "userDefined" "automaticUpdateMode"= "windowsDefault" "microsoftUpdateServiceAllowed"= $true "driversExcluded"= $false "qualityUpdatesDeferralPeriodInDays"= 3 "featureUpdatesDeferralPeriodInDays"= 0 "qualityUpdatesPaused"= $false "featureUpdatesPaused"= $false "businessReadyUpdatesOnly"= "userDefined" "skipChecksBeforeRestart"= $false "featureUpdatesRollbackWindowInDays"= 30 "qualityUpdatesWillBeRolledBack"= $false "featureUpdatesWillBeRolledBack"= $false "deadlineForFeatureUpdatesInDays"= 0 "deadlineForQualityUpdatesInDays"= 0 "deadlineGracePeriodInDays"= 2 "postponeRebootUntilAfterDeadline"= $true "autoRestartNotificationDismissal"= "notConfigured" "userPauseAccess"= "disabled" "userWindowsUpdateScanAccess"= "enabled" "updateNotificationLevel"= "defaultNotifications" "allowWindows11Upgrade"= $false "roleScopeTagIds"= @("0") "supportsScopeTags"= $true "createdDateTime"= "2023-10-27T15:13:33.3648624Z" "lastModifiedDateTime"= "2023-10-27T15:13:33.3648624Z" } $ring = $params.displayName # Create the update ring policy in Intune $null = New-MgDeviceManagementDeviceConfiguration -BodyParameter $params Write-Host "✅ Successfully created $ring" $params = @{ "@odata.type"= "#microsoft.graph.windowsUpdateForBusinessConfiguration" "displayName"= "Win - Windows Updates - Ring 3 - Production" "description"= "Devices in this ring receive updates 10 days after release and have a 2-day deadline on install with 1 day grace period before a forced reboot." "version"= 1 "deliveryOptimizationMode"= "userDefined" "prereleaseFeatures"= "userDefined" "automaticUpdateMode"= "windowsDefault" "microsoftUpdateServiceAllowed"= $true "driversExcluded"= $false "qualityUpdatesDeferralPeriodInDays"= 10 "featureUpdatesDeferralPeriodInDays"= 0 "qualityUpdatesPaused"= $false "featureUpdatesPaused"= $false "businessReadyUpdatesOnly"= "userDefined" "skipChecksBeforeRestart"= $false "featureUpdatesRollbackWindowInDays"= 30 "qualityUpdatesWillBeRolledBack"= $false "featureUpdatesWillBeRolledBack"= $false "deadlineForFeatureUpdatesInDays"= 2 "deadlineForQualityUpdatesInDays"= 2 "deadlineGracePeriodInDays"= 1 "postponeRebootUntilAfterDeadline"= $true "autoRestartNotificationDismissal"= "notConfigured" "userPauseAccess"= "disabled" "userWindowsUpdateScanAccess"= "enabled" "updateNotificationLevel"= "defaultNotifications" "allowWindows11Upgrade"= $false "roleScopeTagIds"= @("0") "supportsScopeTags"= $true "createdDateTime"= "2023-10-27T15:13:33.5897267Z" "lastModifiedDateTime"= "2023-10-27T15:13:33.5897267Z" } $ring = $params.displayName # Create the update ring policy in Intune $null = New-MgDeviceManagementDeviceConfiguration -BodyParameter $params Write-Host "✅ Successfully created $ring" $uri = "https://graph.microsoft.com/beta/deviceManagement/windowsDriverUpdateProfiles" # Define the JSON body for the new driver update profile $body = @{ "displayName" = "Win - Drivers - Ring 1 - Pilot" "description" = "" # Empty description field from original JSON "approvalType" = "automatic" # "automatic" from the original JSON "deploymentDeferralInDays" = 0 # "0" from the original JSON "newUpdates" = 0 # "0" from the original JSON "roleScopeTagIds" = @("0") # Role Scope Tag ID from the original JSON } $ring = $body.displayName $groupBodyJson = $Body | ConvertTo-Json -Depth 100 # Send the POST request to create the Driver Update Profile $null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $ring" $uri = "https://graph.microsoft.com/beta/deviceManagement/windowsDriverUpdateProfiles" # Define the JSON body for the new driver update profile $body = @{ "displayName" = "Win - Drivers - Ring 2 - UAT" "description" = "" # Empty description field from original JSON "approvalType" = "automatic" # "automatic" from the original JSON "deploymentDeferralInDays" = 3 # "3" from the original JSON "newUpdates" = 0 # "0" from the original JSON "roleScopeTagIds" = @("0") # Role Scope Tag ID from the original JSON } $ring = $body.displayName $groupBodyJson = $Body | ConvertTo-Json -Depth 100 # Send the POST request to create the Driver Update Profile $null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $ring" $uri = "https://graph.microsoft.com/beta/deviceManagement/windowsDriverUpdateProfiles" # Define the JSON body for the new driver update profile $body = @{ "displayName" = "Win - Drivers - Ring 3 - Production" "description" = "" # Empty description field from original JSON "approvalType" = "automatic" # "automatic" from the original JSON "deploymentDeferralInDays" = 10 # "10" from the original JSON "newUpdates" = 0 # "0" from the original JSON "roleScopeTagIds" = @("0") # Role Scope Tag ID from the original JSON } $ring = $body.displayName $groupBodyJson = $Body | ConvertTo-Json -Depth 100 # Send the POST request to create the Driver Update Profile $null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $ring" $null = Disconnect-Graph -ErrorAction SilentlyContinue