Compare commits

...
9 Commits
Author SHA1 Message Date
Mikael Karlsson c16f85a299 3.9.6 2024-04-22 21:48:16 +10:00
Mikael Karlsson 47968b4219 3.9.5 2024-01-24 21:25:53 +11:00
Mikael Karlsson 6ac211a2bf 3.9.4 2023-12-18 19:37:17 +11:00
Mikael Karlsson 83c845fc33 3.9.3 Fix 2023-12-11 19:00:23 +11:00
Mikael Karlsson f5613442bd 3.9.3 2023-12-11 18:58:13 +11:00
Mikael Karlsson ab7b062946 3.9.2 2023-10-17 20:34:44 +11:00
Mikael Karlsson ea3af64316 3.9.1 2023-08-30 20:07:18 +10:00
Mikael Karlsson e6ec048df0 3.9.0 Module
Added version in the module file
2023-05-04 23:42:37 +10:00
Mikael Karlsson 0fd868ff70 3.9.0 2023-05-04 22:00:12 +10:00
84 changed files with 84851 additions and 58222 deletions
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Net;
using System.Net.Http;
using Microsoft.Identity.Client;
public class HttpFactoryWithProxy : IMsalHttpClientFactory
{
private static HttpClient _httpClient;
public HttpFactoryWithProxy(string proxyURI) : this(proxyURI, null, null)
{
}
public HttpFactoryWithProxy(string proxyURI, string proxyUserName = null, string proxyPassword = null)
{
if (_httpClient == null)
{
var proxy = new WebProxy
{
Address = new Uri(proxyURI),
BypassProxyOnLocal = false,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(
userName: proxyUserName,
password: proxyPassword)
};
var httpClientHandler = new HttpClientHandler
{
Proxy = proxy,
};
_httpClient = new HttpClient(handler: httpClientHandler);
}
}
public HttpClient GetHttpClient()
{
return _httpClient;
}
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -12,7 +12,7 @@
RootModule = 'CloudAPIPowerShellManagement.psm1' RootModule = 'CloudAPIPowerShellManagement.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '3.8.1' ModuleVersion = '3.9.6'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()
@@ -27,7 +27,7 @@ Author = 'Mikael Karlsson'
# CompanyName = '' # CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = '(c) 2022 Mikael Karlsson. Software released under MIT License.' Copyright = '(c) 2023 Mikael Karlsson. Software released under MIT License.'
# Description of the functionality provided by this module # Description of the functionality provided by this module
Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Graph API' Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Graph API'
@@ -69,7 +69,7 @@ Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Grap
NestedModules = @() NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @("Initialize-CloudAPIManagement","Initialize-CloudAPIManagement") FunctionsToExport = @("Initialize-CloudAPIManagement")
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
# CmdletsToExport = @() # CmdletsToExport = @()
+14 -4
View File
@@ -88,14 +88,25 @@ function Initialize-CloudAPIManagement
$certificate $certificate
) )
$PSModuleAutoloadingPreference = "none"
$global:wpfNS = "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'" $global:wpfNS = "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'"
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationFramework
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$global:hideUI = ($Silent -eq $true) $global:hideUI = ($Silent -eq $true)
$global:SilentBatchFile = $SilentBatchFile $global:SilentBatchFile = $SilentBatchFile
if($tenantId)
{
$global:AzureAppId = $appId
$global:ClientSecret = $secret
$global:ClientCert = $certificate
}
if($global:hideUI -ne $true) if($global:hideUI -ne $true)
{ {
# Run with UI # Run with UI
@@ -126,12 +137,11 @@ function Initialize-CloudAPIManagement
Write-Error "Tenant Id is missing. Use -TenantId <Tenant-guid> on the command line to run silent batch jobs" Write-Error "Tenant Id is missing. Use -TenantId <Tenant-guid> on the command line to run silent batch jobs"
return return
} }
$global:TenantId = $tenantId
$global:AzureAppId = $appId
$global:ClientSecret = $secret
$global:ClientCert = $certificate
} }
$global:TenantId = $tenantId
if($ShowConsoleWindow -ne $true) if($ShowConsoleWindow -ne $true)
{ {
Hide-Console Hide-Console
+204 -7
View File
@@ -11,7 +11,7 @@ This module handles the WPF UI
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.6'
} }
function Initialize-Window function Initialize-Window
@@ -58,6 +58,7 @@ function Start-CoreApp
$global:useDefaultFolderDialog = $false $global:useDefaultFolderDialog = $false
$global:WindowsAPICodePackLoaded = $false $global:WindowsAPICodePackLoaded = $false
$script:proxyURI = $null
$global:loadedModules = @() $global:loadedModules = @()
$global:viewObjects = @() $global:viewObjects = @()
@@ -235,6 +236,8 @@ function Write-Log
if(-not $global:logFileMaxSize) { [Int64]$global:logFileMaxSize = Get-SettingValue "LogFileSize" 1024; $global:logFileMaxSize = $global:logFileMaxSize * 1kb } if(-not $global:logFileMaxSize) { [Int64]$global:logFileMaxSize = Get-SettingValue "LogFileSize" 1024; $global:logFileMaxSize = $global:logFileMaxSize * 1kb }
if($null -eq $global:logOutputError) { $global:logOutputError = Get-SettingValue "LogOutputError" }
$fi = [IO.FileInfo]$global:logFile $fi = [IO.FileInfo]$global:logFile
if($fi.Length -gt $global:logFileMaxSize) if($fi.Length -gt $global:logFileMaxSize)
@@ -286,12 +289,19 @@ function Write-Log
if($type -eq 2) if($type -eq 2)
{ {
Write-Warning $Text Write-Warning $Text
$typeStr = "Error" $typeStr = "Warning"
} }
elseif($type -eq 3) elseif($type -eq 3)
{
if($global:logOutputError -ne $false)
{ {
$host.ui.WriteErrorLine($Text) $host.ui.WriteErrorLine($Text)
$typeStr = "Warning" }
else
{
Write-Warning $Text
}
$typeStr = "Error"
} }
else else
{ {
@@ -667,8 +677,15 @@ function Show-UpdatesDialog
{ {
if($mystream) { $mystream.Dispose() } if($mystream) { $mystream.Dispose() }
} }
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" $content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" @params
if($content) if($content)
{ {
$txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content))) $txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
@@ -703,7 +720,15 @@ function Get-IsLatestVersion
$gitHubVer = $null $gitHubVer = $null
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" @params
if($content.Name) if($content.Name)
{ {
try try
@@ -715,7 +740,15 @@ function Get-IsLatestVersion
if($null -eq $gitHubVer) if($null -eq $gitHubVer)
{ {
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1" $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1" @params
$gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content))) $gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
$gitHubInfo = Get-ModuleDataTable $gitHubText $gitHubInfo = Get-ModuleDataTable $gitHubText
try try
@@ -1150,6 +1183,10 @@ function Expand-FileName
[Environment]::SetEnvironmentVariable("DateTime",$null,[System.EnvironmentVariableTarget]::Process) [Environment]::SetEnvironmentVariable("DateTime",$null,[System.EnvironmentVariableTarget]::Process)
[Environment]::SetEnvironmentVariable("Organization",$null,[System.EnvironmentVariableTarget]::Process) [Environment]::SetEnvironmentVariable("Organization",$null,[System.EnvironmentVariableTarget]::Process)
# Remove invalid path characters
$re = "[{0}]" -f [RegEx]::Escape(([IO.Path]::GetInvalidPathChars() -join ''))
$fileName = $fileName -replace $re
$fileName $fileName
} }
@@ -1168,6 +1205,8 @@ function Initialize-Settings
$global:Debug = Get-SettingValue "Debug" $global:Debug = Get-SettingValue "Debug"
$global:logFile = $null $global:logFile = $null
$global:logFileMaxSize = $null $global:logFileMaxSize = $null
$global:logOutputError = $null
$script:proxyURI = $null
if($Updated -eq $true) if($Updated -eq $true)
{ {
@@ -1496,7 +1535,7 @@ function Add-RegKeyToSettings
try try
{ {
$keyObj = Get-Item -Path $regKey $keyObj = Get-Item -Path $regKey -ErrorAction SilentlyContinue
foreach($keyValue in ($keyObj.GetValueNames() | Sort)) foreach($keyValue in ($keyObj.GetValueNames() | Sort))
{ {
try try
@@ -1943,6 +1982,14 @@ function Add-DefaultSettings
DefaultValue = 1024 DefaultValue = 1024
}) "General" }) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Add errors to PowerShell output"
Key = "LogOutputError"
Type = "Boolean"
Description = "Write errors to the Error Output of the PS Host. If disabled, errors will be written as a Warning. Eg. disable this if automation should skip logging PowerShell errors."
DefaultValue = $true
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Debug" Title = "Debug"
Key = "Debug" Key = "Debug"
@@ -1998,6 +2045,12 @@ function Add-DefaultSettings
Description = "Adds the organization name next to the login info on the menu bar" Description = "Adds the organization name next to the login info on the menu bar"
}) "General" }) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Proxy URI"
Key = "ProxyURI"
Description = "Specify the URI for the proxy eg http://&lt;server&gt;:&lt;port&gt;"
}) "General"
} }
function Add-SettingsObject function Add-SettingsObject
@@ -2410,6 +2463,7 @@ function Get-MainWindow
Add-XamlEvent $script:welcomeForm "gitHubLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "gitHubLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "licenseLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "licenseLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "chkAcceptConditions" "add_click" { Add-XamlEvent $script:welcomeForm "chkAcceptConditions" "add_click" {
$global:btnAcceptConditions.IsEnabled = ($this.IsChecked -eq $true) $global:btnAcceptConditions.IsEnabled = ($this.IsChecked -eq $true)
@@ -2418,6 +2472,7 @@ function Get-MainWindow
Add-XamlEvent $script:welcomeForm "btnAcceptConditions" "add_click" { Add-XamlEvent $script:welcomeForm "btnAcceptConditions" "add_click" {
Save-Setting "" "LicenseAccepted" "True" Save-Setting "" "LicenseAccepted" "True"
Save-Setting "" "FirstTimeRunning" "False" Save-Setting "" "FirstTimeRunning" "False"
Save-Setting "" "AppChangeInformed" "true"
Show-ModalObject Show-ModalObject
if($global:currentViewObject.ViewInfo.Authentication.ShowErrors) if($global:currentViewObject.ViewInfo.Authentication.ShowErrors)
@@ -2435,6 +2490,44 @@ function Get-MainWindow
Show-ModalForm $window.Title $script:welcomeForm -HideButtons Show-ModalForm $window.Title $script:welcomeForm -HideButtons
} }
else
{
if($global:informOldAzureApp -eq $true)
{
$appIdChangeInformed = Get-Setting "" "AppChangeInformed" "false"
if($appIdChangeInformed -ne "true") {
$script:oldAzureAppForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\OldAzureApp.xaml")
Add-XamlEvent $script:oldAzureAppForm "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true })
Add-XamlEvent $script:oldAzureAppForm "btnOK" "add_click" {
if((Get-XamlProperty $script:oldAzureAppForm "chkChangeApp" "IsChecked") -eq $true) {
Write-Log "Set default app ID to $($global:DefaultAzureApp)"
Save-Setting "EndpointManager" "EMAzureApp" $global:DefaultAzureApp
$script:azureAppChanged = $true
}
if((Get-XamlProperty $script:oldAzureAppForm "chkSkippMessage" "IsChecked") -eq $true) {
Save-Setting "" "AppChangeInformed" "true"
}
Show-ModalObject
if($script:azureAppChanged -eq $true -and $global:currentViewObject) {
[System.Windows.Forms.Application]::DoEvents()
& $global:currentViewObject.ViewInfo.Authenticate
}
}
Show-ModalForm $window.Title $script:oldAzureAppForm -HideButtons
}
}
###!!! Force login here
if($global:currentViewObject.ViewInfo.Authenticate)
{
# Skip for now...need additional code to skip previous login and force this based on setting.
#!!!& $global:currentViewObject.ViewInfo.Authenticate -Params (@{"Interactve"=$true})
}
}
}) })
foreach($view in $global:viewObjects) foreach($view in $global:viewObjects)
@@ -2694,6 +2787,110 @@ function Get-Base64ScriptContent
} }
} }
function Get-ProxyURI
{
if($null -eq $script:proxyURI)
{
$script:proxyUri = Get-SettingValue "ProxyURI"
}
if($null -eq $script:proxyURI)
{
$script:proxyUri = ""
}
return $script:proxyURI
}
function Start-DownloadFile
{
param($sourceURL, $targetFile)
Write-Log "Download file from $sourceURL"
if(-not $sourceURL)
{
return
}
if(-not $targetFile)
{
Write-Log "Target file is missing"
return
}
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$wc = New-Object System.Net.WebClient
$wc.Encoding = [System.Text.Encoding]::UTF8
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$wc.Proxy = [System.Net.WebProxy]::new($proxyURI)
}
try
{
$title = $sourceURL.Split("/")[-1]
$title = $title.Split("/")[0]
}
catch
{
$title = $sourceURL
}
try
{
Write-Status "Download file: `n$title"
$wc.DownloadFile($sourceURL, $targetFile)
Write-Log "File downloaded to $targetFile"
}
catch
{
Write-LogError "Failed to download file" $_.Exception
}
finally
{
$wc.Dispose()
}
}
function Get-ASCIIBytes
{
param($String)
$bytes = [System.Text.Encoding]::ASCII.GetBytes($String)
if ($bytes[0] -eq 0x2b -and $bytes[1] -eq 0x2f -and $bytes[2] -eq 0x76)
{ [Text.Encoding]::UTF7.GetBytes($String) }
elseif ($bytes[0] -eq 0xff -and $bytes[1] -eq 0xfe)
{ [Text.Encoding]::Unicode.GetBytes($String) }
elseif ($bytes[0] -eq 0xfe -and $bytes[1] -eq 0xff)
{ [Text.Encoding]::BigEndianUnicode.GetBytes($String) }
elseif ($bytes[0] -eq 0x00 -and $bytes[1] -eq 0x00 -and $bytes[2] -eq 0xfe -and $bytes[3] -eq 0xff)
{ [Text.Encoding]::UTF32.GetBytes($String) }
elseif ($bytes[0] -eq 0xef -and $bytes[1] -eq 0xbb -and $bytes[2] -eq 0xbf)
{ [Text.Encoding]::UTF8.GetBytes($String) }
$bytes
}
function Get-DataGridValues
{
param($dataGrid)
$dgColumns = $dataGrid.Columns
$properties = @()
foreach($tmpCol in $dgColumns)
{
if(-not $tmpCol.Binding.Path.Path) { continue }
$propName = $tmpCol.Binding.Path.Path
$properties += @{n=$tmpCol.Header;e=([Scriptblock]::Create("`$_.$propName"))}
}
($dataGrid.ItemsSource | Select -Property $properties)
}
New-Alias -Name ?? -value Invoke-Coalesce New-Alias -Name ?? -value Invoke-Coalesce
New-Alias -Name ?: -value Invoke-IfTrue New-Alias -Name ?: -value Invoke-IfTrue
Export-ModuleMember -alias * -function * Export-ModuleMember -alias * -function *
Binary file not shown.
+34 -6
View File
@@ -996,10 +996,24 @@
"category": "Win32Requirements.selectorLabel" "category": "Win32Requirements.selectorLabel"
}, },
{ {
"Columns": [
{
"metadata": {
"entityKey": "property",
"nameResourceKey": "ApplicabilityRules.GridLabel.property"
}
},
{
"metadata": {
"entityKey": "value",
"nameResourceKey": "ApplicabilityRules.GridLabel.value"
}
}
],
"nameResourceKey": "Win32Requirements.AdditionalRequirements.label", "nameResourceKey": "Win32Requirements.AdditionalRequirements.label",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "requirementRulesSummary", "entityKey": "requirementRulesTranslated",
"dataType": 20, "dataType": 21,
"booleanActions": 0, "booleanActions": 0,
"category": "Win32Requirements.selectorLabel" "category": "Win32Requirements.selectorLabel"
}, },
@@ -1012,10 +1026,24 @@
"category": "DetectionRules.selectorLabel" "category": "DetectionRules.selectorLabel"
}, },
{ {
"Columns": [
{
"metadata": {
"entityKey": "property",
"nameResourceKey": "ApplicabilityRules.GridLabel.property"
}
},
{
"metadata": {
"entityKey": "value",
"nameResourceKey": "ApplicabilityRules.GridLabel.value"
}
}
],
"nameResourceKey": "DetectionRules.selectorLabel", "nameResourceKey": "DetectionRules.selectorLabel",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "detectionRulesSummary", "entityKey": "detectionRulesTranslated",
"dataType": 20, "dataType": 21,
"booleanActions": 0, "booleanActions": 0,
"category": "DetectionRules.selectorLabel", "category": "DetectionRules.selectorLabel",
"Condition": { "Condition": {
@@ -1071,12 +1099,12 @@
"category": "SettingDetails.dependencyCategory" "category": "SettingDetails.dependencyCategory"
}, },
{ {
"nameResourceKey": "supersedenceCategory", "nameResourceKey": "AppRelationshipStatus.Tabs.supersedence",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "supersededApps", "entityKey": "supersededApps",
"dataType": 20, "dataType": 20,
"booleanActions": 0, "booleanActions": 0,
"category": "SettingDetails.supersedenceCategory" "category": "AppRelationshipStatus.Tabs.supersedence"
} }
] ]
} }
@@ -393,7 +393,7 @@
"value": "notConfigured" "value": "notConfigured"
}, },
{ {
"nameResourceKey": "microsoftEdge", "nameResourceKey": "microsoftEdgeOptionText",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"value": "microsoftEdge" "value": "microsoftEdge"
}, },
@@ -543,7 +543,7 @@
{ {
"nameResourceKey": "TAPSettings.Tap.numberOfDays", "nameResourceKey": "TAPSettings.Tap.numberOfDays",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "pinRequiredInsteadOfBiometricTimeout", "entityKey": "periodBeforePinReset",
"dataType": 100, "dataType": 100,
"booleanActions": 0, "booleanActions": 0,
"category": "SettingDetails.accessRequirements" "category": "SettingDetails.accessRequirements"
@@ -306,7 +306,7 @@
{ {
"nameResourceKey": "TAPSettings.EncryptData.label", "nameResourceKey": "TAPSettings.EncryptData.label",
"descriptionResourceKey": "TAPSettings.EncryptData.tooltip", "descriptionResourceKey": "TAPSettings.EncryptData.tooltip",
"entityKey": "appDataEncryptionType", "entityKey": "encryptOrgData",
"dataType": 0, "dataType": 0,
"booleanActions": 101, "booleanActions": 101,
"category": "SettingDetails.dataProtection", "category": "SettingDetails.dataProtection",
@@ -354,7 +354,7 @@
"value": "notConfigured" "value": "notConfigured"
}, },
{ {
"nameResourceKey": "microsoftEdge", "nameResourceKey": "microsoftEdgeOptionText",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"value": "microsoftEdge" "value": "microsoftEdge"
}, },
@@ -398,14 +398,12 @@
} }
] ]
}, },
{ {
"dataType": 8, "dataType": 8,
"nameResourceKey": "empty" "nameResourceKey": "empty"
}, },
{ {
"nameResourceKey": "TAPSettings.PinAccess.label", "nameResourceKey": "TAPSettings.PinAccess.label",
"descriptionResourceKey": "TAPSettings.PinAccess.tooltip", "descriptionResourceKey": "TAPSettings.PinAccess.tooltip",
@@ -496,17 +494,17 @@
{ {
"nameResourceKey": "TAPSettings.Tap.numberOfDays", "nameResourceKey": "TAPSettings.Tap.numberOfDays",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "pinRequiredInsteadOfBiometricTimeout", "entityKey": "periodBeforePinReset",
"dataType": 100, "dataType": 100,
"booleanActions": 0, "booleanActions": 0,
"category": "SettingDetails.accessRequirements" "category": "SettingDetails.accessRequirements"
}, },
{ {
"nameResourceKey": "TAPSettings.Tap.previousPinBlockCount", "nameResourceKey": "TAPSettings.AppPIN.label",
"descriptionResourceKey": "", "descriptionResourceKey": "TAPSettings.AppPIN.tooltip",
"entityKey": "previousPinBlockCount", "entityKey": "disableAppPinIfDevicePinIsSet",
"dataType": 14, "dataType": 0,
"booleanActions": 0, "booleanActions": 201,
"category": "SettingDetails.accessRequirements" "category": "SettingDetails.accessRequirements"
}, },
{ {
@@ -0,0 +1,69 @@
[
{
"nameResourceKey": "TableHeaders.policyType",
"descriptionResourceKey": "",
"entityKey": "WindowsDriverUpdateProfile.Subtitle.automatic",
"dataType": 200,
"booleanActions": 0,
"category": 1000,
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "automatic"
}
]
}
},
{
"nameResourceKey": "TableHeaders.policyType",
"descriptionResourceKey": "",
"entityKey": "WindowsDriverUpdateProfile.Subtitle.manual",
"dataType": 200,
"booleanActions": 0,
"category": 1000,
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "manual"
}
]
}
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.Details.ApprovalMethod.label",
"descriptionResourceKey": "",
"entityKey": "approvalType",
"dataType": 16,
"booleanActions": 0,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "WindowsDriverUpdateProfile.ApprovalMethod.automatic",
"value": "automatic"
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.ApprovalMethod.manual",
"value": "manual"
}
]
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.Details.DeploymentDeferralInDays.label",
"descriptionResourceKey": "",
"entityKey": "deploymentDeferralInDays",
"formatStringKey": "WindowsDriverUpdateProfile.Details.DeploymentDeferralInDays.value",
"dataType": 108,
"booleanActions": 0,
"category": "TableHeaders.settings",
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "automatic"
}
]
}
}
]
@@ -113,6 +113,164 @@
"defaultValue": false, "defaultValue": false,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appNameName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "packageName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appId",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appUrlName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appStoreUrl",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appPublisherName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "publisher",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
}
],
"dataType": 21,
"category": 2,
"nameResourceKey": "certificateInstallTitle",
"descriptionResourceKey": "certificateInstallDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certInstallApps",
"booleanActions": 0,
"policyType": 2,
"enabled": false
},
{
"complexOptions": [
{
"dataType": 11,
"category": 2,
"nameResourceKey": "selectSecurityApp",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "securityLogAppId",
"booleanActions": 0,
"policyType": 2,
"enabled": true
}
],
"dataType": 5,
"category": 2,
"nameResourceKey": "securityLogsTitle",
"emptyValueResourceKey": "selectSecurityApp",
"childSettings": [
],
"options": [
],
"entityKey": "securityLogApp",
"booleanActions": 0,
"policyType": 2,
"enabled": false
},
{
"complexOptions": [
{
"dataType": 11,
"category": 2,
"nameResourceKey": "selectNetworkApp",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "networkLogAppId",
"booleanActions": 0,
"policyType": 2,
"enabled": true
}
],
"dataType": 5,
"category": 2,
"nameResourceKey": "networkLogsTitle",
"emptyValueResourceKey": "selectNetworkApp",
"childSettings": [
],
"options": [
],
"entityKey": "networkLogApp",
"booleanActions": 0,
"policyType": 2,
"enabled": false
} }
], ],
"options": [ "options": [
@@ -44,7 +44,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 108, "policyType": 108,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -154,8 +154,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -166,17 +166,17 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified", "value": "basicIntegrityAndCertified",
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -52,8 +52,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -64,17 +64,75 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"children": [
{
"dataType": 16,
"category": 39,
"nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "basicIntegrityAndCertified", "value": "hardwareBacked",
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "securityRequiredAndroidSafetyNetEvaluationType",
"booleanActions": 0,
"defaultValue": "basic",
"unconfiguredValue": "basic",
"policyType": 31,
"enabled": false
}
],
"enabled": true
},
{
"nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified",
"children": [
{
"dataType": 16,
"category": 39,
"nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic",
"enabled": true
},
{
"nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "hardwareBacked",
"enabled": true
}
],
"entityKey": "securityRequiredAndroidSafetyNetEvaluationType",
"booleanActions": 0,
"defaultValue": "basic",
"unconfiguredValue": "basic",
"policyType": 31,
"enabled": false
}
],
"enabled": true
}
],
"entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -103,8 +103,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -115,25 +115,25 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"children": [ "children": [
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeName", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidSafetyNetEvaluationTypeDescription", "descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeBasic", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic", "value": "basic",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeHardwareBacked", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "hardwareBacked", "value": "hardwareBacked",
"enabled": true "enabled": true
} }
@@ -149,25 +149,25 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified", "value": "basicIntegrityAndCertified",
"children": [ "children": [
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeName", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidSafetyNetEvaluationTypeDescription", "descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeBasic", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic", "value": "basic",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeHardwareBacked", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "hardwareBacked", "value": "hardwareBacked",
"enabled": true "enabled": true
} }
@@ -183,7 +183,7 @@
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -1,16 +1,32 @@
{ {
"devicehealth_compliancewindows10": { "devicehealth_compliancewindows10": [
{
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 39, "category": 39,
"nameResourceKey": "complianceWindowsDeviceHealthAttestationHeader", "nameResourceKey": "complianceWindowsDeviceHealthAttestationHeader",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 39,
"nameResourceKey": "complianceWindows10DeviceHealthAttestationHeader",
"childSettings": [ "childSettings": [
{ {
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "bitLockerEnabledName", "nameResourceKey": "bitLockerEnabledName",
"descriptionResourceKey": "bitLockerEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -27,7 +43,6 @@
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "secureBootEnabledName", "nameResourceKey": "secureBootEnabledName",
"descriptionResourceKey": "secureBootEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -44,7 +59,6 @@
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "codeIntegrityEnabledName", "nameResourceKey": "codeIntegrityEnabledName",
"descriptionResourceKey": "codeIntegrityEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -64,5 +78,101 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 35, "policyType": 35,
"enabled": true "enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 39,
"nameResourceKey": "complianceWindows11DeviceHealthAttestationHeader",
"childSettings": [
{
"dataType": 0,
"category": 39,
"nameResourceKey": "earlyLaunchAntiMalwareDriverEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "earlyLaunchAntiMalwareDriverEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "firmwareProtectionEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "firmwareProtectionEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "hvciEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "memoryIntegrityEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "memoryAccessProtectionEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "kernelDmaProtectionEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "virtualizationBasedSecurityEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "virtualizationBasedSecurityEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
} }
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": false
}
]
} }
@@ -53,6 +53,23 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 31, "policyType": 31,
"enabled": true "enabled": true
},
{
"dataType": 0,
"category": 43,
"nameResourceKey": "complianceNoPendingSystemUpdatesName",
"descriptionResourceKey": "complianceNoPendingSystemUpdatesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "requireNoPendingSystemUpdates",
"booleanActions": 1,
"defaultValue": false,
"policyType": 31,
"enabled": false
} }
], ],
"options": [ "options": [
@@ -917,6 +917,39 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
},
{
"dataType": 0,
"category": 44,
"nameResourceKey": "disableDeviceLocationName",
"descriptionResourceKey": "disableDeviceLocationDescription",
"childSettings": [
],
"options": [
],
"entityKey": "disableDeviceLocation",
"booleanActions": 3,
"defaultValue": false,
"policyType": 2,
"enabled": false
},
{
"dataType": 0,
"category": 44,
"nameResourceKey": "disableDeviceLocationSharingName",
"childSettings": [
],
"options": [
],
"entityKey": "shareDeviceLocationDisabled",
"booleanActions": 3,
"defaultValue": false,
"policyType": 2,
"enabled": false
} }
], ],
"options": [ "options": [
@@ -1078,6 +1111,40 @@
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 44,
"nameResourceKey": "fullyManagedAndCorporateOwnedWorkProfileAndroidEnrollmentTypesHeaderName",
"descriptionResourceKey": "fullyManagedAndCorporateOwnedWorkProfileAndroidEnrollmentTypesHeaderDescription",
"childSettings": [
{
"dataType": 0,
"category": 44,
"nameResourceKey": "androidDeviceOwnerLocateDeviceName",
"descriptionResourceKey": "androidDeviceOwnerLocateDeviceLostModeEnabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "locateDeviceLostModeEnabled",
"booleanActions": 0,
"defaultValue": false,
"unconfiguredValue": false,
"policyType": 2,
"enabled": false
}
],
"options": [
],
"booleanActions": 0,
"policyType": 2,
"enabled": true
},
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": true, "showAsSectionHeader": true,
@@ -1200,6 +1267,24 @@
"defaultValue": false, "defaultValue": false,
"policyType": 2, "policyType": 2,
"enabled": false "enabled": false
},
{
"dataType": 0,
"category": 44,
"nameResourceKey": "androidDeviceOwnerLocateDeviceName",
"descriptionResourceKey": "androidDeviceOwnerLocateDeviceUserlessDisabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "locateDeviceUserlessDisabled",
"booleanActions": 3,
"defaultValue": false,
"unconfiguredValue": false,
"policyType": 2,
"enabled": false
} }
], ],
"options": [ "options": [
@@ -277,6 +277,35 @@
"unconfiguredValue": "noneOption", "unconfiguredValue": "noneOption",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
},
{
"dataType": 16,
"category": 44,
"nameResourceKey": "MacAddressRandomizationModeTitleAndroid",
"descriptionResourceKey": "MacAddressRandomizationModeDescriptionAndroid",
"childSettings": [
],
"options": [
{
"nameResourceKey": "MacAddressRandomizationModeDefaultAndroid",
"enabled": true
},
{
"nameResourceKey": "MacAddressRandomizationModeAutomaticAndroid",
"value": "automatic",
"enabled": true
},
{
"nameResourceKey": "MacAddressRandomizationModeHardwareAndroid",
"value": "hardware",
"enabled": true
}
],
"entityKey": "macAddressRandomizationMode",
"booleanActions": 0,
"policyType": 9,
"enabled": false
} }
], ],
"enabled": true "enabled": true
@@ -1395,6 +1424,35 @@
"unconfiguredValue": "noneOption", "unconfiguredValue": "noneOption",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
},
{
"dataType": 16,
"category": 44,
"nameResourceKey": "MacAddressRandomizationModeTitleAndroid",
"descriptionResourceKey": "MacAddressRandomizationModeDescriptionAndroid",
"childSettings": [
],
"options": [
{
"nameResourceKey": "MacAddressRandomizationModeDefaultAndroid",
"enabled": true
},
{
"nameResourceKey": "MacAddressRandomizationModeAutomaticAndroid",
"value": "automatic",
"enabled": true
},
{
"nameResourceKey": "MacAddressRandomizationModeHardwareAndroid",
"value": "hardware",
"enabled": true
}
],
"entityKey": "macAddressRandomizationMode",
"booleanActions": 0,
"policyType": 9,
"enabled": false
} }
], ],
"enabled": true "enabled": true
@@ -617,6 +617,23 @@
"defaultValue": false, "defaultValue": false,
"policyType": 61, "policyType": 61,
"enabled": true "enabled": true
},
{
"dataType": 0,
"category": 44,
"nameResourceKey": "allowActivationLockWhenSupervisedName",
"descriptionResourceKey": "allowActivationLockWhenSupervisedDescription",
"childSettings": [
],
"options": [
],
"entityKey": "activationLockWhenSupervisedAllowed",
"booleanActions": 9,
"defaultValue": false,
"policyType": 61,
"enabled": true
} }
], ],
"options": [ "options": [
@@ -5,7 +5,7 @@
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 72, "category": 72,
"nameResourceKey": "androidGeneralKiosk", "nameResourceKey": "androidRestrictedKiosk",
"childSettings": [ "childSettings": [
], ],
@@ -33,20 +33,33 @@
"enabled": true "enabled": true
}, },
{ {
"dataType": 14, "isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 90, "category": 90,
"nameResourceKey": "minimumPasswordLengthName", "nameResourceKey": "allAndroidVersionsPasswordHeader",
"descriptionResourceKey": "minimumPasswordLengthDescription", "childSettings": [
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen", {
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 90,
"nameResourceKey": "allAndroidVersionsPasswordHeaderDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "passwordMinimumLength",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 4, "policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
}, },
@@ -153,64 +166,6 @@
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
}, },
{
"dataType": 16,
"category": 90,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "requiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
],
"options": [
{
"nameResourceKey": "deviceDefault",
"value": "deviceDefault",
"enabled": true
},
{
"nameResourceKey": "lowSecurityBiometricOption",
"value": "lowSecurityBiometric",
"enabled": true
},
{
"nameResourceKey": "required",
"value": "required",
"enabled": true
},
{
"nameResourceKey": "atLeastNumericOption",
"value": "atLeastNumeric",
"enabled": true
},
{
"nameResourceKey": "numericComplex",
"value": "numericComplex",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphabeticOption",
"value": "atLeastAlphabetic",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphanumericOption",
"value": "atLeastAlphanumeric",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphanumericWithSymbolsOption",
"value": "alphanumericWithSymbols",
"enabled": true
}
],
"entityKey": "passwordRequiredType",
"booleanActions": 0,
"defaultValue": "atLeastNumeric",
"unconfiguredValue": "atLeastNumeric",
"policyType": 13,
"enabled": true
},
{ {
"dataType": 14, "dataType": 14,
"category": 90, "category": 90,
@@ -296,6 +251,181 @@
"defaultValue": false, "defaultValue": false,
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidTwelveAndAbovePasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidTwelveAndAbovePasswordHeaderDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
},
{
"dataType": 16,
"category": 90,
"nameResourceKey": "requiredPasswordComplexityName",
"descriptionResourceKey": "requiredPasswordComplexityDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "none",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "low",
"value": "low",
"enabled": true
},
{
"nameResourceKey": "medium",
"value": "medium",
"enabled": true
},
{
"nameResourceKey": "high",
"value": "high",
"enabled": true
}
],
"entityKey": "requiredPasswordComplexity",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "none",
"policyType": 13,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidElevenAndBelowPasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidElevenAndBelowPasswordHeaderDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
},
{
"dataType": 16,
"category": 90,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "requiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
],
"options": [
{
"nameResourceKey": "deviceDefault",
"value": "deviceDefault",
"enabled": true
},
{
"nameResourceKey": "lowSecurityBiometricOption",
"value": "lowSecurityBiometric",
"enabled": true
},
{
"nameResourceKey": "required",
"value": "required",
"enabled": true
},
{
"nameResourceKey": "atLeastNumericOption",
"value": "atLeastNumeric",
"enabled": true
},
{
"nameResourceKey": "numericComplex",
"value": "numericComplex",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphabeticOption",
"value": "atLeastAlphabetic",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphanumericOption",
"value": "atLeastAlphanumeric",
"enabled": true
},
{
"nameResourceKey": "atLeastAlphanumericWithSymbolsOption",
"value": "alphanumericWithSymbols",
"enabled": true
}
],
"entityKey": "passwordRequiredType",
"booleanActions": 0,
"defaultValue": "atLeastNumeric",
"unconfiguredValue": "atLeastNumeric",
"policyType": 13,
"enabled": true
},
{
"dataType": 14,
"category": 90,
"nameResourceKey": "minimumPasswordLengthName",
"descriptionResourceKey": "minimumPasswordLengthDescription",
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
"childSettings": [
],
"options": [
],
"entityKey": "passwordMinimumLength",
"booleanActions": 0,
"defaultValue": 4,
"policyType": 13,
"enabled": true
} }
] ]
} }
@@ -448,6 +448,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -515,6 +521,22 @@
"policyType": 6, "policyType": 6,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 6,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -418,6 +418,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -485,6 +491,22 @@
"policyType": 17, "policyType": 17,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 17,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -195,6 +195,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -262,6 +268,22 @@
"policyType": 23, "policyType": 23,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 23,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -418,6 +418,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -485,6 +491,22 @@
"policyType": 122, "policyType": 122,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -587,6 +587,22 @@
"policyType": 50, "policyType": 50,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 50,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -587,6 +587,22 @@
"policyType": 63, "policyType": 63,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 63,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -457,6 +457,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -524,6 +530,22 @@
"policyType": 84, "policyType": 84,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 84,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -457,6 +457,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -524,6 +530,22 @@
"policyType": 93, "policyType": 93,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 93,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -234,6 +234,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": true
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -301,6 +307,22 @@
"policyType": 103, "policyType": 103,
"enabled": true "enabled": true
}, },
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 103,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 103,
"enabled": true
},
{ {
"columns": [ "columns": [
{ {
@@ -14,7 +14,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"isSettingDescription": false, "isSettingDescription": false,
@@ -30,7 +30,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"isSettingDescription": false, "isSettingDescription": false,
@@ -46,7 +46,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"isSettingDescription": false, "isSettingDescription": false,
@@ -62,7 +62,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -87,7 +87,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -112,7 +112,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -137,7 +137,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -162,7 +162,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"isSettingDescription": false, "isSettingDescription": false,
@@ -178,7 +178,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"isSettingDescription": false, "isSettingDescription": false,
@@ -194,7 +194,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -226,7 +226,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -432,7 +432,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 0, "defaultValue": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"columns": [ "columns": [
@@ -484,7 +484,7 @@
"entityKey": "startDay", "entityKey": "startDay",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -620,7 +620,7 @@
"entityKey": "startTime", "entityKey": "startTime",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -671,7 +671,7 @@
"entityKey": "endDay", "entityKey": "endDay",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -808,7 +808,7 @@
"entityKey": "endTime", "entityKey": "endTime",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
} }
], ],
@@ -825,7 +825,7 @@
"entityKey": "customUpdateTimeWindows", "entityKey": "customUpdateTimeWindows",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
], ],
"enabled": true "enabled": true
@@ -846,7 +846,7 @@
], ],
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"dataType": 16, "dataType": 16,
@@ -1052,7 +1052,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 0, "defaultValue": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
}, },
{ {
"columns": [ "columns": [
@@ -1104,7 +1104,7 @@
"entityKey": "startDay", "entityKey": "startDay",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -1240,7 +1240,7 @@
"entityKey": "startTime", "entityKey": "startTime",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -1291,7 +1291,7 @@
"entityKey": "endDay", "entityKey": "endDay",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -1428,7 +1428,7 @@
"entityKey": "endTime", "entityKey": "endTime",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
} }
], ],
@@ -1445,7 +1445,7 @@
"entityKey": "customUpdateTimeWindows", "entityKey": "customUpdateTimeWindows",
"booleanActions": 0, "booleanActions": 0,
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
], ],
"enabled": true "enabled": true
@@ -1456,7 +1456,7 @@
"defaultValue": "alwaysUpdate", "defaultValue": "alwaysUpdate",
"unconfiguredValue": "alwaysUpdate", "unconfiguredValue": "alwaysUpdate",
"policyType": 69, "policyType": 69,
"enabled": false "enabled": true
} }
] ]
} }
File diff suppressed because it is too large Load Diff
@@ -1587,6 +1587,46 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 8, "policyType": 8,
"enabled": true "enabled": true
},
{
"complexOptions": [
{
"dataType": 25,
"category": 129,
"nameResourceKey": "vPNPolicyProxyExclListManage",
"emptyValueResourceKey": "vPNPolicyProxyExclListManage",
"childSettings": [
],
"options": [
],
"entityKey": "proxyExclusionList",
"booleanActions": 0,
"unconfiguredValue": [
],
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vPNPolicyProxyExclListName",
"descriptionResourceKey": "vPNPolicyProxyExclListDescription2",
"emptyValueResourceKey": "vPNPolicyProxyExclListManage",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"unconfiguredValue": [
],
"policyType": 8,
"enabled": false
} }
], ],
"dataType": 5, "dataType": 5,
@@ -1707,303 +1747,6 @@
} }
], ],
"enabled": true "enabled": true
},
{
"nameResourceKey": "microsoftTunnelOption",
"value": "microsoftTunnel",
"children": [
{
"complexOptions": [
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyConnectionName",
"descriptionResourceKey": "vPNPolicyConnectionDescription",
"emptyValueResourceKey": "vPNConnectionExample",
"childSettings": [
],
"options": [
],
"entityKey": "connectionName",
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 26,
"category": 129,
"nameResourceKey": "changeMicrosoftTunnelSite",
"descriptionResourceKey": "microsoftTunnelSite",
"emptyValueResourceKey": "selectMicrosoftTunnelSite",
"childSettings": [
],
"options": [
],
"entityKey": "microsoftTunnelSiteId",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "microsoftTunnelSite",
"descriptionResourceKey": "microsoftTunnelSiteDescription",
"emptyValueResourceKey": "selectMicrosoftTunnelSite",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpn",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 129,
"nameResourceKey": "vPNAppsName",
"descriptionResourceKey": "vPNAppsDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 129,
"nameResourceKey": "appId",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appId",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 129,
"nameResourceKey": "appNameName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
}
],
"dataType": 21,
"category": 129,
"nameResourceKey": "Empty",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "targetedMobileApps",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnPerApp",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 0,
"category": 129,
"nameResourceKey": "androidPersonalWorkProfileAlwaysOnVpnEnabledName",
"descriptionResourceKey": "androidEnterpriseWorkProfileAlwaysOnVpnEnabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "alwaysOn",
"booleanActions": 2,
"defaultValue": false,
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnAlwaysOn",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 129,
"nameResourceKey": "vPNPolicyUseProxyServerName",
"descriptionResourceKey": "vPNPolicyUseProxyServerDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyAutomaticConfigurationScriptName",
"descriptionResourceKey": "vPNPolicyAutomaticConfigurationScriptDescription",
"emptyValueResourceKey": "vPNScriptExample",
"childSettings": [
],
"options": [
],
"entityKey": "automaticConfigurationScriptUrl",
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyAddressName",
"descriptionResourceKey": "vPNPolicyAddressDescription",
"emptyValueResourceKey": "vPNAddressExample",
"childSettings": [
],
"options": [
],
"entityKey": "address",
"booleanActions": 0,
"policyType": 8,
"enabled": true
},
{
"dataType": 14,
"category": 129,
"nameResourceKey": "vPNPolicyPortNumberName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "proxyPortExample",
"childSettings": [
],
"options": [
],
"entityKey": "port",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"dataType": 6,
"category": 129,
"nameResourceKey": "vPNPolicyUseProxyServerName",
"descriptionResourceKey": "vPNPolicyUseProxyServerDescription",
"childSettings": [
],
"options": [
],
"entityKey": "proxyServer",
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnProxy",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 8,
"enabled": true
}
],
"enabled": false
} }
], ],
"entityKey": "connectionType", "entityKey": "connectionType",
@@ -1563,6 +1563,46 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 12, "policyType": 12,
"enabled": true "enabled": true
},
{
"complexOptions": [
{
"dataType": 25,
"category": 129,
"nameResourceKey": "vPNPolicyProxyExclListManage",
"emptyValueResourceKey": "vPNPolicyProxyExclListManage",
"childSettings": [
],
"options": [
],
"entityKey": "proxyExclusionList",
"booleanActions": 0,
"unconfiguredValue": [
],
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vPNPolicyProxyExclListName",
"descriptionResourceKey": "vPNPolicyProxyExclListDescription2",
"emptyValueResourceKey": "vPNPolicyProxyExclListManage",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"unconfiguredValue": [
],
"policyType": 12,
"enabled": false
} }
], ],
"dataType": 5, "dataType": 5,
@@ -1683,303 +1723,6 @@
} }
], ],
"enabled": true "enabled": true
},
{
"nameResourceKey": "microsoftTunnelOption",
"value": "microsoftTunnel",
"children": [
{
"complexOptions": [
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyConnectionName",
"descriptionResourceKey": "vPNPolicyConnectionDescription",
"emptyValueResourceKey": "vPNConnectionExample",
"childSettings": [
],
"options": [
],
"entityKey": "connectionName",
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 26,
"category": 129,
"nameResourceKey": "changeMicrosoftTunnelSite",
"descriptionResourceKey": "microsoftTunnelSite",
"emptyValueResourceKey": "selectMicrosoftTunnelSite",
"childSettings": [
],
"options": [
],
"entityKey": "microsoftTunnelSiteId",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "microsoftTunnelSite",
"descriptionResourceKey": "microsoftTunnelSiteDescription",
"emptyValueResourceKey": "selectMicrosoftTunnelSite",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpn",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 129,
"nameResourceKey": "vPNAppsName",
"descriptionResourceKey": "vPNAppsDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 129,
"nameResourceKey": "appId",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appId",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 129,
"nameResourceKey": "appNameName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
}
],
"dataType": 21,
"category": 129,
"nameResourceKey": "Empty",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "targetedMobileApps",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnPerApp",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 0,
"category": 129,
"nameResourceKey": "androidPersonalWorkProfileAlwaysOnVpnEnabledName",
"descriptionResourceKey": "androidEnterpriseWorkProfileAlwaysOnVpnEnabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "alwaysOn",
"booleanActions": 2,
"defaultValue": false,
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnAlwaysOn",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 129,
"nameResourceKey": "vPNPolicyUseProxyServerName",
"descriptionResourceKey": "vPNPolicyUseProxyServerDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyAutomaticConfigurationScriptName",
"descriptionResourceKey": "vPNPolicyAutomaticConfigurationScriptDescription",
"emptyValueResourceKey": "vPNScriptExample",
"childSettings": [
],
"options": [
],
"entityKey": "automaticConfigurationScriptUrl",
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"dataType": 20,
"category": 129,
"nameResourceKey": "vPNPolicyAddressName",
"descriptionResourceKey": "vPNPolicyAddressDescription",
"emptyValueResourceKey": "vPNAddressExample",
"childSettings": [
],
"options": [
],
"entityKey": "address",
"booleanActions": 0,
"policyType": 12,
"enabled": true
},
{
"dataType": 14,
"category": 129,
"nameResourceKey": "vPNPolicyPortNumberName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "proxyPortExample",
"childSettings": [
],
"options": [
],
"entityKey": "port",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"dataType": 6,
"category": 129,
"nameResourceKey": "vPNPolicyUseProxyServerName",
"descriptionResourceKey": "vPNPolicyUseProxyServerDescription",
"childSettings": [
],
"options": [
],
"entityKey": "proxyServer",
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"dataType": 5,
"category": 129,
"nameResourceKey": "vpnProxy",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 12,
"enabled": true
}
],
"enabled": false
} }
], ],
"entityKey": "connectionType", "entityKey": "connectionType",
@@ -559,6 +559,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -2276,6 +2304,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -3993,6 +4049,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -5710,6 +5794,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -7915,6 +8027,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -9632,6 +9772,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -11349,6 +11517,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -13051,6 +13247,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -15141,6 +15365,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -16843,6 +17095,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -18545,6 +18825,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -20289,6 +20597,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -22006,6 +22342,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -23723,6 +24087,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -25440,6 +25832,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -27645,6 +28065,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -29362,6 +29810,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -31079,6 +31555,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -32781,6 +33285,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -34871,6 +35403,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -36573,6 +37133,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -38275,6 +38863,34 @@
"enabled": true "enabled": true
} }
}, },
{
"metadata": {
"dataType": 16,
"category": 129,
"nameResourceKey": "trafficRuleDirectionName",
"descriptionResourceKey": "trafficRuleDirectionDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "outboundOption",
"value": "outbound",
"enabled": true
},
{
"nameResourceKey": "inboundOption",
"value": "inbound",
"enabled": true
}
],
"entityKey": "vpnTrafficDirection",
"booleanActions": 0,
"defaultValue": "outbound",
"policyType": 89,
"enabled": true
}
},
{ {
"metadata": { "metadata": {
"dataType": 14, "dataType": 14,
@@ -50,7 +50,7 @@
"dataType": 20, "dataType": 20,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypePermittedUrlsColumnName", "nameResourceKey": "webContentFilterTypePermittedUrlsColumnName",
"emptyValueResourceKey": "WebContentFilterWhiteListedUrlExample", "emptyValueResourceKey": "WebContentFilterPermittedUrlExample",
"childSettings": [ "childSettings": [
], ],
@@ -86,7 +86,7 @@
"dataType": 20, "dataType": 20,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeBlockedUrlsColumnName", "nameResourceKey": "webContentFilterTypeBlockedUrlsColumnName",
"emptyValueResourceKey": "WebContentFilterBlackListedUrlExample", "emptyValueResourceKey": "WebContentFilterBlockedUrlExample",
"childSettings": [ "childSettings": [
], ],
@@ -119,7 +119,7 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsOption", "nameResourceKey": "webContentFilterTypePermittedUrlsOption",
"value": "#microsoft.graph.iosWebContentFilterSpecificWebsitesAccess", "value": "#microsoft.graph.iosWebContentFilterSpecificWebsitesAccess",
"children": [ "children": [
{ {
@@ -127,7 +127,7 @@
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsHeaderName", "nameResourceKey": "webContentFilterTypePermittedUrlsHeaderName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "empty",
"childSettings": [ "childSettings": [
@@ -144,7 +144,7 @@
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsLinkTextName", "nameResourceKey": "webContentFilterTypePermittedUrlsLinkTextName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "empty",
"childSettings": [ "childSettings": [
@@ -162,7 +162,7 @@
"metadata": { "metadata": {
"dataType": 20, "dataType": 20,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsColumnUrlName", "nameResourceKey": "webContentFilterTypePermittedUrlsColumnUrlName",
"emptyValueResourceKey": "kioskModeAppStoreExample", "emptyValueResourceKey": "kioskModeAppStoreExample",
"childSettings": [ "childSettings": [
@@ -180,7 +180,7 @@
"metadata": { "metadata": {
"dataType": 20, "dataType": 20,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsColumnBookmarkPathName", "nameResourceKey": "webContentFilterTypePermittedUrlsColumnBookmarkPathName",
"emptyValueResourceKey": "WebContentFilterBookmarkPathExample", "emptyValueResourceKey": "WebContentFilterBookmarkPathExample",
"childSettings": [ "childSettings": [
@@ -198,7 +198,7 @@
"metadata": { "metadata": {
"dataType": 20, "dataType": 20,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsColumnTitleName", "nameResourceKey": "webContentFilterTypePermittedUrlsColumnTitleName",
"emptyValueResourceKey": "WebContentFilterBookmarkTitleExample", "emptyValueResourceKey": "WebContentFilterBookmarkTitleExample",
"childSettings": [ "childSettings": [
@@ -215,8 +215,8 @@
], ],
"dataType": 21, "dataType": 21,
"category": 140, "category": 140,
"nameResourceKey": "webContentFilterTypeWhitelistedUrlsTableName", "nameResourceKey": "webContentFilterTypeSpecificUrlsTableName",
"descriptionResourceKey": "webContentFilterTypeWhitelistedUrlsTableDescription", "descriptionResourceKey": "webContentFilterTypeSpecificUrlsTableDescription",
"childSettings": [ "childSettings": [
], ],
@@ -173,6 +173,110 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 124, "policyType": 124,
"enabled": true "enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicyProxySettingsName",
"descriptionResourceKey": "wiFiPolicyProxySettingsDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "noneOption",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "manualOption",
"value": "manual",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerAddressName",
"descriptionResourceKey": "proxyServerAddressDescription",
"emptyValueResourceKey": "proxyAddressExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyManualAddress",
"booleanActions": 0,
"policyType": 124,
"enabled": true
},
{
"dataType": 14,
"category": 121,
"nameResourceKey": "portNumberName",
"descriptionResourceKey": "portNumberDescription",
"emptyValueResourceKey": "proxyPortExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyManualPort",
"booleanActions": 0,
"policyType": 124,
"enabled": true
},
{
"dataType": 12,
"category": 121,
"nameResourceKey": "proxyExclusionListName",
"descriptionResourceKey": "proxyExclusionListDescription",
"emptyValueResourceKey": "proxyExclusionListExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyExclusionList",
"booleanActions": 0,
"policyType": 124,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "automaticOption",
"value": "automatic",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerURLName",
"descriptionResourceKey": "proxyServerURLDescription",
"emptyValueResourceKey": "proxyUrlExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyAutomaticConfigurationUrl",
"booleanActions": 0,
"policyType": 124,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "proxySetting",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"policyType": 124,
"enabled": false
} }
], ],
"enabled": true "enabled": true
@@ -901,6 +1005,110 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 124, "policyType": 124,
"enabled": true "enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicyProxySettingsName",
"descriptionResourceKey": "wiFiPolicyProxySettingsDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "noneOption",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "manualOption",
"value": "manual",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerAddressName",
"descriptionResourceKey": "proxyServerAddressDescription",
"emptyValueResourceKey": "proxyAddressExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyManualAddress",
"booleanActions": 0,
"policyType": 124,
"enabled": true
},
{
"dataType": 14,
"category": 121,
"nameResourceKey": "portNumberName",
"descriptionResourceKey": "portNumberDescription",
"emptyValueResourceKey": "proxyPortExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyManualPort",
"booleanActions": 0,
"policyType": 124,
"enabled": true
},
{
"dataType": 12,
"category": 121,
"nameResourceKey": "proxyExclusionListName",
"descriptionResourceKey": "proxyExclusionListDescription",
"emptyValueResourceKey": "proxyExclusionListExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyExclusionList",
"booleanActions": 0,
"policyType": 124,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "automaticOption",
"value": "automatic",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerURLName",
"descriptionResourceKey": "proxyServerURLDescription",
"emptyValueResourceKey": "proxyUrlExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyAutomaticConfigurationUrl",
"booleanActions": 0,
"policyType": 124,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "proxySetting",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"policyType": 124,
"enabled": false
} }
], ],
"enabled": true "enabled": true
@@ -188,15 +188,15 @@
{ {
"dataType": 4, "dataType": 4,
"category": 149, "category": 149,
"nameResourceKey": "selectCertificateProfile", "nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificateForServerValidationName", "descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "rootCertificateForServerValidation", "entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0, "booleanActions": 0,
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
"policyType": 68, "policyType": 68,
@@ -205,9 +205,9 @@
], ],
"dataType": 5, "dataType": 5,
"category": 149, "category": 149,
"nameResourceKey": "selectRootCertificateForServerValidationName", "nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate", "emptyValueResourceKey": "selectCertificates",
"childSettings": [ "childSettings": [
], ],
@@ -366,15 +366,15 @@
{ {
"dataType": 4, "dataType": 4,
"category": 149, "category": 149,
"nameResourceKey": "selectCertificateProfile", "nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificateForServerValidationName", "descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "rootCertificateForServerValidation", "entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0, "booleanActions": 0,
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
"policyType": 68, "policyType": 68,
@@ -383,9 +383,9 @@
], ],
"dataType": 5, "dataType": 5,
"category": 149, "category": 149,
"nameResourceKey": "selectRootCertificateForServerValidationName", "nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate", "emptyValueResourceKey": "selectCertificates",
"childSettings": [ "childSettings": [
], ],
@@ -640,15 +640,15 @@
{ {
"dataType": 4, "dataType": 4,
"category": 149, "category": 149,
"nameResourceKey": "selectCertificateProfile", "nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificateForServerValidationName", "descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "rootCertificateForServerValidation", "entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0, "booleanActions": 0,
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
"policyType": 68, "policyType": 68,
@@ -657,9 +657,9 @@
], ],
"dataType": 5, "dataType": 5,
"category": 149, "category": 149,
"nameResourceKey": "selectRootCertificateForServerValidationName", "nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate", "emptyValueResourceKey": "selectCertificates",
"childSettings": [ "childSettings": [
], ],
@@ -183,8 +183,78 @@
"booleanActions": 3, "booleanActions": 3,
"defaultValue": false, "defaultValue": false,
"policyType": 13, "policyType": 13,
"enabled": false
},
{
"dataType": 16,
"category": 127,
"nameResourceKey": "blockAddingAccountsName",
"descriptionResourceKey": "blockAddingAccountsDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "allowAllAccountsExceptGoogle",
"value": "allowAllExceptGoogleAccounts",
"enabled": true "enabled": true
}, },
{
"nameResourceKey": "allowAllAccounts",
"value": "allowAll",
"children": [
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 127,
"nameResourceKey": "domainAllowListTableName",
"emptyValueResourceKey": "domainAllowListTableEmptyValueExample",
"childSettings": [
],
"options": [
],
"entityKey": "empty",
"booleanActions": 0,
"policyType": 13,
"enabled": true
}
}
],
"dataType": 21,
"category": 127,
"nameResourceKey": "domainAllowListName",
"descriptionResourceKey": "domainAllowListDescription",
"childSettings": [
],
"options": [
],
"entityKey": "allowedGoogleAccountDomains",
"booleanActions": 0,
"policyType": 13,
"enabled": false
}
],
"enabled": true
},
{
"nameResourceKey": "blockAllAccounts",
"value": "blockAll",
"enabled": true
}
],
"entityKey": "workProfileAccountUse",
"booleanActions": 0,
"defaultValue": "allowAllExceptGoogleAccounts",
"unconfiguredValue": "allowAllExceptGoogleAccounts",
"policyType": 13,
"enabled": false
},
{ {
"dataType": 0, "dataType": 0,
"category": 127, "category": 127,
@@ -304,29 +374,42 @@
"enabled": true "enabled": true
}, },
{ {
"dataType": 0, "isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 127, "category": 127,
"nameResourceKey": "workProfileRequirePasswordName", "nameResourceKey": "allAndroidVersionsPasswordHeader",
"descriptionResourceKey": "workProfileRequirePasswordDescription",
"childSettings": [ "childSettings": [
{ {
"dataType": 14, "isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127, "category": 127,
"nameResourceKey": "workProfileMinimumPasswordLengthName", "nameResourceKey": "allAndroidVersionsPasswordHeaderDescription",
"descriptionResourceKey": "workProfileMinimumPasswordLengthDescription",
"emptyValueResourceKey": "workProfileMinimumPasswordLengthEmptyValueKey",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "workProfilePasswordMinimumLength",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 4, "policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
}, },
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileRequirePasswordName",
"descriptionResourceKey": "workProfileRequirePasswordDescription",
"childSettings": [
{ {
"dataType": 16, "dataType": 16,
"category": 127, "category": 127,
@@ -430,6 +513,208 @@
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
}, },
{
"dataType": 14,
"category": 127,
"nameResourceKey": "workProfileNumberOfPreviousPasswordsToBlockName",
"descriptionResourceKey": "workProfileNumberOfPreviousPasswordsToBlockDescription",
"emptyValueResourceKey": "workProfileNumberOfPreviousPasswordsToBlockEmptyValueKey",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordPreviousPasswordBlockCount",
"booleanActions": 0,
"defaultValue": 5,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockFaceUnlockName",
"descriptionResourceKey": "workProfileBlockFaceUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockFaceUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockFingerprintUnlockName",
"descriptionResourceKey": "workProfileBlockFingerprintUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockFingerprintUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockIrisUnlockName",
"descriptionResourceKey": "workProfileBlockIrisUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockIrisUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockSmartLockName",
"descriptionResourceKey": "workProfileBlockSmartLockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockTrustAgents",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "blockUnifiedPasswordForWorkProfileName",
"descriptionResourceKey": "blockUnifiedPasswordForWorkProfileDescription",
"childSettings": [
],
"options": [
],
"entityKey": "blockUnifiedPasswordForWorkProfile",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": false
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidTwelveAndAbovePasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidTwelveAndAbovePasswordHeaderDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
},
{
"dataType": 16,
"category": 127,
"nameResourceKey": "workProfileRequiredPasswordComplexityName",
"descriptionResourceKey": "workProfileRequiredPasswordComplexityDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "none",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "low",
"value": "low",
"enabled": true
},
{
"nameResourceKey": "medium",
"value": "medium",
"enabled": true
},
{
"nameResourceKey": "high",
"value": "high",
"enabled": true
}
],
"entityKey": "workProfileRequiredPasswordComplexity",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "none",
"policyType": 13,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidElevenAndBelowPasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidElevenAndBelowPasswordHeaderDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 13,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 127, "category": 127,
@@ -549,86 +834,18 @@
{ {
"dataType": 14, "dataType": 14,
"category": 127, "category": 127,
"nameResourceKey": "workProfileNumberOfPreviousPasswordsToBlockName", "nameResourceKey": "workProfileMinimumPasswordLengthName",
"descriptionResourceKey": "workProfileNumberOfPreviousPasswordsToBlockDescription", "descriptionResourceKey": "workProfileMinimumPasswordLengthDescription",
"emptyValueResourceKey": "workProfileNumberOfPreviousPasswordsToBlockEmptyValueKey", "emptyValueResourceKey": "workProfileMinimumPasswordLengthEmptyValueKey",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "workProfilePasswordPreviousPasswordBlockCount", "entityKey": "workProfilePasswordMinimumLength",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 5, "defaultValue": 4,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockFaceUnlockName",
"descriptionResourceKey": "workProfileBlockFaceUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockFaceUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockFingerprintUnlockName",
"descriptionResourceKey": "workProfileBlockFingerprintUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockFingerprintUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockIrisUnlockName",
"descriptionResourceKey": "workProfileBlockIrisUnlockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockIrisUnlock",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": true
},
{
"dataType": 0,
"category": 127,
"nameResourceKey": "workProfileBlockSmartLockName",
"descriptionResourceKey": "workProfileBlockSmartLockDescription",
"childSettings": [
],
"options": [
],
"entityKey": "workProfilePasswordBlockTrustAgents",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
} }
+3888 -2576
View File
File diff suppressed because it is too large Load Diff
+3887 -2575
View File
File diff suppressed because it is too large Load Diff
+3884 -2572
View File
File diff suppressed because it is too large Load Diff
+3889 -2577
View File
File diff suppressed because it is too large Load Diff
+3892 -2580
View File
File diff suppressed because it is too large Load Diff
+3887 -2575
View File
File diff suppressed because it is too large Load Diff
+3890 -2578
View File
File diff suppressed because it is too large Load Diff
+3902 -2590
View File
File diff suppressed because it is too large Load Diff
+3891 -2579
View File
File diff suppressed because it is too large Load Diff
+3890 -2578
View File
File diff suppressed because it is too large Load Diff
+3890 -2578
View File
File diff suppressed because it is too large Load Diff
+3884 -2572
View File
File diff suppressed because it is too large Load Diff
+3887 -2575
View File
File diff suppressed because it is too large Load Diff
+3895 -2583
View File
File diff suppressed because it is too large Load Diff
+3892 -2580
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+3884 -2572
View File
File diff suppressed because it is too large Load Diff
+69 -29
View File
@@ -11,7 +11,7 @@ Objects can be compared based on Properties or Documentatation info.
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.0.10' '1.0.11'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -160,8 +160,8 @@ function Invoke-ViewActivated
function Show-CompareBulkForm function Show-CompareBulkForm
{ {
$script:form = Get-XamlObject ($global:AppRootFolder + "\Xaml\BulkCompare.xaml") -AddVariables $script:cmpForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\BulkCompare.xaml") -AddVariables
if(-not $script:form) { return } if(-not $script:cmpForm) { return }
$global:cbCompareProvider.ItemsSource = @(($global:compareProviders | Where BulkCompare -ne $null)) $global:cbCompareProvider.ItemsSource = @(($global:compareProviders | Where BulkCompare -ne $null))
$global:cbCompareProvider.SelectedValue = (Get-Setting "Compare" "Provider" "export") $global:cbCompareProvider.SelectedValue = (Get-Setting "Compare" "Provider" "export")
@@ -210,12 +210,12 @@ function Show-CompareBulkForm
$global:dgObjectsToCompare.ItemsSource = $script:compareObjects $global:dgObjectsToCompare.ItemsSource = $script:compareObjects
Add-XamlEvent $script:form "btnClose" "add_click" { Add-XamlEvent $script:cmpForm "btnClose" "add_click" {
$script:form = $null $script:cmpForm = $null
Show-ModalObject Show-ModalObject
} }
Add-XamlEvent $script:form "btnStartCompare" "add_click" { Add-XamlEvent $script:cmpForm "btnStartCompare" "add_click" {
Write-Status "Compare objects" Write-Status "Compare objects"
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
@@ -233,7 +233,7 @@ function Show-CompareBulkForm
Set-CompareProviderOptions $global:cbCompareProvider Set-CompareProviderOptions $global:cbCompareProvider
Show-ModalForm "Bulk Compare Objects" $script:form -HideButtons Show-ModalForm "Bulk Compare Objects" $script:cmpForm -HideButtons
} }
function Set-CompareProviderOptions function Set-CompareProviderOptions
@@ -516,7 +516,11 @@ function Start-BulkCompareExportObjects
Write-Log "****************************************************************" Write-Log "****************************************************************"
$compareObjectsResult = @() $compareObjectsResult = @()
$txtNameFilter = (Get-XamlProperty $global:ccContentProviderOptions.Content "txtCompareNameFilter" "Text").Trim() $txtNameFilter = (Get-XamlProperty $global:ccContentProviderOptions.Content "txtCompareNameFilter" "Text")
if($txtNameFilter -is [String])
{
$txtNameFilter = $txtNameFilter.Trim()
}
$rootFolder = (Get-XamlProperty $global:ccContentProviderOptions.Content "txtExportPath" "Text") $rootFolder = (Get-XamlProperty $global:ccContentProviderOptions.Content "txtExportPath" "Text")
$compareProps = $script:defaultCompareProps $compareProps = $script:defaultCompareProps
@@ -1110,12 +1114,12 @@ function Set-ColumnVisibility
function Add-CompareProperty function Add-CompareProperty
{ {
param($name, $value1, $value2, $category, $subCategory, $match = $null) param($name, $value1, $value2, $category, $subCategory, $match = $null, [switch]$skip)
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") } $value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") } $value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
$script:compareProperties += [PSCustomObject]@{ $compare += [PSCustomObject]@{
PropertyName = $name PropertyName = $name
Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" } Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" }
Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" } Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" }
@@ -1123,6 +1127,11 @@ function Add-CompareProperty
SubCategory = $subCategory SubCategory = $subCategory
Match = ?? $match ($value1 -eq $value2) Match = ?? $match ($value1 -eq $value2)
} }
if($skip -eq $true) {
$compare.Match = $null
}
$script:compareProperties += $compare
} }
function Compare-ObjectsBasedonProperty function Compare-ObjectsBasedonProperty
@@ -1133,8 +1142,11 @@ function Compare-ObjectsBasedonProperty
Set-ColumnVisibility $false Set-ColumnVisibility $false
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
$coreProps = @((?? $objectType.NameProperty "displayName"), "Description", "Id", "createdDateTime", "lastModifiedDateTime", "version") $coreProps = @((?? $objectType.NameProperty "displayName"), "Description", "Id", "createdDateTime", "lastModifiedDateTime", "version")
$postProps = @("Advertisements") $postProps = @("Advertisements")
$skipProps = @("@ObjectFromFile")
foreach ($propName in $coreProps) foreach ($propName in $coreProps)
{ {
@@ -1144,7 +1156,7 @@ function Compare-ObjectsBasedonProperty
} }
$val1 = ($obj1.$propName | ConvertTo-Json -Depth 10) $val1 = ($obj1.$propName | ConvertTo-Json -Depth 10)
$val2 = ($obj2.$propName | ConvertTo-Json -Depth 10) $val2 = ($obj2.$propName | ConvertTo-Json -Depth 10)
Add-CompareProperty $propName $val1 $val2 Add-CompareProperty $propName $val1 $val2 -Skip:($skipBasicProperties -eq $true)
} }
$addedProps = @() $addedProps = @()
@@ -1152,19 +1164,21 @@ function Compare-ObjectsBasedonProperty
{ {
if($propName -in $coreProps) { continue } if($propName -in $coreProps) { continue }
if($propName -in $postProps) { continue } if($propName -in $postProps) { continue }
if($propName -in $skipProps) { continue }
if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue } if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue }
$addedProps += $propName $addedProps += $propName
$val1 = ($obj1.$propName | ConvertTo-Json -Depth 10) $val1 = ($obj1.$propName | ConvertTo-Json -Depth 10)
$val2 = ($obj2.$propName | ConvertTo-Json -Depth 10) $val2 = ($obj2.$propName | ConvertTo-Json -Depth 10)
Add-CompareProperty $propName $val1 $val2 Add-CompareProperty $propName $val1 $val2 -Skip:($skipBasicProperties -eq $true)
} }
foreach ($propName in ($obj2.PSObject.Properties | Select Name).Name) foreach ($propName in ($obj2.PSObject.Properties | Select Name).Name)
{ {
if($propName -in $coreProps) { continue } if($propName -in $coreProps) { continue }
if($propName -in $postProps) { continue } if($propName -in $postProps) { continue }
if($propName -in $skipProps) { continue }
if($propName -in $addedProps) { continue } if($propName -in $addedProps) { continue }
if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue } if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue }
@@ -1174,6 +1188,7 @@ function Compare-ObjectsBasedonProperty
Add-CompareProperty $propName $val1 $val2 Add-CompareProperty $propName $val1 $val2
} }
$skipAssignments = Get-XamlProperty $script:cmpForm "chkSkipCompareAssignments" "IsChecked"
foreach ($propName in $postProps) foreach ($propName in $postProps)
{ {
if(-not ($obj1.PSObject.Properties | Where Name -eq $propName)) if(-not ($obj1.PSObject.Properties | Where Name -eq $propName))
@@ -1182,7 +1197,7 @@ function Compare-ObjectsBasedonProperty
} }
$val1 = ($obj1.$propName | ConvertTo-Json -Depth 10) $val1 = ($obj1.$propName | ConvertTo-Json -Depth 10)
$val2 = ($obj2.$propName | ConvertTo-Json -Depth 10) $val2 = ($obj2.$propName | ConvertTo-Json -Depth 10)
Add-CompareProperty $propName $val1 $val2 Add-CompareProperty $propName $val1 $val2 -Skip:($skipAssignments -eq $true)
} }
$script:compareProperties $script:compareProperties
@@ -1226,10 +1241,12 @@ function Compare-ObjectsBasedonDocumentation
$settingsValue = ?? $objectType.CompareValue "Value" $settingsValue = ?? $objectType.CompareValue "Value"
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
if($docObj1.BasicInfo -and -not ($docObj1.BasicInfo | where Value -eq $obj1.Id)) if($docObj1.BasicInfo -and -not ($docObj1.BasicInfo | where Value -eq $obj1.Id))
{ {
# Make sure the Id property is included # Make sure the Id property is included
Add-CompareProperty "Id" $obj1.Id $obj2.Id $docObj1.BasicInfo[0].Category Add-CompareProperty "Id" $obj1.Id $obj2.Id $docObj1.BasicInfo[0].Category -Skip:($skipBasicProperties -eq $true)
} }
foreach ($prop in $docObj1.BasicInfo) foreach ($prop in $docObj1.BasicInfo)
@@ -1237,7 +1254,7 @@ function Compare-ObjectsBasedonDocumentation
$val1 = $prop.Value $val1 = $prop.Value
$prop2 = $docObj2.BasicInfo | Where Name -eq $prop.Name $prop2 = $docObj2.BasicInfo | Where Name -eq $prop.Name
$val2 = $prop2.Value $val2 = $prop2.Value
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category Add-CompareProperty $prop.Name $val1 $val2 $prop.Category -Skip:($skipBasicProperties -eq $true)
} }
$addedProperties = @() $addedProperties = @()
@@ -1246,11 +1263,16 @@ function Compare-ObjectsBasedonDocumentation
{ {
foreach ($prop in $docObj1.Settings) foreach ($prop in $docObj1.Settings)
{ {
if(($prop.SettingId + $prop.ParentSettingId) -in $addedProperties) { continue } if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.ParentSettingId) $addedProperties += ($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex)
$val1 = $prop.Value $val1 = $prop.Value
$prop2 = $docObj2.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.ParentSettingId -eq $prop.ParentSettingId } $prop2 = $docObj2.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.ParentSettingId -eq $prop.ParentSettingId -and $_.RowIndex -eq $prop.RowIndex }
if($val1 -isnot [Array] -and $prop2.Value -is [Array])
{
Write-Log "Compare property for $($prop.SettingId) found based on value" 2
$prop2 = $prop2 | Where Value -eq $val1
}
$val2 = $prop2.Value $val2 = $prop2.Value
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
@@ -1261,12 +1283,18 @@ function Compare-ObjectsBasedonDocumentation
# Add children defined on Object 1 property # Add children defined on Object 1 property
foreach ($childProp in $children1) foreach ($childProp in $children1)
{ {
if(($childProp.SettingId + $childProp.ParentSettingId) -in $addedProperties) { continue } if(($childProp.SettingId + $childProp.ParentSettingId + $childProp.RowIndex) -in $addedProperties) { continue }
$addedProperties += ($childProp.SettingId + $childProp.ParentSettingId) $addedProperties += ($childProp.SettingId + $childProp.ParentSettingId + $childProp.RowIndex)
$val1 = $childProp.Value $val1 = $childProp.Value
$prop2 = $docObj2.Settings | Where { $_.SettingId -eq $childProp.SettingId -and $_.ParentSettingId -eq $childProp.ParentSettingId } $prop2 = $docObj2.Settings | Where { $_.SettingId -eq $childProp.SettingId -and $_.ParentSettingId -eq $childProp.ParentSettingId -and $_.RowIndex -eq $childProp.RowIndex}
if($val1 -isnot [Array] -and $prop2.Value -is [Array])
{
Write-Log "Compare property for $($childProp.SettingId) found based on value" 2
$prop2 = $prop2 | Where Value -eq $val1
}
$val2 = $prop2.Value $val2 = $prop2.Value
Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category
} }
@@ -1274,11 +1302,16 @@ function Compare-ObjectsBasedonDocumentation
# This is to make sure all children are added under its parent and not last in the table # This is to make sure all children are added under its parent and not last in the table
foreach ($childProp in $children2) foreach ($childProp in $children2)
{ {
if(($childProp.SettingId + $childProp.ParentSettingId) -in $addedProperties) { continue } if(($childProp.SettingId + $childProp.ParentSettingId + $childProp.RowIndex) -in $addedProperties) { continue }
$addedProperties += ($childProp.SettingId + $childProp.ParentSettingId) $addedProperties += ($childProp.SettingId + $childProp.ParentSettingId + $childProp.RowIndex)
$val2 = $childProp.Value $val2 = $childProp.Value
$prop2 = $docObj1.Settings | Where { $_.SettingId -eq $childProp.SettingId -and $_.ParentSettingId -eq $childProp.ParentSettingId } $prop2 = $docObj1.Settings | Where { $_.SettingId -eq $childProp.SettingId -and $_.ParentSettingId -eq $childProp.ParentSettingId -and $_.RowIndex -eq $childProp.RowIndex }
if($val2 -isnot [Array] -and $prop2.Value -is [Array])
{
Write-Log "Compare property for $($childProp.SettingId) found based on value" 2
$prop2 = $prop2 | Where Value -eq $val1
}
$val1 = $prop2.Value $val1 = $prop2.Value
Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category
} }
@@ -1287,11 +1320,16 @@ function Compare-ObjectsBasedonDocumentation
# These objects are defined only on Object 2. They will be last in the table # These objects are defined only on Object 2. They will be last in the table
foreach ($prop in $docObj2.Settings) foreach ($prop in $docObj2.Settings)
{ {
if(($prop.SettingId + $prop.ParentSettingId) -in $addedProperties) { continue } if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.ParentSettingId) $addedProperties += ($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex)
$val2 = $prop.Value $val2 = $prop.Value
$prop2 = $docObj1.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.ParentSettingId -eq $prop.ParentSettingId } $prop2 = $docObj1.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.ParentSettingId -eq $prop.ParentSettingId -and $_.RowIndex -eq $childProp.RowIndex }
if($val2 -isnot [Array] -and $prop2.Value -is [Array])
{
Write-Log "Compare property for $($prop.SettingId) found based on value" 2
$prop2 = $prop2 | Where Value -eq $val2
}
$val1 = $prop2.Value $val1 = $prop2.Value
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
} }
@@ -1460,12 +1498,14 @@ function Add-AssignmentInfo
$val2 = $tmpVal $val2 = $tmpVal
} }
$skipAssignments = Get-XamlProperty $script:cmpForm "chkSkipCompareAssignments" "IsChecked"
if($assignment.RawIntent) if($assignment.RawIntent)
{ {
Add-CompareProperty $assignment.Category $val1 $val2 -Category $assignment.GroupMode -match $match Add-CompareProperty $assignment.Category $val1 $val2 -Category $assignment.GroupMode -match $match -Skip:($skipAssignments -eq $true)
} }
else else
{ {
Add-CompareProperty $assignmentStr $val1 $val2 -Category $assignment.GroupMode -match $match Add-CompareProperty $assignmentStr $val1 $val2 -Category $assignment.GroupMode -match $match -Skip:($skipAssignments -eq $true)
} }
} }
+99 -8
View File
@@ -20,7 +20,7 @@ $global:documentationProviders = @()
function Get-ModuleVersion function Get-ModuleVersion
{ {
'2.0.0' '2.2.0'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -61,6 +61,7 @@ function Invoke-InitializeModule
Settings="TableHeaders.settings" Settings="TableHeaders.settings"
returnCode='Win32ReturnCodes.Columns.returnCode' returnCode='Win32ReturnCodes.Columns.returnCode'
type='Win32ReturnCodes.Columns.codeType' type='Win32ReturnCodes.Columns.codeType'
RecommendedValue="AzureIAMCommon.Recommended"
} }
} }
@@ -227,6 +228,7 @@ function Get-ObjectDocumentation
$script:applicabilityRules = @() $script:applicabilityRules = @()
$script:objectAssignments = @() $script:objectAssignments = @()
$script:objectScripts = @() $script:objectScripts = @()
$script:admxCategories = $null
$script:ObjectTypeFullTable = @{} # Hash table with objects that should be documented in a single table eg ScopeTags $script:ObjectTypeFullTable = @{} # Hash table with objects that should be documented in a single table eg ScopeTags
@@ -290,7 +292,8 @@ function Get-ObjectDocumentation
elseif($type -eq "#microsoft.graph.deviceManagementIntent") elseif($type -eq "#microsoft.graph.deviceManagementIntent")
{ {
Invoke-TranslateIntentObject $obj $objectType | Out-Null Invoke-TranslateIntentObject $obj $objectType | Out-Null
$properties = @("Name","Value","Category","FullValueTable","RawValue","SettingId","Description") $properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description")
$defaultDocumentationProperties = @("Name","Value","RecommendedValue")
} }
#endregion #endregion
#region Administrative Templates #region Administrative Templates
@@ -382,6 +385,7 @@ function Invoke-ObjectDocumentation
$global:catRecommendedSettings = $null $global:catRecommendedSettings = $null
$global:intentCategoryDefs = $null $global:intentCategoryDefs = $null
$global:cfgCategories = $null $global:cfgCategories = $null
$script:admxCategories = $null
$script:DocumentationLanguage = "en" $script:DocumentationLanguage = "en"
$script:objectSeparator = [System.Environment]::NewLine $script:objectSeparator = [System.Environment]::NewLine
@@ -541,6 +545,10 @@ function Get-ObjectTypeString
{ {
return (Get-LanguageString "Titles.windows10QualityUpdate") return (Get-LanguageString "Titles.windows10QualityUpdate")
} }
elseif($objTypeId -eq "WinDriverUpdatePolicies")
{
return (Get-LanguageString "Titles.windows10DriverUpdate")
}
elseif($objTypeId -eq "TenantAdmin") elseif($objTypeId -eq "TenantAdmin")
{ {
return (Get-LanguageString "Titles.tenantAdmin") return (Get-LanguageString "Titles.tenantAdmin")
@@ -873,7 +881,8 @@ function Invoke-TranslateADMXObject
{ {
if(-not $definitionValue.definition -and $definitionValues.'definition@odata.bind') if(-not $definitionValue.definition -and $definitionValues.'definition@odata.bind')
{ {
$definition = Invoke-GraphRequest -Url $definitionValue.'definition@odata.bind' -ODataMetadata "minimal" @params $url = $definitionValue.'definition@odata.bind' -replace $global:graphURL, ("https://$((?? $global:MSALGraphEnvironment "graph.microsoft.com"))/beta")
$definition = Invoke-GraphRequest -Url $url -ODataMetadata "minimal" @params
if($definition) if($definition)
{ {
$definitionValue | Add-Member -MemberType NoteProperty -Name "definition" -Value $definition $definitionValue | Add-Member -MemberType NoteProperty -Name "definition" -Value $definition
@@ -1047,15 +1056,40 @@ function Invoke-TranslateSettingsObject
#> #>
$cfgSettings = (Invoke-GraphRequest "/deviceManagement/configurationPolicies('$($obj.Id)')/settings?`$expand=settingDefinitions&top=1000" -ODataMetadata "minimal" @params).Value $cfgSettings = (Invoke-GraphRequest "/deviceManagement/configurationPolicies('$($obj.Id)')/settings?`$expand=settingDefinitions&top=1000" -ODataMetadata "minimal" @params).Value
if($obj.'@ObjectFromFile')
{
$cfgSettings = $obj.Settings
}
if(-not $global:cfgCategories) if(-not $global:cfgCategories)
{ {
$global:cfgCategories = (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value $global:cfgCategories = (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value
} }
if(-not $global:cachedCfgSettings)
{
$global:cachedCfgSettings = @{}
}
$script:settingCatalogasCategories = @{} $script:settingCatalogasCategories = @{}
foreach($cfgSetting in $cfgSettings) foreach($cfgSetting in $cfgSettings)
{
if($obj.'@ObjectFromFile' -and -not $cfgSetting.settingDefinitions)
{
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$defObj = Invoke-GraphRequest "/deviceManagement/configurationSettings/$($cfgSetting.settingInstance.settingDefinitionId)"
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
else
{ {
$defObj = $cfgSetting.settingDefinitions | Where id -eq $cfgSetting.settingInstance.settingDefinitionId $defObj = $cfgSetting.settingDefinitions | Where id -eq $cfgSetting.settingInstance.settingDefinitionId
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
#$defObj = $cfgSetting.settingDefinitions | Where { $_.id -eq $cfgSetting.settingInstance.settingDefinitionId -or $_.id -eq $cfgSettings.settingInstanceTemplate.settingDefinitionId } #$defObj = $cfgSetting.settingDefinitions | Where { $_.id -eq $cfgSetting.settingInstance.settingDefinitionId -or $_.id -eq $cfgSettings.settingInstanceTemplate.settingDefinitionId }
if(-not $defObj -or $script:settingCatalogasCategories.ContainsKey($defObj.categoryId)) { continue } if(-not $defObj -or $script:settingCatalogasCategories.ContainsKey($defObj.categoryId)) { continue }
@@ -1102,6 +1136,18 @@ function Add-SettingsSetting
$childSettings = @() $childSettings = @()
$settingsDef = $settingsDefs | Where id -eq $settingInstance.settingDefinitionId $settingsDef = $settingsDefs | Where id -eq $settingInstance.settingDefinitionId
if(-not $settingsDef -and $settingInstance.settingDefinitionId)
{
if($global:cachedCfgSettings.ContainsKey($settingInstance.settingDefinitionId) -eq $false)
{
$settingsDef = Invoke-GraphRequest "/deviceManagement/configurationSettings/$($settingInstance.settingDefinitionId)"
$global:cachedCfgSettings.Add($settingInstance.settingDefinitionId, $settingsDef)
}
else
{
$settingsDef = $global:cachedCfgSettings[$settingInstance.settingDefinitionId]
}
}
$categoryDef = $global:cfgCategories | Where Id -eq $settingsDef.categoryId #$script:settingCatalogasCategories[$settingsDef.categoryId] $categoryDef = $global:cfgCategories | Where Id -eq $settingsDef.categoryId #$script:settingCatalogasCategories[$settingsDef.categoryId]
if($settingsDef.categoryId -ne $categoryDef.rootCategoryId) if($settingsDef.categoryId -ne $categoryDef.rootCategoryId)
@@ -1118,6 +1164,7 @@ function Add-SettingsSetting
$settingInfo = [PSCustomObject]@{ $settingInfo = [PSCustomObject]@{
SettingId = $settingsDef.Id SettingId = $settingsDef.Id
SettingKey = ""
SettingName = $settingsDef.Name SettingName = $settingsDef.Name
Name = $settingsDef.displayName Name = $settingsDef.displayName
Description=$settingsDef.description Description=$settingsDef.description
@@ -1136,6 +1183,7 @@ function Add-SettingsSetting
Show = $show Show = $show
Type = $settingInstance.'@odata.type' Type = $settingInstance.'@odata.type'
PropertyIndex = 0 PropertyIndex = 0
RowIndex = 0
ChildSettings = @() #($childSettings | Sort DisplayName) ChildSettings = @() #($childSettings | Sort DisplayName)
} }
@@ -1201,13 +1249,13 @@ function Add-SettingsSetting
{ {
$childSettingsArr = @() $childSettingsArr = @()
# Not sure if this is the best way but it looks better for tested policies # Not sure if this is the best way but it looks better for tested policies
if($script:currentObject.templateReference.templateId) if($script:currentObject.templateReference.templateId -and $settingsDefs)
{ {
$childIDs = $settingsDefs.id # Endpoint Security objects $childIDs = $settingsDefs.id # Endpoint Security objects
} }
else else
{ {
$childIDs = $settingsDef.childIds # Setings Catalog $childIDs = $settingsDef.childIds # Setings Catalog and from file documentation
} }
#foreach($childId in $settingsDefs.id) #$settingsDef.childIds) #foreach($childId in $settingsDefs.id) #$settingsDef.childIds)
foreach($childId in $childIDs) foreach($childId in $childIDs)
@@ -1218,6 +1266,7 @@ function Add-SettingsSetting
if($tmpSetting) if($tmpSetting)
{ {
$tmpSetting.Parent = $childSettings $tmpSetting.Parent = $childSettings
$tmpSetting.RowIndex = $index
$childSettings += $tmpSetting $childSettings += $tmpSetting
$childSettingsArr += $tmpSetting $childSettingsArr += $tmpSetting
if($settingsDef.childIds.Count -gt 1) if($settingsDef.childIds.Count -gt 1)
@@ -1225,6 +1274,7 @@ function Add-SettingsSetting
$tmpSetting.PropertyIndex = $childSettingsArr.Count $tmpSetting.PropertyIndex = $childSettingsArr.Count
} }
} }
$rowIndex++
} }
$settingInfo.ChildSettings += [PSCustomObject]@{ $settingInfo.ChildSettings += [PSCustomObject]@{
@@ -1300,6 +1350,12 @@ function Get-IntentCategory
{ {
param($templateType) param($templateType)
if(-not $templateType)
{
Write-Log "Get-IntentCategory called with empty Category" 2
return
}
if($templateType.StartsWith("endpointSecurity")) if($templateType.StartsWith("endpointSecurity"))
{ {
$templateType = $templateType.Substring(16) $templateType = $templateType.Substring(16)
@@ -1334,6 +1390,7 @@ function Get-IntentCategory
return (Get-LanguageString "SecurityTemplate.firewall") return (Get-LanguageString "SecurityTemplate.firewall")
} }
elseif($templateType -eq "securityBaseline" -or elseif($templateType -eq "securityBaseline" -or
$templateType -eq "baseline" -or
$templateType -eq "advancedThreatProtectionSecurityBaseline" -or $templateType -eq "advancedThreatProtectionSecurityBaseline" -or
$templateType -eq "microsoftEdgeSecurityBaseline") $templateType -eq "microsoftEdgeSecurityBaseline")
{ {
@@ -1482,6 +1539,12 @@ function Add-IntentSettingObjectToList
$objSetting.Level = $objSetting.Level + 1 $objSetting.Level = $objSetting.Level + 1
} }
$recommendedSetting = $global:catRecommendedSettings[$objSetting.CategoryObject.Id] | Where definitionId -eq $objSetting.SettingId
if($recommendedSetting.valueJson -and ($objSetting.ValueSet -eq $false -or $recommendedSetting.valueJson -ne ($objSetting.RawValue | ConvertTo-Json -Compress))) {
$objSetting | Add-Member Noteproperty -Name "RecommendedValue" -Value ($recommendedSetting.valueJson | ConvertFrom-Json) -Force
}
$script:objectSettingsData += $objSetting $script:objectSettingsData += $objSetting
if($objSetting.ValueSet -eq $false) { return } if($objSetting.ValueSet -eq $false) { return }
@@ -1906,7 +1969,8 @@ function Get-LanguageString
if(-not $script:languageStrings) if(-not $script:languageStrings)
{ {
$fileContent = Get-Content ($global:AppRootFolder + "\Documentation\Strings-$($script:DocumentationLanguage).json") -Encoding UTF8 $lng = ?? $script:DocumentationLanguage "en"
$fileContent = Get-Content ($global:AppRootFolder + "\Documentation\Strings-$($lng).json") -Encoding UTF8
$script:languageStrings = $fileContent | ConvertFrom-Json $script:languageStrings = $fileContent | ConvertFrom-Json
} }
@@ -2070,6 +2134,7 @@ function Invoke-TranslateSection
if($prop.dataType -eq 8) if($prop.dataType -eq 8)
{ {
if($prop.nameResourceKey -eq "LearnMore") { continue } if($prop.nameResourceKey -eq "LearnMore") { continue }
elseif($prop.nameResourceKey -eq "Empty") { $script:CurrentSubCategory = $null }
elseif($prop.nameResourceKey -in $script:categoriesToIgnore) { continue } elseif($prop.nameResourceKey -in $script:categoriesToIgnore) { continue }
elseif($prop.nameResourceKey) elseif($prop.nameResourceKey)
{ {
@@ -2409,6 +2474,17 @@ function Invoke-TranslateSection
} }
$value = $arrTmp -join $script:objectSeparator $value = $arrTmp -join $script:objectSeparator
} }
elseif($prop.dataType -eq 108) # String with format
{
$value = $propValue
if($prop.formatStringKey) {
$str = Get-LanguageString $prop.formatStringKey
if($str)
{
$value = $str -f $propValue
}
}
}
else else
{ {
Write-Log "Unsupported property '$((Get-LanguageString "SettingDetails.$($prop.nameResourceKey)"))' ($($prop.nameResourceKey)) for object property $($prop.entityKey). Type: $($prop.dataType)" 2 Write-Log "Unsupported property '$((Get-LanguageString "SettingDetails.$($prop.nameResourceKey)"))' ($($prop.nameResourceKey)) for object property $($prop.entityKey). Type: $($prop.dataType)" 2
@@ -3588,7 +3664,7 @@ function Invoke-TranslateAssignments
$hours = ($endTime.ToUniversalTime() - $endTime).Hours $hours = ($endTime.ToUniversalTime() - $endTime).Hours
$endTime = $endTime.AddHours($hours) $endTime = $endTime.AddHours($hours)
} }
$value = "$($instTime.ToShortDateString()) $($instTime.ToShortTimeString())" $value = "$($endTime.ToShortDateString()) $($endTime.ToShortTimeString())"
} }
} }
@@ -4403,7 +4479,7 @@ function local:Invoke-StartDocumentatiom
# Add each object to the documentation # Add each object to the documentation
foreach($curGroupId in ($sourceList.ObjectType | Select GroupID -Unique).GroupID) foreach($curGroupId in ($sourceList.ObjectType | Select GroupID -Unique).GroupID)
{ {
# New object group e.g. Script, Tennant, Device Configuration # New object group e.g. Script, Tenant, Device Configuration
# A group matches a menu item in the protal but can contain multiple object types # A group matches a menu item in the protal but can contain multiple object types
if($global:cbDocumentationType.SelectedItem.NewObjectGroup) if($global:cbDocumentationType.SelectedItem.NewObjectGroup)
{ {
@@ -5012,3 +5088,18 @@ function Set-TableObjects
$script:ObjectTypeFullTable.Add($objectInfo.ObjectType.Id, $objectInfo) $script:ObjectTypeFullTable.Add($objectInfo.ObjectType.Id, $objectInfo)
} }
} }
function Get-PolicyTypeName
{
param($type, $default = $null)
$categoryObj = Get-TranslationFiles $type
if($null -eq $categoryObj) { return $default }
$lngStr = Get-LanguageString "PolicyType.$($categoryObj.PolicyTypeLanguageId)"
if($lngStr) { return $lngStr }
return $defult
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.0.0' '1.0.1'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -374,7 +374,7 @@ function Invoke-HTMLProcessItem
$isFilterAssignment = $false $isFilterAssignment = $false
foreach($assignment in $documentedObj.Assignments) foreach($assignment in $documentedObj.Assignments)
{ {
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType")) if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
{ {
$isFilterAssignment = $true $isFilterAssignment = $true
break break
+2 -2
View File
@@ -1,6 +1,6 @@
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.1.0' '1.1.1'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -331,7 +331,7 @@ function Invoke-MDProcessItem
$isFilterAssignment = $false $isFilterAssignment = $false
foreach($assignment in $documentedObj.Assignments) foreach($assignment in $documentedObj.Assignments)
{ {
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType")) if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
{ {
$isFilterAssignment = $true $isFilterAssignment = $true
break break
+3 -3
View File
@@ -3,7 +3,7 @@
#https://docs.microsoft.com/en-us/office/vba/api/overview/word #https://docs.microsoft.com/en-us/office/vba/api/overview/word
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.5.0' '1.6.0'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -600,7 +600,7 @@ function Invoke-WordProcessItem
$isFilterAssignment = $false $isFilterAssignment = $false
foreach($assignment in $documentedObj.Assignments) foreach($assignment in $documentedObj.Assignments)
{ {
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType")) if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
{ {
$isFilterAssignment = $true $isFilterAssignment = $true
break break
@@ -752,7 +752,7 @@ function Add-DocTableItems
$range = $script:doc.application.selection.range $range = $script:doc.application.selection.range
$script:docTable = $script:doc.Tables.Add($range, ($items.Count + 1), $properties.Count, [Microsoft.Office.Interop.Word.WdDefaultTableBehavior]::wdWord9TableBehavior, [Microsoft.Office.Interop.Word.WdAutoFitBehavior]::wdAutoFitWindow) $script:docTable = $script:doc.Tables.Add($range, (($items | measure).Count + 1), $properties.Count, [Microsoft.Office.Interop.Word.WdDefaultTableBehavior]::wdWord9TableBehavior, [Microsoft.Office.Interop.Word.WdAutoFitBehavior]::wdAutoFitWindow)
$script:docTable.ApplyStyleHeadingRows = $true $script:docTable.ApplyStyleHeadingRows = $true
Set-DocObjectStyle $script:docTable $global:txtWordTableStyle.Text | Out-null Set-DocObjectStyle $script:docTable $global:txtWordTableStyle.Text | Out-null
+518 -35
View File
@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.6'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -73,6 +73,37 @@ function Invoke-InitializeModule
SubPath = "EndpointManager" SubPath = "EndpointManager"
}) "EndpointManager" }) "EndpointManager"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Save Encryption File"
Key = "EMSaveEncryptionFile"
Type = "Boolean"
Description = "Save encryption file when uploading an app. This can then be used to when downloading the app file."
SubPath = "EndpointManager"
}) "EndpointManager"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "App download folder"
Key = "EMIntuneAppDownloadFolder"
Type = "Folder"
Description = "Folder where app packages will be downloaded and where encryption files will be saved"
SubPath = "EndpointManager"
}) "EndpointManager"
Get-SettingValue "ProxyURI"
if($global:FirstTimeRunning) {
Save-Setting "EndpointManager" "EMAzureApp" $global:DefaultAzureApp
}
$currentAppID = Get-SettingValue "EMAzureApp"
$customAppID = Get-SettingValue "EMCustomAppId"
$global:informOldAzureApp = $false
if(($global:OldAzureApps -is [Array] -and $currentAppID -in $global:OldAzureApps) -or (-not $currentAppID -and -not $customAppID))
{
$global:informOldAzureApp = $true
Write-Log "Microsoft Intune PowerShell is being decomissioned. Please change to a supported app eg Microsoft Graph or a custom app!" 2
}
$viewPanel = Get-XamlObject ($global:AppRootFolder + "\Xaml\EndpointManagerPanel.xaml") -AddVariables $viewPanel = Get-XamlObject ($global:AppRootFolder + "\Xaml\EndpointManagerPanel.xaml") -AddVariables
@@ -89,8 +120,8 @@ function Invoke-InitializeModule
Deactivating = { Invoke-EMDeactivateView } Deactivating = { Invoke-EMDeactivateView }
Activating = { Invoke-EMActivatingView } Activating = { Invoke-EMActivatingView }
Authentication = (Get-MSALAuthenticationObject) Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMAuthenticateToMSAL } Authenticate = { Invoke-EMAuthenticateToMSAL @args }
AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM") AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM")
SaveSettings = { Invoke-EMSaveSettings } SaveSettings = { Invoke-EMSaveSettings }
Permissions = @() Permissions = @()
@@ -120,7 +151,7 @@ function Invoke-InitializeModule
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/identity/conditionalAccess/policies" API = "/identity/conditionalAccess/policies"
Permissons=@("Policy.Read.All","Policy.ReadWrite.ConditionalAccess","Application.Read.All") Permissons=@("Policy.Read.All","Policy.ReadWrite.ConditionalAccess","Application.Read.All")
Dependencies = @("NamedLocations","Applications","TermsOfUse","AuthenticationStrengths") Dependencies = @("NamedLocations","Applications","TermsOfUse","AuthenticationStrengths","AssignmentFilters")
GroupId = "ConditionalAccess" GroupId = "ConditionalAccess"
ImportExtension = { Add-ConditionalAccessImportExtensions @args } ImportExtension = { Add-ConditionalAccessImportExtensions @args }
PreImportCommand = { Start-PreImportConditionalAccess @args } PreImportCommand = { Start-PreImportConditionalAccess @args }
@@ -128,8 +159,6 @@ function Invoke-InitializeModule
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
}) })
if((Get-SettingValue "PreviewFeatures" $false) -eq $true)
{
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
Title = "Terms of use" Title = "Terms of use"
Id = "TermsOfUse" Id = "TermsOfUse"
@@ -143,7 +172,6 @@ function Invoke-InitializeModule
PostExportCommand = { Start-PostExportTermsOfUse @args } PostExportCommand = { Start-PostExportTermsOfUse @args }
GroupId = "ConditionalAccess" GroupId = "ConditionalAccess"
}) })
}
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
Title = "Named Locations" Title = "Named Locations"
@@ -262,6 +290,7 @@ function Invoke-InitializeModule
#QUERYLIST = "`$filter=endsWith(id,'Windows10EnrollmentCompletionPageConfiguration')" #QUERYLIST = "`$filter=endsWith(id,'Windows10EnrollmentCompletionPageConfiguration')"
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All") Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
SkipRemoveProperties = @('Id') SkipRemoveProperties = @('Id')
Dependencies = @("Applications")
AssignmentsType = "enrollmentConfigurationAssignments" AssignmentsType = "enrollmentConfigurationAssignments"
PropertiesToRemoveForUpdate = @('priority') PropertiesToRemoveForUpdate = @('priority')
GroupId = "WinEnrollment" GroupId = "WinEnrollment"
@@ -316,7 +345,7 @@ function Invoke-InitializeModule
PostFileImportCommand = { Start-PostFileImportAdministrativeTemplate @args } PostFileImportCommand = { Start-PostFileImportAdministrativeTemplate @args }
PreImportCommand = { Start-PreImportAdministrativeTemplate @args } PreImportCommand = { Start-PreImportAdministrativeTemplate @args }
LoadObject = { Start-LoadAdministrativeTemplate @args } LoadObject = { Start-LoadAdministrativeTemplate @args }
PropertiesToRemove = @("definitionValues") PropertiesToRemove = @("definitionValues","policyConfigurationIngestionType")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="DeviceConfiguration" Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration" GroupId = "DeviceConfiguration"
@@ -456,7 +485,10 @@ function Invoke-InitializeModule
PreDeleteCommand = { Start-PreDeleteApplications @args } PreDeleteCommand = { Start-PreDeleteApplications @args }
PostExportCommand = { Start-PostExportApplications @args } PostExportCommand = { Start-PostExportApplications @args }
PostListCommand = { Start-PostListApplications @args } PostListCommand = { Start-PostListApplications @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportApplications @args }
PostGetCommand = { Start-PostGetApplications @args }
PostImportCommand = { Start-PostImportApplications @args }
PostFilesImportCommand = { Start-PostFilesImportApplications @args }
GroupId = "Apps" GroupId = "Apps"
ScopeTagsReturnedInList = $false ScopeTagsReturnedInList = $false
}) })
@@ -670,6 +702,7 @@ function Invoke-InitializeModule
GroupId = "EndpointAnalytics" GroupId = "EndpointAnalytics"
Icon = "Report" Icon = "Report"
AssignmentsType = "deviceHealthScriptAssignments" AssignmentsType = "deviceHealthScriptAssignments"
AssignmentProperties = @("target","runSchedule","runRemediationScript")
PropertiesToRemoveForUpdate = @('version','isGlobalScript','highestAvailableVersion') PropertiesToRemoveForUpdate = @('version','isGlobalScript','highestAvailableVersion')
}) })
@@ -686,6 +719,7 @@ function Invoke-InitializeModule
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
PreFilesImportCommand = { Start-PreFilesImportADMXFiles @args } PreFilesImportCommand = { Start-PreFilesImportADMXFiles @args }
PreImportCommand = { Start-PreImportADMXFiles @args } PreImportCommand = { Start-PreImportADMXFiles @args }
PostImportCommand = { Start-PostImportADMXFiles @args }
PreDeleteCommand = { Start-PreDeleteADMXFiles @args } PreDeleteCommand = { Start-PreDeleteADMXFiles @args }
ViewProperties = @("fileName","status","Id") ViewProperties = @("fileName","status","Id")
PropertiesToRemove = @("languageCodes","targetPrefix","targetNamespace","policyType","revision","status","uploadDateTime") PropertiesToRemove = @("languageCodes","targetPrefix","targetNamespace","policyType","revision","status","uploadDateTime")
@@ -733,13 +767,60 @@ function Invoke-InitializeModule
Icon = "ConditionalAccess" Icon = "ConditionalAccess"
GroupId = "EndpointSecurity" GroupId = "EndpointSecurity"
}) })
Add-ViewItem (New-Object PSObject -Property @{
Title = "Authentication Context"
Id = "AuthenticationContext"
ViewID = "IntuneGraphAPI"
API = "/identity/conditionalAccess/authenticationContextClassReferences"
PropertiesToRemove = @("@odata.type")
SkipRemoveProperties = @('Id')
ImportOrder = 46
PreImportCommand = { Start-PreImportCommandAuthenticationContext @args }
Permissons=@("Policy.ReadWrite.ConditionalAccess")
ExpandAssignmentsList = $false
Icon = "ConditionalAccess"
GroupId = "EndpointSecurity"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "W365 Provisioning Policies"
Id = "W365ProvisioningPolicies"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/virtualEndpoint/provisioningPolicies"
Permissons=@("CloudPC.ReadWrite.All")
Icon = "Devices"
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "W365 User Settings"
Id = "W365UserSettings"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/virtualEndpoint/userSettings"
Permissons = @("CloudPC.ReadWrite.All")
Icon = "Devices"
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Driver Update Profiles"
Id = "DriverUpdateProfiles"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/windowsDriverUpdateProfiles"
Permissons = @("DeviceManagementConfiguration.ReadWrite.All")
Icon = "UpdatePolicies"
GroupId = "WinDriverUpdatePolicies"
})
} }
function Invoke-EMAuthenticateToMSAL function Invoke-EMAuthenticateToMSAL
{ {
$global:EMViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM" param($params = @{})
$global:EMViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM"
Set-MSALCurrentApp $global:EMViewObject.AppInfo Set-MSALCurrentApp $global:EMViewObject.AppInfo
& $global:msalAuthenticator.Login -Account (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser")) & $global:msalAuthenticator.Login -Account (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser")) @params
} }
function Invoke-EMDeactivateView function Invoke-EMDeactivateView
@@ -753,7 +834,7 @@ function Invoke-EMActivatingView
Show-MSALError Show-MSALError
# Refresh values in case they have changed # Refresh values in case they have changed
$global:EMViewObject.AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM") $global:EMViewObject.AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM")
if(-not $global:EMViewObject.Authentication) if(-not $global:EMViewObject.Authentication)
{ {
$global:EMViewObject.Authentication = Get-MSALAuthenticationObject $global:EMViewObject.Authentication = Get-MSALAuthenticationObject
@@ -765,7 +846,7 @@ function Invoke-EMActivatingView
function Invoke-EMSaveSettings function Invoke-EMSaveSettings
{ {
$tmpApp = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" $tmpApp = Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp
if($global:appObj.ClientID -ne $tmpApp.ClientId -and $global:MSALToken) if($global:appObj.ClientID -ne $tmpApp.ClientId -and $global:MSALToken)
{ {
@@ -784,6 +865,8 @@ function Invoke-EMSaveSettings
function Invoke-GraphAuthenticationUpdated function Invoke-GraphAuthenticationUpdated
{ {
Set-EMUIStatus Set-EMUIStatus
$script:CustomADMXDefinitions = $null
} }
function Set-EMUIStatus function Set-EMUIStatus
@@ -1064,7 +1147,7 @@ function Start-PostExportEndpointSecurity
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
$fileName = (Get-GraphObjectName $obj $objectType) $fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id) if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
{ {
$fileName = ($fileName + "_" + $obj.Id) $fileName = ($fileName + "_" + $obj.Id)
@@ -1938,24 +2021,44 @@ function local:Start-ImportApp
if($appType -eq "microsoft.graph.win32LobApp") if($appType -eq "microsoft.graph.win32LobApp")
{ {
Copy-Win32LOBPackage $packageFile $obj $fileEncryptionInfo = Copy-Win32LOBPackage $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.windowsMobileMSI") elseif($appType -eq "microsoft.graph.windowsMobileMSI")
{ {
Copy-MSILOB $packageFile $obj $fileEncryptionInfo = Copy-MSILOB $packageFile $obj
}
elseif($appType -eq "microsoft.graph.windowsUniversalAppX")
{
$fileEncryptionInfo = Copy-MSIXLOB $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.iosLOBApp") elseif($appType -eq "microsoft.graph.iosLOBApp")
{ {
Copy-iOSLOB $packageFile $obj $fileEncryptionInfo = Copy-iOSLOB $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.androidLOBApp") elseif($appType -eq "microsoft.graph.androidLOBApp")
{ {
Copy-AndroidLOB $packageFile $obj $fileEncryptionInfo = Copy-AndroidLOB $packageFile $obj
} }
else else
{ {
Write-Log "Unsupported application type $appType. File will not be uploaded" 2 Write-Log "Unsupported application type $appType. File will not be uploaded" 2
} }
if((Get-SettingValue "EMSaveEncryptionFile") -eq $true)
{
if($fileEncryptionInfo)
{
$jsonEncryptionInfo = $fileEncryptionInfo | ConvertTo-Json -Depth 10
$pkgPath = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
if($pkgPath -and [IO.Directory]::Exists($pkgPath))
{
$obj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.id)" -ODataMetadata "Minimal"
$fullPath = $pkgPath + "\$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion).json"
$jsonEncryptionInfo | Out-File -FilePath $fullPath -Force -Encoding utf8
}
}
}
} }
function Start-PreUpdateApplication function Start-PreUpdateApplication
@@ -2045,6 +2148,101 @@ function Add-DetailExtensionApplications
$tmp.Children.Insert($index, $btnUpload) $tmp.Children.Insert($index, $btnUpload)
} }
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Download'
$btnDownload.Name = 'btnDownloadAppfile'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Write-Status "Download file"
$obj = $global:dgObjects.SelectedItem.Object
#$obj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.id)"
$pkgPath = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
$dlgSave = [System.Windows.Forms.SaveFileDialog]::new()
$dlgSave.InitialDirectory = $pkgPath
$dlgSave.FileName = ($obj.FileName + ".encrypted")
$dlgSave.DefaultExt = "*.encrypted"
$dlgSave.Filter = "Encrypted intunewin (*.encrypted)|*.encrypted|All files (*.*)|*.*"
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
$contentFileObj = Start-DownloadAppContent $obj $dlgSave.FileName
if([IO.File]::Exists($dlgSave.FileName))
{
$fullPath = Find-AppEncryptionFile $obj $contentFileObj $pkgPath
if([IO.File]::Exists($fullPath) -eq $false)
{
if(([System.Windows.MessageBox]::Show("Could not find decryption file for $($obj.displayName)`nApp Id: $($obj.id)`nContent version $($obj.committedContentVersion)`n`nDo you want to browse for the file?", "Encryption file not found", "YesNo", "Warning")) -eq "Yes")
{
$of = [System.Windows.Forms.OpenFileDialog]::new()
$of.InitialDirectory = $pkgPath
$of.DefaultExt = "*.json"
$of.Filter = "Json (*.json)|*.json"
$of.Multiselect = $false
if($of.ShowDialog() -eq "OK")
{
$fullPath = $of.FileName
}
}
}
if([IO.File]::Exists($fullPath))
{
Write-Status "Decrypting file"
$encryptionInfo = ConvertFrom-Json (Get-Content -Path $fullPath -Raw)
if($encryptionInfo.fileEncryptionInfo)
{
$encryptionInfo = $encryptionInfo.fileEncryptionInfo
}
$destination = $pkgPath + "\$($obj.FileName)"
Start-DecryptFile $dlgSave.Filename $destination $encryptionInfo.encryptionKey $encryptionInfo.initializationVector
try { [IO.File]::Delete($dlgSave.Filename) }
catch {
Write-LogError "Failed to delete exported encrypted file" $_.Exception
}
}
else
{
Write-Log "Decryption file for $($obj.displayName) not found. Skipping decryption" 2
}
}
}
Write-Status ""
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
}
function Find-AppEncryptionFile
{
param($obj, $contentFileObj, $rootFolders)
$search = @()
$search += "$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion)"
$search += "$([IO.Path]::GetFileNameWithoutExtension($obj.fileName))_$($contentFileObj.size)"
$search += "$($obj.displayName)_$($contentFileObj.size)"
foreach($rootFolder in $rootFolders)
{
foreach($searchName in $search)
{
$fullName = ($rootFolder + "\$($searchName).json")
if([IO.File]::Exists($fullName))
{
return $fullName
}
}
}
} }
function Start-PreImportAssignmentsApplications function Start-PreImportAssignmentsApplications
@@ -2060,6 +2258,29 @@ function Start-PreImportAssignmentsApplications
} }
@{"Assignments"=$assignments} @{"Assignments"=$assignments}
} }
elseif($obj.'@odata.type' -eq "#microsoft.graph.winGetApp")
{
Write-LogDebug "Wait for app to be published"
$i = 2
Start-Sleep -s ($i)
$x = 0
while($x -lt 10)
{
###!!!
$appInfo = Invoke-GraphRequest -Url "$($objectType.API)/$($obj.id)" -ODataMetadata "skip"
if($appInfo.publishingState -eq "Published")
{
Write-LogDebug "Application $($obj.displayName) is published"
return
}
Start-Sleep -s ($i)
$x++
if($x -ge 5) { $i++ }
}
Write-Log "Application '$($obj.displayName)' is not published. Skipping assignment" 2
@{"Import"=$false}
}
} }
function Start-PreDeleteApplications function Start-PreDeleteApplications
@@ -2107,6 +2328,47 @@ function Start-PostExportApplications
Write-LogError "Failed to export scripts" $_.Exception Write-LogError "Failed to export scripts" $_.Exception
} }
} }
Save-Setting "Intune" "ExportAppFile" $global:chkExportApplicationFile.IsChecked
if($global:chkExportApplicationFile.IsChecked)
{
$encryptionSource = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
$pkgPath = $path
if($pkgPath)
{
Write-Status "Download file"
$exportFile = $pkgPath + "\$($obj.FileName).encrypted"
$contentFileObj = Start-DownloadAppContent $obj $exportFile -GetContentFileInfoOnly
$encryptionFile = Find-AppEncryptionFile $obj $contentFileObj $encryptionSource
if($encryptionFile -and [IO.File]::Exists($encryptionFile))
{
Start-DownloadFile $contentFileObj.azureStorageUri $exportFile
if([IO.File]::Exists($exportFile))
{
Write-Status "Decrypting file"
$encryptionInfo = ConvertFrom-Json (Get-Content -Path $encryptionFile -Raw)
if($encryptionInfo.fileEncryptionInfo)
{
$encryptionInfo = $encryptionInfo.fileEncryptionInfo
}
$destination = $pkgPath + "\$($obj.FileName)"
Start-DecryptFile $exportFile $destination $encryptionInfo.encryptionKey $encryptionInfo.initializationVector
}
try { [IO.File]::Delete($exportFile) }
catch {
Write-LogError "Failed to delete exported encrypted file" $_.Exception
}
}
else
{
Write-Log "Cound not file encryption file"
}
}
}
} }
function Start-PostListApplications function Start-PostListApplications
@@ -2134,6 +2396,177 @@ function Start-PostListApplications
$objList $objList
} }
function Add-ScriptExportApplications
{
param($form, $buttonPanel, $index = 0)
Add-ScriptExportExtensions $form $buttonPanel $index
$ctrl = $form.FindName("chkExportApplicationFile")
if(-not $ctrl)
{
$xaml = @"
<StackPanel $($global:wpfNS) Orientation="Horizontal" Margin="0,0,5,0">
<Label Content="Export application file" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Export the application file. Note: Application file will only be exported if ecryption file is found." />
</StackPanel>
"@
$label = [Windows.Markup.XamlReader]::Parse($xaml)
$global:chkExportApplicationFile = [System.Windows.Controls.CheckBox]::new()
$global:chkExportApplicationFile.IsChecked = ((Get-Setting "Intune" "ExportAppFile" "false") -eq "true")
$global:chkExportApplicationFile.VerticalAlignment = "Center"
$global:chkExportApplicationFile.Name = "chkExportApplicationFile"
@($label, $global:chkExportApplicationFile)
}
}
function Start-PostGetApplications {
param($obj, $objectType)
if($obj.Object.dependentAppCount -is [Int] -and ($obj.Object.dependentAppCount -gt 0 -or $obj.Object.supersededAppCount -gt 0)) {
$relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value
$dependencyApps = @()
$supersededApps = @()
foreach ($rel in $relationships) {
if ($rel."@odata.type" -eq "#microsoft.graph.mobileAppDependency") {
$dependencyApps += "$($rel.targetDisplayName)|!|$($rel.targetDisplayVersion)|!|$($rel.targetId)|!|$($rel.dependencyType)"
}
elseif ($rel."@odata.type" -eq "#microsoft.graph.mobileAppSupersedence") {
$supersededApps += "$($rel.targetDisplayName)|!|$($rel.targetDisplayVersion)|!|$($rel.targetId)|!|$($rel.supersedenceType)"
}
}
if ($dependencyApps.Count -gt 0) {
$obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefDependency" -Value ($dependencyApps -join "|*|")
}
if ($supersededApps.Count -gt 0) {
$obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefSupersedence" -Value ($supersededApps -join "|*|")
}
}
}
function Start-PostImportApplications
{
param($obj, $objectType, $file)
#$tmpObj = Get-GraphObjectFromFile $file
}
function Start-PostFilesImportApplications
{
param($objType, $importedObjects, $importedFiles)
$refObjects = $importedFiles | Where { $null -ne $_.Object."#CustomRefDependency" -or $null -ne $_.Object."#CustomRefSupersedence" }
if(($refObjects | measure).Count -gt 0)
{
Write-Log "Applicetions with Depnedency or Supersedence detected"
foreach($file in $refObjects)
{
Add-ApplicationReferences $file.ImportedObject $file.Object
}
}
}
function local:Add-ApplicationReferences
{
param($obj, $fileObj)
if($fileObj."#CustomRefDependency" -or $fileObj."#CustomRefSupersedence")
{
Write-Log "Adding app references for $($obj.displayName)"
$depAppsInfo = $fileObj."#CustomRefDependency"
$supAppsInfo = $fileObj."#CustomRefSupersedence"
$releationShips = [PSCustomObject]@{
relationships = @()
}
if($depAppsInfo)
{
foreach($depApp in ($depAppsInfo -split "[|][*][|]"))
{
$appName, $appVer, $appId, $appType = $depApp -split "[|][!][|]"
if(-not $appName -or -not $appVer)
{
Write-Log "Could not get Name and Version from string: $appApp" 2
continue
}
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
if(-not $tmpApps)
{
Write-Log "No application found with name $appName" 2
continue
}
$tmpApp = $tmpApps | Where displayVersion -eq $appVer
if(-not $tmpApp)
{
Write-Log "No $appName application found with version $appVer" 2
continue
}
elseif(-not ($tmpApp | measure).Count -gt 1)
{
Write-Log "Multiple $appName application found with version $appVer" 2
continue
}
Write-Log "Add $appName ($appVer) to Dependency list"
$releationShips.relationships += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.mobileAppDependency"
targetId = $tmpApp.Id
dependencyType = $appType
}
}
}
if($supAppsInfo)
{
foreach($suppApp in ($supAppsInfo -split "[|][*][|]"))
{
$appName, $appVer, $appId, $appType = $suppApp -split "[|][!][|]"
if(-not $appName -or -not $appVer)
{
Write-Log "Could not get Name and Version from string: $appApp" 2
continue
}
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
if(-not $tmpApps)
{
Write-Log "No application found with name $appName" 2
continue
}
$tmpApp = $tmpApps | Where displayVersion -eq $appVer
if(-not $tmpApp)
{
Write-Log "No $appName application found with version $appVer" 2
continue
}
elseif(-not ($tmpApp | measure).Count -gt 1)
{
Write-Log "Multiple $appName application found with version $appVer" 2
continue
}
Write-Log "Add $appName ($appVer) to Supersedence list"
$releationShips.relationships += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.mobileAppSupersedence"
targetId = $tmpApp.Id
supersedenceType = $appType
}
}
}
if($releationShips.relationships.Count -gt 0)
{
$json = Update-JsonForEnvironment (ConvertTo-Json $releationShips -Depth 20)
Write-Log "Update app references"
Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/updateRelationships" -Method "POST" -Body $json
}
}
}
#endregion #endregion
#region Group Policy/Administrative Templates functions #region Group Policy/Administrative Templates functions
@@ -2143,6 +2576,13 @@ function Get-GPOObjectSettings
$gpoSettings = @() $gpoSettings = @()
if ($GPOObj.policyConfigurationIngestionType -eq "unknown") {
$tmpObj = (Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations?`$filter=id eq '$($GPOObj.id)'").value[0]
if ($tmpObj.policyConfigurationIngestionType) {
$GPOObj.policyConfigurationIngestionType = $tmpObj.policyConfigurationIngestionType
}
}
# Get all configured policies in the Administrative Templates profile # Get all configured policies in the Administrative Templates profile
$GPODefinitionValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues?`$expand=definition" -ODataMetadata "skip" $GPODefinitionValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues?`$expand=definition" -ODataMetadata "skip"
foreach($definitionValue in $GPODefinitionValues.value) foreach($definitionValue in $GPODefinitionValues.value)
@@ -2156,7 +2596,7 @@ function Get-GPOObjectSettings
"definition@odata.bind" = "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')" "definition@odata.bind" = "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')"
} }
if($GPOObj.policyConfigurationIngestionType -eq "Custom") if($definitionValue.definition.categoryPath)
{ {
$obj.Add("#Definition_Id", $definitionValue.definition.id) $obj.Add("#Definition_Id", $definitionValue.definition.id)
$obj.Add("#Definition_displayName", $definitionValue.definition.displayName) $obj.Add("#Definition_displayName", $definitionValue.definition.displayName)
@@ -2174,7 +2614,7 @@ function Get-GPOObjectSettings
# Add presentation@odata.bind property that links the value to the presentation object # Add presentation@odata.bind property that links the value to the presentation object
$presentationValue | Add-Member -MemberType NoteProperty -Name "presentation@odata.bind" -Value "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')/presentations('$($presentationValue.presentation.id)')" $presentationValue | Add-Member -MemberType NoteProperty -Name "presentation@odata.bind" -Value "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')/presentations('$($presentationValue.presentation.id)')"
if($GPOObj.policyConfigurationIngestionType -eq "Custom") if($definitionValue.definition.categoryPath)
{ {
$presentationValue | Add-Member -MemberType NoteProperty -Name "#Presentation_Id" -Value $presentationValue.presentation.id $presentationValue | Add-Member -MemberType NoteProperty -Name "#Presentation_Id" -Value $presentationValue.presentation.id
$presentationValue | Add-Member -MemberType NoteProperty -Name "#Presentation_Label" -Value $presentationValue.presentation.label $presentationValue | Add-Member -MemberType NoteProperty -Name "#Presentation_Label" -Value $presentationValue.presentation.label
@@ -2198,15 +2638,15 @@ function Get-GPOObjectSettings
function Import-GPOSetting function Import-GPOSetting
{ {
param($obj, $settings, [switch]$CustomADMX) param($obj, $settings)
if($obj) if($obj)
{ {
Write-Status "Import settings for $($obj.displayName)" Write-Status "Import settings for $($obj.displayName)"
$isCustomADMX = $CustomADMX -eq $true $hasCustomADMX = $null -ne ($settings | Where { $null -ne $_.'#Definition_categoryPath' })
if($isCustomADMX) if($hasCustomADMX)
{ {
Write-Status "Import custom ADMX settings" Write-Status "Import custom ADMX settings"
if(-not $script:CustomADMXDefinitions) if(-not $script:CustomADMXDefinitions)
@@ -2225,8 +2665,13 @@ function Import-GPOSetting
Category = $tmpCat Category = $tmpCat
Presentations = $null Presentations = $null
} }
try {
$script:CustomADMXDefinitions.Add($key, $val) $script:CustomADMXDefinitions.Add($key, $val)
} }
catch {
Write-Log "Failed to add '$($tmpDef.displayName)' in category '$($tmpDef.categoryPath)' of class $($tmpDef.classType)" 3
}
}
} }
} }
} }
@@ -2234,7 +2679,7 @@ function Import-GPOSetting
foreach($setting in $settings) foreach($setting in $settings)
{ {
if($isCustomADMX -and $script:CustomADMXDefinitions -is [HashTable] -and $script:CustomADMXDefinitions.Count -gt 0) if($setting.'#Definition_categoryPath' -and $script:CustomADMXDefinitions -is [HashTable] -and $script:CustomADMXDefinitions.Count -gt 0)
{ {
$defVal = $null $defVal = $null
$key = ($setting.'#Definition_displayName' + $setting.'#Definition_categoryPath' + $setting.'#Definition_classType').ToLower() $key = ($setting.'#Definition_displayName' + $setting.'#Definition_categoryPath' + $setting.'#Definition_classType').ToLower()
@@ -2289,7 +2734,7 @@ function Import-GPOSetting
Write-Log "Settings might not be available if imported in another environment" 3 Write-Log "Settings might not be available if imported in another environment" 3
} }
} }
elseif($isCustomADMX) elseif($setting.'#Definition_categoryPath')
{ {
Write-Log "Custom AMDX settings cannot be imported without ADMX file imported. Definitions not found" 2 Write-Log "Custom AMDX settings cannot be imported without ADMX file imported. Definitions not found" 2
continue continue
@@ -2297,7 +2742,7 @@ function Import-GPOSetting
Start-GraphPreImport $setting Start-GraphPreImport $setting
if($true) #$isCustomADMX) if($true)
{ {
foreach($tmpProp in (($setting.PSObject.Properties | Where Name -like "#*").Name)) foreach($tmpProp in (($setting.PSObject.Properties | Where Name -like "#*").Name))
{ {
@@ -2323,7 +2768,7 @@ function Start-PostExportAdministrativeTemplate
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
$fileName = (Get-GraphObjectName $obj $objectType) $fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id) if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
{ {
$fileName = ($fileName + "_" + $obj.Id) $fileName = ($fileName + "_" + $obj.Id)
@@ -2362,7 +2807,7 @@ function Start-PostFileImportAdministrativeTemplate
{ {
$tmpObj = Get-GraphObjectFromFile $file $tmpObj = Get-GraphObjectFromFile $file
Import-GPOSetting $obj $settings -CustomADMX:($tmpObj.policyConfigurationIngestionType -eq "Custom") Import-GPOSetting $obj $settings
} }
} }
@@ -2587,7 +3032,7 @@ function Start-PostExportRoleDefinitions
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
$fileName = (Get-GraphObjectName $obj $objectType) $fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id) if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
{ {
$fileName = ($fileName + "_" + $obj.Id) $fileName = ($fileName + "_" + $obj.Id)
@@ -3087,7 +3532,9 @@ function Add-EMAssignmentsToExportFile
{ {
param($obj, $objectType, $path, $Url = "") param($obj, $objectType, $path, $Url = "")
$fileName = (Get-GraphObjectName $obj $objectType) if($global:chkExportAssignments.IsChecked -ne $true) { return }
$fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id) if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
{ {
$fileName = ($fileName + "_" + $obj.Id) $fileName = ($fileName + "_" + $obj.Id)
@@ -3194,6 +3641,11 @@ function Add-ConditionalAccessImportExtensions
$label = [Windows.Markup.XamlReader]::Parse($xaml) $label = [Windows.Markup.XamlReader]::Parse($xaml)
$CAStates = @() $CAStates = @()
$CAStates += [PSCustomObject]@{
Name = "As Exported - Change On to Report-only"
Value = "AsExportedReportOnly"
}
$CAStates += [PSCustomObject]@{ $CAStates += [PSCustomObject]@{
Name = "As Exported" Name = "As Exported"
Value = "AsExported" Value = "AsExported"
@@ -3218,7 +3670,7 @@ function Add-ConditionalAccessImportExtensions
$global:cbImportCAState.DisplayMemberPath = "Name" $global:cbImportCAState.DisplayMemberPath = "Name"
$global:cbImportCAState.SelectedValuePath = "Value" $global:cbImportCAState.SelectedValuePath = "Value"
$global:cbImportCAState.ItemsSource = $CAStates $global:cbImportCAState.ItemsSource = $CAStates
$global:cbImportCAState.SelectedValue = "AsExported" $global:cbImportCAState.SelectedValue = "disabled"
$global:cbImportCAState.Margin="0,5,0,0" $global:cbImportCAState.Margin="0,5,0,0"
$global:cbImportCAState.HorizontalAlignment="Left" $global:cbImportCAState.HorizontalAlignment="Left"
$global:cbImportCAState.Width=250 $global:cbImportCAState.Width=250
@@ -3231,10 +3683,15 @@ function Start-PreImportConditionalAccess
{ {
param($obj, $objectType, $file, $assignments) param($obj, $objectType, $file, $assignments)
if($global:cbImportCAState.SelectedValue -and $global:cbImportCAState.SelectedValue -ne "AsExported") if ($global:cbImportCAState.SelectedValue -and $global:cbImportCAState.SelectedValue -ne "AsExported") {
{ if ($global:cbImportCAState.SelectedValue -eq "AsExportedReportOnly" -and $obj.state -eq "enabled") {
Write-Log "Change Enabled policy to Report-only"
$obj.state = "enabledForReportingButNotEnforced"
}
else {
$obj.state = $global:cbImportCAState.SelectedValue $obj.state = $global:cbImportCAState.SelectedValue
} }
}
if($obj.grantControls.authenticationStrength) if($obj.grantControls.authenticationStrength)
{ {
@@ -3246,6 +3703,11 @@ function Start-PreImportConditionalAccess
} }
$obj.grantControls.authenticationStrength = $authSetting $obj.grantControls.authenticationStrength = $authSetting
} }
if($obj.sessionControls.disableResilienceDefaults -eq $false)
{
$obj.sessionControls.disableResilienceDefaults = $null
}
} }
function Start-PostExportConditionalAccess function Start-PostExportConditionalAccess
@@ -3400,10 +3862,13 @@ function Start-PreImportADMXFiles
return return
} }
$bytes = [IO.File]::ReadAllBytes($admxFile) #$bytes = [IO.File]::ReadAllBytes($admxFile)
$bytes = Get-ASCIIBytes ([IO.File]::ReadAllText($admxFile))
$obj.content = [Convert]::ToBase64String($bytes) $obj.content = [Convert]::ToBase64String($bytes)
$bytes = [IO.File]::ReadAllBytes($admlFile) #$bytes = [IO.File]::ReadAllBytes($admlFile)
$bytes = Get-ASCIIBytes ([IO.File]::ReadAllText($admlFile))
$obj.groupPolicyUploadedLanguageFiles += [PSCustomObject]@{ $obj.groupPolicyUploadedLanguageFiles += [PSCustomObject]@{
fileName = [io.path]::GetFileName($admlFile) fileName = [io.path]::GetFileName($admlFile)
content = [Convert]::ToBase64String($bytes) content = [Convert]::ToBase64String($bytes)
@@ -3412,6 +3877,13 @@ function Start-PreImportADMXFiles
$obj.defaultLanguageCode = "" $obj.defaultLanguageCode = ""
} }
function Start-PostImportADMXFiles
{
param($obj, $objectType, $file)
$script:CustomADMXDefinitions = $null
}
function Start-PreDeleteADMXFiles function Start-PreDeleteADMXFiles
{ {
param($obj, $objectType) param($obj, $objectType)
@@ -3455,4 +3927,15 @@ function Start-PreImportCommandAuthenticationStrengths
} }
#endregion #endregion
#region Authentication Strength
function Start-PreImportCommandAuthenticationContext
{
param($obj, $objectType, $file, $assignments)
#@{ "Method" = "PATCH" }
}
#endregion
Export-ModuleMember -alias * -function * Export-ModuleMember -alias * -function *
+57 -3
View File
@@ -10,7 +10,7 @@ This module is for the Endpoint Info View. It shows read-only objects in Intune
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.5.0' '3.9.6'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -22,11 +22,12 @@ function Invoke-InitializeModule
ID = "EMInfoGraphAPI" ID = "EMInfoGraphAPI"
ViewPanel = $viewPanel ViewPanel = $viewPanel
AuthenticationID = "MSAL" AuthenticationID = "MSAL"
AllowDelete = $false
ItemChanged = { Show-GraphObjects -ObjectTypeChanged; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""} ItemChanged = { Show-GraphObjects -ObjectTypeChanged; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""}
Activating = { Invoke-EMInfoActivatingView } Activating = { Invoke-EMInfoActivatingView }
Authentication = (Get-MSALAuthenticationObject) Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMInfoAuthenticateToMSAL } Authenticate = { Invoke-EMInfoAuthenticateToMSAL }
AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM") AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM")
SaveSettings = { Invoke-EMSaveSettings } SaveSettings = { Invoke-EMSaveSettings }
Permissions = @() Permissions = @()
}) })
@@ -87,6 +88,24 @@ function Invoke-InitializeModule
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All") Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{
Title = "Tenant Settings"
Id = "TenantSettings"
ViewID = "EMInfoGraphAPI"
API = "deviceManagement/settings"
NameProperty = "Name"
AlwaysImport = $true
#ExportFullObject = $true
ViewProperties = @("Name")
ShowButtons = @("Import","Export","View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
PreImportCommand = { Start-PreImportTenantSettings @args }
GetObjectName = { Start-GetObjectNameTenantSettings @args }
PostListCommand = { Start-PostListTenantSettings @args }
Icon="TenantSettings"
ExpandAssignmentsList = $false
})
} }
function Invoke-EMInfoActivatingView function Invoke-EMInfoActivatingView
@@ -100,7 +119,7 @@ function Invoke-EMInfoActivatingView
function Invoke-EMInfoAuthenticateToMSAL function Invoke-EMInfoAuthenticateToMSAL
{ {
$global:EMInfoViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM" $global:EMInfoViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM"
Set-MSALCurrentApp $global:EMInfoViewObject.AppInfo Set-MSALCurrentApp $global:EMInfoViewObject.AppInfo
$usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser")) $usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser"))
if($usr) if($usr)
@@ -108,3 +127,38 @@ function Invoke-EMInfoAuthenticateToMSAL
& $global:msalAuthenticator.Login -Account $usr & $global:msalAuthenticator.Login -Account $usr
} }
} }
function Start-PreImportTenantSettings
{
param($obj, $objectType)
$objClone = $obj | ConvertTo-Json -Depth 50 | ConvertFrom-Json
if($objClone.deviceComplianceCheckinThresholdDays -lt 1)
{
$objClone.deviceComplianceCheckinThresholdDays = 30
}
Remove-Property $objClone "@odata.type"
$json = @{ "settings" = $objClone } | ConvertTo-Json -Depth 50
(Invoke-GraphRequest -Url "deviceManagement" -Content $json -HttpMethod "PATCH") | Out-Null
return (@{"Import"=$false})
}
function Start-GetObjectNameTenantSettings
{
param($objList, $objectType)
return "Tenant Settings"
}
function Start-PostListTenantSettings
{
param($objList, $objectType)
if(($objList | measure).Count -eq 1)
{
$objList[0].Name = "Tenant Settings"
#$objList[0] | Add-Member -MemberType NoteProperty -Name "SettingName" -Value "Tenant Settings"
}
$objList
}
+201 -17
View File
@@ -10,7 +10,7 @@ This module manages Application objects in Intune e.g. uploading application fil
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.7.4' '3.9.6'
} }
######################################################################################### #########################################################################################
@@ -94,14 +94,18 @@ function Copy-MSILOB
$tmpFile = [IO.Path]::GetTempFileName() $tmpFile = [IO.Path]::GetTempFileName()
$msiInfo = Get-MSIFileInformation $msiFile @("ProductName", "ProductCode", "ProductVersion", "ProductLanguage") $msiInfo = Get-MSIFileInformation $msiFile @("ProductName", "ProductCode", "ProductVersion", "ProductLanguage", "UpgradeCode", "ALLUSERS")
if(-not $msiInfo) { return } if(-not $msiInfo) { return }
$fileEncryptionInfo = New-IntuneEncryptedFile $msiFile $tmpFile $fileEncryptionInfo = New-IntuneEncryptedFile $msiFile $tmpFile
[xml]$manifestXML = '<MobileMsiData MsiExecutionContext="Any" MsiRequiresReboot="false" MsiUpgradeCode="" MsiIsMachineInstall="true" MsiIsUserInstall="false" MsiIncludesServices="false" MsiContainsSystemRegistryKeys="false" MsiContainsSystemFolders="false"></MobileMsiData>' [xml]$manifestXML = '<MobileMsiData MsiExecutionContext="Any" MsiRequiresReboot="false" MsiUpgradeCode="" MsiIsMachineInstall="true" MsiIsUserInstall="false" MsiIncludesServices="false" MsiContainsSystemRegistryKeys="false" MsiContainsSystemFolders="false"></MobileMsiData>'
$manifestXML.MobileMsiData.MsiUpgradeCode = $msiInfo["ProductCode"] $manifestXML.MobileMsiData.MsiUpgradeCode = $msiInfo["UpgradeCode"]
if($msiInfo["ALLUSERS"] -eq 1)
{
$manifestXML.MobileMsiData.MsiExecutionContext = "System"
}
$appFileBody = @{ $appFileBody = @{
"@odata.type" = "#microsoft.graph.mobileAppContentFile" "@odata.type" = "#microsoft.graph.mobileAppContentFile"
@@ -109,11 +113,50 @@ function Copy-MSILOB
size = (Get-Item $msiFile).Length size = (Get-Item $msiFile).Length
sizeEncrypted = (Get-Item $tmpFile).Length sizeEncrypted = (Get-Item $tmpFile).Length
manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifestXML.OuterXml)) manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifestXML.OuterXml))
isDependency = $false
} }
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
}
function Copy-MSIXLOB
{
param($msixFile, $appObj)
if(-not $msixFile -or (Test-Path $msixFile) -eq $false)
{
return
}
$fi = [IO.FileInfo]$msixFile
$appId = $appObj.Id
$appType = $appObj.'@odata.type'.Trim('#')
$tmpFile = [IO.Path]::GetTempFileName()
$fileEncryptionInfo = New-IntuneEncryptedFile $msixFile $tmpFile
$manifest = $fi.Name
$appFileBody = @{
"@odata.type" = "#microsoft.graph.mobileAppContentFile"
name = [IO.Path]::GetFileName($msixFile)
size = (Get-Item $msixFile).Length
sizeEncrypted = (Get-Item $tmpFile).Length
manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifest))
isDependency = $false
}
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-iOSLOB function Copy-iOSLOB
@@ -149,6 +192,8 @@ function Copy-iOSLOB
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-AndroidLOB function Copy-AndroidLOB
@@ -185,6 +230,8 @@ function Copy-AndroidLOB
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-Win32LOBPackage function Copy-Win32LOBPackage
@@ -235,7 +282,7 @@ function Copy-Win32LOBPackage
$fileBody = @{ $fileBody = @{
"@odata.type" = "#microsoft.graph.mobileAppContentFile" "@odata.type" = "#microsoft.graph.mobileAppContentFile"
name = $DetectionXML.ApplicationInfo.FileName name = "IntunePackage.intunewin"
size = [int64]$DetectionXML.ApplicationInfo.UnencryptedContentSize size = [int64]$DetectionXML.ApplicationInfo.UnencryptedContentSize
sizeEncrypted = (Get-Item $tmpIntunewinFile).Length sizeEncrypted = (Get-Item $tmpIntunewinFile).Length
manifest = $null manifest = $null
@@ -246,45 +293,58 @@ function Copy-Win32LOBPackage
# Remove extracted inintunewin file # Remove extracted inintunewin file
Remove-Item $tmpIntunewinPath -Force -Recurse Remove-Item $tmpIntunewinPath -Force -Recurse
$fileEncryptionInfo
} }
function Add-FileToIntuneApp function Add-FileToIntuneApp
{ {
param($appId, $appType, $appFile, $fileBody) param($appId, $appType, $appFile, $fileBody)
$contentVersion = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions" -HttpMethod POST -Content "{}" $contentVersion = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions" -HttpMethod POST -Content "{}" -ODataMetadata "Minimal"
$contentVersionId = $contentVersion.id $contentVersionId = $contentVersion.id
$fileObj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files" -HttpMethod POST -Content (ConvertTo-Json $fileBody -Depth 5) $fileObj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files" -HttpMethod POST -Content (ConvertTo-Json $fileBody -Depth 5) -ODataMetadata "Minimal"
if(-not $fileObj) if(-not $fileObj)
{ {
return return
} }
Write-Log "File object created. ID: $($fileObj.id)"
# Wait for Azure storage URI # Wait for Azure storage URI
$fileObj = Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "AzureStorageUriRequest" $fileObj = Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "AzureStorageUriRequest"
if(-not $fileObj) if(-not $fileObj)
{ {
Write-Log "No File Object returned from commit. Upload failed" 3
return return
} }
# Upload file # Upload file
Send-IntuneFileToAzureStorage $fileObj.azureStorageUri $appFile "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" Send-IntuneFileToAzureStorage $fileObj.azureStorageUri $appFile "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" | Out-Null
# Commit the file # Commit the file
$reponse = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)/commit" -HttpMethod POST -Content (ConvertTo-Json $fileEncryptionInfo -Depth 5) Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)/commit" -HttpMethod POST -Content (ConvertTo-Json $fileEncryptionInfo -Depth 5) | Out-Null
Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "CommitFile" Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "CommitFile" | Out-Null
$fiUpload = [IO.FileInfo]$appFile
# Commit the content version # Commit the content version
$commitAppBody = @{ $commitAppBody = @{
"@odata.type" = "#$appType" "@odata.type" = "#$appType"
committedContentVersion = $contentVersionId committedContentVersion = $contentVersionId
fileName = $fiUpload.Name
} }
$reponse = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId" -HttpMethod PATCH -Content (ConvertTo-Json $commitAppBody -Depth 5) # if($fileBody.Name) {
# $fileUploadName = $fileBody.Name
# }
# else {
$fiUpload = [IO.FileInfo]$appFile
$fileUploadName = $fiUpload.Name
# }
$commitAppBody.Add("fileName",$fileUploadName)
Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId" -HttpMethod PATCH -Content (ConvertTo-Json $commitAppBody -Depth 5) | Out-Null
Write-Log "Upload finished for file $fileUploadName version $contentVersionId"
} }
function Wait-IntuneFileState function Wait-IntuneFileState
@@ -318,7 +378,7 @@ function Wait-IntuneFileState
return return
} }
Start-Sleep -s 5 Start-Sleep -Seconds 1
} }
if($succes -eq $false) if($succes -eq $false)
@@ -357,7 +417,7 @@ function Send-IntuneFileToAzureStorage
$ids += $id $ids += $id
$start = $chunk * $chunkSizeInBytes $start = $chunk * $chunkSizeInBytes
$length = [Math]::Min($chunkSizeInBytes, $fileSize - $start) $length = [Math]::Min([uint64]($chunkSizeInBytes), [uint64]($fileSize - $start))
$bytes = $reader.ReadBytes($length) $bytes = $reader.ReadBytes($length)
$currentChunk = $chunk + 1 $currentChunk = $chunk + 1
@@ -423,9 +483,17 @@ function Set-FinalizeAzureStorageUpload
} }
$xml += '</BlockList>' $xml += '</BlockList>'
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
try try
{ {
Invoke-RestMethod $uri -Method Put -Body $xml Invoke-RestMethod $uri -Method Put -Body $xml @params
} }
catch catch
{ {
@@ -457,12 +525,18 @@ function Write-AzureStorageChunk
$success = $false $success = $false
$retryCount = 0 $retryCount = 0
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
}
while($true) while($true)
{ {
try try
{ {
$response = Invoke-WebRequest $uri -Method Put -Headers $headers -Body $encodedBody $response = Invoke-WebRequest $uri -Method Put -Headers $headers -Body $encodedBody -UseBasicParsing @params
if($retryCount -gt 0) if($retryCount -gt 0)
{ {
Write-Log "Chunk uploaded successfully" Write-Log "Chunk uploaded successfully"
@@ -622,3 +696,113 @@ function New-IntuneEncryptedFile
$fileEncryptionInfo $fileEncryptionInfo
} }
function Start-DecryptFile
{
param($sourceFile, $targetFile, $encryptionKey, $initializationVector)
if([IO.File]::Exists($targetFile))
{
$fi = [IO.FileInfo]$targetFile
$newName = $fi.Name + "_$((Get-Date).ToString("yyyyMMdd_HHmm"))" + $fi.Extension
$targetFile = $fi.DirectoryName + "\$newName"
Write-Log "Target file exists. Changing target file to $targetFile" 2
}
$bufferBlockSize = 1024 * 4
try
{
$aes = [System.Security.Cryptography.Aes]::Create()
$buffer = New-Object byte[] $bufferBlockSize
$bytesRead = 0
$targetStream = [System.IO.File]::Open($targetFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
try
{
$sourceStream = [System.IO.File]::Open($sourceFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::None)
$decryptor = $aes.CreateDecryptor([Convert]::FromBase64String($encryptionKey), [Convert]::FromBase64String($initializationVector))
$decryptoStream = New-Object System.Security.Cryptography.CryptoStream -ArgumentList @($targetStream, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Write)
$sourceStream.Seek(48L, [System.IO.SeekOrigin]::Begin)
while (($bytesRead = $sourceStream.Read($buffer, 0, $bufferBlockSize)) -gt 0)
{
$decryptoStream.Write($buffer, 0, $bytesRead)
$decryptoStream.Flush()
}
$decryptoStream.FlushFinalBlock()
}
finally
{
if ($null -ne $decryptoStream) { $decryptoStream.Dispose() }
if ($null -ne $targetStream) { $targetStream.Dispose() }
if ($null -ne $decryptor) { $decryptor.Dispose() }
if ($null -ne $sourceStream) { $sourceStream.Dispose() }
}
}
finally
{
if ($null -ne $sourceStream) { $sourceStream.Dispose() }
if ($null -ne $aes) { $aes.Dispose() }
}
}
function Start-DownloadAppContent
{
param($obj, $destinationFile, [switch]$GetContentFileInfoOnly)
# Not use but kept for reference. File can be download but it will be encrypted
if([IO.File]::Exists($destinationFile))
{
try { [IO.File]::Delete($encryptionFile) }
catch {}
}
$appId = $obj.Id
$appInfo = Invoke-GraphRequest -Url "$($global:graphURL)/deviceAppManagement/mobileApps/$appId"
$appType = $appInfo.'@odata.type'.Trim('#')
#$contentVersions = Invoke-GraphRequest -Url "$($global:graphURL)/deviceAppManagement/mobileApps/$appId/$appType/contentVersions"
#$contentVerId = $contentVersions.Value[0].id
$contentVerId = $appInfo.committedContentVersion
$contentFiles = Invoke-GraphRequest "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files"
$contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($contentFiles.value[-1].Id)" -NoError
if(-not $contentFile)
{
foreach($file in $contentFiles.value)
{
if($contentFiles.value[-1].Id -eq $file.id) { continune }
# 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
if($contentFile)
{
break
}
}
}
if($contentFile.azureStorageUri)
{
if($GetContentFileInfoOnly -ne $true)
{
Start-DownloadFile $contentFile.azureStorageUri $destinationFile
}
return $contentFile
}
else
{
Write-Log "Could not find file object for app $($obj.displayName) ($($appId))" 2
}
}
+422
View File
@@ -0,0 +1,422 @@
<#
.SYNOPSIS
Module for listing Intune assignment filter usage
.DESCRIPTION
.NOTES
Author: Mikael Karlsson
#>
function Get-ModuleVersion
{
'1.1.1'
}
function Invoke-InitializeModule
{
Add-EMToolsViewItem (New-Object PSObject -Property @{
Title = "Intune Filter Usage"
Id = "IntuneFilterUsage"
ViewID = "EMTools"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="DeviceConfiguration"
ShowViewItem = { Show-IntuneToolsFilterUsage }
})
}
function Show-IntuneToolsFilterUsage
{
if(-not $script:frmIntuneFilterUsage)
{
$script:frmIntuneFilterUsage = Get-XamlObject ($global:AppRootFolder + "\Xaml\IntuneToolsFiterUsage.xaml") #-AddVariables
if(-not $script:frmIntuneFilterUsage) { return }
Add-XamlEvent $script:frmIntuneFilterUsage "btnGetIntuneFilterUsage" "add_click" ({
Write-Status "Get Intune Filter Usage"
Get-EMIntuneFilterUsage
Write-Status ""
})
Add-XamlEvent $script:frmIntuneFilterUsage "btnIntuneFilterUsageCopy" "add_click" ({
$dgValues = Get-DataGridValues ($script:frmIntuneFilterUsage.FindName("dgIntuneFilterUsage"))
$dgValues | ConvertTo-Csv -NoTypeInformation | Set-Clipboard
})
Add-XamlEvent $script:frmIntuneFilterUsage "btnIntuneFilterUsagesSave" "add_click" ({
$dlgSave = New-Object -Typename System.Windows.Forms.SaveFileDialog
$dlgSave.FileName = $obj.FileName
$dlgSave.DefaultExt = "*.csv"
$dlgSave.Filter = "CSV (*.csv)|*.csv|All files (*.*)| *.*"
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
$dgValues = Get-DataGridValues ($script:frmIntuneFilterUsage.FindName("dgIntuneFilterUsage"))
$dgValues | ConvertTo-Csv -NoTypeInformation | Out-File -LiteralPath $dlgSave.Filename -Encoding UTF8 -Force
}
})
}
$global:grdToolsMain.Children.Clear()
$global:grdToolsMain.Children.Add($frmIntuneFilterUsage)
}
function Get-DataGridValues_old
{
param($dataGrid)
$dgColumns = $dataGrid.Columns
#$dgColumns = Get-XamlProperty $script:frmIntuneFilterUsage "dgIntuneFilterUsage" "Columns"
$properties = @()
foreach($tmpCol in $dgColumns)
{
$propName = $tmpCol.Binding.Path.Path
$properties += @{n=$tmpCol.Header;e=([Scriptblock]::Create("`$_.$propName"))}
}
($script:objFilterUsage | Select -Property $properties)
}
function Get-EMIntuneFilterUsage
{
param($rootDir)
Write-Status "Gather Intune Filter Information"
Set-XamlProperty $script:frmIntuneFilterUsage "dgIntuneFilterUsage" "ItemsSource" $null
$objectType = Get-GraphObjectType "AssignmentFilters"
$loadedGroups = @{}
$loadedGroups.Add("adadadad-808e-44e2-905a-0b7873a8a531","All Devices")
$loadedGroups.Add("acacacac-9df4-4c7d-9d50-4ef0226f57a9","All Users")
$script:objFilters = (Invoke-GraphRequest -Url $objectType.API).Value
$script:objFilterUsage = @()
$groupIDs = @()
foreach($filter in $script:objFilters)
{
Write-Status "Get payloads for filter $($filter.displayName)"
$payloadsManual = @()
$payloads = (Invoke-GraphRequest -Url "$($objectType.API)/$($filter.ID)/payloads").value
$batchObjs = @()
foreach($payload in $payloads)
{
$guid = [Guid]::NewGuid().Guid
$payloadsObj = @{
Payload = $payload
ID = $guid
Requests = @()
}
if($groupIDs -notcontains $payload.groupId)
{
$groupIDs += $payload.groupId
}
$batchObjs += $payloadsObj
if($payload.payloadType -eq "win32app")
{
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_deviceHealthScripts"
method = "GET"
url = "/deviceManagement/deviceHealthScripts/$($payload.payloadId)/?`$select=displayName,isGlobalScript"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
}
elseif($payload.payloadType -eq "application")
{
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_mobileApps"
method = "GET"
url = "/deviceAppManagement/mobileApps/$($payload.payloadId)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
}
elseif($payload.payloadType -eq "deviceManagmentConfigurationAndCompliancePolicy")
{
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_configurationPolicies"
method = "GET"
url = "/deviceManagement/configurationPolicies/$($payload.payloadId)/?`$select=name,platforms,technologies,templateReference"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
}
elseif($payload.payloadType -eq "groupPolicyConfiguration")
{
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_groupPolicyConfigurations"
method = "GET"
url = "/deviceManagement/groupPolicyConfigurations/$($payload.payloadId)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
}
elseif($payload.payloadType -eq "enrollmentConfiguration")
{
if(-not $script:enrolmentConfigurations)
{
$script:enrolmentConfigurations = @()
$script:enrolmentConfigurations += (Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations?`$select=displayName,id,deviceEnrollmentConfigurationType").value
$script:enrolmentConfigurations += (Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations?`$select=displayName,id,deviceEnrollmentConfigurationType&`$filter=deviceEnrollmentConfigurationType eq 'EnrollmentNotificationsConfiguration'").value
}
$payloadsManual += $payload
<#
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_enrollmentConfiguration"
method = "GET"
url = "/deviceManagement/deviceEnrollmentConfigurations/$($enrolmentConfig.Id)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
#>
}
else
{
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_deviceCompliancePolicies"
method = "GET"
url = "/deviceManagement/deviceCompliancePolicies/$($payload.payloadId)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_deviceConfigurations"
method = "GET"
url = "/deviceManagement/deviceConfigurations/$($payload.payloadId)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
$payloadsObj.Requests += [ordered]@{
id = "$($guid)_mobileAppConfigurations"
method = "GET"
url = "/deviceAppManagement/mobileAppConfigurations/$($payload.payloadId)/?`$select=displayName"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadNames_BatchItem"}
}
}
}
if($batchObjs.Count -gt 0)
{
$objName = Get-GraphObjectName $filter $objectType
$responses = Invoke-GraphBatchRequest @($batchObjs.Requests) $objName -SkipWarnings
foreach($response in ($responses | Where Status -lt 300))
{
$payload = ($batchObjs | Where { $response.id -like "$($_.ID)*"}).Payload
if($payload.assignmentFilterType -eq "Include")
{
$filterType = "Include"
}
else
{
$filterType = "Exclude"
}
$typeStr = $null
if($payload.payloadType -eq "application")
{
$typeStr = Get-LanguageString "AppType.windowsClassicApp"
}
elseif($payload.payloadType -eq "win32app")
{
$typeStr = "Proactive Remediations"
}
elseif($payload.payloadType -eq "groupPolicyConfiguration")
{
$typeStr = "Settings Catalog"
}
elseif($payload.payloadType -eq "deviceManagmentConfigurationAndCompliancePolicy")
{
$typeStr = "Administrative Templates"
}
else
{
$typeStr = (Get-PolicyTypeName $response.body.'@odata.type' $payload.payloadType)
}
if(-not $typeStr) { $typeStr = $payload.payloadType}
$script:objFilterUsage += [PSCustomObject]@{
FiterObject = $filter
PayloadObject = $payload
FilterName = $filter.displayName
PolicyName = ?? $response.body.Name $response.body.displayName
Type = $response.body.'@odata.type'
PayloadType = $typeStr
Mode = $filterType
GroupID = $payload.groupId
GroupName = $payload.groupId
}
}
foreach($response in ($responses | Where Status -ge 300))
{
$payload = ($batchObjs | Where { $response.id -like "$($_.ID)*"}).Payload
Write-Log "Failed to get info for payload with id $($payload.payloadId) of type $($payload.payloadType). Might be deleted or not supported." 2
}
}
foreach($payload in $payloadsManual)
{
$payloadPolicy = $script:enrolmentConfigurations | Where Id -like "$($payload.payloadId)*" | Select -First 1
if($payloadPolicy)
{
if($payloadPolicy.deviceEnrollmentConfigurationType -eq "enrollmentNotificationsConfiguration")
{
$typeStr = "Enrollment notifications"
}
elseif($payloadPolicy.deviceEnrollmentConfigurationType -eq "windows10EnrollmentCompletionPageConfiguration")
{
$typeStr = "Enrollment Status Page"
}
else
{
$typeStr = (Get-PolicyTypeName $payloadPolicy.body.'@odata.type' $payload.payloadType)
}
if($payload.assignmentFilterType -eq "Include")
{
$filterType = "Include"
}
else
{
$filterType = "Exclude"
}
$script:objFilterUsage += [PSCustomObject]@{
FiterObject = $filter
PayloadObject = $payload
FilterName = $filter.displayName
PolicyName = ?? $payloadPolicy.Name $payloadPolicy.displayName
Type = $payloadPolicy.'@odata.type'
PayloadType = $typeStr
Mode = $filterType
GroupID = $payload.groupId
GroupName = $payload.groupId
}
}
}
}
if($groupIDs.Count -gt 0)
{
$guid = [Guid]::NewGuid().Guid
$groupObjs = @()
$x = 1
foreach($groupID in $groupIDs)
{
if($loadedGroups.ContainsKey($groupID)) { continue }
$groupObjs += [ordered]@{
id= "$($guid)_$x"
method="GET"
url="/groups/$($groupID)/?`$select=displayName,id"
headers = @{"x-ms-command-name"="AssignmentFilterPayloadProxy_resolvePayloadGroupAssignments_BatchItem"}
}
$x++
}
if($groupObjs.Count -gt 0)
{
$responses = Invoke-GraphBatchRequest $groupObjs "Groups"
$batchObj = [ordered]@{
requests = @($groupObjs)
}
$responses = (Invoke-GraphRequest -Url "`$batch" -Body ($batchObj | ConvertTo-Json -Depth 50 -Compress) -Method "POST").responses
foreach($response in ($responses | Where Status -eq 200))
{
if($response.body.displayName -and $response.body.id -and $loadedGroups.ContainsKey($response.body.id) -eq $false)
{
$loadedGroups.Add($response.body.id, $response.body.displayName)
}
}
}
foreach($groupID in $loadedGroups.Keys)
{
$filterObjs = $script:objFilterUsage | WHere GroupID -eq $groupID
if($filterObjs -and $loadedGroups[$groupID])
{
foreach($filterObj in $filterObjs) {
$filterObj.GroupName = $loadedGroups[$groupID]
}
}
}
$script:enrolmentConfigurations = $null
}
Add-XamlEvent $script:frmIntuneFilterUsage "txtIntuneFilterUsageFilter" "Add_LostFocus" ({
Invoke-IntueFilterUsageBoxChanged $this
})
Add-XamlEvent $script:frmIntuneFilterUsage "txtIntuneFilterUsageFilter" "Add_GotFocus" ({
if($this.Tag -eq "1" -and $this.Text -eq "Filter") { $this.Text = "" }
Invoke-IntueFilterUsageBoxChanged $this ($script:frmIntuneFilterUsage.FindName("dgIntuneFilterUsage"))
})
Add-XamlEvent $script:frmIntuneFilterUsage "txtIntuneFilterUsageFilter" "Add_TextChanged" ({
Invoke-IntueFilterUsageBoxChanged $this ($script:frmIntuneFilterUsage.FindName("dgIntuneFilterUsage"))
})
Invoke-IntueFilterUsageBoxChanged ($script:frmIntuneFilterUsage.FindName("txtIntuneFilterUsageFilter")) ($script:frmIntuneFilterUsage.FindName("dgIntuneFilterUsage"))
$ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new(@($script:objFilterUsage))
Set-XamlProperty $script:frmIntuneFilterUsage "dgIntuneFilterUsage" "ItemsSource" ([System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList))
}
function Invoke-IntueFilterUsageBoxChanged
{
param($txtBox, $dgObject)
$filter = $null
if($txtBox.Text.Trim() -eq "" -and $txtBox.IsFocused -eq $false)
{
$txtBox.FontStyle = "Italic"
$txtBox.Tag = 1
$txtBox.Text = "Filter"
$txtBox.Foreground="Lightgray"
}
elseif($txtBox.Tag -eq "1" -and $txtBox.Text -eq "Filter" -and $txtBox.IsFocused -eq $false)
{
}
else
{
$txtBox.FontStyle = "Normal"
$txtBox.Tag = $null
$txtBox.Foreground="Black"
$txtBox.Background="White"
if($txtBox.Text)
{
$filter = {
param ($item)
return ($item.FilterName -match [regex]::Escape($txtBox.Text) -or $item.PolicyName -match [regex]::Escape($txtBox.Text) -or $item.GroupName -match [regex]::Escape($txtBox.Text) )
}
}
}
if($dgObject.ItemsSource -is [System.Windows.Data.ListCollectionView] -and $txtBox.IsFocused -eq $true)
{
# This causes odd behaviour with focus e.g. and item has to be clicked twice to be selected
$dgObject.ItemsSource.Filter = $filter
#$dgObject.ItemsSource.Refresh()
}
}
+3 -3
View File
@@ -22,7 +22,7 @@ $global:EMToolsViewObject = $null
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.0.3' '1.0.5'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -82,7 +82,7 @@ function Add-EMToolsViewItem
Activating = { Invoke-EMToolsActivatingView } Activating = { Invoke-EMToolsActivatingView }
Authentication = (Get-MSALAuthenticationObject) Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMToolsAuthenticateToMSAL } Authenticate = { Invoke-EMToolsAuthenticateToMSAL }
AppInfo = (Get-GraphAppInfo "EM" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547") AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp)
SaveSettings = { Invoke-EMSaveSettings } SaveSettings = { Invoke-EMSaveSettings }
Permissions = @() Permissions = @()
}) })
@@ -121,7 +121,7 @@ function Invoke-EMToolsActivatingView
function Invoke-EMToolsAuthenticateToMSAL function Invoke-EMToolsAuthenticateToMSAL
{ {
$global:EMToolsViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" $global:EMToolsViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp
Set-MSALCurrentApp $global:EMToolsViewObject.AppInfo Set-MSALCurrentApp $global:EMToolsViewObject.AppInfo
$usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser")) $usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser"))
if($usr) if($usr)
+178 -9
View File
@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.3'
} }
$global:msalAuthenticator = $null $global:msalAuthenticator = $null
@@ -158,6 +158,10 @@ function Clear-MSALCurentUserVaiables
{ {
$global:MSALTenantId = $null $global:MSALTenantId = $null
$global:MSALGraphEnvironment = $null $global:MSALGraphEnvironment = $null
$script:jwtAccessToken = $null
$script:jwtIdToken = $null
} }
function Get-MSALCurrentApp function Get-MSALCurrentApp
@@ -223,6 +227,9 @@ function Get-MSALUserInfo
if($global:MSALToken) if($global:MSALToken)
{ {
Write-Log "Get current user" Write-Log "Get current user"
if($script:jwtAccessToken.Payload.idtyp -ne "app")
{
$tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip" $tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip"
if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation") if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation")
{ {
@@ -232,6 +239,12 @@ function Get-MSALUserInfo
$global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg" $global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg"
MSGraph\Invoke-GraphRequest "me/photos/48x48/`$value" -OutFile $global:profilePhoto -SkipAuthentication -NoError | Out-Null MSGraph\Invoke-GraphRequest "me/photos/48x48/`$value" -OutFile $global:profilePhoto -SkipAuthentication -NoError | Out-Null
} }
}
else
{
$global:profilePhoto = $null
$global:me = $script:jwtAccessToken.Payload.app_displayname
}
Write-Log "Get organization info" Write-Log "Get organization info"
$global:Organization = (MSGraph\Invoke-GraphRequest -Url "Organization" -SkipAuthentication -ODataMetadata "Skip").Value $global:Organization = (MSGraph\Invoke-GraphRequest -Url "Organization" -SkipAuthentication -ODataMetadata "Skip").Value
@@ -535,12 +548,14 @@ function Add-MSALPrereq
Write-Log "Some MSAL features might not work!" 3 Write-Log "Some MSAL features might not work!" 3
Write-Log "This could happen if another version of MSAL.DLL was loaded beforethe script tried to load it" 3 Write-Log "This could happen if another version of MSAL.DLL was loaded beforethe script tried to load it" 3
$RequiredAssemblies.Add($fiLoaded.FullName) $RequiredAssemblies.Add($fiLoaded.FullName)
$script:msalFile = $fiLoaded.FullName
} }
else else
{ {
Write-Log "Using MSAL file $msalPath. Version: $($fi.VersionInfo.FileVersion)" Write-Log "Using MSAL file $msalPath. Version: $($fi.VersionInfo.FileVersion)"
[void][System.Reflection.Assembly]::LoadFile($msalPath) [void][System.Reflection.Assembly]::LoadFile($msalPath)
$RequiredAssemblies.Add($msalPath) $RequiredAssemblies.Add($msalPath)
$script:msalFile = $msalPath
} }
$RequiredAssemblies.Add('System.Security.dll') $RequiredAssemblies.Add('System.Security.dll')
@@ -598,6 +613,7 @@ function Connect-MSALClientApp
{ {
return return
} }
Add-MSALProxy $ClientApplicationBuilder
$script:MSALApp = $ClientApplicationBuilder.Build() $script:MSALApp = $ClientApplicationBuilder.Build()
} }
@@ -677,6 +693,43 @@ function Get-MsalAuthenticationToken
$authResult $authResult
} }
function Add-MSALProxy
{
param($appBuilder)
$proxy = Get-SettingValue "ProxyURI"
if($proxy)
{
Write-Log "Use proxy $proxy"
if(-not ("HttpFactoryWithProxy" -as [type]))
{
try
{
Write-Log "Add type HttpFactoryWithProxy"
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
$RequiredAssemblies.Add($script:msalFile)
$RequiredAssemblies.Add('System.Net.Http.dll')
$RequiredAssemblies.Add('System.Net.Primitives.dll')
Add-Type -Path ($global:AppRootFolder + "\CS\HttpFactoryWithProxy.cs") -ReferencedAssemblies $RequiredAssemblies
}
catch
{
Write-LogError "Failed to compile HttpFactoryWithProxy" $_.Exception
}
}
try
{
$hcf = [HttpFactoryWithProxy]::new($proxy)
[void] $appBuilder.WithHttpClientFactory($hcf)
}
catch
{
Write-LogError "Failed to set proxy for MSAL" $_.Exception
}
}
}
function Get-MSALLoginEnvironment function Get-MSALLoginEnvironment
{ {
$loginEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public") $loginEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public")
@@ -717,6 +770,8 @@ function Get-MSALApp
[void] $appBuilder.WithClientName("CloudAPIPowerShellManagement") [void] $appBuilder.WithClientName("CloudAPIPowerShellManagement")
[void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion) [void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion)
Add-MSALProxy $appBuilder
# Ceck if correct version... # Ceck if correct version...
#$appBuilder.WithMultiCloudSupport($true) #$appBuilder.WithMultiCloudSupport($true)
@@ -792,6 +847,42 @@ function Connect-MSALUser
Write-LogDebug "Authenticate" Write-LogDebug "Authenticate"
if($global:MainAppStarted -eq $false)
{
$script:AppLogin = (Get-SettingValue "GraphAzureAppLogin") -or ($global:TenantId -and $global:AzureAppId -and ($global:ClientSecret -or $global:ClientCert))
}
if($script:AppLogin)
{
if($global:MSALToken -and $global:MSALToken.ExpiresOn.LocalDateTime.Ticks -gt ((Get-Date).AddMinutes(-5)).Ticks)
{
return
}
# Get login info for silent job from settings
if(-not $global:AzureAppId) { $global:AzureAppId = Get-SettingValue "GraphAzureAppId" -TenantID $global:TenantId }
if(-not $global:ClientSecret -and -not $global:ClientCert) { $global:ClientSecret = Get-SettingValue "GraphAzureAppSecret" -TenantID $global:TenantId }
if(-not $global:ClientSecret -and -not $global:ClientCert) { $global:ClientCert = Get-SettingValue "GraphAzureAppCert" -TenantID $global:TenantId }
if($global:AzureAppId -and $global:ClientSecret -and $global:TenantId)
{
Connect-MSALClientApp $global:AzureAppId $global:TenantId -secret $global:ClientSecret
}
elseif($global:AzureAppId -and $global:ClientCert -and $global:TenantId)
{
Connect-MSALClientApp $global:AzureAppId $global:TenantId -certificate $global:ClientCert
}
else
{
Write-Log "Azure AppId, Tenant Id and Sercret/Cert must be specified for App logins" 3
}
Invoke-MSALAuthenticationUpdated $global:MSALToken
return
}
if($ShowMenu -eq $true -and ((Get-SettingValue "AzureADLoginMenu") -eq $true)) if($ShowMenu -eq $true -and ((Get-SettingValue "AzureADLoginMenu") -eq $true))
{ {
if((Show-MSALLoginMenu) -eq $false) { return } if((Show-MSALLoginMenu) -eq $false) { return }
@@ -1057,7 +1148,7 @@ function Connect-MSALUser
######################################################################################################### #########################################################################################################
try try
{ {
Write-Log "Get tennant list" Write-Log "Get tenant list"
# Can we reuse the app used for login? # Can we reuse the app used for login?
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($global:appObj.ClientID) $appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($global:appObj.ClientID)
@@ -1065,6 +1156,8 @@ function Connect-MSALUser
else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) } else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) }
if($global:appObj.RedirectUri) { [void]$appBuilder.WithRedirectUri($global:appObj.RedirectUri) } if($global:appObj.RedirectUri) { [void]$appBuilder.WithRedirectUri($global:appObj.RedirectUri) }
Add-MSALProxy $appBuilder
$app = $appBuilder.Build() $app = $appBuilder.Build()
if((Get-SettingValue "CacheMSALToken")) if((Get-SettingValue "CacheMSALToken"))
@@ -1093,7 +1186,15 @@ function Connect-MSALUser
'ExpiresOn' = $tmpResults.ExpiresOn 'ExpiresOn' = $tmpResults.ExpiresOn
} }
$ret = Invoke-RestMethod "https://management.azure.com/tenants?api-version=2020-01-01" -Headers $Headers $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$ret = Invoke-RestMethod "https://management.azure.com/tenants?api-version=2020-01-01" -Headers $Headers @params
if($ret) if($ret)
{ {
$script:AccessableTenants = $ret.Value $script:AccessableTenants = $ret.Value
@@ -1115,7 +1216,8 @@ function Connect-MSALUser
Save-Setting "" "LastLoggedOnUser" $authResult.Account.UserName Save-Setting "" "LastLoggedOnUser" $authResult.Account.UserName
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
} }
Invoke-MSALAuthenticationUpdated $authResult
<#
Write-LogDebug "User, tenant or app has changed" Write-LogDebug "User, tenant or app has changed"
Get-MSALUserInfo Get-MSALUserInfo
if($authResult) if($authResult)
@@ -1123,9 +1225,26 @@ function Connect-MSALUser
Invoke-MSALCheckObjectViewAccess $authResult Invoke-MSALCheckObjectViewAccess $authResult
} }
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated" Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
#>
} }
} }
function local:Invoke-MSALAuthenticationUpdated
{
param($authResult)
Write-LogDebug "User, tenant or app has changed"
$script:jwtAccessToken = Get-JWTtoken $global:MSALToken.AccessToken
$script:jwtIdToken = Get-JWTtoken $global:MSALToken.IdToken
Get-MSALUserInfo
if($authResult)
{
Invoke-MSALCheckObjectViewAccess $authResult
}
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
}
function Start-MSALConsentPrompt function Start-MSALConsentPrompt
{ {
param([switch]$PassThru, $authToken) param([switch]$PassThru, $authToken)
@@ -1202,6 +1321,22 @@ function Invoke-MSALCheckObjectViewAccess
Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Visible" Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Visible"
} }
$accessToken = $null
if($authToken)
{
$accessToken = Get-JWTtoken $authToken.AccessToken
}
$curPermissions = $null
if($accessToken.Payload.idtyp -eq "app")
{
$curPermissions = $accessToken.Payload.roles
}
elseif($accessToken.Payload.scp)
{
$curPermissions = $accessToken.Payload.scp.Split(" ")
}
foreach($viewObjInfo in ($global:viewObjects | Where { $_.ViewInfo.AuthenticationID -eq "MSAL" })) foreach($viewObjInfo in ($global:viewObjects | Where { $_.ViewInfo.AuthenticationID -eq "MSAL" }))
{ {
$viewObjInfo = $global:viewObjects | Where { $_.ViewInfo.Id -eq $global:EMViewObject.Id } $viewObjInfo = $global:viewObjects | Where { $_.ViewInfo.Id -eq $global:EMViewObject.Id }
@@ -1210,10 +1345,8 @@ function Invoke-MSALCheckObjectViewAccess
{ {
if($authToken) if($authToken)
{ {
$accessToken = Get-JWTtoken $authToken.AccessToken if($curPermissions)
if($accessToken.Payload.scp)
{ {
$curPermissions = $accessToken.Payload.scp.Split(" ")
foreach($viewItem in $viewObjInfo.ViewItems) foreach($viewItem in $viewObjInfo.ViewItems)
{ {
$full = 0 $full = 0
@@ -1511,6 +1644,10 @@ function Get-MSALProfileEllipse
{ {
$initials = "$($global:me.userPrincipalName[0])".ToUpper() $initials = "$($global:me.userPrincipalName[0])".ToUpper()
} }
elseif($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$initials = "APP"
}
$grd = Get-MSALUserPhotoEllips -size $size -fontSize $fontSize -Color $Color $grd = Get-MSALUserPhotoEllips -size $size -fontSize $fontSize -Color $Color
@@ -1534,8 +1671,15 @@ function Get-MSALProfileEllipse
$global:grdProfileInfo.Tag = $grd $global:grdProfileInfo.Tag = $grd
$grd.Tag = $global:grdProfileInfo $grd.Tag = $global:grdProfileInfo
Set-XamlProperty $global:grdProfileInfo "txtOrganization" "Text" $global:Organization.displayName Set-XamlProperty $global:grdProfileInfo "txtOrganization" "Text" $global:Organization.displayName
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" "App Login"
}
else
{
Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" $global:me.displayName Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" $global:me.displayName
Set-XamlProperty $global:grdProfileInfo "txtLogonName" "Text" $global:me.userPrincipalName Set-XamlProperty $global:grdProfileInfo "txtLogonName" "Text" $global:me.userPrincipalName
}
$global:tokenInfo = Get-JWTtoken $global:MSALToken.AccessToken $global:tokenInfo = Get-JWTtoken $global:MSALToken.AccessToken
if($global:tokenInfo) if($global:tokenInfo)
@@ -1560,12 +1704,19 @@ function Get-MSALProfileEllipse
$profileGrid.Children.Add($tmpObj) | Out-Null $profileGrid.Children.Add($tmpObj) | Out-Null
} }
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$tmpObj.Visibility = "Collapsed"
}
$global:grdProfileInfo.Add_Loaded({param($obj, $e) $global:grdProfileInfo.Add_Loaded({param($obj, $e)
$point = $obj.Tag.TransformToAncestor($window).Transform([System.Windows.Point]::new(0,0)); $point = $obj.Tag.TransformToAncestor($window).Transform([System.Windows.Point]::new(0,0));
[System.Windows.Controls.Canvas]::SetLeft($obj,($point.X - $obj.ActualWidth + $obj.Tag.ActualWidth)) [System.Windows.Controls.Canvas]::SetLeft($obj,($point.X - $obj.ActualWidth + $obj.Tag.ActualWidth))
[System.Windows.Controls.Canvas]::SetTop($obj,($point.Y + $obj.Tag.ActualHeight)) [System.Windows.Controls.Canvas]::SetTop($obj,($point.Y + $obj.Tag.ActualHeight))
}) })
if($script:jwtAccessToken.Payload.idtyp -ne "app")
{
######################################################################################################### #########################################################################################################
### Show / Hide consent button ### Show / Hide consent button
######################################################################################################### #########################################################################################################
@@ -1696,6 +1847,7 @@ function Get-MSALProfileEllipse
catch {} catch {}
} }
} }
}
######################################################################################################### #########################################################################################################
### Add event handling ### Add event handling
@@ -1756,6 +1908,11 @@ function Get-MSALProfileEllipse
Show-GraphObjects Show-GraphObjects
} }
} }
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
Set-XamlProperty $tmpObj "lnkLogout" "Visibility" "Collapsed"
}
} }
catch { catch {
Write-LogError "Failed to create profile information object. Error: " $_.Exception Write-LogError "Failed to create profile information object. Error: " $_.Exception
@@ -1931,12 +2088,21 @@ function Get-MSALMissingScopes
$script:missingPermissions = @() $script:missingPermissions = @()
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$curScopes = $script:jwtAccessToken.Payload.roles
}
else
{
$curScopes = $authToken.Scopes
}
foreach($scope in $reqScopes) foreach($scope in $reqScopes)
{ {
$tmpScope = $scope.Split('/')[-1] $tmpScope = $scope.Split('/')[-1]
if($tmpScope -eq ".default") { continue } if($tmpScope -eq ".default") { continue }
if($authToken.Scopes -contains $tmpScope) { continue } if($curScopes -contains $tmpScope) { continue }
if(($authToken.Scopes -like "*/$tmpScope")) { continue } if(($curScopes -like "*/$tmpScope")) { continue }
$arrTemp = $tmpScope.Split(".") $arrTemp = $tmpScope.Split(".")
if($arrTemp[1] -eq "Read") if($arrTemp[1] -eq "Read")
{ {
@@ -1960,6 +2126,9 @@ function Show-MSALDecodedToken {
$tokenData, $tokenData,
$title $title
) )
if(-not $tokenData.Header) { return }
$tokenArr = @() $tokenArr = @()
foreach($prop in ($tokenData.Header | GM | Where MemberType -eq NoteProperty)) foreach($prop in ($tokenData.Header | GM | Where MemberType -eq NoteProperty))
{ {
+270 -78
View File
@@ -10,15 +10,19 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.6'
} }
$global:MSGraphGlobalApps = @( $global:MSGraphGlobalApps = @(
(New-Object PSObject -Property @{Name="";ClientId="";RedirectUri="";Authority=""}), (New-Object PSObject -Property @{Name="";ClientId="";RedirectUri="";Authority=""}),
(New-Object PSObject -Property @{Name="Microsoft Intune PowerShell";ClientId="d1ddf0e4-d672-4dae-b554-9d5bdfd93547";RedirectUri="urn:ietf:wg:oauth:2.0:oob"; }), (New-Object PSObject -Property @{Name="Microsoft Graph PowerShell";ClientId="14d82eec-204b-4c2f-b7e8-296a70dab67e";RedirectUri="https://login.microsoftonline.com/common/oauth2/nativeclient";}),
(New-Object PSObject -Property @{Name="Microsoft Graph PowerShell";ClientId="14d82eec-204b-4c2f-b7e8-296a70dab67e";RedirectUri="https://login.microsoftonline.com/common/oauth2/nativeclient";}) (New-Object PSObject -Property @{Name="Decomissioned - Don't use - Microsoft Intune PowerShell";ClientId="d1ddf0e4-d672-4dae-b554-9d5bdfd93547";RedirectUri="urn:ietf:wg:oauth:2.0:oob"; })
) )
$global:DefaultAzureApp = "14d82eec-204b-4c2f-b7e8-296a70dab67e"
$global:OldAzureApps = @("d1ddf0e4-d672-4dae-b554-9d5bdfd93547")
function Invoke-InitializeModule function Invoke-InitializeModule
{ {
$global:graphURL = "https://graph.microsoft.com/beta" $global:graphURL = "https://graph.microsoft.com/beta"
@@ -183,6 +187,14 @@ function Invoke-InitializeModule
Description = "Certificate for Azure App" Description = "Certificate for Azure App"
}) "GraphSilent" }) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Login with App in UI (Preview)"
Key = "GraphAzureAppLogin"
Type = "Boolean"
DefaultValue = $false
Description = "Login with specified app in the UI. Note: Change will require app restart"
}) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Refresh Objects after copy" Title = "Refresh Objects after copy"
Key = "RefreshObjectsAfterCopy" Key = "RefreshObjectsAfterCopy"
@@ -214,6 +226,15 @@ function Invoke-InitializeModule
DefaultValue = $false DefaultValue = $false
Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info" Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info"
}) "GraphGeneral" }) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Use Graph 1.0 (Not Recommended)"
Key = "UseGraphV1"
Type = "Boolean"
DefaultValue = $false
Description = "This will use production verionof graph, v1.0. Note: Thot officially supported since this can have unpredicted results. Some parts will require Beta version of Graph."
}) "GraphGeneral"
} }
function Get-GraphAppInfo function Get-GraphAppInfo
@@ -261,6 +282,7 @@ function Invoke-GraphAuthenticationUpdated
$global:MigrationTableCacheId = $null $global:MigrationTableCacheId = $null
$global:LoadedDependencyObjects = $null $global:LoadedDependencyObjects = $null
$global:migFileObj = $null $global:migFileObj = $null
$global:AADObjectCache = $null
} }
function Invoke-SettingsUpdated function Invoke-SettingsUpdated
@@ -270,7 +292,7 @@ function Invoke-SettingsUpdated
function Initialize-GraphSettings function Initialize-GraphSettings
{ {
$script:defaultVersion = ""
} }
function Invoke-GraphRequest function Invoke-GraphRequest
@@ -297,7 +319,7 @@ function Invoke-GraphRequest
$ODataMetadata = "full", # full, minimal, none or skip $ODataMetadata = "full", # full, minimal, none or skip
[ValidateSet("beta","v1.0")] [ValidateSet("beta","v1.0")]
$GraphVersion = "beta", $GraphVersion = "",
[switch] [switch]
$AllPages, $AllPages,
@@ -317,6 +339,22 @@ function Invoke-GraphRequest
Connect-MSALUser Connect-MSALUser
} }
if(-not $GraphVersion)
{
if(-not $script:defaultVersion)
{
if((Get-SettingValue "UseGraphV1") -eq $true)
{
$script:defaultVersion = "v1.0"
}
else
{
$script:defaultVersion = "beta"
}
}
$GraphVersion = $script:defaultVersion
}
$params = @{} $params = @{}
$requestId = [Guid]::NewGuid().guid $requestId = [Guid]::NewGuid().guid
@@ -394,6 +432,13 @@ function Invoke-GraphRequest
$url = "$($url.Trim())`$top=$($PageSize)" $url = "$($url.Trim())`$top=$($PageSize)"
} }
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$ret = $null $ret = $null
$retryCount = 0 $retryCount = 0
@@ -543,7 +588,7 @@ function Get-GraphObjects
if($SinglePage -eq $true) if($SinglePage -eq $true)
{ {
#Use default page size or use below for a specific page size for testing #Use default page size or use below for a specific page size for testing
#$params.Add("pageSize",10) #!!! #$params.Add("pageSize",5) #!!!
} }
elseif($SingleObject -ne $true -and $SinglePage -ne $true) elseif($SingleObject -ne $true -and $SinglePage -ne $true)
{ {
@@ -819,6 +864,7 @@ function Show-GraphObjects
if($ctrl.Name -eq "btnDelete") if($ctrl.Name -eq "btnDelete")
{ {
$allowDelete = Get-SettingValue "EMAllowDelete" $allowDelete = Get-SettingValue "EMAllowDelete"
if($global:currentViewObject.ViewInfo.AllowDelete -eq $false) { $allowDelete = $false }
$ctrl.Visibility = (?: ($allowDelete -eq $true) "Visible" "Collapsed") $ctrl.Visibility = (?: ($allowDelete -eq $true) "Visible" "Collapsed")
} }
elseif(-not $global:curObjectType.ShowButtons -or ($global:curObjectType.ShowButtons | Where-Object { $ctrl.Name -like "*$($_)" } )) elseif(-not $global:curObjectType.ShowButtons -or ($global:curObjectType.ShowButtons | Where-Object { $ctrl.Name -like "*$($_)" } ))
@@ -1027,8 +1073,15 @@ function Get-GraphMetaData
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$wc = New-Object System.Net.WebClient $wc = New-Object System.Net.WebClient
$wc.Encoding = [System.Text.Encoding]::UTF8 $wc.Encoding = [System.Text.Encoding]::UTF8
$proxyURI = Get-ProxyURI
try try
{ {
if($proxyURI)
{
$wc.Proxy = [System.Net.WebProxy]::new($proxyURI)
}
[xml]$global:metaDataXML = $wc.DownloadString($url) [xml]$global:metaDataXML = $wc.DownloadString($url)
# Download to string and then use Save to format the XML output # Download to string and then use Save to format the XML output
$global:metaDataXML.Save($fi.FullName) $global:metaDataXML.Save($fi.FullName)
@@ -1042,6 +1095,16 @@ function Get-GraphMetaData
$wc.Dispose() $wc.Dispose()
} }
} }
if(-not $global:metaDataXML -and $fi.Exists)
{
Write-Log "Using old version of Graph MetaData file" 2
try
{
[xml]$global:metaDataXML = Get-Content $fi.FullName
}
catch { }
}
} }
} }
@@ -1362,8 +1425,8 @@ function Start-GraphObjectExport
Write-Log "Start bulk export" Write-Log "Start bulk export"
Write-Log "****************************************************************" Write-Log "****************************************************************"
$tmpFolder = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text") $script:exportRoot = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
Write-Log "Export root folder: $tmpFolder" Write-Log "Export root folder: $script:exportRoot"
$global:AADObjectCache = $null $global:AADObjectCache = $null
@@ -1377,10 +1440,11 @@ function Start-GraphObjectExport
$txtNameFilter = $global:txtExportNameFilter.Text.Trim() $txtNameFilter = $global:txtExportNameFilter.Text.Trim()
Save-Setting "" "ExportNameFilter" $txtNameFilter Save-Setting "" "ExportNameFilter" $txtNameFilter
if($txtNameFilter) { Write-Log "Name filter: $txtNameFilter" } if($txtNameFilter) { Write-Log "Name filter: $txtNameFilter" }
try try
{ {
$folder = Get-GraphObjectFolder $item.ObjectType (Get-XamlProperty $script:exportForm "txtExportPath" "Text") (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked") $folder = Get-GraphObjectFolder $item.ObjectType $script:exportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked")
$folder = Expand-FileName $folder $folder = Expand-FileName $folder
@@ -1670,6 +1734,7 @@ function Show-GraphImportForm
$importedObjectsCurType = 0 $importedObjectsCurType = 0
$navigationPropObjects = @() $navigationPropObjects = @()
$arrImportedObjects = @()
foreach ($fileObj in $filesToImport) foreach ($fileObj in $filesToImport)
{ {
if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObject $fileObj $global:dgObjects.ItemsSource)) if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObject $fileObj $global:dgObjects.ItemsSource))
@@ -1685,9 +1750,15 @@ function Show-GraphImportForm
ImportedObject = $importedObj ImportedObject = $importedObj
} }
} }
$arrImportedObjects += $importedObj
$importedObjectsCurType++ $importedObjectsCurType++
} }
if($global:curObjectType.PostFilesImportCommand)
{
& $global:curObjectType.PostFilesImportCommand $global:curObjectType $arrImportedObjects $filesToImport
}
if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($global:curObjectType.Id)) if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($global:curObjectType.Id))
{ {
Write-Log "Remove $($global:curObjectType.Title) from dependency cache" Write-Log "Remove $($global:curObjectType.Title) from dependency cache"
@@ -1856,7 +1927,6 @@ function Show-GraphBulkImportForm
function Start-GraphObjectImport function Start-GraphObjectImport
{ {
Write-Status "Import objects" -Block Write-Status "Import objects" -Block
Write-Log "****************************************************************" Write-Log "****************************************************************"
Write-Log "Start bulk import" Write-Log "Start bulk import"
@@ -1906,6 +1976,8 @@ function Start-GraphObjectImport
$importedObjectsCurType = 0 $importedObjectsCurType = 0
$arrImportedObjects = @()
foreach ($fileObj in @($filesToImport)) foreach ($fileObj in @($filesToImport))
{ {
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType $objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
@@ -1929,11 +2001,17 @@ function Start-GraphObjectImport
ImportedObject = $importedObj ImportedObject = $importedObj
} }
} }
$arrImportedObjects = $importedObj
$importedObjects++ $importedObjects++
$importedObjectsCurType++ $importedObjectsCurType++
} }
if($item.ObjectType.PostFilesImportCommand)
{
& $item.ObjectType.PostFilesImportCommand $item.ObjectType $arrImportedObjects $filesToImport
}
if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($item.ObjectType.Id)) if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($item.ObjectType.Id))
{ {
Write-Log "Remove $($item.ObjectType.Title) from dependency cache" Write-Log "Remove $($item.ObjectType.Title) from dependency cache"
@@ -2229,6 +2307,11 @@ function Import-GraphFile
Import-GraphObjectAssignment $newObj $file.ObjectType $objClone.Assignments $file.FileInfo.FullName | Out-Null Import-GraphObjectAssignment $newObj $file.ObjectType $objClone.Assignments $file.FileInfo.FullName | Out-Null
} }
if($newObj)
{
$file | Add-Member -NotePropertyName "ImportedObject" -NotePropertyValue $newObj
}
if($PassThru -eq $true -and $newObj) if($PassThru -eq $true -and $newObj)
{ {
$newObj $newObj
@@ -2247,9 +2330,9 @@ function Reset-GraphObject
$nameProp = ?? $fileObj.ObjectType.NameProperty "displayName" $nameProp = ?? $fileObj.ObjectType.NameProperty "displayName"
$curObject = $objectList | Where { $_.Object.$nameProp -eq $fileObj.Object.$nameProp -and $_.Object.'@OData.Type' -eq $fileObj.Object.'@OData.Type' } $curObject = $objectList | Where { $_.Object.$nameProp -eq $fileObj.Object.$nameProp -and $_.Object.'@OData.Type' -eq $fileObj.Object.'@OData.Type' }
if($global:cbImportType.SelectedValue -eq "skipIfExist" -and ($curObject | measure).Count -gt 0) if($global:cbImportType.SelectedValue -eq "skipIfExist" -and ($curObject | measure).Count -gt 0 -and $fileObj.ObjectType.AlwaysImport -ne $true)
{ {
Write-Log "Objects with name $($fileObj.Object.$nameProp) already exists. Object will not be imported" Write-Log "Object with name $($fileObj.Object.$nameProp) already exists. Object will not be imported"
return $true return $true
} }
elseif(($curObject | measure).Count -gt 1) elseif(($curObject | measure).Count -gt 1)
@@ -2259,7 +2342,12 @@ function Reset-GraphObject
} }
elseif(($curObject | measure).Count -eq 1) elseif(($curObject | measure).Count -eq 1)
{ {
Write-Log "Update $((Get-GraphObjectName $fileObj.Object $fileObj.ObjectType)) with id $($curObject.Object.Id)" $idInfo = ""
if([String]::IsNullOrEmpty($curObject.Object.Id) -eq $false)
{
$idInfo = " with id $($curObject.Object.Id)"
}
Write-Log "Update $((Get-GraphObjectName $fileObj.Object $fileObj.ObjectType))$idInfo"
$objectType = $fileObj.ObjectType $objectType = $fileObj.ObjectType
# Clone the object before removing properties # Clone the object before removing properties
@@ -2491,6 +2579,15 @@ function Set-ScopeTags
else { return } else { return }
$scopesIds = @() $scopesIds = @()
if($global:chkReplaceDependencyIDs.IsChecked -eq $false -and $global:chkReplaceDependencyIDs.IsEnabled -eq $false)
{
if($global:chkImportScopes.IsChecked -eq $true)
{
$scopesIds += $obj.$scopeTagProperty
}
}
else
{
$loadedScopeTags = $global:LoadedDependencyObjects["ScopeTags"] $loadedScopeTags = $global:LoadedDependencyObjects["ScopeTags"]
$usingDefault = (($obj."$scopeTagProperty" | measure).Count -eq 1 -and ($obj."$scopeTagProperty")[0] -eq "0") $usingDefault = (($obj."$scopeTagProperty" | measure).Count -eq 1 -and ($obj."$scopeTagProperty")[0] -eq "0")
if($loadedScopeTags -and $global:chkImportScopes.IsChecked -eq $true -and $usingDefault -eq $false -and $loadedScopeTags) if($loadedScopeTags -and $global:chkImportScopes.IsChecked -eq $true -and $usingDefault -eq $false -and $loadedScopeTags)
@@ -2510,6 +2607,8 @@ function Set-ScopeTags
} }
} }
} }
}
if($scopesIds.Count -eq 0) if($scopesIds.Count -eq 0)
{ {
$scopesIds += "0" # Import with Default ScopeTag as default. $scopesIds += "0" # Import with Default ScopeTag as default.
@@ -2538,7 +2637,6 @@ function Add-GraphMigrationInfo
if($objType -eq "#microsoft.graph.groupAssignmentTarget" -or if($objType -eq "#microsoft.graph.groupAssignmentTarget" -or
$objType -eq "#microsoft.graph.exclusionGroupAssignmentTarget") $objType -eq "#microsoft.graph.exclusionGroupAssignmentTarget")
{ {
#Add-GroupMigrationObject $objInfo.groupid
Add-GraphMigrationObject $objInfo.groupid "/groups" "Group" Add-GraphMigrationObject $objInfo.groupid "/groups" "Group"
} }
elseif($objType -eq "#microsoft.graph.allLicensedUsersAssignmentTarget" -or elseif($objType -eq "#microsoft.graph.allLicensedUsersAssignmentTarget" -or
@@ -2608,7 +2706,7 @@ function Add-GroupMigrationObject
if(-not $groupId) { return } if(-not $groupId) { return }
$path = Get-GraphMigrationTableFile $global:txtExportPath.Text $path = Get-GraphMigrationTableFile $script:ExportRoot
if(-not $path) { return } if(-not $path) { return }
@@ -2649,7 +2747,7 @@ function Add-GraphMigrationObject
if(-not $objId) { return } if(-not $objId) { return }
$path = Get-GraphMigrationTableFile $global:txtExportPath.Text $path = Get-GraphMigrationTableFile $script:ExportRoot
if(-not $path) { return } if(-not $path) { return }
@@ -2657,16 +2755,16 @@ function Add-GraphMigrationObject
# Check if object is already processed # Check if object is already processed
$graphObj = Get-GraphMigrationObject $objId $graphObj = Get-GraphMigrationObject $objId
if(-not $graphObj) if(-not $graphObj -and ($global:AADObjectCache.ContainsKey($objId) -eq $false))
{ {
# Get object info # Get object info
$graphObj = Invoke-GraphRequest "$($grapAPI)/$objId" -ODataMetadata "none" $graphObj = Invoke-GraphRequest "$($grapAPI)/$objId" -ODataMetadata "none" -NoError
} }
if($graphObj) if($graphObj)
{ {
# Add object to cache # Add object to cache
if($global:AADObjectCache.ContainsKey($objId) -eq $false) { $global:AADObjectCache.Add($objId, $ugraphObjserObj) } if($global:AADObjectCache.ContainsKey($objId) -eq $false) { $global:AADObjectCache.Add($objId, $graphObj ) }
# Add object to migration file # Add object to migration file
if((Add-GraphMigrationObjectToFile $graphObj $path $objTypeName)) if((Add-GraphMigrationObjectToFile $graphObj $path $objTypeName))
@@ -2681,6 +2779,11 @@ function Add-GraphMigrationObject
} }
} }
} }
else
{
if($global:AADObjectCache.ContainsKey($objId) -eq $false) { $global:AADObjectCache.Add($objId, $null) }
Write-Log "No $objTypeName found with ID $($objId). It might be deleted." 2
}
} }
function Get-GraphMigrationObject function Get-GraphMigrationObject
@@ -2806,14 +2909,15 @@ function Get-GraphMigrationObjectsFromFile
{ {
if($migObj.Type -like "*group*") if($migObj.Type -like "*group*")
{ {
$obj = (Invoke-GraphRequest "/groups?`$filter=displayName eq '$($migObj.DisplayName)'").Value $migTableGroupName = $migObj.DisplayName.Trim()
$obj = (Invoke-GraphRequest "/groups?`$filter=displayName eq '$($migTableGroupName)'").Value
if(-not $obj) if(-not $obj)
{ {
$groupFi = $null $groupFi = $null
if($global:GraphMigrationTable) if($global:GraphMigrationTable)
{ {
$fi = [IO.FileInfo]$global:GraphMigrationTable $fi = [IO.FileInfo]$global:GraphMigrationTable
$groupFi = [IO.FileInfo]($fi.DirectoryName + "\Groups\$((Remove-InvalidFileNameChars $migObj.DisplayName)).json") $groupFi = [IO.FileInfo]($fi.DirectoryName + "\Groups\$((Remove-InvalidFileNameChars $migTableGroupName)).json")
} }
if($groupFi.Exists -eq $true) if($groupFi.Exists -eq $true)
@@ -2830,26 +2934,41 @@ function Get-GraphMigrationObjectsFromFile
Remove-Property $groupObj $prop.Name Remove-Property $groupObj $prop.Name
} }
$groupObj.displayName = $groupObj.displayName.Trim()
$groupJson = ConvertTo-Json $groupObj -Depth 50 $groupJson = ConvertTo-Json $groupObj -Depth 50
} }
else else
{ {
Write-Log "No group object found for $($migObj.DisplayName). Creating a cloud group with default settings" 2 $groupName = $migTableGroupName
Write-Log "No group object found for $groupName. Creating a cloud group with default settings" 2
$dateStr = ((Get-Date).ToString("yyMMddHHmmss"))
if(($groupName.Length + $dateStr.Length) -gt 64)
{
$nickName = $groupName.Substring(0,(64-$dateStr.Length))
}
else
{
$nickName = $groupName
}
$nickName = $nickName + $dateStr
$groupJson = @" $groupJson = @"
{ {
"displayName": "$($migObj.DisplayName)", "displayName": "$($groupName)",
"groupTypes": [
],
"mailEnabled": false, "mailEnabled": false,
"mailNickname" "NotSet" "mailNickname": "$($nickName)",
"securityEnabled": true "securityEnabled": true
} }
"@ "@
} }
Write-Log "Create AAD Group $($migObj.DisplayName)" Write-Log "Create AAD Group $($migTableGroupName)"
$obj = Invoke-GraphRequest "/groups" -HttpMethod "POST" -Content $groupJson $obj = Invoke-GraphRequest "/groups" -HttpMethod "POST" -Content $groupJson
} }
if($obj)
{
$global:MigrationTableCache += (New-Object PSObject -Property @{ $global:MigrationTableCache += (New-Object PSObject -Property @{
OriginalId = $migObj.Id OriginalId = $migObj.Id
Id = $obj.Id Id = $obj.Id
@@ -2859,6 +2978,7 @@ function Get-GraphMigrationObjectsFromFile
} }
} }
} }
}
function Update-JsonForEnvironment function Update-JsonForEnvironment
{ {
param($json) param($json)
@@ -2935,7 +3055,7 @@ function Add-GraphDependencyObjects
{ {
if($global:LoadedDependencyObjects.ContainsKey($dep)) { continue } if($global:LoadedDependencyObjects.ContainsKey($dep)) { continue }
$depObjectType = $global:currentViewObject.ViewItems | Where Id -eq $Dep $depObjectType = $global:viewObjects.ViewItems | Where Id -eq $Dep
if(-not $depObjectType) if(-not $depObjectType)
{ {
@@ -2968,7 +3088,7 @@ function Add-GraphDependencyObjects
$url = "$($url.Trim())&$($depObjectType.QUERYLIST.Trim())" $url = "$($url.Trim())&$($depObjectType.QUERYLIST.Trim())"
} }
$depObjects = (Invoke-GraphRequest $url -ODataMetadata "none").Value $depObjects = (Invoke-GraphRequest $url -ODataMetadata "none" -AllPages).Value
$arrDepObjects = @() $arrDepObjects = @()
foreach($depObject in $depObjects) foreach($depObject in $depObjects)
{ {
@@ -3022,8 +3142,8 @@ function Export-GraphObjects
$objectType = $global:curObjectType $objectType = $global:curObjectType
Write-Status "Export $($objectType.Title)" Write-Status "Export $($objectType.Title)"
$global:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text") $script:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
$folder = Get-GraphObjectFolder $objectType $global:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked") $folder = Get-GraphObjectFolder $objectType $script:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked")
$folder = Expand-FileName $folder $folder = Expand-FileName $folder
@@ -3054,7 +3174,7 @@ function Export-GraphObjects
} }
Save-Setting "" "LastUsedFullPath" $folder Save-Setting "" "LastUsedFullPath" $folder
Save-Setting "" "LastUsedRoot" $global:ExportRoot Save-Setting "" "LastUsedRoot" $script:ExportRoot
Write-Status "" Write-Status ""
} }
@@ -3096,7 +3216,7 @@ function Export-GraphObject
[IO.Directory]::CreateDirectory($exportFolder) | Out-Null [IO.Directory]::CreateDirectory($exportFolder) | Out-Null
} }
if($chkExportAssignments.IsChecked -ne $true -and $obj.Assignments) if($global:chkExportAssignments.IsChecked -ne $true -and $obj.Assignments)
{ {
Remove-Property $obj "Assignments" Remove-Property $obj "Assignments"
} }
@@ -3172,12 +3292,23 @@ function Set-GraphNavigationProperties
# Is this the correct way of filter out Assignments, summaries etc.? # Is this the correct way of filter out Assignments, summaries etc.?
if($prop.ContainsTarget -eq $true) { continue } if($prop.ContainsTarget -eq $true) { continue }
if(-not ($oldObj."$($prop.Name)@odata.associationLink")) { continue } if(-not ($oldObj."$($prop.Name)@odata.associationLink")) { continue }
$associationLink = $oldObj."$($prop.Name)@odata.associationLink" -replace $oldObj.Id,$newObj.Id $associationLink = $oldObj."$($prop.Name)@odata.associationLink" -replace $oldObj.Id,$newObj.Id
$refBodyObjs = $null #@() $refBodyObjs = @()
$refObjName = $null $refObjName = $null
$refObjId = $null $refObjId = $null
if($prop.Type -like "Collection(*")
{
$multiNavProperty = $true
$method = "POST"
}
else
{
$multiNavProperty = $false
$method = "PUT"
}
if($FromOldObject -eq $true) if($FromOldObject -eq $true)
{ {
@@ -3185,13 +3316,26 @@ function Set-GraphNavigationProperties
if(-not $navProp) { continue } if(-not $navProp) { continue }
$refObjName = Get-GraphObjectName $navProp $navProp if($multiNavProperty)
$refObjId = $navProp.Id {
$navProperties = $navProp.Value
}
else
{
$navProperties = $navProp
}
$refBodyObjs = ([PSCustomObject]@{ foreach($navProp in $navProperties)
{
$refBodyObjs += [PSCustomObject]@{
RefObjName = $navProp.displayName ### NOT Correct. Migh be another property but we don't know the type
RefObjId = $navProp.Id
RefBody = ([PSCustomObject]@{
"@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($navProp.Id)')") "@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($navProp.Id)')")
}) })
} }
}
}
else else
{ {
if(-not ($oldObj."#CustomRef_$($prop.Name)")) { continue } # Not included in the export file if(-not ($oldObj."#CustomRef_$($prop.Name)")) { continue } # Not included in the export file
@@ -3199,13 +3343,15 @@ function Set-GraphNavigationProperties
$idx = $oldObj."#CustomRef_$($prop.Name)".IndexOf("|:|") $idx = $oldObj."#CustomRef_$($prop.Name)".IndexOf("|:|")
if($idx -gt -1) if($idx -gt -1)
{ {
$refObjName = $oldObj."#CustomRef_$($prop.Name)".SubString(0,$idx) $refObjNames = $oldObj."#CustomRef_$($prop.Name)".SubString(0,$idx)
} }
else else
{ {
$refObjName = $oldObj."#CustomRef_$($prop.Name)" $refObjNames = $oldObj."#CustomRef_$($prop.Name)"
} }
foreach($refObjName in $refObjNames.Split(","))
{
$refObjects = Invoke-GraphRequest -URL "$($objectType.API)?`$filter=$($nameProp) eq '$($refObjName)'" -NoError $refObjects = Invoke-GraphRequest -URL "$($objectType.API)?`$filter=$($nameProp) eq '$($refObjName)'" -NoError
$objectsFound = ($refObjects.value | measure).Count $objectsFound = ($refObjects.value | measure).Count
@@ -3215,10 +3361,13 @@ function Set-GraphNavigationProperties
# Are there any references that allows multiple ref objects? # Are there any references that allows multiple ref objects?
foreach($refObj in $refObjects.value) foreach($refObj in $refObjects.value)
{ {
$refBodyObjs = ([PSCustomObject]@{ $refBodyObjs += [PSCustomObject]@{
RefObjName = $refObjName
RefObjId = $refObj.Id
RefBody = ([PSCustomObject]@{
"@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($refObj.Id)')") "@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($refObj.Id)')")
}) })
$refObjId = $refObj.Id }
} }
} }
elseif($objectsFound -gt 1) elseif($objectsFound -gt 1)
@@ -3232,17 +3381,20 @@ function Set-GraphNavigationProperties
continue continue
} }
} }
}
Write-Log "Add $refObjName ($refObjId) to navigation property $($prop.Name)" foreach($refObject in $refBodyObjs)
{
$body = $refBodyObjs | ConvertTo-Json -Depth 50 Write-Log "Add $($refObject.RefObjName) ($($refObject.RefObjId)) to navigation property $($prop.Name)"
Invoke-GraphRequest -URL $associationLink -HttpMethod "PUT" -Content $body | Out-Null $body = $refObject.RefBody | ConvertTo-Json -Depth 50
Invoke-GraphRequest -URL $associationLink -HttpMethod $method -Content $body | Out-Null
}
} }
} }
<# <#
Add Navigation Property data to the object so it included in the exported json file Add Navigation Property data to the object so they are included in the exported json file
#> #>
function Add-GraphNavigationProperties function Add-GraphNavigationProperties
{ {
@@ -3302,10 +3454,9 @@ function Get-GraphBatchObjects
{ {
param($objects, $txtNameFilter) param($objects, $txtNameFilter)
$curBatch = 1
$batchResults = @() $batchResults = @()
$batchArr = @() $batchArr = @()
$batchTotal = 0 $skipped = 0
$objectType = $null $objectType = $null
foreach($obj in $objects) foreach($obj in $objects)
@@ -3315,7 +3466,7 @@ function Get-GraphBatchObjects
if($objName -and $txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter)) if($objName -and $txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{ {
$batchTotal++ $skipped++
} }
else else
{ {
@@ -3327,17 +3478,59 @@ function Get-GraphBatchObjects
headers = @{"Accept"="application/json;odata.metadata=$ometadata"} headers = @{"Accept"="application/json;odata.metadata=$ometadata"}
} }
} }
if($batchArr.Count -eq 20 -or ($batchTotal + $batchArr.Count -eq $objects.Count))
{
$batchObj = [PSCustomObject]@{
requests = $batchArr
} }
Write-Status "Get batch $curBatch $($obj.ObjectType.Title)" -Force if($batchArr.Count -eq 0) { return }
$batchResults = @((Invoke-GraphBatchRequest $batchArr $objectType.Title).body)
if(($batchResults | measure).Count -ne ($objects.Count - $skipped))
{
Write-Log "Not all batch objects returned. Expected $($objects.Count - $skipped) but only got $(($batchResults | measure).Count)"
}
if($objectType -and ($batchResults | measure).Count -gt 0)
{
$batchResultsTmp = $batchResults
$batchResults = Add-GraphObjectProperties $batchResultsTmp $objectType -property $objectType.ViewProperties
$curObj = 1
foreach($obj in $batchResults)
{
if($obj.Object -and $obj.ObjectType.PostGetCommand)
{
Write-Status "Run PostGetCommand - $((Get-GraphObjectName $obj.Object $obj.ObjectType)) ($($curObj)/$(@($batchResults).Count))" -Force
& $obj.ObjectType.PostGetCommand $obj $obj.ObjectType
}
$curObj++
}
}
$batchResults
}
function Invoke-GraphBatchRequest
{
param($batchObjects, $batchType, [switch]$SkipWarnings, [switch]$IncludedFailed)
$batchArr = @()
$batchResults = @()
$batchTotal = 0
$curBatch = 1
foreach($obj in $batchObjects)
{
$batchArr += $obj
if($batchArr.Count -eq 20 -or (($batchTotal + $batchArr.Count) -eq $batchObjects.Count))
{
$batchObj = [PSCustomObject]@{
requests = @($batchArr)
}
Write-Status "Get batch $curBatch $batchType" -Force
$batchTotal += $batchArr.Count $batchTotal += $batchArr.Count
$json = $batchObj | ConvertTo-Json -Depth 50 $json = $batchObj | ConvertTo-Json -Depth 50
$maxRetryCount = 10 $maxRetryCount = 10
$curRetry = 0 $curRetry = 0
@@ -3346,10 +3539,11 @@ function Get-GraphBatchObjects
$retry = $false $retry = $false
$retryArr = @() $retryArr = @()
$retryAfter = 0 $retryAfter = 0
$tmpResults = Invoke-GraphRequest -Url "`$batch" -Content $json -HttpMethod "POST" -Batch #-Url $api -property $obj.ObjectType.ViewProperties -objectType $obj.ObjectType - $tmpResults = Invoke-GraphRequest -Url "`$batch" -Body $json -Method "POST"
foreach($batchResult in ($tmpResults.responses | Sort -Property Id)) foreach($batchResult in ($tmpResults.responses | Sort -Property Id))
{ {
if($batchResult.Status -ne "200" -or -not $batchResult.body) if($batchResult.Status -ge 300 -or -not $batchResult.body)
{ {
$reqObj = $batchObj.requests | where id -eq $batchResult.Id $reqObj = $batchObj.requests | where id -eq $batchResult.Id
if($batchResult.Status -eq 429 -and $reqObj) if($batchResult.Status -eq 429 -and $reqObj)
@@ -3365,12 +3559,20 @@ function Get-GraphBatchObjects
$retryArr += $reqObj $retryArr += $reqObj
} }
else else
{
if($SkipWarnings -ne $true)
{ {
Write-Log "Batch result $($batchResult.Status) for URL $($reqObj.URL). Skipping..." 2 Write-Log "Batch result $($batchResult.Status) for URL $($reqObj.URL). Skipping..." 2
} }
if($IncludedFailed -eq $true)
{
$batchResults += $batchResult
}
}
continue continue
} }
$batchResults += $batchResult.body $batchResults += $batchResult
} }
if($retryArr.Count -gt 0) if($retryArr.Count -gt 0)
@@ -3399,27 +3601,11 @@ function Get-GraphBatchObjects
} }
} }
if($batchResults.Count -ne $objects.Count) if($batchResults.Count -ne $batchObjects.Count -and $SkipWarnings -ne $true)
{ {
Write-Log "Not all batch objects returned. Expected $($objects.Count) but only got $($batchResults.Count)" Write-Log "Not all batch objects returned. Expected $($batchObjects.Count) but only got $($batchResults.Count)" 2
} }
if($objectType -and $batchResults.Count -gt 0)
{
$batchResultsTmp = $batchResults
$batchResults = Add-GraphObjectProperties $batchResultsTmp $objectType -property $objectType.ViewProperties
$curObj = 1
foreach($obj in $batchResults)
{
if($obj.Object -and $obj.ObjectType.PostGetCommand)
{
Write-Status "Get full info - $((Get-GraphObjectName $obj.Object $obj.ObjectType)) ($($curObj)/$(@($batchResults).Count))" -Force
& $obj.ObjectType.PostGetCommand $obj $obj.ObjectType
}
$curObj++
}
}
$batchResults $batchResults
} }
@@ -4032,6 +4218,12 @@ function Get-GraphObjectName
{ {
param($obj, $objectType) param($obj, $objectType)
if($objectType.GetObjectName)
{
return (& $objectType.GetObjectName $obj $objectType)
}
$obj."$((?? ($objectType.NameProperty) "displayName"))" $obj."$((?? ($objectType.NameProperty) "displayName"))"
} }
@@ -4221,7 +4413,7 @@ function Save-GraphObjectToFile
function Get-GraphObjectFile function Get-GraphObjectFile
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
$fileName = (Get-GraphObjectName $obj $objectType) $fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id) if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
{ {
+278
View File
@@ -1,4 +1,282 @@
# Release Notes # Release Notes
## 3.9.6 - 2024-04-22
**BREAKING CHANGE**<br />
Microsoft are decommissioning the Intune PowerShell App with id d1ddf0e4-d672-4dae-b554-9d5bdfd93547, mentioned [here](https://learn.microsoft.com/en-us/mem/intune/fundamentals/whats-new#plan-for-change-update-your-powershell-scripts-with-a-microsoft-entra-id-registered-app-id-by-april-2024)<br />
This was the default app in IntuneManagement. The default app is now changed to Microsoft Graph PowerShell app with id 14d82eec-204b-4c2f-b7e8-296a70dab67e<br />
The script will automatically use that app for new installationsbr<br />
A warning to change will be displayed if d1ddf0e4-d672-4dae-b554-9d5bdfd93547 is used<br />
You can also register a new app, documented [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) and then configure that app in Settings<br />
<br />
*Note*: This might require consent for the required permissions<br />
<br />
There is no change if you are currently using a custom app or already changed to Microsoft Graph PowerShell in Settings<br />
<br />
Also note that changing application will reset cached accounts<br />
**New features**
- **Compare**<br />
- Added support for ignoring Basic properties and Assignments<br />
Based on [Issue 203](https://github.com/Micke-K/IntuneManagement/issues/203) and [Issue 128](https://github.com/Micke-K/IntuneManagement/issues/128)<br />
**NOTE:** Properties will be logged but with empty value for Match<br />
**Fixes**
- **Compare**<br />
- Fixed issue when comparing Settings Catalog settings with child settings eg Hardened UNC Paths in Security Baseline<br />
- **Import/Export**<br />
- Added support for import of MSIX app content<br />
Based on [Discussion 191](https://github.com/Micke-K/IntuneManagement/discussions/191)<br />
- Disable autoload of modules to prevent loading MSGraph module if found<br />
Based on [Issue 208](https://github.com/Micke-K/IntuneManagement/issues/208)<br />
- **Documentation**<br />
- Language files re-generated.<br />
- AppTypes file re-generated. Some apps were not documented with proper name.<br />
<br />
## 3.9.5 - 2024-01-20
**Fixes**
- **Import/Export**<br />
- Assignments were not exported for some policies with trailing . in the name<br />
Based on [Issue 184](https://github.com/Micke-K/IntuneManagement/issues/184)<br />
**NOTE:** Policy will not export if full path is over 260 characters<br />
- Fixed issue with policies not being exported when Batch was enabled in Settings<br />
and there was only one policy for the specified object type<br />
- Failed to get App Protection policies when Proxy was configured<br />
- Fixed issue with importing policies with dependency in tenants with 100+ policies for a single policy type<br />
Dependency only imported first page. All pages will be imported now to resolve dependencies<br />
Based on [Issue 183](https://github.com/Micke-K/IntuneManagement/issues/183)<br />
- Fixed issue with multiple export folders when using %DateTime% in path<br />
Based on [Issue 189](https://github.com/Micke-K/IntuneManagement/issues/189)<br />
- **Get Assignment Filter usage**<br />
- Filters not returned if only assigned to one policy<br />
Based on [Issue 141](https://github.com/Micke-K/IntuneManagement/issues/141)<br />
**NOTE:** Start the tool from: Views -> Intune Tools -> Intune Filter Usage<br />
- **Compare**<br />
- Comparing Settings Catalog objects with exported objects failed<br />
Issue cause by offline documentation was not working<br />
Based on [Issue 183](https://github.com/Micke-K/IntuneManagement/issues/183)<br />
- **Documentation**<br />
- Offline documentation of Settings Catalog was not working.<br />
Values were always documented from online object<br />
- Conditional Access documentation updates for Android and iOS<br />
- App Protection documentation updates for Android and iOS<br />
- Language files re-generated. Azure shou now be Entra for some documentations.<br />
<br />
## 3.9.4 - 2023-12-18
**Fixes**
- **Get Assignment Filter usage**<br />
- All policies that supports filter should now be collected<br />
Please create an issue if not all expected filters are listed<br />
Based on [Issue 141](https://github.com/Micke-K/IntuneManagement/issues/141)<br />
**NOTE:** Start the tool from: Views -> Intune Tools -> Intune Filter Usage<br />
- **Documentation**<br />
- Added support for documenting Conditional Access policies based on Workloads<br />
Not 100% tested. Please report if not documented correctly<br />
<br />
## 3.9.3 - 2023-12-11
**New features**
- **New tool - Get Assignment Filter usage**<br />
- List all policies and assignments with a Filter defined<br />
Based on [Issue 141](https://github.com/Micke-K/IntuneManagement/issues/141)<br />
**NOTE:** Start the tool from: Views -> Intune Tools -> Intune Filter Usage<br />
- **Batch Export of App Content Encryption Key from Intunewin files**<br />
This script can export encryption keys from existing intunewin files<br />
Example:<br />
Export-EncrytionKeys -RootFolder C:\Intune\Packages -ExportFolder C:\Intune\Download<br />
This will export the encryption key information for each .intunewinfiles under C:\Intune\Packages<br />
One json file will be created (for each .intunwinfile) in the C:\Intune\Download folder<br />
File name will be **<*IntunewinFileBaseName*>_<*UnencryptedFileSize*>.json**<br />
Do **NOT** rename this file since the script will search for that file when downloading or exporting App content<br />
The script will not require authentication and it will have no knowledge of apps in Intune<br />
Filename and unencrypted file size is used as the identifier to match app content in Intune with encryption file<br />
**Important notes:**<br />
Exported and decrypted .intunewin files are not supported to use for import at the moment.<br />
These files are just the "zip" version of the source and can be unzipped with any zip extraction tool<br />
The .intunewin file used for import has the "zip" version of the file and an xml with the encryption information +<br />
additional file information eg. msi properties, file size etc.<br />
Use the exported unencrypted "zip" version to restore the original files. Re-run the packaging tool if it should be re-used as applications content<br />
<br />
Please report any issues or create a discussion if there are any questions<br />
Script is located: **<*RootFolder*>\Scripts\Export-EncrytionKeys.ps1**<br />
<br />
**Fixes**
- **Export**<br />
- Fixed issue where Assignments were included in export even if 'Export Assignments' was unchecked<br />
Based on [Issue 171](https://github.com/Micke-K/IntuneManagement/issues/171)<br />
- **Documentation**<br />
- Fixed issue where filter was not documented on some policies<br />
- Fixed issue with Word Output provider if a policy only had one settings<br />
- **Custom ADMX Files**<br />
- Fixed bug with migrating custom policies between environments. Cache was not cleared when swapping tenants or imported additional ADMX files<br />
- Fixed documentention issue with Administrative template policies in GCC environment. Name and Category was missing<br />
Based on [Issue 174](https://github.com/Micke-K/IntuneManagement/issues/174)<br />
- Custom ADMX based policies was missing properties when swapping tenant<br />
Based on [Issue 124](https://github.com/Micke-K/IntuneManagement/issues/124)<br />
- **Generic**<br />
- Fixed logging issues when processing objects with a group that was deleted. ID was not reported<br />
- Generic Batch request function created to support other batch requests eg Groups<br />
<br />
## 3.9.2 - 2023-10-17
**New features**
- **Application Content Export - Experimental**<br />
- Added support for Exporting Appliction with decrypted content<br />
App file can be downloaded during export or from the detail view of the Application<br />
Enable "Save Encryption File" and specify "App download folder" in Settings<br />
"App download folder" is used for encryption file and manual download<br />
File content will be downloaded to the export foler during export<br />
Files will be downloaded with .encrypted extension and then decrypted to original file name<br />
Please report any issue or any suggestions<br />
**NOTE:** This will ONLY work if the encryption file is exported and available<br />
- **Authentication**<br />
- Login with application<br />
This will login with specified Azure App ID and Secret/Certificate that is used for Batch processes<br />
NOTE: This will require a restart of the app<br />
Start with app **must** use -TenantID on command line. AppID and Secret/Certificate can be specified in Settings or command line<br />
Example: Start-IntuneManagement.ps1 -tenantId \"&lt;TenantID&gt;\" -appid \"&lt;AppID&gt;\" -secret \"&lt;Secret&gt;\"<br />
See *Start-WithApp.cmd* for samle file<br />
Based on [Issue 122](https://github.com/Micke-K/IntuneManagement/issues/122) and [Issue 134](https://github.com/Micke-K/IntuneManagement/issues/134)<br />
- **Support for new Settings**<br />
- Save encryption file - Saves a json file with encryption data when an application file is uploaded eg created or uploaded in details view<br />
- App download folder - Folder where application files should be downloaded and decrypted<br />
- Login with App in UI (Preview) - Use app batch login in UI<br />
- Use Graph 1.0 (Not Recommended) - Use Graph v1.0 instead of Beta. **Note:** Some features will NOT work in v1.0<br />
Based on [Issue 170](https://github.com/Micke-K/IntuneManagement/issues/170)<br />
**Fixes**
- **Documentation**<br />
- Language files re-generated eg Supersedence (preview) -> Supersedence<br />
- Added support for documenting "Filter for devices" info for Conditional Access policies<br />
Based on [Issue 168](https://github.com/Micke-K/IntuneManagement/issues/168)<br />
- **Custom ADMX Files**<br />
- Fixed issues with migrating custom policies between environments (3rd time)<br />
Based on [Issue 124](https://github.com/Micke-K/IntuneManagement/issues/124)<br />
- Fixed issue when importing ADMX files - Encoding issue eg ADMX/ADML file was UTF8<br />
Based on [Issue 169](https://github.com/Micke-K/IntuneManagement/issues/169)<br />
- **Importing Windows LoB Apps**<br />
- Fixed issue when importing LoB Apps that was only targeted to System context<br />
Available Assignment option was missing after import<br />
Based on [Discussion 164](https://github.com/Micke-K/IntuneManagement/discussions/164)<br />
- Added support for Depnedency and Supersedence reations at import<br />
Application will need to be re-exported since additinal data is added to the export file<br />
Based on [Discussion 159](https://github.com/Micke-K/IntuneManagement/discussions/159)<br />
- **Generic**<br />
- Fixed issue when compiling Procxy CS file<br />
- Tls 1.2 is now enforced.<br />
Based on [Discussion 166](https://github.com/Micke-K/IntuneManagement/discussions/166)<br />
<br />
## 3.9.1 - 2023-08-30
**New features**
- **Added support for Windows Update Driver Policies**<br />
- **Support for new Settings**<br />
- Proxy configuration - If configured, Proxy will be used for authentication, APIs and upload<br />
- Disable Write-Error output - Skip PowerShell errors in output<br />
**Default Settings Value Changes**
- Conditional Access policies will now be imported as Disabled by default<br />
- New import option added: As Exported - Change On to Report-only<br />
- This is to avoid being locked out from the tenant when importing Conditional Access policies<br />
- Based on [Discussion 139](https://github.com/Micke-K/IntuneManagement/discussions/139)<br />
**Fixes**
- **Documentation**<br />
- Fixed issues with some Feature Updates properties<br />
- Added missing strings on Windows Update polices<br />
- Regenerated Language files and Translation tables for Template policies<br />
Note: Conditional Access string has changed file in background. Please report if there is anything missing<br />
- **Custom ADMX Files**<br />
- Fixed issues with migrating custom policies between environments<br />
- Case reopened due to something broke the initial functionality<br />
- Only custom ADMX policies with #Definition properties can be imported into a new environment<br />
- Based on [Issue 124](https://github.com/Micke-K/IntuneManagement/issues/124)<br />
- **Scope Tags**<br />
- Fixed issues with importing policies with Scope Tags but they were not set<br />
- Based on [Issue 133](https://github.com/Micke-K/IntuneManagement/issues/133)<br />
**Generic**<br />
- Remove invalid characters from path.<br />
- Based on [Issue 150](https://github.com/Micke-K/IntuneManagement/issues/150)<br />
<br />
## 3.9.0 - 2023-05-04
**New features**
- **Added support for Authentication Context objects**<br />
- These are used by Conditional Access policies<br />
Based on [Issue 109](https://github.com/Micke-K/IntuneManagement/issues/109)<br />
- **Added support for Windows 365 Cloud PC settings**<br />
- Based on [Issue 125](https://github.com/Micke-K/IntuneManagement/issues/125)<br />
- **Added support for Export/Import Tennant Settings**<br />
- This is added the Intune Info view for now (Views -> Intune Info)<br />
This means that there is no support for Bulk Import/Export. It must be done manually<br />
This is to minimize the risk of re-importing Tenant settings<br />
Based on [Discussion 131](https://github.com/Micke-K/IntuneManagement/discussions/131)<br />
**Fixes**
- **Documentation**<br />
- Added full documentation of Requirement and Detection rules for Win Apps<br />
Based on [Issue 119](https://github.com/Micke-K/IntuneManagement/issues/119)<br />
- Fixed issue were documentation could crash if Reusable Settings policies exists<br />
Based on [Issue 123](https://github.com/Micke-K/IntuneManagement/issues/123)<br />
- Regenerated Language files and Translation tables for Template policies<br />
- **Intunwin File Upload**<br />
- Fixed issue when uploading very large files<br />
Based on [Issue 112](https://github.com/Micke-K/IntuneManagement/issues/112)<br />
- Fixed issue when IE not installed<br />
- **Compare**<br />
- Fixed issue where Compare could generate an exception in the log<br />
Based on [Issue 128](https://github.com/Micke-K/IntuneManagement/issues/128)<br />
**Note:** Issue 128 is only partially fixed. Compare needs a major update to fix the rest<br />
- **Import**<br />
- Fixed an issue when creating Cloud groups based on on-prem groups without MigTable<br />
- Fixed an issue when importing groups with a space in the beginning<br />
**Note:** Inital spaces will be removed when importing groups<br />
- Fixed issue when importing Endpoint Status Page polices with applications defined<br />
- Fixed issue when importing Proactive Remediations (Health Scripts) with assignments<br />
- Fixed issue when importing a Conditional Policy with Session propery disableResilienceDefaults set to $false<br />
- Fixed issue when importing WiFi profiles. Support for multiple references was added eg multiple server verification certificates<br />
Based on [Issue 114](https://github.com/Micke-K/IntuneManagement/issues/114)<br />
- Terms of Use was not visible in the menu<br />
**Note:** This might generate a Consent prompt if Use Default Permissions is not enabled<br />
Additional permission required on the Azure App: Agreement.ReadWrite.All<br />
<br />
## 3.8.1 - 2023-01-26 ## 3.8.1 - 2023-01-26
**New features** **New features**
+159
View File
@@ -0,0 +1,159 @@
<#
Export encryption keys from .intunewin files.
This can be used when downloading intunewin files from Intune.
This is a prt of the IntuneManage GitHub Repository
https://github.com/Micke-K/IntuneManagement/
(c) Mikael Karlsson MIT License - https://github.com/Micke-K/IntuneManagement/blob/master/LICENSE
Exprot file name will be <IntunewinFileBaseName>_<UnencryptedFileSize>.json
Do NOT rename the exported file. The script will try to find excryption file based on the generated name.
Encryption information is file specific. If the same .intunewin file is imported in multiple tenants,
the same ecryption file can be used to decrypt it when downloading or exporting the app content.
.Sample
Export-EncrytionKeys -RootFolder C:\Intune\Packages -ExportFolder C:\Intune\Download
This will search C:\Intune\Packages and all subfolder for .intunewin files and export
the encryption keys to the C:\Intune\Download.
#>
param(
[Alias("RF")]
# Root folder where intunewin files are located.
$RootFolder,
[Alias("EF")]
# Folder where encryption files should be exported to
# If this is empty, the encryption file will be saved to the same folder as the intunewin file
$ExportFolder)
function Export-IntunewinFileObject
{
param($file, $objectName, $toFile)
try
{
Add-Type -Assembly System.IO.Compression.FileSystem
$zip = [IO.Compression.ZipFile]::OpenRead($file)
$zip.Entries | where { $_.Name -like $objectName } | foreach {
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $toFile, $true)
}
$zip.Dispose()
return $true
}
catch
{
Write-Warning "Failed to get info from $file. Error: $($_.Exception.Message)"
return $false
}
}
function Export-EncryptionKeys
{
param(
[Parameter(ValueFromPipeline=$true)]
$fileInfo,
$exportFolder = $fileInfo.DirectoryName
)
begin
{
}
process
{
if($fileInfo -isnot [IO.FileInfo]) { return }
if(-not $exportFolder) { $exportFolder = $fileInfo.DirectoryName }
$tmpFile = [IO.Path]::GetTempFileName()
if((Export-IntunewinFileObject $fileInfo.FullName "detection.xml" $tmpFile) -ne $true)
{
return
}
$tmpFI = [IO.FileInfo]$tmpFile
try
{
if($tmpFI.Length -eq 0)
{
throw "Detection.xml not exported"
}
[xml]$DetectionXML = Get-Content $tmpFile
}
catch
{
Write-Warning "Failed to export detection.xml file. Error: $($_.Exception.Message)"
return
}
finally
{
Remove-Item -Path $tmpFile -Force | Out-Null
}
# Get encryption info from detection.xml and build encryptionInfo object
$encryptionInfo = @{}
$encryptionInfo.encryptionKey = $DetectionXML.ApplicationInfo.EncryptionInfo.EncryptionKey
$encryptionInfo.macKey = $DetectionXML.ApplicationInfo.EncryptionInfo.macKey
$encryptionInfo.initializationVector = $DetectionXML.ApplicationInfo.EncryptionInfo.initializationVector
$encryptionInfo.mac = $DetectionXML.ApplicationInfo.EncryptionInfo.mac
$encryptionInfo.profileIdentifier = "ProfileVersion1"
$encryptionInfo.fileDigest = $DetectionXML.ApplicationInfo.EncryptionInfo.fileDigest
$encryptionInfo.fileDigestAlgorithm = $DetectionXML.ApplicationInfo.EncryptionInfo.fileDigestAlgorithm
$fileData = @{}
$fileData.Name = $DetectionXML.ApplicationInfo.Name
$fileData.UnencryptedContentSize = $DetectionXML.ApplicationInfo.UnencryptedContentSize
$fileData.SetupFile = $DetectionXML.ApplicationInfo.SetupFile
$msiInfo = @{}
if($DetectionXML.ApplicationInfo.MsiInfo)
{
$msiInfo.MsiPublisher = $DetectionXML.ApplicationInfo.MsiInfo.MsiPublisher
$msiInfo.MsiProductCode = $DetectionXML.ApplicationInfo.MsiInfo.Publisher
$msiInfo.MsiProductVersion = $DetectionXML.ApplicationInfo.MsiInfo.MsiProductVersion
$msiInfo.MsiPackageCode = $DetectionXML.ApplicationInfo.MsiInfo.MsiPackageCode
$msiInfo.MsiUpgradeCode = $DetectionXML.ApplicationInfo.MsiInfo.MsiUpgradeCode
$msiInfo.MsiIsMachineInstall = $DetectionXML.ApplicationInfo.MsiInfo.MsiIsMachineInstall
$msiInfo.MsiIsUserInstall = $DetectionXML.ApplicationInfo.MsiInfo.MsiIsUserInstall
$msiInfo.MsiIncludesServices = $DetectionXML.ApplicationInfo.MsiInfo.MsiIncludesServices
$msiInfo.MsiIncludesODBCDataSource = $DetectionXML.ApplicationInfo.MsiInfo.MsiIncludesODBCDataSource
$msiInfo.MsiContainsSystemRegistryKeys = $DetectionXML.ApplicationInfo.MsiInfo.MsiContainsSystemRegistryKeys
$msiInfo.MsiContainsSystemFolders = $DetectionXML.ApplicationInfo.MsiInfo.MsiContainsSystemFolders
}
# Create mobileAppContentFile object for the file
$fileEncryptionInfo = @{}
$fileEncryptionInfo.fileEncryptionInfo = $encryptionInfo
$fileEncryptionInfo.fileData = $fileData
if($msiInfo.Count -gt 0)
{
$fileEncryptionInfo.MsiInfo = $msiInfo
}
$json = $fileEncryptionInfo | ConvertTo-Json -Depth 10
if([IO.Directory]::Exists($exportFolder) -eq $false)
{
md $exportFolder | Out-Null
}
$fileName = $exportFolder + "\$($fileInfo.BaseName)_$($DetectionXML.ApplicationInfo.UnencryptedContentSize).json"
Write-Host "Save encryption for $($fileInfo.BaseName) file $fileName"
$json | Out-File -FilePath $fileName -Force -Encoding utf8
}
end
{
}
}
Get-ChildItem -Path $RootFolder -Filter "*.intunewin" -Recurse | Export-EncryptionKeys -exportFolder $ExportFolder
+1
View File
@@ -0,0 +1 @@
cmd /c powershell -version 5 -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -tenantId "<TenantID>" -appid "<AppID>" -secret "<Secret>"
+22 -8
View File
@@ -34,6 +34,8 @@
<Grid Grid.Row='2' VerticalAlignment="Stretch" > <Grid Grid.Row='2' VerticalAlignment="Stretch" >
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
@@ -44,27 +46,39 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='0'> <StackPanel Orientation="Horizontal" Grid.Row='0' Margin="0,5,5,0" >
<Label Content="Skip Basic Properties" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skip basic properties like name, description, modified etc." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='0' Name='chkSkipCompareBasicProperties' VerticalAlignment="Center" IsChecked="false" />
<StackPanel Orientation="Horizontal" Grid.Row='1' Margin="0,5,5,0" >
<Label Content="Skip Assignments" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skip comapring assignments." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='1' Name='chkSkipCompareAssignments' VerticalAlignment="Center" IsChecked="false" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='2'>
<Label Content="Save as" /> <Label Content="Save as" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specifies how the export csv should be saved. One file per ObjectType or one file for all objects." /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specifies how the export csv should be saved. One file per ObjectType or one file for all objects." />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareSave" Margin="0,5,0,0" MinWidth="250" Grid.Row='0' Grid.Column="1" HorizontalAlignment="Left" <ComboBox Name="cbCompareSave" Margin="0,5,0,0" MinWidth="250" Grid.Row='2' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" /> DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='1' > <StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='3' >
<Label Content="Comparison Type" /> <Label Content="Comparison Type" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='1' Grid.Column="1" HorizontalAlignment="Left" <ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='3' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" /> DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='2' > <StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='4' >
<Label Content="CSV Delimiter" /> <Label Content="CSV Delimiter" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating properties in the CSV file" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating properties in the CSV file" />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareCSVDelimiter" Margin="0,5,0,0" MinWidth="250" Grid.Row='2' Grid.Column="1" HorizontalAlignment="Left" /> <ComboBox Name="cbCompareCSVDelimiter" Margin="0,5,0,0" MinWidth="250" Grid.Row='4' Grid.Column="1" HorizontalAlignment="Left" />
<Grid Margin="0,0,5,0" Grid.Row='3' > <Grid Margin="0,0,5,0" Grid.Row='5' >
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
@@ -74,7 +88,7 @@
</StackPanel> </StackPanel>
</Grid> </Grid>
<DataGrid Name="dgObjectsToCompare" Margin="0,5,0,5" Grid.Row='3' Grid.Column='1' CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White" /> <DataGrid Name="dgObjectsToCompare" Margin="0,5,0,5" Grid.Row='5' Grid.Column='1' CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White" />
</Grid> </Grid>
+15 -1
View File
@@ -14,6 +14,8 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -45,10 +47,22 @@
</Grid> </Grid>
<StackPanel Orientation="Horizontal" Grid.Row='2' Margin="0,5,5,0" > <StackPanel Orientation="Horizontal" Grid.Row='2' Margin="0,5,5,0" >
<Label Content="Skip Basic Properties" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skip basic properties like name, description, modified etc." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='2' Name='chkSkipCompareBasicProperties' VerticalAlignment="Center" IsChecked="false" />
<StackPanel Orientation="Horizontal" Grid.Row='3' Margin="0,5,5,0" >
<Label Content="Skip Assignments" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skip comapring assignments." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='3' Name='chkSkipCompareAssignments' VerticalAlignment="Center" IsChecked="false" />
<StackPanel Orientation="Horizontal" Grid.Row='4' Margin="0,5,5,0" >
<Label Content="Comparison Type" /> <Label Content="Comparison Type" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='2' Grid.Column="1" HorizontalAlignment="Left" <ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='4' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" /> DisplayMemberPath="Name" SelectedValuePath="Value" />
<TextBlock Grid.Row='999' TextWrapping="Wrap" Margin="5,20,5,0" Grid.ColumnSpan="2"> <TextBlock Grid.Row='999' TextWrapping="Wrap" Margin="5,20,5,0" Grid.ColumnSpan="2">
@@ -41,22 +41,13 @@
<Button Grid.Column="4" Name="btnGetIntuneAssignments" Padding="5,2,5,2" Content="Get Assignments" ToolTip="Get assignments from the selected exported folder" /> <Button Grid.Column="4" Name="btnGetIntuneAssignments" Padding="5,2,5,2" Content="Get Assignments" ToolTip="Get assignments from the selected exported folder" />
</Grid> </Grid>
<StackPanel Grid.Row='1' Orientation="Horizontal" Margin="0,0,5,5" > <StackPanel Grid.Row='1' Orientation="Horizontal" Margin="0,0,5,0" >
<Label Content="Filter" /> <Label Content="Filter" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Filter rows" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Filter rows" />
</StackPanel> </StackPanel>
<Grid Grid.Column='1' Grid.Row='1'> <TextBox Text="" Grid.Column='1' Grid.Row='1' Margin="0,2,0,2" Name="txtIntuneAssignmentsFilter" ToolTip="Filter items" />
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Text="" Name="txtIntuneAssignmentsFilter" ToolTip="Filter items" />
</Grid>
</Grid> </Grid>
<DataGrid Name="dgIntuneAssignments" Margin="0,5,0,0" Grid.Row="1" <DataGrid Name="dgIntuneAssignments" Margin="0,5,0,0" Grid.Row="1"
+26
View File
@@ -0,0 +1,26 @@
<Viewbox Width="18" Height="18" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas Height="18" Width="18">
<Canvas.Resources>
<LinearGradientBrush x:Key="deed83ab-7995-4b1b-9000-e569a21c2014" StartPoint="0.064690001308918,0.0795900002121925" EndPoint="0.064690001308918,0.187000006437302" MappingMode="RelativeToBoundingBox">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.225" Color="#50e6ff" />
<GradientStop Offset="1" Color="#198ab3" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="deed83ab-7995-4b1b-9000-e569a21c2015" StartPoint="0.0619699992239475,0.0220100004225969" EndPoint="0.0698100030422211,0.119529999792576" MappingMode="RelativeToBoundingBox">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.225" Color="#50e6ff" />
<GradientStop Offset="1" Color="#198ab3" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Canvas.Resources>
<Path Data="M11.783 16.761a1.15 1.15 0 0 0 1.154-1.146 1.08 1.08 0 0 0-.008-.139c-.452-3.615-2.515-6.56-6.45-6.56-4 0-6.07 2.493-6.473 6.57a1.158 1.158 0 0 0 1.032 1.269 1.112 1.112 0 0 0 .116.006Z" Fill="{StaticResource deed83ab-7995-4b1b-9000-e569a21c2014}" />
<Path Data="M6.541 9.773A3.6 3.6 0 0 1 4.577 9.2l1.944 5.08 1.931-5.051a3.608 3.608 0 0 1-1.911.544Z" Fill="#FFFFFF" />
<Ellipse Canvas.Left="2.886" Canvas.Top="2.518" Width="7.256" Height="7.256" Fill="{StaticResource deed83ab-7995-4b1b-9000-e569a21c2015}" />
<Path Data="M18 8.611V7.127l-.208-.078-1.592-.521-.416-1.015L16.6 3.8l-1.047-1.046-.208.1-1.483.754-1.015-.408-.647-1.8h-1.488l-.078.208-.52 1.592-1.009.414a3.61 3.61 0 0 1 .966 1.833 2.851 2.851 0 1 1 1.422 5.32 2.884 2.884 0 0 1-.641-.078 7.369 7.369 0 0 1 1.68 2.972l.341-1.039 1.015-.417 1.717.807 1.042-1.041-.1-.208-.754-1.484.407-1.018Z" Fill="#0078d4" />
</Canvas>
</Viewbox>
+54
View File
@@ -0,0 +1,54 @@
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Grid.IsSharedSizeScope='True'>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TitleColumn" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Name="btnGetIntuneFilterUsage" Grid.Column='1' Grid.Row='0' Width="150" Padding="5,2,5,2" Content="Get Filter Usage" ToolTip="Get all Intune Filter assignment usage" />
<StackPanel Grid.Row='2' Orientation="Horizontal" Margin="5,0,0,4" >
<Label Content="Filter" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Filter rows" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='2' Text="" Margin="5,3,0,5" Name="txtIntuneFilterUsageFilter" ToolTip="Filter items" />
</Grid>
<DataGrid Name="dgIntuneFilterUsage" Margin="0,5,0,0" Grid.Row="1"
AutoGenerateColumns="False"
SelectionMode="Single"
SelectionUnit="FullRow"
CanUserAddRows="False"
ItemsSource="">
<DataGrid.Columns>
<DataGridTextColumn Header="Filter Name" Binding="{Binding FilterName}" IsReadOnly="True" />
<DataGridTextColumn Header="Policy Name" Binding="{Binding PolicyName}" IsReadOnly="True" />
<DataGridTextColumn Header="Type" Binding="{Binding PayloadType, Mode=OneWay}" IsReadOnly="True" />
<DataGridTextColumn Header="Mode" Binding="{Binding Mode}" IsReadOnly="True" />
<DataGridTextColumn Header="Group" Binding="{Binding GroupName}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0" >
<Button Name="btnIntuneFilterUsageCopy" Content="Copy" MinWidth="100" Margin="0,0,5,0" ToolTip="Copy the Filter usage as a CSV to the clipboard" />
<Button Name="btnIntuneFilterUsagesSave" Content="Save" MinWidth="100" />
</StackPanel>
</Grid>
+1 -1
View File
@@ -135,7 +135,7 @@
<Label Content="Current settings:" /> <Label Content="Current settings:" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Current property settings. Only updated when saved" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Current property settings. Only updated when saved" />
</StackPanel> </StackPanel>
<Label Name="lblObjectColumnsConfig" Content="" Margin="0,0,5,0" Grid.Row="3" /> <Label Name="lblObjectColumnsConfig" Content="" Margin="0,0,5,0" Grid.Row="3" Grid.ColumnSpan="2" />
<StackPanel Orientation="Horizontal" Grid.Column="1" Margin="5,5,5,0" Grid.Row="4" Grid.ColumnSpan="2" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" Grid.Column="1" Margin="5,5,5,0" Grid.Row="4" Grid.ColumnSpan="2" HorizontalAlignment="Right">
<Button Name="btnObjectColumnsReset" Content="Reset" Margin="0,0,5,0" Width="100" ToolTip="Revert all changes" /> <Button Name="btnObjectColumnsReset" Content="Reset" Margin="0,0,5,0" Width="100" ToolTip="Revert all changes" />
+41
View File
@@ -0,0 +1,41 @@
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Name="scrollViewerObj"
Margin="5">
<TextBlock
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="{Binding ElementName=scrollViewerObj, Path=ViewportHeight}"
Width="{Binding ElementName=scrollViewerObj, Path=ViewportWidth}"
MinWidth="500"
MinHeight="300"
>
<Bold>'Microsoft Intune PowerShell' is being decommissioned!</Bold>
<LineBreak/><LineBreak/>
The current Entra application Microsoft Intune PowerShell with id 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' is being decommissioned by Microsoft.
<LineBreak /><LineBreak />
The app might still work but might be retired at any time.
<LineBreak/>
Please change Apllication in Settings. Either use 'Microsoft Graph PowerShell' or register a custom app.
<LineBreak /><LineBreak />
See <Hyperlink Name="addCustomApp" NavigateUri="https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app"> Quickstart: Register an application with the Microsoft identity platform</Hyperlink>.
<LineBreak /><LineBreak />
<CheckBox Name='chkChangeApp' VerticalAlignment="Center" IsChecked="false" Margin="5,0,0,0" >Change app to 'Microsoft Graph PowerShell'</CheckBox>
<LineBreak /><LineBreak />
<Bold>Note:</Bold>
<LineBreak />
This might require additional consent prompt and additional app permissions.
</TextBlock>
</ScrollViewer>
<StackPanel Grid.Row='1' Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,5">
<CheckBox Name='chkSkippMessage' VerticalAlignment="Center" IsChecked="false" Margin="5,0,0,0" >Do not show this message again</CheckBox>
<Button Name="btnOK" Content="OK" Width='100' Margin="5,0,0,0" />
</StackPanel>
</Grid>
+2 -2
View File
@@ -34,9 +34,9 @@
<LineBreak /><LineBreak /> <LineBreak /><LineBreak />
<Bold>Note:</Bold> <Bold>Note:</Bold>
<LineBreak /> <LineBreak />
The 'Microsoft Intune PowerShell' Enterprise App in Azure is used by default for API calls. The 'Microsoft Graph PowerShell' Enterprise App in Azure is used by default for API calls.
<LineBreak /> <LineBreak />
Go to Settings if you want to use 'Microsoft Graph PowerShell' or a custom App. Go to Settings if you want to use a custom App. For mor info, see <Hyperlink Name="addCustomApp" NavigateUri="https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app"> Quickstart: Register an application with the Microsoft identity platform</Hyperlink>.
<LineBreak /> <LineBreak />
This software might use permissions not granted for the existing App. This software might use permissions not granted for the existing App.
<LineBreak /> <LineBreak />