mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
IntuneManagement 4.0.0-beta1
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
# Generic Profile input provider.
|
||||
#
|
||||
# Ported from old Extensions/Documentation.psm1:2057 (Invoke-TranslateProfile-
|
||||
# Object). Claims any @odata.type catalogued in Config/ObjectCategories.json
|
||||
# that isn't already handled by a more-specific input provider or handler
|
||||
# (first-match-wins dispatch in [DocumentationRegistry]).
|
||||
#
|
||||
# For each catalogued type:
|
||||
# 1. Emit BasicInfo via Add-BasicDefaultValues (which itself reads
|
||||
# ObjectCategories.json for Platform-supported + Profile-type rows)
|
||||
# 2. Emit Created/Modified/Version via Add-BasicAdditionalValues
|
||||
# 3. Find category files: either the explicit Categories list, or every
|
||||
# file matching *_<policyType>.json under Config/ObjectInfo/
|
||||
# 4. Load each as JSON, dispatch to Invoke-TranslateSection walker
|
||||
#
|
||||
# The walker handles all the per-prop dataType dispatching to translate
|
||||
# primitives (Boolean/Option/MultiOption/Table/Duration etc.).
|
||||
|
||||
function Invoke-InitializeProfileInput {
|
||||
Add-DocumentationInputProvider ([PSCustomObject]@{
|
||||
Name = 'Profile'
|
||||
Order = 60
|
||||
Match = {
|
||||
param($PolicyObject)
|
||||
$odata = $PolicyObject.JsonObject.'@odata.type'
|
||||
if (-not $odata) { return $false }
|
||||
if (-not (Get-Command Get-PolicyObjectCategoryInfo -ErrorAction SilentlyContinue)) { return $false }
|
||||
$info = Get-PolicyObjectCategoryInfo $odata
|
||||
return ($null -ne $info -and $null -ne $info.PolicyType)
|
||||
}
|
||||
Translate = { param($PolicyObject, $Context) Invoke-TranslateProfilePolicyObject $PolicyObject $Context }
|
||||
})
|
||||
}
|
||||
|
||||
function Invoke-TranslateProfilePolicyObject {
|
||||
param($PolicyObject, [DocumentationContext]$Context)
|
||||
|
||||
$obj = $PolicyObject.JsonObject
|
||||
|
||||
$objInfo = Get-PolicyObjectCategoryInfo $obj.'@odata.type'
|
||||
if (-not $objInfo) { return }
|
||||
|
||||
# Header rows
|
||||
Add-BasicDefaultValues $PolicyObject
|
||||
Add-BasicAdditionalValues $PolicyObject
|
||||
# Pin '@ObjectFromFile' so the walker's source-unavailable branches (linked
|
||||
# certificates etc.) treat the input as a file-based object even when
|
||||
# SourceTenantUnavailable isn't set.
|
||||
if (-not $obj.PSObject.Properties['@ObjectFromFile']) {
|
||||
$obj | Add-Member -MemberType NoteProperty -Name '@ObjectFromFile' -Value $true -Force
|
||||
}
|
||||
$Context.CurrentObject = $obj
|
||||
Initialize-DocumentationObjectInfoObject $obj
|
||||
|
||||
# Resolve the list of ObjectInfo JSON files to walk for this PolicyType
|
||||
$objectInfoDir = Join-Path $script:AppRootFolder 'Config\ObjectInfo'
|
||||
$allFiles = @()
|
||||
|
||||
if ($objInfo.Categories -and $objInfo.Categories.Count -gt 0) {
|
||||
foreach ($cat in $objInfo.Categories) {
|
||||
$path = Join-Path $objectInfoDir "$($cat.ToLower())_$($objInfo.PolicyType.ToLower()).json"
|
||||
if (Test-Path -LiteralPath $path) {
|
||||
$allFiles += [IO.FileInfo]$path
|
||||
}
|
||||
else {
|
||||
Write-Log "ObjectInfo file '$path' not found for $($objInfo.PolicyType)" 2
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Single-file path — find any *_<policyType>.json
|
||||
$pattern = "*_$($objInfo.PolicyType.ToLower()).json"
|
||||
if (Test-Path $objectInfoDir) {
|
||||
$files = Get-ChildItem -Path $objectInfoDir -Filter $pattern -ErrorAction SilentlyContinue
|
||||
if (-not $files) {
|
||||
Write-Log "No ObjectInfo files matching '$pattern' for $($objInfo.PolicyType)" 2
|
||||
}
|
||||
foreach ($f in $files) { $allFiles += $f }
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($fi in $allFiles) {
|
||||
try {
|
||||
$categoryObj = [IO.File]::ReadAllText($fi.FullName) | ConvertFrom-Json
|
||||
$Context.CurrentSubCategory = ''
|
||||
# Per-file custom handlers override the generic walker (old code:
|
||||
# Invoke-CDDocumentTranslateSectionFile, called via docProvider.
|
||||
# TranslateSectionFile hook from Invoke-TranslateProfileObject).
|
||||
# Returns $true if the custom handler emitted rows; $false to fall
|
||||
# through to Invoke-TranslateSection.
|
||||
if (Invoke-DocCustomSectionFileTranslator -Obj $obj -FileInfo $fi -CategoryObj $categoryObj -ObjInfo $objInfo) {
|
||||
continue
|
||||
}
|
||||
# Each ObjectInfo file wraps its section array under a key matching the file's basename
|
||||
$sections = $categoryObj."$($fi.BaseName)"
|
||||
if ($sections) {
|
||||
Invoke-TranslateSection $obj $sections $objInfo
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-LogError "Failed to translate ObjectInfo file $($fi.Name)" $_.Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Custom per-(odata.type, fileBaseName) section-file translators. Mirrors old
|
||||
# Extensions/DocumentationCustom.psm1's Invoke-CDDocumentTranslateSectionFile.
|
||||
# Each block returns $true if it emitted rows and the generic walker should be
|
||||
# skipped for this file, $false to fall through.
|
||||
function Invoke-DocCustomSectionFileTranslator {
|
||||
param($Obj, [IO.FileInfo]$FileInfo, $CategoryObj, $ObjInfo)
|
||||
|
||||
# --- Compliance: Custom Compliance category (Windows 10) ----------------
|
||||
# Generic walker can't emit useful rows for `customcompliance_compliancewindows10`
|
||||
# because the manifest's dataType=25 ("home screen", unused) is the child
|
||||
# carrying the actual content, and the rules live on a separate
|
||||
# $obj.deviceCompliancePolicyScript navigation property rather than on the
|
||||
# boolean entityKey the parent points to. Three rows are emitted by hand:
|
||||
# - Custom compliance (Require / Not configured)
|
||||
# - Select your discovery script (resolved displayName)
|
||||
# - Upload and validate the JSON file (base64-decoded rulesContent)
|
||||
if ($Obj.'@odata.type' -eq '#microsoft.graph.windows10CompliancePolicy' -and
|
||||
$FileInfo.BaseName -eq 'customcompliance_compliancewindows10') {
|
||||
|
||||
$category = Get-PolicyObjectCategoryString ($CategoryObj."$($FileInfo.BaseName)".category)
|
||||
|
||||
if ($null -eq $Obj.deviceCompliancePolicyScript) {
|
||||
$propValue = Get-LanguageString 'BooleanActions.notConfigured'
|
||||
$rawValue = 'notConfigured'
|
||||
} else {
|
||||
$propValue = Get-LanguageString 'BooleanActions.require'
|
||||
$rawValue = 'require'
|
||||
}
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString 'SettingDetails.adminConfiguredComplianceSettingName'
|
||||
Value = $propValue
|
||||
EntityKey = 'deviceCompliancePolicyScript'
|
||||
RawValue = $rawValue
|
||||
Category = $category
|
||||
SubCategory = $null
|
||||
})
|
||||
|
||||
if ($Obj.deviceCompliancePolicyScript) {
|
||||
# Resolve script displayName via shared cache. Offline runs / cache
|
||||
# miss fall back to the script id so the row isn't blank.
|
||||
$scriptId = [string]$Obj.deviceCompliancePolicyScript.deviceComplianceScriptId
|
||||
$scriptName = $scriptId
|
||||
if (-not [string]::IsNullOrEmpty($scriptId)) {
|
||||
$cache = Get-CacheObject 'DocAllCustomCompliancePolicies'
|
||||
# Custom compliance scripts are authored in the source tenant (not
|
||||
# generic schema), so this is gated on source-tenant availability.
|
||||
if (-not $cache -and -not (Get-CurrentDocumentationContext).SourceTenantUnavailable -and (Test-DocumentationGraphAvailable)) {
|
||||
try {
|
||||
$cache = @((Invoke-MSGraphAPI -Url "/deviceManagement/deviceComplianceScripts?`$select=displayName,id" -ODataMetadata 'minimal').value)
|
||||
Set-CacheObject 'DocAllCustomCompliancePolicies' $cache
|
||||
} catch {
|
||||
Write-Log "Failed to fetch deviceComplianceScripts for resolution: $($_.Exception.Message)" 2
|
||||
}
|
||||
}
|
||||
if ($cache) {
|
||||
$match = $cache | Where-Object Id -EQ $scriptId | Select-Object -First 1
|
||||
if ($match.displayName) { $scriptName = $match.displayName }
|
||||
}
|
||||
}
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString 'CustomCompliance.FilePicker.scriptFileLabel'
|
||||
Value = $scriptName
|
||||
EntityKey = 'deviceComplianceScriptName'
|
||||
Category = $category
|
||||
SubCategory = $null
|
||||
})
|
||||
|
||||
if ($Obj.deviceCompliancePolicyScript.rulesContent) {
|
||||
$rules = try {
|
||||
[System.Text.Encoding]::UTF8.GetString(
|
||||
[System.Convert]::FromBase64String($Obj.deviceCompliancePolicyScript.rulesContent))
|
||||
} catch {
|
||||
[string]$Obj.deviceCompliancePolicyScript.rulesContent
|
||||
}
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString 'CustomCompliance.UploadFile.jsonFileLabel'
|
||||
Value = $rules
|
||||
EntityKey = 'jsonFileContent'
|
||||
Category = $category
|
||||
SubCategory = $null
|
||||
})
|
||||
}
|
||||
}
|
||||
return $true
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
Invoke-InitializeProfileInput
|
||||
Reference in New Issue
Block a user