3.2.0
This commit is contained in:
@@ -11,7 +11,7 @@ Objects can be compared based on Properties or Documentatation info.
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.5'
|
||||
'1.0.6'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -160,6 +160,9 @@ function Show-CompareBulkForm
|
||||
$global:cbCompareType.ItemsSource = $global:comparisonTypes | Where ShowOnBulk -ne $false
|
||||
$global:cbCompareType.SelectedValue = (Get-Setting "Compare" "Type" "property")
|
||||
|
||||
$global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|")
|
||||
$global:cbCompareCSVDelimiter.SelectedValue = (Get-Setting "Compare" "Delimiter" ";")
|
||||
|
||||
$script:compareObjects = @()
|
||||
foreach($objType in $global:lstMenuItems.ItemsSource)
|
||||
{
|
||||
@@ -202,8 +205,9 @@ function Show-CompareBulkForm
|
||||
|
||||
Add-XamlEvent $script:form "btnStartCompare" "add_click" {
|
||||
Write-Status "Compare objects"
|
||||
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
|
||||
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
|
||||
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
|
||||
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
|
||||
Save-Setting "Compare" "Delimiter" $global:cbCompareCSVDelimiter.SelectedValue
|
||||
if($global:cbCompareProvider.SelectedItem.BulkCompare)
|
||||
{
|
||||
& $global:cbCompareProvider.SelectedItem.BulkCompare
|
||||
@@ -530,7 +534,8 @@ function Start-BulkCompareExportObjects
|
||||
}
|
||||
else
|
||||
{
|
||||
$sourceObj = Get-GraphObject $curObject.Object $curObject.ObjectType
|
||||
$sourceObj = Get-GraphObject $curObject.Object $curObject.ObjectType
|
||||
$fileObj.Object | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
|
||||
$compareProperties = Compare-Objects $sourceObj.Object $fileObj.Object $item.ObjectType
|
||||
}
|
||||
|
||||
@@ -618,8 +623,20 @@ function Save-BulkCompareResults
|
||||
|
||||
if($compResultValues.Count -gt 0)
|
||||
{
|
||||
$params = @{}
|
||||
try
|
||||
{
|
||||
if($global:cbCompareCSVDelimiter.Text)
|
||||
{
|
||||
$params.Add("Delimiter", [char]$global:cbCompareCSVDelimiter.Text)
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
Write-Log "Save bulk comare results to $file"
|
||||
$compResultValues | Select -Property $props | ConvertTo-Csv -NoTypeInformation | Out-File -LiteralPath $file -Force -Encoding UTF8
|
||||
$compResultValues | Select -Property $props | ConvertTo-Csv -NoTypeInformation @params | Out-File -LiteralPath $file -Force -Encoding UTF8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,6 +815,8 @@ function Start-CompareExportObject
|
||||
}
|
||||
}
|
||||
|
||||
$compareObj | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
|
||||
|
||||
$compareResult = Compare-Objects $obj.Object $compareObj $obj.ObjectType
|
||||
|
||||
$global:dgCompareInfo.ItemsSource = $compareResult
|
||||
@@ -817,16 +836,6 @@ function Compare-Objects
|
||||
{
|
||||
Write-Log "Selected comparison type ($($global:cbCompareType.SelectedItem.Name)) does not have a Compare property specified" 3
|
||||
}
|
||||
<#
|
||||
elseif($global:cbCompareType.SelectedValue -eq "property")
|
||||
{
|
||||
$compareResult = Compare-ObjectsBasedonProperty $obj1 $obj2 $objectType
|
||||
}
|
||||
elseif($global:cbCompareType.SelectedValue -eq "doc")
|
||||
{
|
||||
$compareResult = Compare-ObjectsBasedonDocumentation $obj1 $obj2 $objectType
|
||||
}
|
||||
#>
|
||||
|
||||
$compareResult
|
||||
}
|
||||
@@ -854,10 +863,6 @@ function Add-CompareProperty
|
||||
|
||||
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
|
||||
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
|
||||
if( ($value1 -eq $value2) -eq $false)
|
||||
{
|
||||
$dummy = 1
|
||||
}
|
||||
|
||||
$script:compareProperties += [PSCustomObject]@{
|
||||
PropertyName = $name
|
||||
@@ -962,7 +967,6 @@ function Compare-ObjectsBasedonDocumentation
|
||||
ObjectType = $objectType
|
||||
})
|
||||
|
||||
$obj2 | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
|
||||
|
||||
$docObj2 = Invoke-ObjectDocumentation ([PSCustomObject]@{
|
||||
Object = $obj2
|
||||
@@ -1049,7 +1053,7 @@ function Compare-ObjectsBasedonDocumentation
|
||||
|
||||
$addedProperties += ($prop.EntityKey + $prop.Category + $prop.SubCategory)
|
||||
$val1 = $prop.$settingsValue
|
||||
$prop2 = $docObj2.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory }
|
||||
$prop2 = $docObj2.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory -and $_.Enabled -eq $prop.Enabled }
|
||||
$val2 = $prop2.$settingsValue
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
|
||||
}
|
||||
@@ -1061,7 +1065,7 @@ function Compare-ObjectsBasedonDocumentation
|
||||
|
||||
$addedProperties += ($prop.EntityKey + $prop.Category + $prop.SubCategory)
|
||||
$val2 = $prop.$settingsValue
|
||||
$prop2 = $docObj1.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory }
|
||||
$prop2 = $docObj1.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory -and $_.Enabled -eq $prop.Enabled }
|
||||
$val1 = $prop2.$settingsValue
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ $global:documentationProviders = @()
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.5'
|
||||
'1.0.6'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -283,7 +283,8 @@ function Get-ObjectDocumentation
|
||||
DefaultDocumentationProperties = $defaultDocumentationProperties
|
||||
ErrorText = $status
|
||||
InputType = $inputType
|
||||
UpdateFilteredObject = $updateFilteredObject
|
||||
UpdateFilteredObject = $updateFilteredObject
|
||||
UnconfiguredProperties = $obj."@UnconfiguredProperties"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1175,6 +1176,7 @@ function Get-IntentSettingInfo
|
||||
; # Skip child settings
|
||||
}
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementCollectionSettingInstance' -or
|
||||
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingDefinition' -or
|
||||
$defObj."valueType" -eq "collection")
|
||||
{
|
||||
$valueArr = @()
|
||||
@@ -1231,9 +1233,10 @@ function Get-IntentSettingInfo
|
||||
}
|
||||
$valueSet = $valueArr.Count -gt 0
|
||||
}
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance')
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -or
|
||||
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingDefinition')
|
||||
{
|
||||
$tmpDef = $category.settingDefinitions | Where id -eq $rawValue.'$implementationId'
|
||||
$tmpDef = $category.settingDefinitions | Where id -eq $rawValue.implementationId
|
||||
if($tmpDef)
|
||||
{
|
||||
$itemValue = $tmpDef.displayName
|
||||
@@ -1284,7 +1287,8 @@ function Get-IntentSettingInfo
|
||||
{
|
||||
; # Skip children if value is not set...
|
||||
}
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingInstance')
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingInstance' -or
|
||||
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingDefinition')
|
||||
{
|
||||
if($valueObj.Value)
|
||||
{
|
||||
@@ -1373,7 +1377,9 @@ function Get-IntentSettingInfo
|
||||
$curObjectInfo.Value = ?: $isValueSet "Configure" (Get-LanguageString "SettingDetails.notConfigured")
|
||||
$curObjectInfo.ValueSet = $isValueSet
|
||||
}
|
||||
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -and $rawValue -and $tmpDef )
|
||||
elseif(($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -or
|
||||
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingDefinition') -and
|
||||
$rawValue -and $tmpDef)
|
||||
{
|
||||
foreach($childDefId in $tmpDef.propertyDefinitionIds)
|
||||
{
|
||||
@@ -1675,7 +1681,7 @@ function Invoke-TranslateSection
|
||||
}
|
||||
elseif($tmpStr)
|
||||
{
|
||||
Write-Log "SubCategpry ignored based on length: $tmpStr" 2
|
||||
Write-LogDebug "SubCategpry ignored based on length: $tmpStr" 2
|
||||
}
|
||||
}
|
||||
Invoke-ChildSections $obj $prop
|
||||
@@ -1741,6 +1747,7 @@ function Invoke-TranslateSection
|
||||
if($rawValue -eq $null -and ![String]::IsNullOrEmpty($prop.unconfiguredValue) -and $global:chkSetUnconfiguredValue.IsChecked)
|
||||
{
|
||||
$propValue = $prop.unconfiguredValue
|
||||
Add-NotConfiguredProperty $prop
|
||||
}
|
||||
elseif($rawValue -eq $null -and ![String]::IsNullOrEmpty($prop.defaultValue) -and $global:chkSetDefaultValue.IsChecked)
|
||||
{
|
||||
@@ -2366,10 +2373,24 @@ function Invoke-TranslateBoolean
|
||||
}
|
||||
else
|
||||
{
|
||||
Add-NotConfiguredProperty $prop
|
||||
Get-LanguageString "BooleanActions.notConfigured"
|
||||
}
|
||||
}
|
||||
|
||||
function Add-NotConfiguredProperty
|
||||
{
|
||||
param($prop)
|
||||
|
||||
# Add not configured prop to the base object
|
||||
if(-not ($script:currentObject.PSObject.Properties | Where Name -eq "@UnconfiguredProperties"))
|
||||
{
|
||||
$script:currentObject | Add-Member Noteproperty -Name "@UnconfiguredProperties" -Value @() -Force
|
||||
}
|
||||
|
||||
$script:currentObject.'@UnconfiguredProperties' += $prop
|
||||
}
|
||||
|
||||
function Invoke-TranslateOption
|
||||
{
|
||||
param($obj, $prop, [Switch]$SkipOptionChildren, $propValue = $null)
|
||||
@@ -2398,6 +2419,11 @@ function Invoke-TranslateOption
|
||||
}
|
||||
elseif($option.nameResourceKey)
|
||||
{
|
||||
if($option.nameResourceKey -eq "notConfigured")
|
||||
{
|
||||
Add-NotConfiguredProperty $prop
|
||||
}
|
||||
|
||||
$optionValue = (Get-LanguageString (?: $option.nameResourceKey.Contains(".") $option.nameResourceKey "SettingDetails.$($option.nameResourceKey)"))
|
||||
}
|
||||
else
|
||||
@@ -2477,6 +2503,7 @@ function Invoke-TranslateMultiOption
|
||||
}
|
||||
else
|
||||
{
|
||||
Add-NotConfiguredProperty $prop
|
||||
Get-LanguageString "BooleanActions.notConfigured"
|
||||
}
|
||||
}
|
||||
@@ -2841,6 +2868,10 @@ function Invoke-TranslateAssignments
|
||||
if($assignment.target.GroupId)
|
||||
{
|
||||
$groupName = ($groupInfo | Where id -eq $assignment.target.GroupId).displayName
|
||||
if(-not $groupName)
|
||||
{
|
||||
$groupName = $assignment.target.GroupId
|
||||
}
|
||||
}
|
||||
elseif($assignment.target.'@odata.type' -eq "#microsoft.graph.allDevicesAssignmentTarget")
|
||||
{
|
||||
@@ -3386,10 +3417,11 @@ function Show-DocumentationForm
|
||||
Add-RawDataInfo $obj.Object $obj.ObjectType
|
||||
|
||||
$updateNotConfigured = $true
|
||||
$notConfiguredLoc = Get-LanguageString "BooleanActions.notConfigured"
|
||||
$notConfiguredText = ""
|
||||
if($global:cbNotConifugredText.SelectedValue -eq "notConfigured")
|
||||
{
|
||||
$notConfiguredText = Get-LanguageString "BooleanActions.notConfigured"
|
||||
$notConfiguredText = $notConfiguredLoc
|
||||
}
|
||||
elseif($global:cbNotConifugredText.SelectedValue -eq "asis")
|
||||
{
|
||||
@@ -3409,9 +3441,14 @@ function Show-DocumentationForm
|
||||
break
|
||||
}
|
||||
|
||||
if($global:chkSkipNotConfigured.IsChecked -and (([String]::IsNullOrEmpty($item.RawValue) -or $item.RawValue -eq "notConfigured")))
|
||||
if($global:chkSkipNotConfigured.IsChecked -and (([String]::IsNullOrEmpty($item.RawValue) -or ("$($item.RawValue)" -eq "notConfigured"))))
|
||||
{
|
||||
# Skip unconfigured items
|
||||
# Skip unconfigured items e.g. properties with null values
|
||||
continue
|
||||
}
|
||||
elseif($global:chkSkipNotConfigured.IsChecked -and $documentedObj.UnconfiguredProperties -and ($documentedObj.UnconfiguredProperties | Where EntityKey -eq $item.EntityKey))
|
||||
{
|
||||
# Skip unconfigured items e.g. boolean with a value but Not Configured
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -3438,7 +3475,14 @@ function Show-DocumentationForm
|
||||
if($updateNotConfigured -and ($item.RawValue -eq $null -or "$($item.RawValue)" -eq "" -or "$($item.RawValue)" -eq "notConfigured") -and [String]::IsNullOrEmpty($item.Value))
|
||||
{
|
||||
$item.Value = $notConfiguredText
|
||||
}
|
||||
}
|
||||
|
||||
if($global:chkSkipNotConfigured.IsChecked -and $item.Value -eq $notConfiguredLoc)
|
||||
{
|
||||
# Skip unconfigured items based on value e.g. value = Not Configured
|
||||
Write-Log "Skipping property $($itenm.Name) based on '$($notConfiguredLoc)' string value" 2
|
||||
continue
|
||||
}
|
||||
|
||||
$filteredSettings += $item
|
||||
}
|
||||
@@ -3577,6 +3621,13 @@ function Add-CSVOptionsControl
|
||||
$global:spCSVCustomProperties.Visibility = (?: ($global:cbCSVDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
|
||||
$global:txtCSVCustomProperties.Visibility = (?: ($global:cbCSVDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
|
||||
|
||||
$global:cbCSVDelimiter.ItemsSource = @("", ",",";","-","|")
|
||||
try
|
||||
{
|
||||
$global:cbCSVDelimiter.SelectedIndex = $global:cbCSVDelimiter.ItemsSource.IndexOf((Get-Setting "Documentation" "CSVDelimiter"))
|
||||
}
|
||||
catch {}
|
||||
|
||||
Add-XamlEvent $script:csvForm "browseCSVDocumentationPath" "add_click" {
|
||||
$folder = Get-Folder (Get-XamlProperty $script:csvForm "txtCSVDocumentationPath" "Text") "Select root folder for export"
|
||||
if($folder)
|
||||
@@ -3603,6 +3654,7 @@ function Invoke-CSVPreProcessItems
|
||||
{
|
||||
Save-Setting "Documentation" "CSVExportProperties" $global:cbCSVDocumentationProperties.SelectedValue
|
||||
Save-Setting "Documentation" "CSVCustomDisplayProperties" $global:txtCSVCustomProperties.Text
|
||||
Save-Setting "Documentation" "CSVDelimiter" $global:cbCSVDelimiter.Text
|
||||
}
|
||||
|
||||
function Invoke-CSVProcessItem
|
||||
@@ -3630,6 +3682,12 @@ function Invoke-CSVProcessItem
|
||||
|
||||
$itemsToExport = @()
|
||||
|
||||
$params = @{}
|
||||
if($global:cbCSVDelimiter.Text)
|
||||
{
|
||||
$params.Add('Delimiter',$global:cbCSVDelimiter.Text)
|
||||
}
|
||||
|
||||
if(($global:cbCSVDocumentationProperties.SelectedValue -eq 'extended' -and $documentedObj.DisplayProperties) -or
|
||||
($global:cbCSVDocumentationProperties.SelectedValue -eq 'custom' -and $global:txtCSVCustomProperties.Text))
|
||||
{
|
||||
@@ -3687,14 +3745,14 @@ function Invoke-CSVProcessItem
|
||||
$itemsToExport += ""
|
||||
$itemsToExport += "# Assignments"
|
||||
$itemsToExport += ""
|
||||
$itemsToExport += $documentedObj.Assignments | Select $properties | ConvertTo-Csv -NoTypeInformation
|
||||
$itemsToExport += $documentedObj.Assignments | Select $properties | ConvertTo-Csv -NoTypeInformation @params
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$itemsToExport += $documentedObj.BasicInfo
|
||||
$itemsToExport += $documentedObj.FilteredSettings
|
||||
$itemsToExport = $itemsToExport | Select Name,Value | ConvertTo-Csv -NoTypeInformation
|
||||
$itemsToExport = $itemsToExport | Select Name,Value | ConvertTo-Csv -NoTypeInformation @params
|
||||
}
|
||||
|
||||
$fileName = $folder + "\$((Remove-InvalidFileNameChars $objName)).csv"
|
||||
|
||||
@@ -10,7 +10,7 @@ This module will also document some objects based on PowerShell functions
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.3'
|
||||
'1.0.4'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -295,7 +295,7 @@ function Add-CDDocumentCustomProfileValue
|
||||
return $false
|
||||
}
|
||||
}
|
||||
elseif($topObj.'@OData.Type' -like "#microsoft.graph.windows10EndpointProtectionConfiguration")
|
||||
elseif($topObj.'@OData.Type' -like "#microsoft.graph.windowsHealthMonitoringConfiguration")
|
||||
{
|
||||
if($prop.EntityKey -eq "configDeviceHealthMonitoringScope")
|
||||
{
|
||||
@@ -713,14 +713,13 @@ function Add-CDDocumentCustomProfileProperty
|
||||
Add-DefenderFirewallSettings $obj.firewallProfilePrivate "Private"
|
||||
Add-DefenderFirewallSettings $obj.firewallProfilePublic "Public"
|
||||
|
||||
$obj | Add-Member Noteproperty -Name "bitLockerBaseConfigureEncryptionMethods" -Value ($obj.bitLockerSystemDrivePolicy.encryptionMethod -ne $null) -Force
|
||||
$obj | Add-Member Noteproperty -Name "bitLockerBaseConfigureEncryptionMethods" -Value (?: ($obj.bitLockerSystemDrivePolicy.encryptionMethod -ne $null) $true $null) -Force
|
||||
$obj | Add-Member Noteproperty -Name "bitLockerSystemDriveEncryptionMethod" -Value $obj.bitLockerSystemDrivePolicy.encryptionMethod -Force
|
||||
$obj | Add-Member Noteproperty -Name "bitLockerFixedDriveEncryptionMethod" -Value $obj.bitLockerFixedDrivePolicy.encryptionMethod -Force
|
||||
$obj | Add-Member Noteproperty -Name "bitLockerRemovableDriveEncryptionMethod" -Value $obj.bitLockerRemovableDrivePolicy.encryptionMethod -Force
|
||||
|
||||
#$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) -Force
|
||||
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) -Force
|
||||
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicybitLockerDriveRecovery" -Value ($obj.bitLockerSystemDrivePolicy.recoveryOptions -ne $null) -Force
|
||||
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value (?: ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) $true $null) -Force
|
||||
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicybitLockerDriveRecovery" -Value (?: ($obj.bitLockerSystemDrivePolicy.recoveryOptions -ne $null) $true $null) -Force
|
||||
|
||||
if($obj.bitLockerSystemDrivePolicy.prebootRecoveryUrl -eq $null -and $obj.bitLockerSystemDrivePolicy.prebootRecoveryEnableMessageAndUrl -eq $null)
|
||||
{
|
||||
@@ -746,7 +745,7 @@ function Add-CDDocumentCustomProfileProperty
|
||||
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicy$($tmpProp)" -Value $obj.bitLockerSystemDrivePolicy.recoveryOptions.$tmpProp -Force
|
||||
}
|
||||
|
||||
$obj.bitLockerFixedDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticFixedDrivePolicybitLockerDriveRecovery" -Value ($obj.bitLockerFixedDrivePolicy.recoveryOptions -ne $null) -Force
|
||||
$obj.bitLockerFixedDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticFixedDrivePolicybitLockerDriveRecovery" -Value (?: ($obj.bitLockerFixedDrivePolicy.recoveryOptions -ne $null) $true $null) -Force
|
||||
|
||||
foreach($tmpProp in ($obj.bitLockerFixedDrivePolicy.recoveryOptions.PSObject.Properties).Name)
|
||||
{
|
||||
@@ -2194,15 +2193,17 @@ function Invoke-CDDocumentCustomOMAUri
|
||||
|
||||
foreach($setting in $obj.omaSettings)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "TableHeaders.name")
|
||||
# Add the name of the OMA-URI setting
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "SettingDetails.nameName")
|
||||
Value = $setting.displayName
|
||||
EntityKey = "displayName_$($setting.omaUri)"
|
||||
Category = $category
|
||||
SubCategory = $setting.displayName
|
||||
})
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
# Add the description of the OMA-URI setting
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "TableHeaders.description")
|
||||
Value = $setting.description
|
||||
EntityKey = "description_$($setting.omaUri)"
|
||||
@@ -2210,7 +2211,8 @@ function Invoke-CDDocumentCustomOMAUri
|
||||
SubCategory = $setting.displayName
|
||||
})
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
# Add the OMA-URI path of the OMA-URI setting
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "SettingDetails.oMAURIName")
|
||||
Value = $setting.omaUri
|
||||
EntityKey = "omaUri_$($setting.omaUri)"
|
||||
@@ -2253,6 +2255,7 @@ function Invoke-CDDocumentCustomOMAUri
|
||||
|
||||
if($value)
|
||||
{
|
||||
# Add the type of the OMA-URI setting
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "SettingDetails.dataTypeName")
|
||||
Value = $value
|
||||
@@ -2262,15 +2265,40 @@ function Invoke-CDDocumentCustomOMAUri
|
||||
})
|
||||
}
|
||||
|
||||
$value = $setting.value
|
||||
# Add the type of the OMA-URI setting
|
||||
if($setting.isEncrypted -ne $true)
|
||||
{
|
||||
if($setting.'@OData.Type' -eq '#microsoft.graph.omaSettingStringXml')
|
||||
{
|
||||
$value = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($value))
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "SettingDetails.valueName")
|
||||
Value = $setting.value
|
||||
Value = $value
|
||||
EntityKey = "value_$($setting.omaUri)"
|
||||
Category = $category
|
||||
SubCategory = $setting.displayName
|
||||
})
|
||||
}
|
||||
else # ToDo: Add check button
|
||||
{
|
||||
if($obj.'@ObjectFromFile' -ne $true)
|
||||
{
|
||||
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($setting.secretReferenceValueId)')"
|
||||
$value = $xmlValue.Value
|
||||
if($value)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = (Get-LanguageString "SettingDetails.valueName")
|
||||
Value = $value
|
||||
EntityKey = "value_$($setting.omaUri)"
|
||||
Category = $category
|
||||
SubCategory = $setting.displayName
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#https://docs.microsoft.com/en-us/office/vba/api/overview/word
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.2'
|
||||
'1.0.3'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -54,9 +54,7 @@ function Invoke-InitializeModule
|
||||
CombinedValueWithLabel="TableHeaders.value"
|
||||
CombinedValue="TableHeaders.value"
|
||||
useDeviceLicensing="TableHeaders.licenseType"
|
||||
#filterMode="Filter mode" # Not in any sring file yet
|
||||
|
||||
|
||||
#filterMode="Filter mode" # Not in any string file yet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +81,10 @@ function Add-WordOptionsControl
|
||||
$global:txtWordTableHeaderStyle.Text = Get-Setting "Documentation" "WordTableHeaderStyle" ""
|
||||
$global:txtWordCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordCategoryHeaderStyle" ""
|
||||
$global:txtWordSubCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordSubCategoryHeaderStyle" ""
|
||||
$global:txtWordContentControls.Text = Get-Setting "Documentation" "WordContentControls" "Year=;Address="
|
||||
$global:txtWordTitleProperty.Text = Get-Setting "Documentation" "WordTitleProperty" "Intune documentation"
|
||||
$global:txtWordSubjectProperty.Text = Get-Setting "Documentation" "WordSubjectProperty" "Intune documentation"
|
||||
|
||||
|
||||
$global:chkWordOpenDocument.IsChecked = ((Get-Setting "Documentation" "WordOpenDocument" "true") -ne "false")
|
||||
|
||||
@@ -125,6 +127,9 @@ function Invoke-WordPreProcessItems
|
||||
Save-Setting "Documentation" "WordTableHeaderStyle" $global:txtWordTableHeaderStyle.Text
|
||||
Save-Setting "Documentation" "WordCategoryHeaderStyle" $global:txtWordCategoryHeaderStyle.Text
|
||||
Save-Setting "Documentation" "WordSubCategoryHeaderStyle" $global:txtWordSubCategoryHeaderStyle.Text
|
||||
Save-Setting "Documentation" "WordContentControls" $global:txtWordContentControls.Text
|
||||
Save-Setting "Documentation" "WordTitleProperty" $global:txtWordTitleProperty.Text
|
||||
Save-Setting "Documentation" "WordSubjectProperty" $global:txtWordSubjectProperty.Text
|
||||
|
||||
try
|
||||
{
|
||||
@@ -205,6 +210,69 @@ function Invoke-WordPreProcessItems
|
||||
}
|
||||
|
||||
$script:builtinStyles = [Enum]::GetNames([Microsoft.Office.Interop.Word.wdBuiltinStyle])
|
||||
|
||||
if(-not $global:txtWordDocumentTemplate.Text)
|
||||
{
|
||||
$script:doc.Application.Templates.LoadBuildingBlocks()
|
||||
$BuildingBlocks = $script:doc.Application.Templates | Where {$_.name -eq 'Built-In Building Blocks.dotx'}
|
||||
if($BuildingBlocks)
|
||||
{
|
||||
$coverPageName = ?? $global:txtWordCoverPage.Text 'Ion (Dark)'
|
||||
try
|
||||
{
|
||||
$blocks = @()
|
||||
|
||||
for($i = 1;$i -le $BuildingBlocks.BuildingBlockEntries.Count;$i++)
|
||||
{
|
||||
$blocks += $BuildingBlocks.BuildingBlockEntries.Item($i)
|
||||
}
|
||||
|
||||
$coverPages = (($blocks | Where { $_.Type.Index -eq 2 } | Select Name) | Sort -Property Name).Name
|
||||
|
||||
if(($coverPages | measure).Count -gt 0)
|
||||
{
|
||||
if($coverPageName -notin $coverPages)
|
||||
{
|
||||
Write-Log "$coverPageName not found in available Cover Page list. Using: $($coverPages[0])"
|
||||
Write-Log "Available Cover Pages: $(($coverPages -join ","))"
|
||||
$coverPageName = $coverPages[0]
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Log "Add Cover Page: $coverPageName"
|
||||
}
|
||||
}
|
||||
|
||||
$coverPage = $BuildingBlocks.BuildingBlockEntries.Item($coverPageName)
|
||||
$coverPage.Insert($script:wordApp.Selection.Range,$true) | Out-Null
|
||||
$script:wordApp.Selection.InsertNewPage()
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-LogError "Failed to create Cover Page" $_.Exception
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$coverPageProps = $script:doc.CustomXMLParts | where { $_.NamespaceURI -match "coverPageProps$" }
|
||||
if($coverPageProps)
|
||||
{
|
||||
Write-Log "Available Cover Page properties for $($coverPageName): $(((([xml]$coverPageProps.DocumentElement.XML).ChildNodes[0].ChildNodes).Name -join ","))"
|
||||
}
|
||||
}
|
||||
catch{}
|
||||
|
||||
try
|
||||
{
|
||||
$script:doc.TablesOfContents.Add($script:wordApp.Selection.Range) | out-null
|
||||
$script:wordApp.Selection.InsertNewPage()
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-LogError "Failed to create Table of Contents" $_.Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-WordPostProcessItems
|
||||
@@ -216,17 +284,34 @@ function Invoke-WordPostProcessItems
|
||||
}
|
||||
|
||||
#Add properties - ToDo: This is static...
|
||||
Set-WordDocBuiltInProperty "wdPropertyTitle" "Intune documentation"
|
||||
Set-WordDocBuiltInProperty "wdPropertySubject" "Intune documentation"
|
||||
Set-WordDocBuiltInProperty "wdPropertyTitle" (?? $global:txtWordTitleProperty.Text "Intune documentation")
|
||||
Set-WordDocBuiltInProperty "wdPropertySubject" (?? $global:txtWordSubjectProperty.Text "Intune documentation")
|
||||
Set-WordDocBuiltInProperty "wdPropertyAuthor" $userName
|
||||
Set-WordDocBuiltInProperty "wdPropertyCompany" $global:Organization.displayName
|
||||
Set-WordDocBuiltInProperty "wdPropertyKeywords" "Intune,Endpoint Manager,MEM"
|
||||
|
||||
try
|
||||
{
|
||||
# ToDo: Add support for custom properties
|
||||
# Add: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.core.documentproperties.add?view=office-pia
|
||||
# Types: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.core.msodocproperties?view=office-pia
|
||||
#$coverPageProps = $script:doc.CustomXMLParts | where { $_.NamespaceURI -match "coverPageProps$" }
|
||||
#[System.__ComObject].InvokeMember("add",[System.Reflection.BindingFlags]::InvokeMethod,$null,$script:doc.CustomDocumentProperties,([array]("PropName", $false, 4, "PropValue")))
|
||||
|
||||
$ContentControlProperties = $global:txtWordContentControls.Text #"Year=;Address=TestAddress"
|
||||
foreach($ccObj in $ContentControlProperties.Split(';'))
|
||||
{
|
||||
$ccName,$ccVal = $ccObj.Split('=')
|
||||
Set-WordContentControlText $ccName $ccVal
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
|
||||
#update fields, ToC etc.
|
||||
$script:doc.Fields | ForEach-Object -Process { $_.Update() | Out-Null }
|
||||
$script:doc.TablesOfContents | ForEach-Object -Process { $_.Update() | Out-Null }
|
||||
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
|
||||
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
|
||||
$script:doc.TablesOfAuthorities | ForEach-Object -Process { $_.Update() | Out-Null }
|
||||
|
||||
$fileName = $global:txtWordDocumentName.Text
|
||||
if(-not $fileName)
|
||||
@@ -250,15 +335,57 @@ function Invoke-WordPostProcessItems
|
||||
|
||||
if($global:chkWordOpenDocument.IsChecked -eq $true)
|
||||
{
|
||||
$wordApp.Visible = $true
|
||||
$wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize
|
||||
$wordApp.Activate()
|
||||
[Console.Window]::SetForegroundWindow($wordApp.ActiveWindow.Hwnd) | Out-Null
|
||||
$script:wordApp.Visible = $true
|
||||
$script:wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize
|
||||
$script:wordApp.Activate()
|
||||
[Console.Window]::SetForegroundWindow($script:wordApp.ActiveWindow.Hwnd) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
$script:doc.Close([Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges)
|
||||
$wordApp.Quit()
|
||||
$script:wordApp.Quit()
|
||||
}
|
||||
}
|
||||
|
||||
function Set-WordContentControlText
|
||||
{
|
||||
param($controlName, $value)
|
||||
|
||||
if(-not $controlName) { return }
|
||||
|
||||
try
|
||||
{
|
||||
$ctrl = $script:doc.SelectContentControlsByTitle($controlName)
|
||||
|
||||
if($ctrl)
|
||||
{
|
||||
Write-LogDebug "Update ContentControl $controlName (Type: $($ctrl[1].Type))"
|
||||
if($ctrl[1].Type -eq 6)
|
||||
{
|
||||
if($ctrl[1].DateDisplayFormat)
|
||||
{
|
||||
$ctrl[1].Range.Text = (Get-Date).ToString($ctrl[1].DateDisplayFormat)
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctrl[1].Range.Text = (Get-Date).ToShortDateString()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(-not $value) { return }
|
||||
|
||||
$ctrl[1].Range.Text = $value
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Log "No ContentControl found with name $controlName" 2
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-LogError "Failed to set ContentControl $controlName" $_.Exception
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.1.8'
|
||||
'3.1.9'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -106,7 +106,9 @@ function Invoke-InitializeModule
|
||||
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
|
||||
PropertiesToRemove = @("privacyAccessControls")
|
||||
PostFileImportCommand = { Start-PostFileImportDeviceConfiguration @args }
|
||||
PreCopyCommand = { Start-PreCopyDeviceConfiguration @args }
|
||||
PostCopyCommand = { Start-PostCopyDeviceConfiguration @args }
|
||||
PostExportCommand = { Start-PostExportDeviceConfiguration @args }
|
||||
GroupId = "DeviceConfiguration"
|
||||
})
|
||||
|
||||
@@ -187,6 +189,7 @@ function Invoke-InitializeModule
|
||||
|
||||
# Could work with https://main.iam.ad.ext.azure.com/api/LoginTenantBrandings
|
||||
|
||||
#>
|
||||
|
||||
Add-ViewItem (New-Object PSObject -Property @{
|
||||
Title = "Azure Branding"
|
||||
@@ -196,12 +199,12 @@ function Invoke-InitializeModule
|
||||
ViewProperties = @("Id")
|
||||
PreImportCommand = { Start-PreImportAzureBranding @args }
|
||||
PostListCommand = { Start-PostListAzureBranding @args }
|
||||
ShowButtons = @("Export","View")
|
||||
NameProperty = "Id"
|
||||
Permissons=@("Organization.ReadWrite.All")
|
||||
Icon = "Branding"
|
||||
SkipRemoveProperties = @('Id')
|
||||
})
|
||||
#>
|
||||
|
||||
Add-ViewItem (New-Object PSObject -Property @{
|
||||
Title = "Enrollment Status Page"
|
||||
@@ -381,6 +384,7 @@ function Invoke-InitializeModule
|
||||
ODataMetadata="minimal" # categories property not supported with ODataMetadata full
|
||||
PostFileImportCommand = { Start-PostFileImportApplications @args }
|
||||
PreUpdateCommand = { Start-PreUpdateApplication @args }
|
||||
PreImportCommand = { Start-PreImportCommandApplication @args }
|
||||
GroupId = "Apps"
|
||||
})
|
||||
|
||||
@@ -393,6 +397,7 @@ function Invoke-InitializeModule
|
||||
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
|
||||
PreImportAssignmentsCommand = { Start-PreImportAssignmentsAutoPilot @args }
|
||||
PreDeleteCommand = { Start-PreDeleteAutoPilot @args }
|
||||
PropertiesToRemoveForUpdate = @('managementServiceAppId')
|
||||
GroupId = "WinEnrollment"
|
||||
})
|
||||
|
||||
@@ -666,28 +671,28 @@ function Set-EMViewPanel
|
||||
})
|
||||
|
||||
Add-XamlEvent $panel "txtFilter" "Add_LostFocus" ({ #param($obj, $e)
|
||||
Invoke-FiterBoxChanged $this
|
||||
Invoke-FilterBoxChanged $this
|
||||
#$e.Handled = $true
|
||||
})
|
||||
|
||||
Add-XamlEvent $panel "txtFilter" "Add_GotFocus" ({
|
||||
if($this.Tag -eq "1" -and $this.Text -eq "Filter") { $this.Text = "" }
|
||||
Invoke-FiterBoxChanged $this
|
||||
Invoke-FilterBoxChanged $this
|
||||
})
|
||||
|
||||
Add-XamlEvent $panel "txtFilter" "Add_TextChanged" ({
|
||||
Invoke-FiterBoxChanged $this
|
||||
Invoke-FilterBoxChanged $this
|
||||
})
|
||||
|
||||
Invoke-FiterBoxChanged ($panel.FindName("txtFilter"))
|
||||
Invoke-FilterBoxChanged ($panel.FindName("txtFilter"))
|
||||
|
||||
$allowDelete = Get-SettingValue "EMAllowDelete"
|
||||
Set-XamlProperty $panel "btnDelete" "Visibility" (?: ($allowDelete -eq $true) "Visible" "Collapsed")
|
||||
|
||||
$global:dgObjects.add_selectionChanged({
|
||||
Set-XamlProperty $this.Parent "btnView" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null) $false $true)
|
||||
Set-XamlProperty $this.Parent "btnCopy" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null) $false $true)
|
||||
Set-XamlProperty $this.Parent "btnDelete" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null -and $global:curObjectType.AllowDelete -ne $false) $false $true)
|
||||
Set-XamlProperty $this.Parent "btnView" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem) $false $true)
|
||||
Set-XamlProperty $this.Parent "btnCopy" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem) $false $true)
|
||||
Set-XamlProperty $this.Parent "btnDelete" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem -and $global:curObjectType.AllowDelete -ne $false) $false $true)
|
||||
})
|
||||
|
||||
# ToDo: Move this to the view object
|
||||
@@ -696,7 +701,7 @@ function Set-EMViewPanel
|
||||
{
|
||||
$dpd.AddValueChanged($global:dgObjects, {
|
||||
Set-XamlProperty $global:dgObjects.Parent "txtFilter" "Text" ""
|
||||
$enabled = (?: ($this.ItemsSource -eq $null -or ($this.ItemsSource | measure).Count -eq 0) $false $true)
|
||||
$enabled = (?: ($null -eq $this.ItemsSource -or ($this.ItemsSource | measure).Count -eq 0) $false $true)
|
||||
Set-XamlProperty $global:dgObjects.Parent "btnImport" "IsEnabled" $true # Always all Import if ObjectType allows it
|
||||
Set-XamlProperty $global:dgObjects.Parent "btnExport" "IsEnabled" $enabled
|
||||
})
|
||||
@@ -726,7 +731,7 @@ function Set-EMViewPanel
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-FiterBoxChanged
|
||||
function Invoke-FilterBoxChanged
|
||||
{
|
||||
param($txtBox)
|
||||
|
||||
@@ -751,9 +756,12 @@ function Invoke-FiterBoxChanged
|
||||
{
|
||||
$filter = {
|
||||
param ($item)
|
||||
foreach($prop in ($item.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object")}))
|
||||
|
||||
return ($null -ne ($item.PSObject.Properties | Where { $_.Name -notin @("IsSelected","Object", "ObjectType") -and $_.Value -match [regex]::Escape($txtBox.Text) }))
|
||||
|
||||
foreach($prop in ($item.PSObject.Properties | Where { $_.Name -notin @("IsSelected","Object", "ObjectType")}))
|
||||
{
|
||||
if($prop.Value -match $txtBox.Text) { return $true }
|
||||
if($prop.Value -match [regex]::Escape($txtBox.Text)) { return $true }
|
||||
}
|
||||
$false
|
||||
}
|
||||
@@ -941,9 +949,82 @@ function Start-PostCopyDeviceConfiguration
|
||||
windowsPrivacyAccessControls = $objCopyFrom.privacyAccessControls
|
||||
}
|
||||
$json = $privacyObj | ConvertTo-Json -Depth 20
|
||||
$ret = Invoke-GraphRequest -Url "deviceManagement/deviceConfigurations('$($objNew.Id)')/windowsPrivacyAccessControls" -Body $json -Method "POST"
|
||||
Invoke-GraphRequest -Url "deviceManagement/deviceConfigurations('$($objNew.Id)')/windowsPrivacyAccessControls" -Body $json -Method "POST" | Out-null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Start-PreCopyDeviceConfiguration
|
||||
{
|
||||
param($obj, $objectType, $newName)
|
||||
|
||||
if(($obj.omaSettings | measure).Count -gt 0)
|
||||
{
|
||||
foreach($omaSetting in ($obj.omaSettings | Where isEncrypted -eq $true))
|
||||
{
|
||||
if($omaSetting.isEncrypted -eq $false) { continue }
|
||||
|
||||
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($omaSetting.secretReferenceValueId)')"
|
||||
if($xmlValue.Value)
|
||||
{
|
||||
$omaSetting.isEncrypted = $false
|
||||
$omaSetting.secretReferenceValueId = $null
|
||||
|
||||
if($omaSetting.'@odata.type' -eq "#microsoft.graph.omaSettingStringXml" -or
|
||||
$omaSetting.'value@odata.type' -eq "#Binary")
|
||||
{
|
||||
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($xmlValue.Value)
|
||||
$omaSetting.value = [Convert]::ToBase64String($bytes)
|
||||
}
|
||||
else
|
||||
{
|
||||
$omaSetting.value = $xmlValue.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$false
|
||||
}
|
||||
|
||||
function Start-PostExportDeviceConfiguration
|
||||
{
|
||||
param($obj, $objectType, $path)
|
||||
|
||||
$fileName = "$path\$((Remove-InvalidFileNameChars (Get-GraphObjectName $obj $objectType))).json"
|
||||
|
||||
if(($obj.omaSettings | measure).Count -gt 0)
|
||||
{
|
||||
$updated = $false
|
||||
foreach($omaSetting in @(($obj.omaSettings | Where isEncrypted -eq $true)))
|
||||
{
|
||||
if($omaSetting.isEncrypted -eq $false) { continue }
|
||||
|
||||
# Get decrypted value and mark OMA-URI setting as not encrypted
|
||||
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($omaSetting.secretReferenceValueId)')"
|
||||
if($xmlValue.Value)
|
||||
{
|
||||
$omaSetting.isEncrypted = $false
|
||||
$omaSetting.secretReferenceValueId = $null
|
||||
if($omaSetting.'@odata.type' -eq "#microsoft.graph.omaSettingStringXml" -or
|
||||
$omaSetting.'value@odata.type' -eq "#Binary")
|
||||
{
|
||||
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($xmlValue.Value)
|
||||
$omaSetting.value = [Convert]::ToBase64String($bytes)
|
||||
}
|
||||
else
|
||||
{
|
||||
$omaSetting.value = $xmlValue.Value
|
||||
}
|
||||
$updated = $true
|
||||
}
|
||||
}
|
||||
|
||||
if($updated)
|
||||
{
|
||||
$obj | ConvertTo-Json -Depth 20 | Out-File -LiteralPath $fileName -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1041,7 +1122,7 @@ function Start-PostImportIntuneBranding
|
||||
Remove-Property $global:brandingClone $prop
|
||||
}
|
||||
$json = ($global:brandingClone | ConvertTo-Json -Depth 20)
|
||||
$ret = Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -Body $json -Method "PATCH"
|
||||
Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -Body $json -Method "PATCH" | Out-Null
|
||||
}
|
||||
|
||||
function Start-PostGetIntuneBranding
|
||||
@@ -1285,7 +1366,7 @@ function Start-PostListAppProtection
|
||||
# App Configurations for Managed Apps are included in App Protections e.g. the /deviceAppManagement/managedAppPolicies API
|
||||
# For some reason, the $filter option is not supported to filter out these objects
|
||||
# e.g. not isof(...) to excluded the type, not startsWith(id, 'A_') to exlude based on Id
|
||||
# These filters generates a request error so fiter them out manually in this function instead
|
||||
# These filters generates a request error so filter them out manually in this function instead
|
||||
# The portal is probably doing the same thing since these are included in the return but not in the UI
|
||||
$objList | Where { $_.Object.'@OData.Type' -ne '#microsoft.graph.targetedManagedAppConfiguration' }
|
||||
}
|
||||
@@ -1521,6 +1602,18 @@ function Start-PreUpdateApplication
|
||||
|
||||
Remove-Property $obj "appStoreUrl"
|
||||
}
|
||||
|
||||
function Start-PreImportCommandApplication
|
||||
{
|
||||
param($obj, $objectType, $file, $assignments)
|
||||
|
||||
if($obj.'@OData.Type' -in @('#microsoft.graph.microsoftStoreForBusinessApp','#microsoft.graph.androidStoreApp'))
|
||||
{
|
||||
Write-Log "App type '$($obj.'@OData.Type')' not supported for import" 2
|
||||
@{ "Import" = $false }
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Group Policy/Administrative Templates functions
|
||||
@@ -1927,7 +2020,7 @@ function Start-PostFileImportNotifications
|
||||
{
|
||||
param($obj, $objectType, $file)
|
||||
|
||||
$tmpObj = Get-Content $file | ConvertFrom-Json
|
||||
$tmpObj = Get-Content -LiteralPath $file | ConvertFrom-Json
|
||||
|
||||
foreach($localizedNotificationMessage in $tmpObj.localizedNotificationMessages)
|
||||
{
|
||||
@@ -2004,6 +2097,12 @@ function Start-PreImportEnrollmentRestrictions
|
||||
{
|
||||
Remove-Property $obj "Id"
|
||||
}
|
||||
|
||||
if($obj.windowsMobileRestriction)
|
||||
{
|
||||
# Windows Phone operations are no longer supported
|
||||
Remove-Property $obj "windowsMobileRestriction"
|
||||
}
|
||||
}
|
||||
|
||||
function Start-PreDeleteEnrollmentRestrictions
|
||||
|
||||
2054
Extensions/IntuneTools.psm1
Normal file
2054
Extensions/IntuneTools.psm1
Normal file
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.0.4'
|
||||
'3.0.5'
|
||||
}
|
||||
|
||||
$global:msalAuthenticator = $null
|
||||
@@ -20,6 +20,7 @@ function Invoke-InitializeModule
|
||||
$global:MSALToken = $null
|
||||
$global:MSALAuthority = $null
|
||||
$script:AccessableTenants = $null
|
||||
$global:SkipTokenCacheHelperEx = $null
|
||||
|
||||
$global:appSettingSections += (New-Object PSObject -Property @{
|
||||
Title = "MSAL"
|
||||
@@ -404,7 +405,15 @@ function Add-MSALPrereq
|
||||
$RequiredAssemblies.Add($msalPath)
|
||||
$RequiredAssemblies.Add('System.Security.dll')
|
||||
|
||||
Add-Type -Path ($global:AppRootFolder + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies
|
||||
try
|
||||
{
|
||||
Add-Type -Path ($global:AppRootFolder + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies
|
||||
}
|
||||
catch
|
||||
{
|
||||
$global:SkipTokenCacheHelperEx = $true
|
||||
Write-LogError "Failed to compile TokenCacheHelperEx. The access token will not be cached. Check write access to the CS folder and ASR policies" $_.Exception
|
||||
}
|
||||
}
|
||||
|
||||
function Get-MsalAuthenticationToken
|
||||
@@ -496,7 +505,7 @@ function Get-MSALApp
|
||||
|
||||
$msalApp = $appBuilder.Build()
|
||||
|
||||
if((Get-SettingValue "CacheMSALToken"))
|
||||
if($global:SkipTokenCacheHelperEx -ne $true -and (Get-SettingValue "CacheMSALToken"))
|
||||
{
|
||||
[TokenCacheHelperEx]::EnableSerialization($msalApp.UserTokenCache, "%LOCALAPPDATA%\CloudAPIPowerShellManagement\msalcahce.bin3")
|
||||
}
|
||||
@@ -540,16 +549,16 @@ function Connect-MSALUser
|
||||
return
|
||||
}
|
||||
|
||||
if (-not ("TokenCacheHelperEx" -as [type]))
|
||||
if ($global:SkipTokenCacheHelperEx -ne $true -and -not ("TokenCacheHelperEx" -as [type]))
|
||||
{
|
||||
Add-MSALPrereq
|
||||
}
|
||||
|
||||
if (-not ("TokenCacheHelperEx" -as [type]))
|
||||
{
|
||||
Write-Log "Failed to compile TokenCacheHelperEx class"
|
||||
return
|
||||
}
|
||||
#if (-not ("TokenCacheHelperEx" -as [type]))
|
||||
#{
|
||||
# Write-Log "Failed to compile TokenCacheHelperEx class"
|
||||
# return
|
||||
#}
|
||||
|
||||
$curTicks = $global:MSALToken.ExpiresOn.LocalDateTime.Ticks
|
||||
|
||||
@@ -977,7 +986,7 @@ function Get-MSALProfileEllipse
|
||||
Write-Status ""
|
||||
})
|
||||
|
||||
AddGridObject $otherLogins $lnkButton
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
@@ -1019,7 +1028,7 @@ function Get-MSALProfileEllipse
|
||||
Write-Status ""
|
||||
})
|
||||
|
||||
AddGridObject $otherLogins $lnkButton
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
|
||||
$loginPanel.Tag = $this.Content
|
||||
|
||||
@@ -1228,7 +1237,7 @@ function Get-MSALProfileEllipse
|
||||
|
||||
$grdAccount.Children.Add($lnkButton) | Out-Null
|
||||
|
||||
AddGridObject $otherLogins $grdAccount
|
||||
Add-GridObject $otherLogins $grdAccount
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
@@ -1271,7 +1280,7 @@ function Get-MSALProfileEllipse
|
||||
Write-Status ""
|
||||
})
|
||||
|
||||
AddGridObject $otherLogins $lnkButton
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
|
||||
if(($script:AccessableTenants | measure).Count -gt 1)
|
||||
{
|
||||
@@ -1281,7 +1290,7 @@ function Get-MSALProfileEllipse
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS><Bold>Tenants:</Bold></TextBlock>")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
|
||||
AddGridObject $otherLogins $lbObj
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
foreach($tenant in $script:AccessableTenants)
|
||||
{
|
||||
try
|
||||
@@ -1312,13 +1321,13 @@ function Get-MSALProfileEllipse
|
||||
}
|
||||
Write-Status ""
|
||||
})
|
||||
AddGridObject $otherLogins $lnkButton
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
}
|
||||
else
|
||||
{
|
||||
$lbObj.Background = $window.TryFindResource("SelectedRowBackgroundColor")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
AddGridObject $otherLogins $lbObj
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
|
||||
@@ -10,7 +10,7 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.1.4'
|
||||
'3.1.5'
|
||||
}
|
||||
|
||||
$global:MSGraphGlobalApps = @(
|
||||
@@ -430,42 +430,48 @@ function Show-GraphObjects
|
||||
|
||||
$graphObjects = @(Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType)
|
||||
|
||||
if(($graphObjects | measure).Count -eq 0) { return }
|
||||
|
||||
$dgObjects.AutoGenerateColumns = $false
|
||||
$dgObjects.Columns.Clear()
|
||||
$tmpObj = $graphObjects | Select -First 1
|
||||
|
||||
$prop = $tmpObj.PSObject.Properties | Where Name -eq "IsSelected"
|
||||
if($prop)
|
||||
{
|
||||
$column = Get-GridCheckboxColumn "IsSelected"
|
||||
$dgObjects.Columns.Add($column)
|
||||
if(($graphObjects | measure).Count -gt 0)
|
||||
{
|
||||
$tmpObj = $graphObjects | Select -First 1
|
||||
|
||||
$column.Header.add_Click({
|
||||
foreach($item in $global:dgObjects.ItemsSource)
|
||||
{
|
||||
$item.IsSelected = $this.IsChecked
|
||||
}
|
||||
$global:dgObjects.Items.Refresh()
|
||||
})
|
||||
$prop = $tmpObj.PSObject.Properties | Where Name -eq "IsSelected"
|
||||
if($prop)
|
||||
{
|
||||
$column = Get-GridCheckboxColumn "IsSelected"
|
||||
$dgObjects.Columns.Add($column)
|
||||
|
||||
$column.Header.add_Click({
|
||||
foreach($item in $global:dgObjects.ItemsSource)
|
||||
{
|
||||
$item.IsSelected = $this.IsChecked
|
||||
}
|
||||
$global:dgObjects.Items.Refresh()
|
||||
})
|
||||
}
|
||||
|
||||
$tableColumns = @()
|
||||
# Add other columns
|
||||
foreach($prop in ($tmpObj.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object","ObjectType")}))
|
||||
{
|
||||
$binding = [System.Windows.Data.Binding]::new($prop.Name)
|
||||
$column = [System.Windows.Controls.DataGridTextColumn]::new()
|
||||
$column.Header = $prop.Name
|
||||
$column.IsReadOnly = $true
|
||||
$column.Binding = $binding
|
||||
|
||||
$tableColumns += $prop.Name
|
||||
$dgObjects.Columns.Add($column)
|
||||
}
|
||||
$ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new($graphObjects)
|
||||
$dgObjects.ItemsSource = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList)
|
||||
}
|
||||
|
||||
$tableColumns = @()
|
||||
# Add other columns
|
||||
foreach($prop in ($tmpObj.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object","ObjectType")}))
|
||||
else
|
||||
{
|
||||
$binding = [System.Windows.Data.Binding]::new($prop.Name)
|
||||
$column = [System.Windows.Controls.DataGridTextColumn]::new()
|
||||
$column.Header = $prop.Name
|
||||
$column.IsReadOnly = $true
|
||||
$column.Binding = $binding
|
||||
|
||||
$tableColumns += $prop.Name
|
||||
$dgObjects.Columns.Add($column)
|
||||
$dgObjects.ItemsSource = $null
|
||||
}
|
||||
$ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new($graphObjects)
|
||||
$dgObjects.ItemsSource = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList)
|
||||
|
||||
# Show/Hide buttons based on object type
|
||||
foreach($ctrl in $spSubMenu.Children)
|
||||
@@ -1236,7 +1242,7 @@ function Show-GraphBulkDeleteForm
|
||||
return
|
||||
}
|
||||
|
||||
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete all objects of the selected type(s)?`n`n$selCount type(s) selected", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
|
||||
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete all objects of the selected type(s)?`n`n$selCount type(s) selected`n`nEnvironment: $($global:Organization.displayName)", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
|
||||
{
|
||||
return
|
||||
}
|
||||
@@ -1331,7 +1337,10 @@ function Import-GraphFile
|
||||
return
|
||||
}
|
||||
|
||||
Get-GraphMigrationObjectsFromFile
|
||||
if($global:chkImportAssignments -and $global:chkImportAssignments.IsChecked -eq $true)
|
||||
{
|
||||
Get-GraphMigrationObjectsFromFile
|
||||
}
|
||||
|
||||
Get-GraphDependencyObjects $file.ObjectType
|
||||
|
||||
@@ -2268,7 +2277,7 @@ function Remove-GraphObjects
|
||||
return
|
||||
}
|
||||
|
||||
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete $($objectsToDelete.Count) $($global:curObjectType.Title) object(s)?", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
|
||||
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete $($objectsToDelete.Count) $($global:curObjectType.Title) object(s)?`n`nEnvironment: $($global:Organization.displayName)", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
|
||||
{
|
||||
return
|
||||
}
|
||||
@@ -2344,9 +2353,12 @@ function Copy-GraphObject
|
||||
{
|
||||
# Export profile
|
||||
Write-Status "Export $((Get-GraphObjectName $dgObjects.SelectedItem $global:curObjectType))"
|
||||
|
||||
$exportObj = (Get-GraphObject $dgObjects.SelectedItem.Object $global:curObjectType -SkipAssignments).Object
|
||||
|
||||
if($global:curObjectType.PreCopyCommand)
|
||||
{
|
||||
if((& $global:curObjectType.PreCopyCommand $dgObjects.SelectedItem.Object $global:curObjectType $ret))
|
||||
if((& $global:curObjectType.PreCopyCommand $exportObj $global:curObjectType $ret))
|
||||
{
|
||||
Show-GraphObjects
|
||||
Write-Status ""
|
||||
@@ -2354,8 +2366,6 @@ function Copy-GraphObject
|
||||
}
|
||||
}
|
||||
|
||||
$exportObj = (Get-GraphObject $dgObjects.SelectedItem.Object $global:curObjectType -SkipAssignments).Object
|
||||
|
||||
# Convert to Json and back to clone the object
|
||||
$obj = ConvertTo-Json $exportObj -Depth 10 | ConvertFrom-Json
|
||||
if($obj)
|
||||
|
||||
Reference in New Issue
Block a user