mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
378 lines
13 KiB
PowerShell
378 lines
13 KiB
PowerShell
#ImportOrder 220
|
|
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("TypeNotFound","", Justification = "")]
|
|
class ComplianceGroup : IntunePolicyGroupBase
|
|
{
|
|
ComplianceGroup() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._ID = "Compliance"
|
|
$this._Name = "Compliance"
|
|
$this._Icon = "CompliancePolicies"
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# Device Compliance
|
|
#
|
|
#########################################################################################
|
|
|
|
# region Device Compliance
|
|
class DeviceComplianceType : IntunePolicyTypeBase
|
|
{
|
|
DeviceComplianceType() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._PolicyGroup = (Get-SingletonObject "ComplianceGroup")
|
|
$this._PolicyName = "Compliance Policy"
|
|
$this._ID = "CompliancePolicies"
|
|
$this._API = "deviceManagement/deviceCompliancePolicies"
|
|
# This endpoint answers HTTP 400 to startswith() on displayName
|
|
# (verified 2026-08-27; 'displayName eq' works, prefix search does not),
|
|
# so name searches filter client-side instead.
|
|
$this._SupportsNameFilter = $false
|
|
$this._Permissions = @("DeviceManagementConfiguration.ReadWrite.All")
|
|
$this._Expand = "scheduledActionsForRule(`$expand=scheduledActionConfigurations)"
|
|
# "Locations" (v3's deprecated Intune managementConditions type) is not a
|
|
# PolicyType here, so listing it resolved to nothing on import.
|
|
$this._Dependencies = @("Notifications","ComplianceScripts")
|
|
$this._ObjectClass = "DeviceComplianceObject"
|
|
|
|
if($null -ne $this._PolicyGroup) {
|
|
$this._PolicyGroup.AddPolicyType($this)
|
|
}
|
|
}
|
|
|
|
PostExportCommand([PSCustomObject]$PolicyObject, [String]$PathToFile)
|
|
{
|
|
foreach($scheduledActionsForRule in $PolicyObject.JsonObject.scheduledActionsForRule)
|
|
{
|
|
foreach($scheduledActionConfiguration in $scheduledActionsForRule.scheduledActionConfigurations)
|
|
{
|
|
foreach($notificationMessageCCGroup in $scheduledActionConfiguration.notificationMessageCCList)
|
|
{
|
|
Add-GraphMigrationObject $notificationMessageCCGroup "groups" "Group" ([IO.Path]::GetDirectoryName($PathToFile)) $PolicyObject._TokenId
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Hashtable]PreUpdateCommand([PSCustomObject]$PolicyObject, [PSCustomObject]$SourceObject)
|
|
{
|
|
$api = "deviceManagement/deviceCompliancePolicies/$($PolicyObject.Id)/scheduleActionsForRules"
|
|
|
|
$tmpObj = [PSCustomObject]@{
|
|
deviceComplianceScheduledActionForRules = $PolicyObject.JsonObject.scheduledActionsForRule
|
|
}
|
|
|
|
$json = ConvertTo-Json $tmpObj -Depth 20
|
|
Invoke-MSGraphAPI -Url $api -Content $json -HttpMethod "POST" -TokenId $PolicyObject._TokenId | Out-Null
|
|
|
|
Remove-Property $PolicyObject.JsonObject "scheduledActionsForRule"
|
|
|
|
return (@{})
|
|
}
|
|
}
|
|
|
|
Class DeviceComplianceObject : IntunePolicyBase
|
|
{
|
|
DeviceComplianceObject([PSCustomObject]$JsonObj) : Base($JsonObj) { $this.Init() }
|
|
|
|
DeviceComplianceObject() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Hidden Init()
|
|
{
|
|
$this._PolicyType = (Get-SingletonObject "DeviceComplianceType")
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# Device Compliance V2
|
|
#
|
|
#########################################################################################
|
|
|
|
Class DeviceComplianceV2Type : IntunePolicyTypeBase
|
|
{
|
|
DeviceComplianceV2Type() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._PolicyGroup = (Get-SingletonObject "ComplianceGroup")
|
|
# Its own name so a mixed Compliance list tells V1 from V2 without a
|
|
# separate "Policy base" column.
|
|
$this._PolicyName = "Compliance Policy (Settings Catalog)"
|
|
$this._PolicyBaseName = "Compliance Policy V2"
|
|
$this._APITitle = "Compliance Policy (Linux)"
|
|
$this._ID = "CompliancePoliciesV2"
|
|
$this._API = "deviceManagement/compliancePolicies"
|
|
$this._PropertiesToRemove = @('settingCount')
|
|
$this._Permissions = @("DeviceManagementConfiguration.ReadWrite.All")
|
|
$this._NameProperty = "Name"
|
|
$this._Expand = "settings"
|
|
$this._ObjectClass = "DeviceComplianceV2Object"
|
|
$this._Icon = "CompliancePolicies"
|
|
|
|
if($null -ne $this._PolicyGroup) {
|
|
$this._PolicyGroup.AddPolicyType($this)
|
|
}
|
|
}
|
|
|
|
[Hashtable]PreUpdateCommand([PSCustomObject]$PolicyObject, [PSCustomObject]$SourceObject)
|
|
{
|
|
# V2 compliance runs on the settings-catalog engine: updates must PUT
|
|
# the full body (including settings); PATCH with settings is rejected.
|
|
return @{ "Method" = "PUT" }
|
|
}
|
|
}
|
|
|
|
Class DeviceComplianceV2Object : IntunePolicyBase
|
|
{
|
|
DeviceComplianceV2Object([PSCustomObject]$JsonObj) : Base($JsonObj) { $this.Init() }
|
|
|
|
DeviceComplianceV2Object() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Hidden Init()
|
|
{
|
|
$this._PolicyType = (Get-SingletonObject "DeviceComplianceV2Type")
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# Compliance Scripts
|
|
#
|
|
#########################################################################################
|
|
|
|
Class ComplianceScriptsType : IntunePolicyTypeBase
|
|
{
|
|
ComplianceScriptsType() : Base()
|
|
{
|
|
([ComplianceScriptsType]$this).Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._PolicyGroup = (Get-SingletonObject "ComplianceGroup")
|
|
$this._APITitle = "Compliance Scripts"
|
|
$this._PolicyName = "Compliance Script"
|
|
$this._ID = "ComplianceScripts"
|
|
$this._API = "deviceManagement/deviceComplianceScripts"
|
|
$this._Permissions = @("DeviceManagementConfiguration.ReadWrite.All")
|
|
$this._ObjectClass = "ComplianceScriptObject"
|
|
$this._Icon = "Scripts"
|
|
# Graph rejects PATCHing the read-only version back ("Invalid property
|
|
# name: Version").
|
|
$this._PropertiesToRemoveForUpdate = @('version')
|
|
# Custom compliance scripts are REFERENCED by compliance policies, not
|
|
# assigned to devices - the portal has no Assignments blade and Graph's
|
|
# /assign action rejects the request (400 "Action parameters do not
|
|
# contain parameter 'deviceHealthScriptAssignments'").
|
|
$this._SupportsAssignments = $false
|
|
|
|
if($null -ne $this._PolicyGroup) {
|
|
$this._PolicyGroup.AddPolicyType($this)
|
|
}
|
|
}
|
|
}
|
|
|
|
Class ComplianceScriptObject : IntunePolicyBase
|
|
{
|
|
ComplianceScriptObject([PSCustomObject]$JsonObj) : Base($JsonObj) { $this.Init() }
|
|
|
|
ComplianceScriptObject() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Hidden Init()
|
|
{
|
|
$this._PlatformName = Get-LanguageString "Platform.windows10AndLater"
|
|
$this._PolicyType = (Get-SingletonObject "ComplianceScriptsType")
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# Compliance Scripts - Linux
|
|
#
|
|
#########################################################################################
|
|
|
|
Class ComplianceScriptsLinuxType : ReusableSettingsTypeBase
|
|
{
|
|
ComplianceScriptsLinuxType() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._PolicyGroup = (Get-SingletonObject "ComplianceGroup")
|
|
$this._APITitle = "Compliance Scripts (Linux)"
|
|
$this._PolicyName = "Compliance Script"
|
|
$this._ID = "ComplianceScriptsScriptsLinux"
|
|
$this._QueryList = "?`$filter=settingDefinitionId eq 'linux_customcompliance_discoveryscript_reusablesetting'"
|
|
# Reusable settings carry no roleScopeTagIds in the Graph schema.
|
|
$this._ScopeTagProperty = ""
|
|
$this._ObjectClass = "ComplianceScriptLinuxObject"
|
|
$this._Icon = "Scripts"
|
|
$this._Folder = "ReusableSettings"
|
|
$this._PolicyTypeOrder = 140
|
|
$this._ExpandAssignmentsList = $false
|
|
$this._SupportsAssignments = $false
|
|
|
|
if($null -ne $this._PolicyGroup) {
|
|
$this._PolicyGroup.AddPolicyType($this)
|
|
}
|
|
}
|
|
|
|
[Boolean]CheckPolicy([PSCustomObject]$PolicyObject)
|
|
{
|
|
if($PolicyObject.'@odata.type' -ne "#microsoft.graph.deviceManagementReusablePolicySetting") { return $false }
|
|
|
|
if($PolicyObject.settingDefinitionId -eq 'linux_customcompliance_discoveryscript_reusablesetting') {
|
|
return $true
|
|
}
|
|
|
|
return $false
|
|
}
|
|
}
|
|
|
|
Class ComplianceScriptLinuxObject : ReusableSettingsObjectBase
|
|
{
|
|
ComplianceScriptLinuxObject([PSCustomObject]$JsonObj) : Base($JsonObj) { $this.Init() }
|
|
|
|
ComplianceScriptLinuxObject() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Hidden Init()
|
|
{
|
|
$this._PolicyType = (Get-SingletonObject "ComplianceScriptsLinuxType")
|
|
$this._PlatformName = Get-LanguageString "Platform.linux" -IgnoreMissing
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# Compliance Notifications
|
|
#
|
|
#########################################################################################
|
|
|
|
Class NotificationsType : IntunePolicyTypeBase
|
|
{
|
|
NotificationsType() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Init()
|
|
{
|
|
$this._PolicyGroup = (Get-SingletonObject "ComplianceGroup")
|
|
$this._PolicyName = "Notifications"
|
|
$this._ID = "Notifications"
|
|
$this._HasPlatform = $false
|
|
$this._API = "deviceManagement/notificationMessageTemplates"
|
|
#$this._QueryList = "?`$filter=displayName ne 'EnrollmentNotificationInternalMEO'"
|
|
$this._Permissions = @("DeviceManagementServiceConfig.ReadWrite.All")
|
|
$this._ObjectClass = "NotificationObject"
|
|
$this._ImportOrder = 40
|
|
$this._Expand = "localizedNotificationMessages"
|
|
$this._ExpandAssignmentsList = $false
|
|
# notificationMessageTemplate has no `assignments` navigation property at
|
|
# all (its only nav is localizedNotificationMessages), so both the nav GET
|
|
# and ?$expand=assignments return 400. Notification templates are targeted
|
|
# from compliance policies, not assigned - don't ask for assignments.
|
|
$this._SupportsAssignments = $false
|
|
# notificationMessageTemplate has no description property in Graph.
|
|
$this._HasDescription = $false
|
|
# localizedNotificationMessages is a navigation property - PATCHing it
|
|
# inline is rejected; messages are managed on their own sub-endpoint.
|
|
$this._PropertiesToRemoveForUpdate = @('localizedNotificationMessages','defaultLocale')
|
|
|
|
if($null -ne $this._PolicyGroup) {
|
|
$this._PolicyGroup.AddPolicyType($this)
|
|
}
|
|
}
|
|
|
|
[Hashtable]PreImportCommand([PSCustomObject]$PolicyObject)
|
|
{
|
|
Remove-Property $PolicyObject.JsonObject "defaultLocale"
|
|
Remove-Property $PolicyObject.JsonObject "localizedNotificationMessages"
|
|
Remove-Property $PolicyObject.JsonObject "localizedNotificationMessages@odata.context"
|
|
|
|
return $null
|
|
}
|
|
|
|
PostImportCommand([PSCustomObject]$PolicyObject, [PSCustomObject]$SourceObject)
|
|
{
|
|
$this.UpdateNotificationMessages($PolicyObject, $SourceObject.JsonObject.localizedNotificationMessages)
|
|
}
|
|
|
|
Hidden UpdateNotificationMessages($PolicyObject, $localizedNotificationMessages)
|
|
{
|
|
if(-not $localizedNotificationMessages) {
|
|
return
|
|
}
|
|
|
|
$updated = $false
|
|
foreach($localizedNotificationMessage in $localizedNotificationMessages)
|
|
{
|
|
Remove-GraphPropertiesForImport $this $localizedNotificationMessage
|
|
$response = Invoke-MSGraphAPI -Url "$($this.API)/$($PolicyObject.Id)/localizedNotificationMessages" -Body ($localizedNotificationMessage | ConvertTo-Json -Depth 20) -Method "POST" -FullResponseObject
|
|
if($response.Success) {
|
|
Write-log "Notification message '$($localizedNotificationMessage.subject)' ($($localizedNotificationMessage.locale)) added successfully"
|
|
$updated = $true
|
|
}
|
|
else {
|
|
Write-log "Failed to add notification message: '$($localizedNotificationMessage.subject)' ($($localizedNotificationMessage.locale))" 3
|
|
}
|
|
}
|
|
if($updated) {
|
|
[void]$PolicyObject.Get()
|
|
}
|
|
}
|
|
|
|
[Boolean]CheckPolicy([PSCustomObject]$PolicyObject)
|
|
{
|
|
if($PolicyObject.'displayName' -eq "EnrollmentNotificationInternalMEO") { return $false } # Skip built in
|
|
|
|
return (([IntunePolicyTypeBase]$this).CheckPolicy($PolicyObject))
|
|
}
|
|
}
|
|
|
|
Class NotificationObject : IntunePolicyBase
|
|
{
|
|
NotificationObject([PSCustomObject]$JsonObj) : Base($JsonObj) { $this.Init() }
|
|
|
|
NotificationObject() : Base()
|
|
{
|
|
$this.Init()
|
|
}
|
|
|
|
Hidden Init()
|
|
{
|
|
$this._PolicyType = (Get-SingletonObject "NotificationsType")
|
|
}
|
|
}
|
|
|