mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
3.10.3
This commit is contained in:
@@ -553,7 +553,7 @@ function Invoke-BulkCompareNamedObjects
|
||||
|
||||
if($compareObjectsResult.Count -eq 0)
|
||||
{
|
||||
[System.Windows.MessageBox]::Show("No objects were comparced. Verify name patterns", "Error", "OK", "Error")
|
||||
[System.Windows.MessageBox]::Show("No objects were compared. Verify name patterns", "Error", "OK", "Error")
|
||||
}
|
||||
elseif($outputType -eq "all")
|
||||
{
|
||||
@@ -966,7 +966,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
|
||||
Write-Status ""
|
||||
if($compareObjectsResult.Count -eq 0)
|
||||
{
|
||||
[System.Windows.MessageBox]::Show("No objects were comparced. Verify folder and exported files", "Error", "OK", "Error")
|
||||
[System.Windows.MessageBox]::Show("No objects were compared. Verify folder and exported files", "Error", "OK", "Error")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1438,7 +1438,7 @@ function Add-CompareProperty
|
||||
$compare.Match = $null
|
||||
}
|
||||
|
||||
Write-Host "Add property $($compare.PropertyName)"
|
||||
Write-LogDebug "Add property $($compare.PropertyName)"
|
||||
$script:compareProperties += $compare
|
||||
}
|
||||
|
||||
|
||||
@@ -1700,7 +1700,7 @@ function Add-IntentSettingObjectToList
|
||||
{
|
||||
$passConstraint = ($dependencyItemObj.RawValue -ne $null -and $dependencyItemObj.RawValue.ToString() -ne "NotConfigured" -and $dependencyItemObj.RawValue.ToString() -ne "False")
|
||||
}
|
||||
if(-not $passConstraint) { break ]}
|
||||
if(-not $passConstraint) { break }
|
||||
}
|
||||
|
||||
if(-not $passConstraint)
|
||||
@@ -4424,7 +4424,7 @@ function local:Invoke-StartDocumentatiom
|
||||
$script:migTable = $null
|
||||
$script:scopeTags = $null
|
||||
|
||||
$diSource = $nul
|
||||
$diSource = $null
|
||||
$global:intentCategories = $null
|
||||
$global:catRecommendedSettings = $null
|
||||
$global:intentCategoryDefs = $null
|
||||
@@ -4486,7 +4486,7 @@ function local:Invoke-StartDocumentatiom
|
||||
$tmpObj | Add-Member Noteproperty -Name "GroupName" -Value (Get-ObjectTypeGroupName $tmpObj.ObjectType) -Force
|
||||
}
|
||||
|
||||
if($groupSourceList.Count -eq 0) { contnue }
|
||||
if($groupSourceList.Count -eq 0) { continue }
|
||||
|
||||
if($curObjectType.GroupId -eq "EndpointSecurity")
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ function Invoke-HTMLPreProcessItems
|
||||
Write-Log "CSS file not specified. Using default" 2
|
||||
$HTMLCssFile = $defaultCSSFile
|
||||
}
|
||||
elseif([IO.File]::Exists($HTMLCssFile) -eq -$false)
|
||||
elseif([IO.File]::Exists($HTMLCssFile) -eq $false)
|
||||
{
|
||||
Write-Log "CSS file $($HTMLCssFile) not found. Using default" 2
|
||||
$HTMLCssFile = $defaultCSSFile
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.0'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
{
|
||||
Add-OutputType ([PSCustomObject]@{
|
||||
Name = "Json"
|
||||
Value = "json"
|
||||
OutputOptions = (Add-JsonOptionsControl)
|
||||
PreProcess = { Invoke-JsonPreProcessItems @args }
|
||||
NewObjectGroup = { Invoke-JsonNewObjectGroup @args }
|
||||
NewObjectType = { Invoke-JsonNewObjectType @args }
|
||||
Process = { Invoke-JsonProcessItem @args }
|
||||
PostProcess = { Invoke-JsonPostProcessItems @args }
|
||||
})
|
||||
}
|
||||
|
||||
function Add-JsonOptionsControl
|
||||
{
|
||||
$script:jsonForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\DocumentationJsonOptions.xaml") -AddVariables
|
||||
|
||||
Set-XamlProperty $script:jsonForm "txtJsonFileName" "Text" (Get-Setting "Documentation" "JsonDocumentName" "")
|
||||
Set-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked" (Get-Setting "Documentation" "JsonOpenFile" $true)
|
||||
$outputFileTypes = '[ { "Name": "Single file", "Value": "Full" }, { "Name": "One file per object type", "Value": "ObjectType" } ]' | ConvertFrom-Json
|
||||
Set-XamlProperty $script:jsonForm "cbJsonOutputFile" "ItemsSource" $outputFileTypes
|
||||
Set-XamlProperty $script:jsonForm "cbJsonOutputFile" "SelectedValue" (Get-Setting "Documentation" "JsonOutputFileType" "Full")
|
||||
|
||||
Add-XamlEvent $script:jsonForm "browseJsonFileName" "add_click" {
|
||||
$sf = [System.Windows.Forms.SaveFileDialog]::new()
|
||||
$sf.DefaultExt = "json"
|
||||
$sf.Filter = "Json (*.json)|*.json|All files (*.*)|*.*"
|
||||
if ($sf.ShowDialog() -eq "OK")
|
||||
{
|
||||
Set-XamlProperty $script:jsonForm "txtJsonFileName" "Text" $sf.FileName
|
||||
Save-Setting "Documentation" "JsonDocumentName" $sf.FileName
|
||||
}
|
||||
}
|
||||
|
||||
$script:jsonForm
|
||||
}
|
||||
|
||||
function Invoke-JsonPreProcessItems
|
||||
{
|
||||
$script:jsonAllObjects = [System.Collections.Generic.List[object]]::new()
|
||||
$script:jsonCurrentTypeObjects = [System.Collections.Generic.List[object]]::new()
|
||||
$script:jsonCurrentTypeName = $null
|
||||
|
||||
$script:jsonOutputType = Get-XamlProperty $script:jsonForm "cbJsonOutputFile" "SelectedValue" "Full"
|
||||
|
||||
$jsonFileName = Get-XamlProperty $script:jsonForm "txtJsonFileName" "Text" ""
|
||||
|
||||
Save-Setting "Documentation" "JsonDocumentName" $jsonFileName
|
||||
Save-Setting "Documentation" "JsonOpenFile" (Get-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked")
|
||||
Save-Setting "Documentation" "JsonOutputFileType" $script:jsonOutputType
|
||||
|
||||
$script:jsonOutFile = Expand-FileName (?? $jsonFileName "%MyDocuments%\%Organization%-%Date%.json")
|
||||
$script:jsonDocumentPath = [IO.Path]::GetDirectoryName($script:jsonOutFile)
|
||||
}
|
||||
|
||||
function Invoke-JsonNewObjectGroup
|
||||
{
|
||||
param($groupId)
|
||||
# Groups are not used in flat Json output
|
||||
}
|
||||
|
||||
function Invoke-JsonNewObjectType
|
||||
{
|
||||
param($objectTypeName)
|
||||
|
||||
if ($script:jsonOutputType -eq "ObjectType" -and
|
||||
$script:jsonCurrentTypeName -and
|
||||
$script:jsonCurrentTypeObjects.Count -gt 0)
|
||||
{
|
||||
Save-JsonTypeFile $script:jsonCurrentTypeName $script:jsonCurrentTypeObjects
|
||||
}
|
||||
|
||||
$script:jsonCurrentTypeName = $objectTypeName
|
||||
$script:jsonCurrentTypeObjects = [System.Collections.Generic.List[object]]::new()
|
||||
}
|
||||
|
||||
function Invoke-JsonProcessItem
|
||||
{
|
||||
param($obj, $objectType, $documentedObj)
|
||||
|
||||
if (-not $documentedObj -or -not $obj -or -not $objectType) { return }
|
||||
|
||||
$objName = Get-GraphObjectName $obj $objectType
|
||||
|
||||
try
|
||||
{
|
||||
$jsonObj = [ordered]@{
|
||||
objectType = $objectType.Title
|
||||
name = $objName
|
||||
}
|
||||
|
||||
# BasicInfo as a flat key/value object
|
||||
if ($documentedObj.BasicInfo.Count -gt 0)
|
||||
{
|
||||
$basicInfo = [ordered]@{}
|
||||
foreach ($item in $documentedObj.BasicInfo)
|
||||
{
|
||||
if ($item.Name) { $basicInfo[$item.Name] = $item.Value }
|
||||
}
|
||||
$jsonObj.basicInfo = $basicInfo
|
||||
}
|
||||
|
||||
# Detailed settings as an array
|
||||
if ($documentedObj.FilteredSettings.Count -gt 0)
|
||||
{
|
||||
$settings = [System.Collections.Generic.List[object]]::new()
|
||||
foreach ($item in $documentedObj.FilteredSettings)
|
||||
{
|
||||
$setting = [ordered]@{ name = $item.Name; value = $item.Value }
|
||||
if ($item.Category) { $setting.category = $item.Category }
|
||||
if ($item.SubCategory) { $setting.subCategory = $item.SubCategory }
|
||||
$settings.Add($setting)
|
||||
}
|
||||
$jsonObj.settings = $settings
|
||||
}
|
||||
|
||||
# Compliance actions
|
||||
if (($documentedObj.ComplianceActions | Measure-Object).Count -gt 0)
|
||||
{
|
||||
$actions = [System.Collections.Generic.List[object]]::new()
|
||||
foreach ($item in $documentedObj.ComplianceActions)
|
||||
{
|
||||
$actions.Add([ordered]@{
|
||||
action = $item.Action
|
||||
schedule = $item.Schedule
|
||||
messageTemplate = $item.MessageTemplate
|
||||
emailCC = $item.EmailCC
|
||||
})
|
||||
}
|
||||
$jsonObj.complianceActions = $actions
|
||||
}
|
||||
|
||||
# Applicability rules
|
||||
if (($documentedObj.ApplicabilityRules | Measure-Object).Count -gt 0)
|
||||
{
|
||||
$rules = [System.Collections.Generic.List[object]]::new()
|
||||
foreach ($item in $documentedObj.ApplicabilityRules)
|
||||
{
|
||||
$rules.Add([ordered]@{
|
||||
rule = $item.Rule
|
||||
property = $item.Property
|
||||
value = $item.Value
|
||||
})
|
||||
}
|
||||
$jsonObj.applicabilityRules = $rules
|
||||
}
|
||||
|
||||
# Custom tables — each becomes a top-level array keyed by the last segment of the language ID
|
||||
foreach ($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
|
||||
{
|
||||
if (-not $customTable.Values -or ($customTable.Values | Measure-Object).Count -eq 0) { continue }
|
||||
|
||||
$tableKey = if ($customTable.LanguageId) { $customTable.LanguageId.Split('.')[-1] } else { "customTable" }
|
||||
$tableArr = [System.Collections.Generic.List[object]]::new()
|
||||
|
||||
foreach ($item in $customTable.Values)
|
||||
{
|
||||
$tableObj = [ordered]@{}
|
||||
foreach ($col in $customTable.Columns)
|
||||
{
|
||||
$colName = $col.Split('.')[-1]
|
||||
$tableObj[$colName] = "$($item.$colName)"
|
||||
}
|
||||
$tableArr.Add($tableObj)
|
||||
}
|
||||
$jsonObj[$tableKey] = $tableArr
|
||||
}
|
||||
|
||||
# Assignments
|
||||
if (($documentedObj.Assignments | Measure-Object).Count -gt 0)
|
||||
{
|
||||
$assignments = [System.Collections.Generic.List[object]]::new()
|
||||
$hasRawIntent = $null -ne $documentedObj.Assignments[0].RawIntent
|
||||
|
||||
foreach ($item in $documentedObj.Assignments)
|
||||
{
|
||||
if ($hasRawIntent)
|
||||
{
|
||||
$assignObj = [ordered]@{
|
||||
groupMode = $item.GroupMode
|
||||
group = $item.Group
|
||||
}
|
||||
if ($null -ne $item.Filter) { $assignObj.filter = $item.Filter }
|
||||
if ($null -ne $item.FilterMode) { $assignObj.filterMode = $item.FilterMode }
|
||||
if ($item.Settings)
|
||||
{
|
||||
$settingsObj = [ordered]@{}
|
||||
foreach ($key in $item.Settings.Keys)
|
||||
{
|
||||
if ($key -in @("Category","RawIntent")) { continue }
|
||||
$settingsObj[$key] = $item.Settings[$key]
|
||||
}
|
||||
$assignObj.settings = $settingsObj
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$assignObj = [ordered]@{ group = $item.Group }
|
||||
if ($item.PSObject.Properties.Name -contains "Filter") { $assignObj.filter = $item.Filter }
|
||||
if ($item.PSObject.Properties.Name -contains "FilterMode") { $assignObj.filterMode = $item.FilterMode }
|
||||
}
|
||||
$assignments.Add($assignObj)
|
||||
}
|
||||
$jsonObj.assignments = $assignments
|
||||
}
|
||||
|
||||
# Scripts — included when "Document scripts" is checked in the documentation form
|
||||
if ($global:chkIncludeScripts.IsChecked -and ($documentedObj.Scripts | Measure-Object).Count -gt 0)
|
||||
{
|
||||
$scripts = [System.Collections.Generic.List[object]]::new()
|
||||
foreach ($scriptItem in $documentedObj.Scripts)
|
||||
{
|
||||
if (-not $scriptItem.ScriptContent) { continue }
|
||||
$scripts.Add([ordered]@{
|
||||
caption = $scriptItem.Caption
|
||||
content = $scriptItem.ScriptContent
|
||||
})
|
||||
}
|
||||
if ($scripts.Count -gt 0) { $jsonObj.scripts = $scripts }
|
||||
}
|
||||
|
||||
$script:jsonCurrentTypeObjects.Add($jsonObj)
|
||||
if ($script:jsonOutputType -ne "ObjectType") { $script:jsonAllObjects.Add($jsonObj) }
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-LogError "Failed to process object $objName" $_.Exception
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-JsonPostProcessItems
|
||||
{
|
||||
$openFile = (Get-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked") -eq $true
|
||||
|
||||
if ($script:jsonOutputType -eq "ObjectType")
|
||||
{
|
||||
if ($script:jsonCurrentTypeName -and $script:jsonCurrentTypeObjects.Count -gt 0)
|
||||
{
|
||||
Save-JsonTypeFile $script:jsonCurrentTypeName $script:jsonCurrentTypeObjects
|
||||
}
|
||||
Write-Log "Json documentation saved to folder: $($script:jsonDocumentPath)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$jsonContent = ConvertTo-Json -InputObject @($script:jsonAllObjects) -Depth 20
|
||||
Save-DocumentationFile $jsonContent $script:jsonOutFile -OpenFile:$openFile
|
||||
}
|
||||
}
|
||||
|
||||
function Save-JsonTypeFile
|
||||
{
|
||||
param($typeName, $objects)
|
||||
|
||||
$safeTypeName = Remove-InvalidFileNameChars ($typeName.Replace(" ", "_"))
|
||||
$typeFileName = [IO.Path]::Combine($script:jsonDocumentPath, "$safeTypeName.json")
|
||||
$jsonContent = ConvertTo-Json -InputObject @($objects) -Depth 20
|
||||
Save-DocumentationFile $jsonContent $typeFileName
|
||||
Write-Log "Saved $($objects.Count) objects to $typeFileName"
|
||||
}
|
||||
@@ -83,7 +83,7 @@ function Invoke-MDPreProcessItems
|
||||
Write-Log "CSS file not specified. Using default" 2
|
||||
$MDCssFile = $defaultCSSFile
|
||||
}
|
||||
elseif([IO.File]::Exists($MDCssFile) -eq -$false)
|
||||
elseif([IO.File]::Exists($MDCssFile) -eq $false)
|
||||
{
|
||||
Write-Log "CSS file $($MDCssFile) not found. Using default" 2
|
||||
$MDCssFile = $defaultCSSFile
|
||||
|
||||
@@ -291,8 +291,8 @@ function Invoke-WordPreProcessItems
|
||||
}
|
||||
|
||||
$script:wordStyles = @()
|
||||
$script:doc.Styles | foreach {
|
||||
$script:wordStyles += [PSCUstomObject]@{
|
||||
$script:doc.Styles | foreach {
|
||||
$script:wordStyles += [PSCustomObject]@{
|
||||
Name=$_.NameLocal
|
||||
Type=$_.Type
|
||||
Style=$_
|
||||
|
||||
@@ -509,7 +509,7 @@ function Invoke-InitializeModule
|
||||
ImportOrder = 60
|
||||
Expand="categories,assignments" # ODataMetadata is set to minimal so assignments can't be autodetected
|
||||
ODataMetadata="minimal" # categories property not supported with ODataMetadata full
|
||||
PostFileImportCommand = { Start-PostFileImportApplication @args }
|
||||
PostFileImportCommand = { Start-PostFileImportApplication @args }
|
||||
PostCopyCommand = { Start-PostCopyApplication @args }
|
||||
PreUpdateCommand = { Start-PreUpdateApplication @args }
|
||||
PreImportCommand = { Start-PreImportCommandApplication @args }
|
||||
@@ -654,7 +654,7 @@ function Invoke-InitializeModule
|
||||
ViewProperties = @("name","description","Id")
|
||||
Expand="Settings"
|
||||
Icon="DeviceConfiguration"
|
||||
GroupId = "DeviceConfiguration"
|
||||
GroupId = "DeviceConfiguration"
|
||||
})
|
||||
|
||||
Add-ViewItem (New-Object PSObject -Property @{
|
||||
@@ -2353,7 +2353,7 @@ function local:Add-AppConfigurationTargets
|
||||
$appName, $appId, $appType = $targetedApp -split "[|][!][|]"
|
||||
if(-not $appName -or -not $appId)
|
||||
{
|
||||
Write-Log "App Name and Id is missing in string: $appApp" 2
|
||||
Write-Log "App Name and Id is missing in string: $targetedApp" 2
|
||||
continue
|
||||
}
|
||||
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
|
||||
@@ -2814,6 +2814,8 @@ function Start-PreImportAssignmentsApplications
|
||||
|
||||
function Start-PreDeleteApplications
|
||||
{
|
||||
param($obj, $objectType)
|
||||
|
||||
if($obj.'@odata.type' -eq "#microsoft.graph.microsoftStoreForBusinessApp")
|
||||
{
|
||||
# Don't delete Microsoft Store for Business Apps
|
||||
@@ -3077,9 +3079,9 @@ function local:Add-ApplicationReferences
|
||||
Write-Log "No $appName application found with version $appVer" 2
|
||||
continue
|
||||
}
|
||||
elseif(-not ($tmpApp | measure).Count -gt 1)
|
||||
elseif(($tmpApp | measure).Count -gt 1)
|
||||
{
|
||||
Write-Log "Multiple $appName application found with version $appVer" 2
|
||||
Write-Log "Multiple $appName applications found with version $appVer" 2
|
||||
continue
|
||||
}
|
||||
Write-Log "Add $appName ($appVer) to Dependency list"
|
||||
@@ -3098,7 +3100,7 @@ function local:Add-ApplicationReferences
|
||||
$appName, $appVer, $appId, $appType = $suppApp -split "[|][!][|]"
|
||||
if(-not $appName -or -not $appVer)
|
||||
{
|
||||
Write-Log "Could not get Name and Version from string: $appApp" 2
|
||||
Write-Log "Could not get Name and Version from string: $suppApp" 2
|
||||
continue
|
||||
}
|
||||
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
|
||||
|
||||
@@ -790,7 +790,7 @@ function Start-DownloadAppContent
|
||||
{
|
||||
foreach($file in $contentFiles.value)
|
||||
{
|
||||
if($contentFiles.value[-1].Id -eq $file.id) { continune }
|
||||
if($contentFiles.value[-1].Id -eq $file.id) { continue }
|
||||
|
||||
# NOT happy about this. file objects are not always returned in the order of upload.
|
||||
$contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($file.Id)" -NoError
|
||||
|
||||
@@ -348,7 +348,7 @@ function Get-EMIntuneFilterUsage
|
||||
|
||||
foreach($groupID in $loadedGroups.Keys)
|
||||
{
|
||||
$filterObjs = $script:objFilterUsage | WHere GroupID -eq $groupID
|
||||
$filterObjs = $script:objFilterUsage | Where GroupID -eq $groupID
|
||||
if($filterObjs -and $loadedGroups[$groupID])
|
||||
{
|
||||
foreach($filterObj in $filterObjs) {
|
||||
|
||||
@@ -1116,7 +1116,6 @@ function Connect-MSALUser
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastUser =
|
||||
$lastUserId = Get-Setting "" "LastLoggedOnUserId"
|
||||
if($lastUserId)
|
||||
{
|
||||
|
||||
@@ -586,7 +586,8 @@ function Invoke-GraphRequest
|
||||
do
|
||||
{
|
||||
$ret = Invoke-RestMethod -Uri $Url -Method $HttpMethod @params
|
||||
if($? -eq $false)
|
||||
$callSucceeded = $?
|
||||
if($callSucceeded -eq $false)
|
||||
{
|
||||
throw $global:error[0]
|
||||
}
|
||||
@@ -622,7 +623,6 @@ function Invoke-GraphRequest
|
||||
if($_.Exception.Response.StatusCode -eq 429 -and $retryCount -le $retryMax)
|
||||
{
|
||||
# NOT OK - Should use the date property but could not replicate the issue
|
||||
$retryCount++
|
||||
$retryRequest = $true
|
||||
Write-Log "429 - Too many requests received. Wait 5 s before retry" 2
|
||||
Start-Sleep -Seconds 5
|
||||
@@ -2244,7 +2244,7 @@ function Start-GraphObjectImport
|
||||
ImportedObject = $importedObj
|
||||
}
|
||||
}
|
||||
$arrImportedObjects = $importedObj
|
||||
$arrImportedObjects += $importedObj
|
||||
|
||||
$importedObjects++
|
||||
$importedObjectsCurType++
|
||||
|
||||
Reference in New Issue
Block a user