# 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 # Define the dynamic membership rule $dynamicRule = '(device.deviceOSType -eq "Windows") and (device.accountEnabled -eq true) and (device.managementType -eq "MDM")' # 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 10 # 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 10 # 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 ($policie in $policies) { $PolicyName = $policie.name $JsonData = Get-Content -Path ./policies/settingscatalog/$PolicieName -Raw $JsonDataUpdated = $JsonData -replace '\$tenantId', $tenantId $PolicyObject = $JsonDataUpdated | ConvertFrom-Json try { $uri = "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies" # Using the beta version $null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body ($PolicyObject | ConvertTo-Json -Depth 10) 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 10 # Send the POST request to create the Driver Update Profile $response = 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 10 # Send the POST request to create the Driver Update Profile $response = 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 10 # Send the POST request to create the Driver Update Profile $response = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $groupBodyJson -ContentType "application/json" Write-Host "✅ Successfully created group $ring" $null = Disconnect-Graph -ErrorAction SilentlyContinue