mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c16f85a299 | ||
|
|
47968b4219 | ||
|
|
6ac211a2bf | ||
|
|
83c845fc33 | ||
|
|
f5613442bd | ||
|
|
ab7b062946 |
@@ -7,7 +7,7 @@ public class HttpFactoryWithProxy : IMsalHttpClientFactory
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
|
||||
public public HttpFactoryWithProxy(string proxyURI) : this(proxyURI, null, null)
|
||||
public HttpFactoryWithProxy(string proxyURI) : this(proxyURI, null, null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'CloudAPIPowerShellManagement.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '3.9.1'
|
||||
ModuleVersion = '3.9.6'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
@@ -69,7 +69,7 @@ Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Grap
|
||||
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.
|
||||
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.
|
||||
# CmdletsToExport = @()
|
||||
|
||||
@@ -88,14 +88,25 @@ function Initialize-CloudAPIManagement
|
||||
$certificate
|
||||
)
|
||||
|
||||
$PSModuleAutoloadingPreference = "none"
|
||||
|
||||
$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")
|
||||
Add-Type -AssemblyName PresentationFramework
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$global:hideUI = ($Silent -eq $true)
|
||||
$global:SilentBatchFile = $SilentBatchFile
|
||||
|
||||
if($tenantId)
|
||||
{
|
||||
$global:AzureAppId = $appId
|
||||
$global:ClientSecret = $secret
|
||||
$global:ClientCert = $certificate
|
||||
}
|
||||
|
||||
if($global:hideUI -ne $true)
|
||||
{
|
||||
# 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"
|
||||
return
|
||||
}
|
||||
$global:TenantId = $tenantId
|
||||
$global:AzureAppId = $appId
|
||||
$global:ClientSecret = $secret
|
||||
$global:ClientCert = $certificate
|
||||
}
|
||||
|
||||
$global:TenantId = $tenantId
|
||||
|
||||
|
||||
if($ShowConsoleWindow -ne $true)
|
||||
{
|
||||
Hide-Console
|
||||
|
||||
@@ -11,7 +11,7 @@ This module handles the WPF UI
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.1'
|
||||
'3.9.6'
|
||||
}
|
||||
|
||||
function Initialize-Window
|
||||
@@ -1535,7 +1535,7 @@ function Add-RegKeyToSettings
|
||||
|
||||
try
|
||||
{
|
||||
$keyObj = Get-Item -Path $regKey
|
||||
$keyObj = Get-Item -Path $regKey -ErrorAction SilentlyContinue
|
||||
foreach($keyValue in ($keyObj.GetValueNames() | Sort))
|
||||
{
|
||||
try
|
||||
@@ -2463,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 "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" {
|
||||
$global:btnAcceptConditions.IsEnabled = ($this.IsChecked -eq $true)
|
||||
@@ -2471,6 +2472,7 @@ function Get-MainWindow
|
||||
Add-XamlEvent $script:welcomeForm "btnAcceptConditions" "add_click" {
|
||||
Save-Setting "" "LicenseAccepted" "True"
|
||||
Save-Setting "" "FirstTimeRunning" "False"
|
||||
Save-Setting "" "AppChangeInformed" "true"
|
||||
Show-ModalObject
|
||||
|
||||
if($global:currentViewObject.ViewInfo.Authentication.ShowErrors)
|
||||
@@ -2490,6 +2492,35 @@ function Get-MainWindow
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -2770,6 +2801,96 @@ function Get-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-IfTrue
|
||||
Export-ModuleMember -alias * -function *
|
||||
Binary file not shown.
@@ -1099,12 +1099,12 @@
|
||||
"category": "SettingDetails.dependencyCategory"
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "supersedenceCategory",
|
||||
"nameResourceKey": "AppRelationshipStatus.Tabs.supersedence",
|
||||
"descriptionResourceKey": "",
|
||||
"entityKey": "supersededApps",
|
||||
"dataType": 20,
|
||||
"booleanActions": 0,
|
||||
"category": "SettingDetails.supersedenceCategory"
|
||||
"category": "AppRelationshipStatus.Tabs.supersedence"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@
|
||||
"value": "notConfigured"
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "microsoftEdge",
|
||||
"nameResourceKey": "microsoftEdgeOptionText",
|
||||
"descriptionResourceKey": "",
|
||||
"value": "microsoftEdge"
|
||||
},
|
||||
@@ -543,7 +543,7 @@
|
||||
{
|
||||
"nameResourceKey": "TAPSettings.Tap.numberOfDays",
|
||||
"descriptionResourceKey": "",
|
||||
"entityKey": "pinRequiredInsteadOfBiometricTimeout",
|
||||
"entityKey": "periodBeforePinReset",
|
||||
"dataType": 100,
|
||||
"booleanActions": 0,
|
||||
"category": "SettingDetails.accessRequirements"
|
||||
|
||||
@@ -306,7 +306,7 @@
|
||||
{
|
||||
"nameResourceKey": "TAPSettings.EncryptData.label",
|
||||
"descriptionResourceKey": "TAPSettings.EncryptData.tooltip",
|
||||
"entityKey": "appDataEncryptionType",
|
||||
"entityKey": "encryptOrgData",
|
||||
"dataType": 0,
|
||||
"booleanActions": 101,
|
||||
"category": "SettingDetails.dataProtection",
|
||||
@@ -354,7 +354,7 @@
|
||||
"value": "notConfigured"
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "microsoftEdge",
|
||||
"nameResourceKey": "microsoftEdgeOptionText",
|
||||
"descriptionResourceKey": "",
|
||||
"value": "microsoftEdge"
|
||||
},
|
||||
@@ -398,14 +398,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"dataType": 8,
|
||||
"nameResourceKey": "empty"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nameResourceKey": "TAPSettings.PinAccess.label",
|
||||
"descriptionResourceKey": "TAPSettings.PinAccess.tooltip",
|
||||
@@ -496,17 +494,17 @@
|
||||
{
|
||||
"nameResourceKey": "TAPSettings.Tap.numberOfDays",
|
||||
"descriptionResourceKey": "",
|
||||
"entityKey": "pinRequiredInsteadOfBiometricTimeout",
|
||||
"entityKey": "periodBeforePinReset",
|
||||
"dataType": 100,
|
||||
"booleanActions": 0,
|
||||
"category": "SettingDetails.accessRequirements"
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "TAPSettings.Tap.previousPinBlockCount",
|
||||
"descriptionResourceKey": "",
|
||||
"entityKey": "previousPinBlockCount",
|
||||
"dataType": 14,
|
||||
"booleanActions": 0,
|
||||
"nameResourceKey": "TAPSettings.AppPIN.label",
|
||||
"descriptionResourceKey": "TAPSettings.AppPIN.tooltip",
|
||||
"entityKey": "disableAppPinIfDevicePinIsSet",
|
||||
"dataType": 0,
|
||||
"booleanActions": 201,
|
||||
"category": "SettingDetails.accessRequirements"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -66,11 +66,69 @@
|
||||
{
|
||||
"nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
|
||||
"value": "basicIntegrity",
|
||||
"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
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
],
|
||||
|
||||
@@ -53,6 +53,23 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 31,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 0,
|
||||
"category": 43,
|
||||
"nameResourceKey": "complianceNoPendingSystemUpdatesName",
|
||||
"descriptionResourceKey": "complianceNoPendingSystemUpdatesDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "requireNoPendingSystemUpdates",
|
||||
"booleanActions": 1,
|
||||
"defaultValue": false,
|
||||
"policyType": 31,
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
|
||||
@@ -917,6 +917,39 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 2,
|
||||
"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": [
|
||||
|
||||
@@ -277,6 +277,35 @@
|
||||
"unconfiguredValue": "noneOption",
|
||||
"policyType": 9,
|
||||
"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
|
||||
@@ -1395,6 +1424,35 @@
|
||||
"unconfiguredValue": "noneOption",
|
||||
"policyType": 9,
|
||||
"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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 72,
|
||||
"nameResourceKey": "androidGeneralKiosk",
|
||||
"nameResourceKey": "androidRestrictedKiosk",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
|
||||
@@ -32,20 +32,6 @@
|
||||
"policyType": 13,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 10,
|
||||
"category": 90,
|
||||
"nameResourceKey": "androidTwelveDeprecationInfoBox",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 13,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
|
||||
@@ -453,7 +453,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -521,6 +521,22 @@
|
||||
"policyType": 6,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 6,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -423,7 +423,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -491,6 +491,22 @@
|
||||
"policyType": 17,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 17,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -268,6 +268,22 @@
|
||||
"policyType": 23,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 23,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -423,7 +423,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -491,6 +491,22 @@
|
||||
"policyType": 122,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 122,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -587,6 +587,22 @@
|
||||
"policyType": 50,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 50,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -587,6 +587,22 @@
|
||||
"policyType": 63,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 63,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -530,6 +530,22 @@
|
||||
"policyType": 84,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 84,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -530,6 +530,22 @@
|
||||
"policyType": 93,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 93,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
"nameResourceKey": "",
|
||||
"displayText": "4096",
|
||||
"value": "size4096",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "keySize",
|
||||
@@ -307,6 +307,22 @@
|
||||
"policyType": 103,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 103,
|
||||
"nameResourceKey": "sCEPPolicyExtendedKeyUsageAnyPurposeCloudCaWarning",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 103,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
|
||||
@@ -137,20 +137,6 @@
|
||||
"nameResourceKey": "compliancePasswordRequirementName",
|
||||
"descriptionResourceKey": "compliancePasswordRequirementDescription",
|
||||
"childSettings": [
|
||||
{
|
||||
"dataType": 10,
|
||||
"category": 113,
|
||||
"nameResourceKey": "androidTwelveDeprecationInfoBox",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
@@ -534,6 +520,410 @@
|
||||
"defaultValue": false,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "complianceWorkProfileSecurityHeader",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 0,
|
||||
"category": 113,
|
||||
"nameResourceKey": "complianceWorkProfilePasswordRequirementName",
|
||||
"childSettings": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "allAndroidVersionsPasswordHeader",
|
||||
"childSettings": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "allAndroidVersionsPasswordHeaderDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "passwordExpirationName",
|
||||
"descriptionResourceKey": "workProfilePasswordExpirationInDaysTooltipText",
|
||||
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueOneYearKey",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordExpirationInDays",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "complianceNumberOfPreviousPasswordsToBlockName",
|
||||
"descriptionResourceKey": "complianceNumberOfPreviousPasswordsToBlockTrimmedDescription",
|
||||
"emptyValueResourceKey": "numberOfPreviousPasswordsToBlockEmptyValueKey",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePreviousPasswordBlockCount",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 113,
|
||||
"nameResourceKey": "complianceMinutesOfInactivityBeforePasswordRequiredName",
|
||||
"descriptionResourceKey": "complianceMinutesOfInactivityBeforePasswordRequiredTrimmedDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "notConfigured",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "oneMinuteOption",
|
||||
"value": 1,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "fiveMinutesOption",
|
||||
"value": 5,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "tenMinutesOption",
|
||||
"value": 10,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "fifteenMinutesOption",
|
||||
"value": 15,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "thirtyMinutesOption",
|
||||
"value": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "oneHourOption",
|
||||
"value": 60,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "fourHoursOption",
|
||||
"value": 240,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "eightHoursOption",
|
||||
"value": 480,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "workProfileInactiveBeforeScreenLockInMinutes",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "androidTwelveAndAbovePasswordHeader",
|
||||
"childSettings": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "androidTwelveAndAbovePasswordHeaderDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 113,
|
||||
"nameResourceKey": "requiredPasswordComplexityName",
|
||||
"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": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "androidElevenAndBelowPasswordHeader",
|
||||
"childSettings": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 113,
|
||||
"nameResourceKey": "androidElevenAndBelowPasswordHeaderDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileRequiredPasswordTypeName",
|
||||
"descriptionResourceKey": "complianceRequiredPasswordTypeTrimmedDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "selectTypeOption",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "deviceDefault",
|
||||
"value": "deviceDefault",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "lowSecurityBiometricOption",
|
||||
"value": "lowSecurityBiometric",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "atLeastNumericOption",
|
||||
"value": "atLeastNumeric",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileMinimumPasswordLengthName",
|
||||
"descriptionResourceKey": "minimumPasswordLengthTooltipText",
|
||||
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordMinimumLength",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "numericComplex",
|
||||
"value": "numericComplex",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileMinimumPasswordLengthName",
|
||||
"descriptionResourceKey": "minimumPasswordLengthTooltipText",
|
||||
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordMinimumLength",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "atLeastAlphabeticOption",
|
||||
"value": "atLeastAlphabetic",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileMinimumPasswordLengthName",
|
||||
"descriptionResourceKey": "minimumPasswordLengthTooltipText",
|
||||
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordMinimumLength",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "atLeastAlphanumericOption",
|
||||
"value": "atLeastAlphanumeric",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileMinimumPasswordLengthName",
|
||||
"descriptionResourceKey": "minimumPasswordLengthTooltipText",
|
||||
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordMinimumLength",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "atLeastAlphanumericWithSymbolsOption",
|
||||
"value": "alphanumericWithSymbols",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 14,
|
||||
"category": 113,
|
||||
"nameResourceKey": "workProfileMinimumPasswordLengthName",
|
||||
"descriptionResourceKey": "minimumPasswordLengthTooltipText",
|
||||
"emptyValueResourceKey": "minimumPasswordLengthEmptyValueKeyFourToSixteen",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfilePasswordMinimumLength",
|
||||
"booleanActions": 0,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "workProfilePasswordRequiredType",
|
||||
"booleanActions": 0,
|
||||
"defaultValue": "deviceDefault",
|
||||
"unconfiguredValue": "deviceDefault",
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "workProfileRequirePassword",
|
||||
"booleanActions": 1,
|
||||
"defaultValue": false,
|
||||
"policyType": 30,
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1587,6 +1587,46 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 8,
|
||||
"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,
|
||||
|
||||
@@ -1563,6 +1563,46 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 12,
|
||||
"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,
|
||||
|
||||
@@ -173,6 +173,110 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 124,
|
||||
"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
|
||||
@@ -901,6 +1005,110 @@
|
||||
"booleanActions": 0,
|
||||
"policyType": 124,
|
||||
"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
|
||||
|
||||
@@ -794,749 +794,7 @@
|
||||
"entityKey": "eapType",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 149,
|
||||
"nameResourceKey": "eAPTypeName",
|
||||
"descriptionResourceKey": "eAPTypeDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "selectEAP",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "eAPFASTName",
|
||||
"value": "eapFast",
|
||||
"children": [
|
||||
{
|
||||
"value": "certificate",
|
||||
"dataType": 9,
|
||||
"category": 149,
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "authenticationMethod",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 149,
|
||||
"nameResourceKey": "pACHeading",
|
||||
"descriptionResourceKey": "empty",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "dontUsePACName",
|
||||
"value": "noProtectedAccessCredential",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "usePACName",
|
||||
"value": "useProtectedAccessCredential",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "provisionPACName",
|
||||
"value": "useProtectedAccessCredentialAndProvision",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "provisionPACAnonName",
|
||||
"value": "useProtectedAccessCredentialAndProvisionAnonymously",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "eapFastConfiguration",
|
||||
"booleanActions": 0,
|
||||
"defaultValue": "noProtectedAccessCredential",
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "eAPTLSName",
|
||||
"value": "eapTls",
|
||||
"children": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trust",
|
||||
"descriptionResourceKey": "trustDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"metadata": {
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "empty",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "trustedServerCertificateNameExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNamesName",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"dataType": 21,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trustedServerCertificateNamesName",
|
||||
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNames",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "rootCertificateForServerValidation",
|
||||
"booleanActions": 0,
|
||||
"unconfiguredValue": "notConfigured",
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "authentication",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"value": "certificate",
|
||||
"dataType": 9,
|
||||
"category": 149,
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "authenticationMethod",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "empty",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "identityCertificateForClientAuthentication",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "certificatesOption",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "enableIdentityPrivacyName",
|
||||
"descriptionResourceKey": "enableIdentityPrivacyDescription",
|
||||
"emptyValueResourceKey": "identityPrivacyExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "enableOuterIdentityPrivacy",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "eAPTTLSName",
|
||||
"value": "eapTtls",
|
||||
"children": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trust",
|
||||
"descriptionResourceKey": "trustDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"metadata": {
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "empty",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "trustedServerCertificateNameExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNamesName",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"dataType": 21,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trustedServerCertificateNamesName",
|
||||
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNames",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "rootCertificateForServerValidation",
|
||||
"booleanActions": 0,
|
||||
"unconfiguredValue": "notConfigured",
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "authentication",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 149,
|
||||
"nameResourceKey": "authenticationMethodName",
|
||||
"descriptionResourceKey": "authenticationMethodTTLSDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "notConfigured",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "usernameAndPasswordOption",
|
||||
"value": "usernameAndPassword",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 149,
|
||||
"nameResourceKey": "nonEapMethodName",
|
||||
"descriptionResourceKey": "nonEapMethodDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "selectNonEapMethod",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "pAPName",
|
||||
"value": "unencryptedPassword",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "cHAPName",
|
||||
"value": "challengeHandshakeAuthenticationProtocol",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "mSCHAPName",
|
||||
"value": "microsoftChap",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "cHAPTWOName",
|
||||
"value": "microsoftChapVersionTwo",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "nonEapAuthenticationMethodForEapTtls",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "enableIdentityPrivacyName",
|
||||
"descriptionResourceKey": "enableIdentityPrivacyDescription",
|
||||
"emptyValueResourceKey": "identityPrivacyExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "enableOuterIdentityPrivacy",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "certificatesOption",
|
||||
"value": "certificate",
|
||||
"children": [
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "empty",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "identityCertificateForClientAuthentication",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "certificatesOption",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "enableIdentityPrivacyName",
|
||||
"descriptionResourceKey": "enableIdentityPrivacyDescription",
|
||||
"emptyValueResourceKey": "identityPrivacyExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "enableOuterIdentityPrivacy",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "authenticationMethod",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "lEAPName",
|
||||
"value": "leap",
|
||||
"children": [
|
||||
{
|
||||
"value": "certificate",
|
||||
"dataType": 9,
|
||||
"category": 149,
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "authenticationMethod",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "pEAPName",
|
||||
"value": "peap",
|
||||
"children": [
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trust",
|
||||
"descriptionResourceKey": "trustDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"metadata": {
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "empty",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "trustedServerCertificateNameExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNamesName",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"dataType": 21,
|
||||
"category": 149,
|
||||
"nameResourceKey": "trustedServerCertificateNamesName",
|
||||
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "trustedServerCertificateNames",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "rootCertificateForServerValidation",
|
||||
"booleanActions": 0,
|
||||
"unconfiguredValue": "notConfigured",
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectRootCertificateForServerValidationName",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": false,
|
||||
"dataType": 8,
|
||||
"category": 149,
|
||||
"nameResourceKey": "authentication",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 16,
|
||||
"category": 149,
|
||||
"nameResourceKey": "authenticationMethodName",
|
||||
"descriptionResourceKey": "authenticationMethodName",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"nameResourceKey": "notConfigured",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "usernameAndPasswordOption",
|
||||
"value": "usernameAndPassword",
|
||||
"children": [
|
||||
{
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "enableIdentityPrivacyName",
|
||||
"descriptionResourceKey": "enableIdentityPrivacyDescription",
|
||||
"emptyValueResourceKey": "identityPrivacyExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "enableOuterIdentityPrivacy",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"nameResourceKey": "certificatesOption",
|
||||
"value": "certificate",
|
||||
"children": [
|
||||
{
|
||||
"complexOptions": [
|
||||
{
|
||||
"dataType": 4,
|
||||
"category": 149,
|
||||
"nameResourceKey": "selectCertificateProfile",
|
||||
"descriptionResourceKey": "empty",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "identityCertificateForClientAuthentication",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"dataType": 5,
|
||||
"category": 149,
|
||||
"nameResourceKey": "certificatesOption",
|
||||
"descriptionResourceKey": "empty",
|
||||
"emptyValueResourceKey": "selectCertificate",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 20,
|
||||
"category": 149,
|
||||
"nameResourceKey": "enableIdentityPrivacyName",
|
||||
"descriptionResourceKey": "enableIdentityPrivacyDescription",
|
||||
"emptyValueResourceKey": "identityPrivacyExample",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"entityKey": "enableOuterIdentityPrivacy",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "authenticationMethod",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"entityKey": "eapType",
|
||||
"booleanActions": 0,
|
||||
"policyType": 68,
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -373,20 +373,6 @@
|
||||
"policyType": 13,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"dataType": 10,
|
||||
"category": 127,
|
||||
"nameResourceKey": "androidTwelveDeprecationInfoBox",
|
||||
"childSettings": [
|
||||
|
||||
],
|
||||
"options": [
|
||||
|
||||
],
|
||||
"booleanActions": 0,
|
||||
"policyType": 13,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"isSettingDescription": false,
|
||||
"showAsSectionHeader": true,
|
||||
|
||||
+582
-388
File diff suppressed because it is too large
Load Diff
+579
-385
File diff suppressed because it is too large
Load Diff
+578
-384
File diff suppressed because it is too large
Load Diff
+581
-387
File diff suppressed because it is too large
Load Diff
+586
-392
File diff suppressed because it is too large
Load Diff
+581
-387
File diff suppressed because it is too large
Load Diff
+580
-386
File diff suppressed because it is too large
Load Diff
+597
-403
File diff suppressed because it is too large
Load Diff
+580
-386
File diff suppressed because it is too large
Load Diff
+582
-388
File diff suppressed because it is too large
Load Diff
+582
-388
File diff suppressed because it is too large
Load Diff
+578
-384
File diff suppressed because it is too large
Load Diff
+580
-386
File diff suppressed because it is too large
Load Diff
+590
-396
File diff suppressed because it is too large
Load Diff
+584
-390
File diff suppressed because it is too large
Load Diff
+578
-384
File diff suppressed because it is too large
Load Diff
+578
-384
File diff suppressed because it is too large
Load Diff
+602
-408
File diff suppressed because it is too large
Load Diff
+580
-386
File diff suppressed because it is too large
Load Diff
+578
-384
File diff suppressed because it is too large
Load Diff
+63
-27
@@ -160,8 +160,8 @@ function Invoke-ViewActivated
|
||||
|
||||
function Show-CompareBulkForm
|
||||
{
|
||||
$script:form = Get-XamlObject ($global:AppRootFolder + "\Xaml\BulkCompare.xaml") -AddVariables
|
||||
if(-not $script:form) { return }
|
||||
$script:cmpForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\BulkCompare.xaml") -AddVariables
|
||||
if(-not $script:cmpForm) { return }
|
||||
|
||||
$global:cbCompareProvider.ItemsSource = @(($global:compareProviders | Where BulkCompare -ne $null))
|
||||
$global:cbCompareProvider.SelectedValue = (Get-Setting "Compare" "Provider" "export")
|
||||
@@ -210,12 +210,12 @@ function Show-CompareBulkForm
|
||||
|
||||
$global:dgObjectsToCompare.ItemsSource = $script:compareObjects
|
||||
|
||||
Add-XamlEvent $script:form "btnClose" "add_click" {
|
||||
$script:form = $null
|
||||
Add-XamlEvent $script:cmpForm "btnClose" "add_click" {
|
||||
$script:cmpForm = $null
|
||||
Show-ModalObject
|
||||
}
|
||||
|
||||
Add-XamlEvent $script:form "btnStartCompare" "add_click" {
|
||||
Add-XamlEvent $script:cmpForm "btnStartCompare" "add_click" {
|
||||
Write-Status "Compare objects"
|
||||
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
|
||||
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
|
||||
@@ -233,7 +233,7 @@ function Show-CompareBulkForm
|
||||
|
||||
Set-CompareProviderOptions $global:cbCompareProvider
|
||||
|
||||
Show-ModalForm "Bulk Compare Objects" $script:form -HideButtons
|
||||
Show-ModalForm "Bulk Compare Objects" $script:cmpForm -HideButtons
|
||||
}
|
||||
|
||||
function Set-CompareProviderOptions
|
||||
@@ -1114,12 +1114,12 @@ function Set-ColumnVisibility
|
||||
|
||||
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("`"") }
|
||||
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
|
||||
|
||||
$script:compareProperties += [PSCustomObject]@{
|
||||
$compare += [PSCustomObject]@{
|
||||
PropertyName = $name
|
||||
Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" }
|
||||
Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" }
|
||||
@@ -1127,6 +1127,11 @@ function Add-CompareProperty
|
||||
SubCategory = $subCategory
|
||||
Match = ?? $match ($value1 -eq $value2)
|
||||
}
|
||||
if($skip -eq $true) {
|
||||
$compare.Match = $null
|
||||
}
|
||||
|
||||
$script:compareProperties += $compare
|
||||
}
|
||||
|
||||
function Compare-ObjectsBasedonProperty
|
||||
@@ -1137,8 +1142,11 @@ function Compare-ObjectsBasedonProperty
|
||||
|
||||
Set-ColumnVisibility $false
|
||||
|
||||
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
|
||||
|
||||
$coreProps = @((?? $objectType.NameProperty "displayName"), "Description", "Id", "createdDateTime", "lastModifiedDateTime", "version")
|
||||
$postProps = @("Advertisements")
|
||||
$skipProps = @("@ObjectFromFile")
|
||||
|
||||
foreach ($propName in $coreProps)
|
||||
{
|
||||
@@ -1148,7 +1156,7 @@ function Compare-ObjectsBasedonProperty
|
||||
}
|
||||
$val1 = ($obj1.$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 = @()
|
||||
@@ -1156,19 +1164,21 @@ function Compare-ObjectsBasedonProperty
|
||||
{
|
||||
if($propName -in $coreProps) { continue }
|
||||
if($propName -in $postProps) { continue }
|
||||
if($propName -in $skipProps) { continue }
|
||||
|
||||
if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue }
|
||||
|
||||
$addedProps += $propName
|
||||
$val1 = ($obj1.$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)
|
||||
{
|
||||
if($propName -in $coreProps) { continue }
|
||||
if($propName -in $postProps) { continue }
|
||||
if($propName -in $skipProps) { continue }
|
||||
if($propName -in $addedProps) { continue }
|
||||
|
||||
if($propName -like "*@OData*" -or $propName -like "#microsoft.graph*") { continue }
|
||||
@@ -1178,6 +1188,7 @@ function Compare-ObjectsBasedonProperty
|
||||
Add-CompareProperty $propName $val1 $val2
|
||||
}
|
||||
|
||||
$skipAssignments = Get-XamlProperty $script:cmpForm "chkSkipCompareAssignments" "IsChecked"
|
||||
foreach ($propName in $postProps)
|
||||
{
|
||||
if(-not ($obj1.PSObject.Properties | Where Name -eq $propName))
|
||||
@@ -1186,7 +1197,7 @@ function Compare-ObjectsBasedonProperty
|
||||
}
|
||||
$val1 = ($obj1.$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
|
||||
@@ -1230,10 +1241,12 @@ function Compare-ObjectsBasedonDocumentation
|
||||
|
||||
$settingsValue = ?? $objectType.CompareValue "Value"
|
||||
|
||||
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
|
||||
|
||||
if($docObj1.BasicInfo -and -not ($docObj1.BasicInfo | where Value -eq $obj1.Id))
|
||||
{
|
||||
# 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)
|
||||
@@ -1241,7 +1254,7 @@ function Compare-ObjectsBasedonDocumentation
|
||||
$val1 = $prop.Value
|
||||
$prop2 = $docObj2.BasicInfo | Where Name -eq $prop.Name
|
||||
$val2 = $prop2.Value
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category -Skip:($skipBasicProperties -eq $true)
|
||||
}
|
||||
|
||||
$addedProperties = @()
|
||||
@@ -1250,11 +1263,16 @@ function Compare-ObjectsBasedonDocumentation
|
||||
{
|
||||
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
|
||||
$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
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
|
||||
|
||||
@@ -1265,12 +1283,18 @@ function Compare-ObjectsBasedonDocumentation
|
||||
# Add children defined on Object 1 property
|
||||
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
|
||||
$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
|
||||
|
||||
Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category
|
||||
}
|
||||
|
||||
@@ -1278,11 +1302,16 @@ function Compare-ObjectsBasedonDocumentation
|
||||
# This is to make sure all children are added under its parent and not last in the table
|
||||
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
|
||||
$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
|
||||
Add-CompareProperty $childProp.Name $val1 $val2 $prop.Category
|
||||
}
|
||||
@@ -1291,11 +1320,16 @@ function Compare-ObjectsBasedonDocumentation
|
||||
# These objects are defined only on Object 2. They will be last in the table
|
||||
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
|
||||
$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
|
||||
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
|
||||
}
|
||||
@@ -1464,12 +1498,14 @@ function Add-AssignmentInfo
|
||||
$val2 = $tmpVal
|
||||
}
|
||||
|
||||
$skipAssignments = Get-XamlProperty $script:cmpForm "chkSkipCompareAssignments" "IsChecked"
|
||||
|
||||
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
|
||||
{
|
||||
Add-CompareProperty $assignmentStr $val1 $val2 -Category $assignment.GroupMode -match $match
|
||||
Add-CompareProperty $assignmentStr $val1 $val2 -Category $assignment.GroupMode -match $match -Skip:($skipAssignments -eq $true)
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ $global:documentationProviders = @()
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'2.0.2'
|
||||
'2.2.0'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -228,6 +228,7 @@ function Get-ObjectDocumentation
|
||||
$script:applicabilityRules = @()
|
||||
$script:objectAssignments = @()
|
||||
$script:objectScripts = @()
|
||||
$script:admxCategories = $null
|
||||
|
||||
$script:ObjectTypeFullTable = @{} # Hash table with objects that should be documented in a single table eg ScopeTags
|
||||
|
||||
@@ -384,6 +385,7 @@ function Invoke-ObjectDocumentation
|
||||
$global:catRecommendedSettings = $null
|
||||
$global:intentCategoryDefs = $null
|
||||
$global:cfgCategories = $null
|
||||
$script:admxCategories = $null
|
||||
|
||||
$script:DocumentationLanguage = "en"
|
||||
$script:objectSeparator = [System.Environment]::NewLine
|
||||
@@ -879,7 +881,8 @@ function Invoke-TranslateADMXObject
|
||||
{
|
||||
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)
|
||||
{
|
||||
$definitionValue | Add-Member -MemberType NoteProperty -Name "definition" -Value $definition
|
||||
@@ -1053,15 +1056,40 @@ function Invoke-TranslateSettingsObject
|
||||
#>
|
||||
$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)
|
||||
{
|
||||
$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 = @{}
|
||||
foreach($cfgSetting in $cfgSettings)
|
||||
{
|
||||
$defObj = $cfgSetting.settingDefinitions | Where id -eq $cfgSetting.settingInstance.settingDefinitionId
|
||||
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
|
||||
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 }
|
||||
if(-not $defObj -or $script:settingCatalogasCategories.ContainsKey($defObj.categoryId)) { continue }
|
||||
|
||||
@@ -1074,7 +1102,7 @@ function Invoke-TranslateSettingsObject
|
||||
Category=$catObj
|
||||
#Settings=$catSettings
|
||||
RootCategory=$rootCatObj
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
$script:curSettingsCatologPolicy = @()
|
||||
@@ -1108,6 +1136,18 @@ function Add-SettingsSetting
|
||||
$childSettings = @()
|
||||
|
||||
$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]
|
||||
|
||||
if($settingsDef.categoryId -ne $categoryDef.rootCategoryId)
|
||||
@@ -1124,6 +1164,7 @@ function Add-SettingsSetting
|
||||
|
||||
$settingInfo = [PSCustomObject]@{
|
||||
SettingId = $settingsDef.Id
|
||||
SettingKey = ""
|
||||
SettingName = $settingsDef.Name
|
||||
Name = $settingsDef.displayName
|
||||
Description=$settingsDef.description
|
||||
@@ -1142,6 +1183,7 @@ function Add-SettingsSetting
|
||||
Show = $show
|
||||
Type = $settingInstance.'@odata.type'
|
||||
PropertyIndex = 0
|
||||
RowIndex = 0
|
||||
ChildSettings = @() #($childSettings | Sort DisplayName)
|
||||
}
|
||||
|
||||
@@ -1207,13 +1249,13 @@ function Add-SettingsSetting
|
||||
{
|
||||
$childSettingsArr = @()
|
||||
# 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
|
||||
}
|
||||
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 $childIDs)
|
||||
@@ -1224,6 +1266,7 @@ function Add-SettingsSetting
|
||||
if($tmpSetting)
|
||||
{
|
||||
$tmpSetting.Parent = $childSettings
|
||||
$tmpSetting.RowIndex = $index
|
||||
$childSettings += $tmpSetting
|
||||
$childSettingsArr += $tmpSetting
|
||||
if($settingsDef.childIds.Count -gt 1)
|
||||
@@ -1231,6 +1274,7 @@ function Add-SettingsSetting
|
||||
$tmpSetting.PropertyIndex = $childSettingsArr.Count
|
||||
}
|
||||
}
|
||||
$rowIndex++
|
||||
}
|
||||
|
||||
$settingInfo.ChildSettings += [PSCustomObject]@{
|
||||
@@ -1346,6 +1390,7 @@ function Get-IntentCategory
|
||||
return (Get-LanguageString "SecurityTemplate.firewall")
|
||||
}
|
||||
elseif($templateType -eq "securityBaseline" -or
|
||||
$templateType -eq "baseline" -or
|
||||
$templateType -eq "advancedThreatProtectionSecurityBaseline" -or
|
||||
$templateType -eq "microsoftEdgeSecurityBaseline")
|
||||
{
|
||||
@@ -1924,7 +1969,8 @@ function Get-LanguageString
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -2088,6 +2134,7 @@ function Invoke-TranslateSection
|
||||
if($prop.dataType -eq 8)
|
||||
{
|
||||
if($prop.nameResourceKey -eq "LearnMore") { continue }
|
||||
elseif($prop.nameResourceKey -eq "Empty") { $script:CurrentSubCategory = $null }
|
||||
elseif($prop.nameResourceKey -in $script:categoriesToIgnore) { continue }
|
||||
elseif($prop.nameResourceKey)
|
||||
{
|
||||
@@ -4432,7 +4479,7 @@ function local:Invoke-StartDocumentatiom
|
||||
# Add each object to the documentation
|
||||
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
|
||||
if($global:cbDocumentationType.SelectedItem.NewObjectGroup)
|
||||
{
|
||||
@@ -5041,3 +5088,18 @@ function Set-TableObjects
|
||||
$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
|
||||
}
|
||||
+355
-140
@@ -10,7 +10,7 @@ This module will also document some objects based on PowerShell functions
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.6.1'
|
||||
'1.6.4'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -35,6 +35,7 @@ function Initialize-CDDocumentation
|
||||
{
|
||||
$script:allTenantApps = $null
|
||||
$script:allTermsOfUse = $null
|
||||
$script:allAuthenticationStrength = $null
|
||||
$script:allAuthenticationContextClasses = $null
|
||||
$script:allCustomCompliancePolicies = $null
|
||||
}
|
||||
@@ -760,9 +761,10 @@ function Add-CDDocumentCustomProfileProperty
|
||||
}
|
||||
elseif($obj.'@OData.Type' -eq "#microsoft.graph.androidManagedAppProtection")
|
||||
{
|
||||
$obj | Add-Member Noteproperty -Name "overrideFingerprint" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null)
|
||||
$obj | Add-Member Noteproperty -Name "pinReset" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null)
|
||||
$obj | Add-Member Noteproperty -Name "overrideFingerprint" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null -and $obj.pinRequiredInsteadOfBiometricTimeout -ne "PT0S")
|
||||
$obj | Add-Member Noteproperty -Name "pinReset" -Value ($obj.periodBeforePinReset -ne $null -and $obj.periodBeforePinReset -ne "PT0S")
|
||||
$obj | Add-Member Noteproperty -Name "managedBrowserSelection" -Value (?: $obj.customBrowserPackageId "unmanagedBrowser" $obj.managedBrowser)
|
||||
$obj | Add-Member Noteproperty -Name "encryptOrgData" -Value ($obj.appDataEncryptionType -ne "useDeviceSettings")
|
||||
|
||||
$retValue = $true
|
||||
}
|
||||
@@ -785,9 +787,10 @@ function Add-CDDocumentCustomProfileProperty
|
||||
|
||||
$obj | Add-Member Noteproperty -Name "sendDataSelector" -Value $sendDataOption
|
||||
|
||||
$obj | Add-Member Noteproperty -Name "overrideFingerprint" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null)
|
||||
$obj | Add-Member Noteproperty -Name "pinReset" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null)
|
||||
$obj | Add-Member Noteproperty -Name "overrideFingerprint" -Value ($obj.pinRequiredInsteadOfBiometricTimeout -ne $null -and $obj.pinRequiredInsteadOfBiometricTimeout -ne "PT0S")
|
||||
$obj | Add-Member Noteproperty -Name "pinReset" -Value ($obj.periodBeforePinReset -ne $null -and $obj.periodBeforePinReset -ne "PT0S")
|
||||
$obj | Add-Member Noteproperty -Name "managedBrowserSelection" -Value (?: $obj.customBrowserPackageId "unmanagedBrowser" $obj.managedBrowser)
|
||||
$obj | Add-Member Noteproperty -Name "encryptOrgData" -Value ($obj.appDataEncryptionType -ne "useDeviceSettings")
|
||||
|
||||
$retValue = $true
|
||||
}
|
||||
@@ -2241,96 +2244,272 @@ function Invoke-CDDocumentConditionalAccess
|
||||
|
||||
Add-BasicAdditionalValues $obj $objectType
|
||||
|
||||
###################################################
|
||||
# User and groups
|
||||
###################################################
|
||||
|
||||
$ids = @()
|
||||
foreach($id in ($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups + $obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups))
|
||||
{
|
||||
if($id -in $ids) { continue }
|
||||
elseif($id -eq "GuestsOrExternalUsers") { continue }
|
||||
elseif($id -eq "All") { continue }
|
||||
elseif($id -eq "None") { continue }
|
||||
|
||||
$ids += $id
|
||||
}
|
||||
|
||||
$roleIds = @()
|
||||
foreach($id in ($obj.conditions.users.includeRoles + $obj.conditions.users.excludeRoles))
|
||||
{
|
||||
if($id -in $ids) { continue }
|
||||
$roleIds += $id
|
||||
}
|
||||
|
||||
$idInfo = $null
|
||||
|
||||
if($ids.Count -gt 0)
|
||||
{
|
||||
$ht = @{}
|
||||
$ht.Add("ids", @($ids | Unique))
|
||||
|
||||
$body = $ht | ConvertTo-Json
|
||||
|
||||
# ToDo: Get from MigFile for Offline
|
||||
$idInfo = (Invoke-GraphRequest -Url "/directoryObjects/getByIds?`$select=displayName,id" -Content $body -Method "Post").Value
|
||||
}
|
||||
|
||||
if($roleIds.Count -gt 0 -and -not $script:allAadRoles)
|
||||
{
|
||||
$script:allAadRoles =(Invoke-GraphRequest -url "/directoryRoleTemplates?`$select=Id,displayName" -ODataMetadata "minimal").value
|
||||
}
|
||||
|
||||
$includeLabel = Get-LanguageString "AzureCA.userSelectionBladeIncludeTabTitle"
|
||||
$excludeLabel = Get-LanguageString "AzureCA.userSelectionBladeExcludeTabTitle"
|
||||
|
||||
$category = Get-LanguageString "AzureCA.usersGroupsLabel"
|
||||
if($obj.conditions.clientApplications.includeServicePrincipals -or $obj.conditions.clientApplications.excludeServicePrincipals)
|
||||
{
|
||||
###################################################
|
||||
# Workload
|
||||
###################################################
|
||||
|
||||
if((($obj.conditions.users.includeUsers | Where { $_ -eq "All"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.allUsersString"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
}
|
||||
elseif((($obj.conditions.users.includeUsers | Where { $_ -eq "None"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.chooseApplicationsNone"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.userSelectionBladeSelectedUsers"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
$ids = @()
|
||||
foreach($id in ($obj.conditions.clientApplications.includeServicePrincipals + $obj.conditions.clientApplications.excludeServicePrincipals))
|
||||
{
|
||||
if($id -in $ids) { continue }
|
||||
elseif($id -eq "ServicePrincipalsInMyTenant") { continue }
|
||||
|
||||
if((($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
|
||||
$ids += $id
|
||||
}
|
||||
|
||||
$category = Get-LanguageString "AzureCA.workloadIdentities"
|
||||
|
||||
$idInfo = $null
|
||||
|
||||
if($ids.Count -gt 0)
|
||||
{
|
||||
$ht = @{}
|
||||
$ht.Add("ids", @($ids | Unique))
|
||||
|
||||
$body = $ht | ConvertTo-Json
|
||||
|
||||
# ToDo: Get from MigFile for Offline
|
||||
$idInfo = (Invoke-GraphRequest -Url "/directoryObjects/getByIds?`$select=displayName,id" -Content $body -Method "Post").Value
|
||||
}
|
||||
|
||||
if((($obj.conditions.clientApplications.includeServicePrincipals | Where { $_ -eq "ServicePrincipalsInMyTenant"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.allGuestUserLabel"
|
||||
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.servicePrincipalRadioAll"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeGuestsOrExternalUsers"
|
||||
EntityKey = "includeServicePrincipals"
|
||||
})
|
||||
}
|
||||
elseif((($obj.conditions.clientApplications.includeServicePrincipals | Where { $_ -eq "None"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.chooseApplicationsNone"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeServicePrincipals"
|
||||
})
|
||||
}
|
||||
elseif($ids.Count -gt 0 -and $obj.conditions.clientApplications.includeServicePrincipals)
|
||||
{
|
||||
#$category = Get-LanguageString "AzureCA.selectedSP"
|
||||
$tmpObjs = @()
|
||||
foreach($id in ($obj.conditions.clientApplications.includeServicePrincipals))
|
||||
{
|
||||
$idObj = $idInfo | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
if($tmpObjs.count -gt 0)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $category
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeServicePrincipals"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if($obj.conditions.clientApplications.servicePrincipalFilter)
|
||||
{
|
||||
if($obj.conditions.clientApplications.servicePrincipalFilter.mode -eq "include")
|
||||
{
|
||||
$filterMode = "included"
|
||||
}
|
||||
else
|
||||
{
|
||||
$filterMode = "excluded"
|
||||
}
|
||||
|
||||
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.AssignmentFilter.Blade
|
||||
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.AppliesTo.$filterMode"
|
||||
Value = $obj.conditions.clientApplications.servicePrincipalFilter.rule
|
||||
Category = $category
|
||||
SubCategory = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title"
|
||||
EntityKey = "excludeServicePrincipalDevices"
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.conditions.users.includeRoles.Count -gt 0)
|
||||
if((($obj.conditions.clientApplications.excludeServicePrincipals | Where { $_ -eq "ServicePrincipalsInMyTenant"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.servicePrincipalRadioAll"
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeServicePrincipals"
|
||||
})
|
||||
}
|
||||
elseif($ids.Count -gt 0)
|
||||
{
|
||||
#$category = Get-LanguageString "AzureCA.selectedSP"
|
||||
$tmpObjs = @()
|
||||
foreach($id in ($obj.conditions.clientApplications.excludeServicePrincipals))
|
||||
{
|
||||
$idObj = $idInfo | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
if($tmpObjs.count -gt 0)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $category
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeServicePrincipals"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
###################################################
|
||||
# User and groups
|
||||
###################################################
|
||||
|
||||
$ids = @()
|
||||
foreach($id in ($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups + $obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups))
|
||||
{
|
||||
if($id -in $ids) { continue }
|
||||
elseif($id -eq "GuestsOrExternalUsers") { continue }
|
||||
elseif($id -eq "All") { continue }
|
||||
elseif($id -eq "None") { continue }
|
||||
|
||||
$ids += $id
|
||||
}
|
||||
|
||||
$roleIds = @()
|
||||
foreach($id in ($obj.conditions.users.includeRoles + $obj.conditions.users.excludeRoles))
|
||||
{
|
||||
if($id -in $ids) { continue }
|
||||
$roleIds += $id
|
||||
}
|
||||
|
||||
$idInfo = $null
|
||||
|
||||
if($ids.Count -gt 0)
|
||||
{
|
||||
$ht = @{}
|
||||
$ht.Add("ids", @($ids | Unique))
|
||||
|
||||
$body = $ht | ConvertTo-Json
|
||||
|
||||
# ToDo: Get from MigFile for Offline
|
||||
$idInfo = (Invoke-GraphRequest -Url "/directoryObjects/getByIds?`$select=displayName,id" -Content $body -Method "Post").Value
|
||||
}
|
||||
|
||||
if($roleIds.Count -gt 0 -and -not $script:allAadRoles)
|
||||
{
|
||||
$script:allAadRoles =(Invoke-GraphRequest -url "/directoryRoleTemplates?`$select=Id,displayName" -ODataMetadata "minimal").value
|
||||
}
|
||||
|
||||
$category = Get-LanguageString "AzureCA.usersGroupsLabel"
|
||||
|
||||
if((($obj.conditions.users.includeUsers | Where { $_ -eq "All"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.allUsersString"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
}
|
||||
elseif((($obj.conditions.users.includeUsers | Where { $_ -eq "None"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.chooseApplicationsNone"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $includeLabel
|
||||
Value = Get-LanguageString "AzureCA.userSelectionBladeSelectedUsers"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsers"
|
||||
})
|
||||
|
||||
if((($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.allGuestUserLabel"
|
||||
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeGuestsOrExternalUsers"
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.conditions.users.includeRoles.Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in $obj.conditions.users.includeRoles)
|
||||
{
|
||||
$idObj = $script:allAadRoles | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.directoryRolesLabel"
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeRoles"
|
||||
})
|
||||
}
|
||||
|
||||
if(($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups).Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in ($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups))
|
||||
{
|
||||
if($id -eq "GuestsOrExternalUsers") { continue }
|
||||
$idObj = $idInfo | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $category
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsersGroups"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if((($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.allGuestUserLabel"
|
||||
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeGuestsOrExternalUsers"
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.conditions.users.excludeRoles.Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in $obj.conditions.users.includeRoles)
|
||||
foreach($id in $obj.conditions.users.excludeRoles)
|
||||
{
|
||||
$idObj = $script:allAadRoles | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
@@ -2340,78 +2519,31 @@ function Invoke-CDDocumentConditionalAccess
|
||||
Name = Get-LanguageString "AzureCA.directoryRolesLabel"
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeRoles"
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeRoles"
|
||||
})
|
||||
}
|
||||
|
||||
if(($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups).Count -gt 0)
|
||||
if(($obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups).Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in ($obj.conditions.users.includeUsers + $obj.conditions.users.includeGroups))
|
||||
foreach($id in ($obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups))
|
||||
{
|
||||
if($id -eq "GuestsOrExternalUsers") { continue }
|
||||
$idObj = $idInfo | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $category
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $includeLabel
|
||||
EntityKey = "includeUsersGroups"
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeUsersGroups"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if((($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.allGuestUserLabel"
|
||||
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeGuestsOrExternalUsers"
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.conditions.users.excludeRoles.Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in $obj.conditions.users.excludeRoles)
|
||||
{
|
||||
$idObj = $script:allAadRoles | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.directoryRolesLabel"
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeRoles"
|
||||
})
|
||||
}
|
||||
|
||||
if(($obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups).Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
foreach($id in ($obj.conditions.users.excludeUsers + $obj.conditions.users.excludeGroups))
|
||||
{
|
||||
if($id -eq "GuestsOrExternalUsers") { continue }
|
||||
$idObj = $idInfo | Where Id -eq $id
|
||||
$tmpObjs += ?? $idObj.displayName $id
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = $category
|
||||
Value = $tmpObjs -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = $excludeLabel
|
||||
EntityKey = "excludeUsersGroups"
|
||||
})
|
||||
}
|
||||
|
||||
###################################################
|
||||
# Cloud apps or actions
|
||||
###################################################
|
||||
@@ -2630,6 +2762,19 @@ function Invoke-CDDocumentConditionalAccess
|
||||
elseif($script:allTermsOfUse -isnot [Object[]]) { $script:allTermsOfUse = @($script:allTermsOfUse ) }
|
||||
}
|
||||
|
||||
<#
|
||||
if(-not $script:allAuthenticationStrength -and (($obj.grantControls.authenticationStrength | measure).Count -gt 0))
|
||||
{
|
||||
$script:allAuthenticationStrength = Get-DocOfflineObjects "AuthenticationStrengths"
|
||||
if(-not $script:allAuthenticationStrength)
|
||||
{
|
||||
$script:allAuthenticationStrength = (Invoke-GraphRequest -url "/identity/conditionalAccess/authenticationStrengths/policies?`$select=displayName,Id" -ODataMetadata "minimal").value
|
||||
}
|
||||
if(-not $script:allAuthenticationStrength ) { $script:allAuthenticationStrength = @()}
|
||||
elseif($script:allAuthenticationStrength -isnot [Object[]]) { $script:allAuthenticationStrength = @($script:allAuthenticationStrength ) }
|
||||
}
|
||||
#>
|
||||
|
||||
if($obj.conditions.locations.includeLocations.Count -gt 0)
|
||||
{
|
||||
$tmpObjs = @()
|
||||
@@ -2745,6 +2890,28 @@ function Invoke-CDDocumentConditionalAccess
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.conditions.devices.deviceFilter)
|
||||
{
|
||||
if($obj.conditions.devices.deviceFilter.mode -eq "include")
|
||||
{
|
||||
$filterMode = "included"
|
||||
}
|
||||
else
|
||||
{
|
||||
$filterMode = "excluded"
|
||||
}
|
||||
|
||||
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.AssignmentFilter.Blade
|
||||
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.AppliesTo.$filterMode"
|
||||
Value = $obj.conditions.devices.deviceFilter.rule
|
||||
Category = $category
|
||||
SubCategory = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title"
|
||||
EntityKey = "includeDevices"
|
||||
})
|
||||
}
|
||||
|
||||
###################################################
|
||||
# Grant
|
||||
###################################################
|
||||
@@ -2848,6 +3015,34 @@ function Invoke-CDDocumentConditionalAccess
|
||||
})
|
||||
}
|
||||
|
||||
if(($obj.grantControls.authenticationStrength | measure).Count -gt 0)
|
||||
{
|
||||
$authenticationStrngth = @()
|
||||
foreach($tmpId in $obj.grantControls.authenticationStrength)
|
||||
{
|
||||
$authenticationStrngth += ?? $obj.grantControls.authenticationStrength.displayName $tmpId
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.WhatIfBlade.authenticationStrength"
|
||||
Value = $termsOfUse -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = ""
|
||||
EntityKey = "authenticationStrength"
|
||||
})
|
||||
}
|
||||
|
||||
if(($obj.grantControls.customAuthenticationFactors | measure).Count -gt 0)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.menuItemClaimProviderControls"
|
||||
Value = $obj.grantControls.customAuthenticationFactors -join $script:objectSeparator
|
||||
Category = $category
|
||||
SubCategory = ""
|
||||
EntityKey = "customAuthenticationFactors"
|
||||
})
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.descriptionContentForControlsAndOr"
|
||||
Value = Get-LanguageString "AzureCA.$((?: ($obj.grantControls.operator -eq "OR") "requireOneControlText" "requireAllControlsText"))"
|
||||
@@ -2891,10 +3086,6 @@ function Invoke-CDDocumentConditionalAccess
|
||||
|
||||
if($obj.sessionControls.signInFrequency.isEnabled -eq $true)
|
||||
{
|
||||
if($obj.sessionControls.cloudAppSecurity.cloudAppSecurityType -eq "mcasConfigured") { $strId = "useCustomControls" }
|
||||
elseif($obj.sessionControls.cloudAppSecurity.cloudAppSecurityType -eq "monitorOnly") { $strId = "monitorOnly" }
|
||||
elseif($obj.sessionControls.cloudAppSecurity.cloudAppSecurityType -eq "blockDownloads") { $strId = "blockDownloads" }
|
||||
|
||||
if($obj.sessionControls.signInFrequency.type -eq "hours")
|
||||
{
|
||||
if($obj.sessionControls.signInFrequency.value -gt 1)
|
||||
@@ -2906,7 +3097,7 @@ function Invoke-CDDocumentConditionalAccess
|
||||
$value = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Hour.singular"
|
||||
}
|
||||
}
|
||||
else
|
||||
elseif($obj.sessionControls.signInFrequency.type -eq "days")
|
||||
{
|
||||
if($obj.sessionControls.signInFrequency.value -gt 1)
|
||||
{
|
||||
@@ -2917,6 +3108,10 @@ function Invoke-CDDocumentConditionalAccess
|
||||
$value = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Day.singular"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = Get-LanguageString "AzureCA.SessionControls.SignInFrequency.everytime"
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.label"
|
||||
@@ -2927,6 +3122,26 @@ function Invoke-CDDocumentConditionalAccess
|
||||
})
|
||||
}
|
||||
|
||||
if($null -ne $obj.sessionControls.continuousAccessEvaluation)
|
||||
{
|
||||
if($obj.sessionControls.continuousAccessEvaluation.mode -eq "strictLocation")
|
||||
{
|
||||
$value = Get-LanguageString "AzureCA.SessionControls.Cae.strictLocation"
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = Get-LanguageString "AzureCA.SessionControls.Cae.disable"
|
||||
}
|
||||
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
Name = Get-LanguageString "AzureCA.SessionControls.Cae.checkboxLabel"
|
||||
Value = $value
|
||||
Category = $category
|
||||
SubCategory = ""
|
||||
EntityKey = "continuousAccessEvaluation"
|
||||
})
|
||||
}
|
||||
|
||||
if($obj.sessionControls.persistentBrowser.isEnabled -eq $true)
|
||||
{
|
||||
Add-CustomSettingObject ([PSCustomObject]@{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.0'
|
||||
'1.0.1'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -374,7 +374,7 @@ function Invoke-HTMLProcessItem
|
||||
$isFilterAssignment = $false
|
||||
foreach($assignment in $documentedObj.Assignments)
|
||||
{
|
||||
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType"))
|
||||
if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
|
||||
{
|
||||
$isFilterAssignment = $true
|
||||
break
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.1.0'
|
||||
'1.1.1'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -331,7 +331,7 @@ function Invoke-MDProcessItem
|
||||
$isFilterAssignment = $false
|
||||
foreach($assignment in $documentedObj.Assignments)
|
||||
{
|
||||
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType"))
|
||||
if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
|
||||
{
|
||||
$isFilterAssignment = $true
|
||||
break
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#https://docs.microsoft.com/en-us/office/vba/api/overview/word
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.5.0'
|
||||
'1.6.0'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -600,7 +600,7 @@ function Invoke-WordProcessItem
|
||||
$isFilterAssignment = $false
|
||||
foreach($assignment in $documentedObj.Assignments)
|
||||
{
|
||||
if(($assignment.target.PSObject.Properties | Where Name -eq "deviceAndAppManagementAssignmentFilterType"))
|
||||
if(($assignment.PSObject.Properties | Where Name -eq "FilterMode"))
|
||||
{
|
||||
$isFilterAssignment = $true
|
||||
break
|
||||
@@ -752,7 +752,7 @@ function Add-DocTableItems
|
||||
|
||||
$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
|
||||
Set-DocObjectStyle $script:docTable $global:txtWordTableStyle.Text | Out-null
|
||||
|
||||
|
||||
+398
-41
@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.1'
|
||||
'3.9.6'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -73,6 +73,37 @@ function Invoke-InitializeModule
|
||||
SubPath = "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
|
||||
|
||||
@@ -90,7 +121,7 @@ function Invoke-InitializeModule
|
||||
Activating = { Invoke-EMActivatingView }
|
||||
Authentication = (Get-MSALAuthenticationObject)
|
||||
Authenticate = { Invoke-EMAuthenticateToMSAL @args }
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM")
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM")
|
||||
SaveSettings = { Invoke-EMSaveSettings }
|
||||
|
||||
Permissions = @()
|
||||
@@ -314,7 +345,7 @@ function Invoke-InitializeModule
|
||||
PostFileImportCommand = { Start-PostFileImportAdministrativeTemplate @args }
|
||||
PreImportCommand = { Start-PreImportAdministrativeTemplate @args }
|
||||
LoadObject = { Start-LoadAdministrativeTemplate @args }
|
||||
PropertiesToRemove = @("definitionValues")
|
||||
PropertiesToRemove = @("definitionValues","policyConfigurationIngestionType")
|
||||
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
|
||||
Icon="DeviceConfiguration"
|
||||
GroupId = "DeviceConfiguration"
|
||||
@@ -454,8 +485,10 @@ function Invoke-InitializeModule
|
||||
PreDeleteCommand = { Start-PreDeleteApplications @args }
|
||||
PostExportCommand = { Start-PostExportApplications @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"
|
||||
ScopeTagsReturnedInList = $false
|
||||
})
|
||||
@@ -686,6 +719,7 @@ function Invoke-InitializeModule
|
||||
ExpandAssignmentsList = $false
|
||||
PreFilesImportCommand = { Start-PreFilesImportADMXFiles @args }
|
||||
PreImportCommand = { Start-PreImportADMXFiles @args }
|
||||
PostImportCommand = { Start-PostImportADMXFiles @args }
|
||||
PreDeleteCommand = { Start-PreDeleteADMXFiles @args }
|
||||
ViewProperties = @("fileName","status","Id")
|
||||
PropertiesToRemove = @("languageCodes","targetPrefix","targetNamespace","policyType","revision","status","uploadDateTime")
|
||||
@@ -784,7 +818,7 @@ function Invoke-EMAuthenticateToMSAL
|
||||
{
|
||||
param($params = @{})
|
||||
|
||||
$global:EMViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM"
|
||||
$global:EMViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM"
|
||||
Set-MSALCurrentApp $global:EMViewObject.AppInfo
|
||||
& $global:msalAuthenticator.Login -Account (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser")) @params
|
||||
}
|
||||
@@ -800,7 +834,7 @@ function Invoke-EMActivatingView
|
||||
Show-MSALError
|
||||
|
||||
# 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)
|
||||
{
|
||||
$global:EMViewObject.Authentication = Get-MSALAuthenticationObject
|
||||
@@ -812,7 +846,7 @@ function Invoke-EMActivatingView
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -831,6 +865,8 @@ function Invoke-EMSaveSettings
|
||||
function Invoke-GraphAuthenticationUpdated
|
||||
{
|
||||
Set-EMUIStatus
|
||||
|
||||
$script:CustomADMXDefinitions = $null
|
||||
}
|
||||
|
||||
function Set-EMUIStatus
|
||||
@@ -1111,7 +1147,7 @@ function Start-PostExportEndpointSecurity
|
||||
{
|
||||
param($obj, $objectType, $path)
|
||||
|
||||
$fileName = (Get-GraphObjectName $obj $objectType)
|
||||
$fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
|
||||
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
|
||||
{
|
||||
$fileName = ($fileName + "_" + $obj.Id)
|
||||
@@ -1985,24 +2021,44 @@ function local:Start-ImportApp
|
||||
|
||||
if($appType -eq "microsoft.graph.win32LobApp")
|
||||
{
|
||||
Copy-Win32LOBPackage $packageFile $obj
|
||||
$fileEncryptionInfo = Copy-Win32LOBPackage $packageFile $obj
|
||||
}
|
||||
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")
|
||||
{
|
||||
Copy-iOSLOB $packageFile $obj
|
||||
$fileEncryptionInfo = Copy-iOSLOB $packageFile $obj
|
||||
}
|
||||
elseif($appType -eq "microsoft.graph.androidLOBApp")
|
||||
{
|
||||
Copy-AndroidLOB $packageFile $obj
|
||||
$fileEncryptionInfo = Copy-AndroidLOB $packageFile $obj
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
@@ -2092,6 +2148,101 @@ function Add-DetailExtensionApplications
|
||||
$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
|
||||
@@ -2177,6 +2328,47 @@ function Start-PostExportApplications
|
||||
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
|
||||
@@ -2204,26 +2396,174 @@ function Start-PostListApplications
|
||||
$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)
|
||||
|
||||
$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)"
|
||||
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)"
|
||||
}
|
||||
}
|
||||
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 ($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 "|*|")
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2256,7 +2596,7 @@ function Get-GPOObjectSettings
|
||||
"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_displayName", $definitionValue.definition.displayName)
|
||||
@@ -2274,7 +2614,7 @@ function Get-GPOObjectSettings
|
||||
# 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)')"
|
||||
|
||||
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_Label" -Value $presentationValue.presentation.label
|
||||
@@ -2298,15 +2638,15 @@ function Get-GPOObjectSettings
|
||||
|
||||
function Import-GPOSetting
|
||||
{
|
||||
param($obj, $settings, [switch]$CustomADMX)
|
||||
param($obj, $settings)
|
||||
|
||||
if($obj)
|
||||
{
|
||||
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"
|
||||
if(-not $script:CustomADMXDefinitions)
|
||||
@@ -2325,7 +2665,12 @@ function Import-GPOSetting
|
||||
Category = $tmpCat
|
||||
Presentations = $null
|
||||
}
|
||||
$script:CustomADMXDefinitions.Add($key, $val)
|
||||
try {
|
||||
$script:CustomADMXDefinitions.Add($key, $val)
|
||||
}
|
||||
catch {
|
||||
Write-Log "Failed to add '$($tmpDef.displayName)' in category '$($tmpDef.categoryPath)' of class $($tmpDef.classType)" 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2334,7 +2679,7 @@ function Import-GPOSetting
|
||||
|
||||
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
|
||||
$key = ($setting.'#Definition_displayName' + $setting.'#Definition_categoryPath' + $setting.'#Definition_classType').ToLower()
|
||||
@@ -2389,7 +2734,7 @@ function Import-GPOSetting
|
||||
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
|
||||
continue
|
||||
@@ -2397,7 +2742,7 @@ function Import-GPOSetting
|
||||
|
||||
Start-GraphPreImport $setting
|
||||
|
||||
if($true) #$isCustomADMX)
|
||||
if($true)
|
||||
{
|
||||
foreach($tmpProp in (($setting.PSObject.Properties | Where Name -like "#*").Name))
|
||||
{
|
||||
@@ -2423,7 +2768,7 @@ function Start-PostExportAdministrativeTemplate
|
||||
{
|
||||
param($obj, $objectType, $path)
|
||||
|
||||
$fileName = (Get-GraphObjectName $obj $objectType)
|
||||
$fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
|
||||
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
|
||||
{
|
||||
$fileName = ($fileName + "_" + $obj.Id)
|
||||
@@ -2462,7 +2807,7 @@ function Start-PostFileImportAdministrativeTemplate
|
||||
{
|
||||
$tmpObj = Get-GraphObjectFromFile $file
|
||||
|
||||
Import-GPOSetting $obj $settings -CustomADMX:($tmpObj.policyConfigurationIngestionType -eq "Custom")
|
||||
Import-GPOSetting $obj $settings
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2687,7 +3032,7 @@ function Start-PostExportRoleDefinitions
|
||||
{
|
||||
param($obj, $objectType, $path)
|
||||
|
||||
$fileName = (Get-GraphObjectName $obj $objectType)
|
||||
$fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
|
||||
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
|
||||
{
|
||||
$fileName = ($fileName + "_" + $obj.Id)
|
||||
@@ -3187,7 +3532,9 @@ function Add-EMAssignmentsToExportFile
|
||||
{
|
||||
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)
|
||||
{
|
||||
$fileName = ($fileName + "_" + $obj.Id)
|
||||
@@ -3515,10 +3862,13 @@ function Start-PreImportADMXFiles
|
||||
return
|
||||
}
|
||||
|
||||
$bytes = [IO.File]::ReadAllBytes($admxFile)
|
||||
#$bytes = [IO.File]::ReadAllBytes($admxFile)
|
||||
$bytes = Get-ASCIIBytes ([IO.File]::ReadAllText($admxFile))
|
||||
$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]@{
|
||||
fileName = [io.path]::GetFileName($admlFile)
|
||||
content = [Convert]::ToBase64String($bytes)
|
||||
@@ -3527,6 +3877,13 @@ function Start-PreImportADMXFiles
|
||||
$obj.defaultLanguageCode = ""
|
||||
}
|
||||
|
||||
function Start-PostImportADMXFiles
|
||||
{
|
||||
param($obj, $objectType, $file)
|
||||
|
||||
$script:CustomADMXDefinitions = $null
|
||||
}
|
||||
|
||||
function Start-PreDeleteADMXFiles
|
||||
{
|
||||
param($obj, $objectType)
|
||||
|
||||
@@ -10,7 +10,7 @@ This module is for the Endpoint Info View. It shows read-only objects in Intune
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.0'
|
||||
'3.9.6'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -27,7 +27,7 @@ function Invoke-InitializeModule
|
||||
Activating = { Invoke-EMInfoActivatingView }
|
||||
Authentication = (Get-MSALAuthenticationObject)
|
||||
Authenticate = { Invoke-EMInfoAuthenticateToMSAL }
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" "EM")
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp "EM")
|
||||
SaveSettings = { Invoke-EMSaveSettings }
|
||||
Permissions = @()
|
||||
})
|
||||
@@ -119,7 +119,7 @@ function Invoke-EMInfoActivatingView
|
||||
|
||||
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
|
||||
$usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser"))
|
||||
if($usr)
|
||||
|
||||
@@ -10,7 +10,7 @@ This module manages Application objects in Intune e.g. uploading application fil
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.1'
|
||||
'3.9.6'
|
||||
}
|
||||
|
||||
#########################################################################################
|
||||
@@ -94,14 +94,18 @@ function Copy-MSILOB
|
||||
|
||||
$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 }
|
||||
|
||||
$fileEncryptionInfo = New-IntuneEncryptedFile $msiFile $tmpFile
|
||||
|
||||
[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 = @{
|
||||
"@odata.type" = "#microsoft.graph.mobileAppContentFile"
|
||||
@@ -109,11 +113,50 @@ function Copy-MSILOB
|
||||
size = (Get-Item $msiFile).Length
|
||||
sizeEncrypted = (Get-Item $tmpFile).Length
|
||||
manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifestXML.OuterXml))
|
||||
isDependency = $false
|
||||
}
|
||||
|
||||
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
|
||||
|
||||
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
|
||||
@@ -149,6 +192,8 @@ function Copy-iOSLOB
|
||||
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
|
||||
|
||||
Remove-Item $tmpFile -Force
|
||||
|
||||
$fileEncryptionInfo
|
||||
}
|
||||
|
||||
function Copy-AndroidLOB
|
||||
@@ -185,6 +230,8 @@ function Copy-AndroidLOB
|
||||
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
|
||||
|
||||
Remove-Item $tmpFile -Force
|
||||
|
||||
$fileEncryptionInfo
|
||||
}
|
||||
|
||||
function Copy-Win32LOBPackage
|
||||
@@ -235,7 +282,7 @@ function Copy-Win32LOBPackage
|
||||
|
||||
$fileBody = @{
|
||||
"@odata.type" = "#microsoft.graph.mobileAppContentFile"
|
||||
name = $DetectionXML.ApplicationInfo.FileName
|
||||
name = "IntunePackage.intunewin"
|
||||
size = [int64]$DetectionXML.ApplicationInfo.UnencryptedContentSize
|
||||
sizeEncrypted = (Get-Item $tmpIntunewinFile).Length
|
||||
manifest = $null
|
||||
@@ -246,45 +293,58 @@ function Copy-Win32LOBPackage
|
||||
|
||||
# Remove extracted inintunewin file
|
||||
Remove-Item $tmpIntunewinPath -Force -Recurse
|
||||
|
||||
$fileEncryptionInfo
|
||||
}
|
||||
|
||||
function Add-FileToIntuneApp
|
||||
{
|
||||
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
|
||||
$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)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
Write-Log "File object created. ID: $($fileObj.id)"
|
||||
|
||||
# Wait for Azure storage URI
|
||||
$fileObj = Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "AzureStorageUriRequest"
|
||||
if(-not $fileObj)
|
||||
{
|
||||
Write-Log "No File Object returned from commit. Upload failed" 3
|
||||
return
|
||||
}
|
||||
|
||||
# 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
|
||||
$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
|
||||
$commitAppBody = @{
|
||||
"@odata.type" = "#$appType"
|
||||
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
|
||||
@@ -318,7 +378,7 @@ function Wait-IntuneFileState
|
||||
return
|
||||
}
|
||||
|
||||
Start-Sleep -s 5
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
|
||||
if($succes -eq $false)
|
||||
@@ -636,3 +696,113 @@ function New-IntuneEncryptedFile
|
||||
|
||||
$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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ $global:EMToolsViewObject = $null
|
||||
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'1.0.4'
|
||||
'1.0.5'
|
||||
}
|
||||
|
||||
function Invoke-InitializeModule
|
||||
@@ -82,7 +82,7 @@ function Add-EMToolsViewItem
|
||||
Activating = { Invoke-EMToolsActivatingView }
|
||||
Authentication = (Get-MSALAuthenticationObject)
|
||||
Authenticate = { Invoke-EMToolsAuthenticateToMSAL }
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547")
|
||||
AppInfo = (Get-GraphAppInfo "EMAzureApp" $global:DefaultAzureApp)
|
||||
SaveSettings = { Invoke-EMSaveSettings }
|
||||
Permissions = @()
|
||||
})
|
||||
@@ -121,7 +121,7 @@ function Invoke-EMToolsActivatingView
|
||||
|
||||
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
|
||||
$usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser"))
|
||||
if($usr)
|
||||
|
||||
+248
-131
@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.1'
|
||||
'3.9.3'
|
||||
}
|
||||
|
||||
$global:msalAuthenticator = $null
|
||||
@@ -158,6 +158,10 @@ function Clear-MSALCurentUserVaiables
|
||||
{
|
||||
$global:MSALTenantId = $null
|
||||
$global:MSALGraphEnvironment = $null
|
||||
|
||||
$script:jwtAccessToken = $null
|
||||
$script:jwtIdToken = $null
|
||||
|
||||
}
|
||||
|
||||
function Get-MSALCurrentApp
|
||||
@@ -223,14 +227,23 @@ function Get-MSALUserInfo
|
||||
if($global:MSALToken)
|
||||
{
|
||||
Write-Log "Get current user"
|
||||
$tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip"
|
||||
if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation")
|
||||
|
||||
if($script:jwtAccessToken.Payload.idtyp -ne "app")
|
||||
{
|
||||
### Only get user info from home tenant
|
||||
$global:Me = $tmpMe
|
||||
Write-Log "Get profile picture"
|
||||
$global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg"
|
||||
MSGraph\Invoke-GraphRequest "me/photos/48x48/`$value" -OutFile $global:profilePhoto -SkipAuthentication -NoError | Out-Null
|
||||
$tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip"
|
||||
if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation")
|
||||
{
|
||||
### Only get user info from home tenant
|
||||
$global:Me = $tmpMe
|
||||
Write-Log "Get profile picture"
|
||||
$global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg"
|
||||
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"
|
||||
@@ -834,6 +847,42 @@ function Connect-MSALUser
|
||||
|
||||
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((Show-MSALLoginMenu) -eq $false) { return }
|
||||
@@ -1099,7 +1148,7 @@ function Connect-MSALUser
|
||||
#########################################################################################################
|
||||
try
|
||||
{
|
||||
Write-Log "Get tennant list"
|
||||
Write-Log "Get tenant list"
|
||||
|
||||
# Can we reuse the app used for login?
|
||||
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($global:appObj.ClientID)
|
||||
@@ -1167,7 +1216,8 @@ function Connect-MSALUser
|
||||
Save-Setting "" "LastLoggedOnUser" $authResult.Account.UserName
|
||||
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
|
||||
}
|
||||
|
||||
Invoke-MSALAuthenticationUpdated $authResult
|
||||
<#
|
||||
Write-LogDebug "User, tenant or app has changed"
|
||||
Get-MSALUserInfo
|
||||
if($authResult)
|
||||
@@ -1175,9 +1225,26 @@ function Connect-MSALUser
|
||||
Invoke-MSALCheckObjectViewAccess $authResult
|
||||
}
|
||||
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
|
||||
{
|
||||
param([switch]$PassThru, $authToken)
|
||||
@@ -1254,6 +1321,22 @@ function Invoke-MSALCheckObjectViewAccess
|
||||
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" }))
|
||||
{
|
||||
$viewObjInfo = $global:viewObjects | Where { $_.ViewInfo.Id -eq $global:EMViewObject.Id }
|
||||
@@ -1262,10 +1345,8 @@ function Invoke-MSALCheckObjectViewAccess
|
||||
{
|
||||
if($authToken)
|
||||
{
|
||||
$accessToken = Get-JWTtoken $authToken.AccessToken
|
||||
if($accessToken.Payload.scp)
|
||||
if($curPermissions)
|
||||
{
|
||||
$curPermissions = $accessToken.Payload.scp.Split(" ")
|
||||
foreach($viewItem in $viewObjInfo.ViewItems)
|
||||
{
|
||||
$full = 0
|
||||
@@ -1563,6 +1644,10 @@ function Get-MSALProfileEllipse
|
||||
{
|
||||
$initials = "$($global:me.userPrincipalName[0])".ToUpper()
|
||||
}
|
||||
elseif($script:jwtAccessToken.Payload.idtyp -eq "app")
|
||||
{
|
||||
$initials = "APP"
|
||||
}
|
||||
|
||||
$grd = Get-MSALUserPhotoEllips -size $size -fontSize $fontSize -Color $Color
|
||||
|
||||
@@ -1586,8 +1671,15 @@ function Get-MSALProfileEllipse
|
||||
$global:grdProfileInfo.Tag = $grd
|
||||
$grd.Tag = $global:grdProfileInfo
|
||||
Set-XamlProperty $global:grdProfileInfo "txtOrganization" "Text" $global:Organization.displayName
|
||||
Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" $global:me.displayName
|
||||
Set-XamlProperty $global:grdProfileInfo "txtLogonName" "Text" $global:me.userPrincipalName
|
||||
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 "txtLogonName" "Text" $global:me.userPrincipalName
|
||||
}
|
||||
|
||||
$global:tokenInfo = Get-JWTtoken $global:MSALToken.AccessToken
|
||||
if($global:tokenInfo)
|
||||
@@ -1612,140 +1704,148 @@ function Get-MSALProfileEllipse
|
||||
$profileGrid.Children.Add($tmpObj) | Out-Null
|
||||
}
|
||||
|
||||
if($script:jwtAccessToken.Payload.idtyp -eq "app")
|
||||
{
|
||||
$tmpObj.Visibility = "Collapsed"
|
||||
}
|
||||
|
||||
$global:grdProfileInfo.Add_Loaded({param($obj, $e)
|
||||
$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]::SetTop($obj,($point.Y + $obj.Tag.ActualHeight))
|
||||
})
|
||||
|
||||
#########################################################################################################
|
||||
### Show / Hide consent button
|
||||
#########################################################################################################
|
||||
$script:userEllipsGrid = $tmpObj
|
||||
if(($script:missingPermissions | measure).Count -eq 0)
|
||||
if($script:jwtAccessToken.Payload.idtyp -ne "app")
|
||||
{
|
||||
Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Collapsed"
|
||||
}
|
||||
Add-XamlEvent $script:userEllipsGrid "lnkRequestConsent" "add_Click" {
|
||||
Start-MSALConsentPrompt
|
||||
}
|
||||
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdCachedAccounts")
|
||||
|
||||
#########################################################################################################
|
||||
### Add cached users
|
||||
#########################################################################################################
|
||||
if((Get-SettingValue "SortAccountList") -eq $true)
|
||||
{
|
||||
$accounts = $global:MSALAccounts | Sort -Property Username
|
||||
}
|
||||
else
|
||||
{
|
||||
$accounts = $global:MSALAccounts
|
||||
}
|
||||
|
||||
foreach($account in $accounts)
|
||||
{
|
||||
# Skip current logged on user
|
||||
if($global:MSALToken.Account.Username -eq $Account.Username -or
|
||||
$global:MSALToken.Account.HomeAccountId.ObjectId -eq $Account.HomeAccountId.ObjectId) { continue }
|
||||
|
||||
Add-CachedUser $account $otherLogins
|
||||
}
|
||||
|
||||
#########################################################################################################
|
||||
### Add login with another user
|
||||
#########################################################################################################
|
||||
$grdAccount = [System.Windows.Controls.Grid]::new()
|
||||
$cd = [System.Windows.Controls.ColumnDefinition]::new()
|
||||
$grdAccount.ColumnDefinitions.Add($cd)
|
||||
$cd = [System.Windows.Controls.ColumnDefinition]::new()
|
||||
$cd.Width = [double]::NaN
|
||||
$grdAccount.ColumnDefinitions.Add($cd)
|
||||
|
||||
$icon = Get-XamlObject ($global:AppRootFolder + "\Xaml\Icons\Logon.xaml")
|
||||
$icon.Width = 24
|
||||
$icon.Height = 24
|
||||
$icon.Margin = "0,0,5,0"
|
||||
$grdAccount.Children.Add($icon) | Out-Null
|
||||
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS>Sign in with a different account</TextBlock>")
|
||||
$lbObj.SetValue([System.Windows.Controls.Grid]::ColumnProperty,1)
|
||||
#$lbObj.Style = $window.TryFindResource("HoverUnderlineStyle")
|
||||
$grdAccount.Children.Add($lbObj) | Out-Null
|
||||
|
||||
$lnkButton = [System.Windows.Controls.Button]::new()
|
||||
$lnkButton.Content = $grdAccount
|
||||
$lnkButton.Style = $window.TryFindResource("LinkButton")
|
||||
$lnkButton.Margin = "0,5,0,0"
|
||||
$lnkButton.Cursor = "Hand"
|
||||
$lnkButton.Tag = $account
|
||||
$lnkButton.add_Click({
|
||||
Write-Status "Logging in..."
|
||||
Hide-Popup
|
||||
Connect-MSALUser -Interactive -ShowMenu
|
||||
if($global:curObjectType)
|
||||
#########################################################################################################
|
||||
### Show / Hide consent button
|
||||
#########################################################################################################
|
||||
$script:userEllipsGrid = $tmpObj
|
||||
if(($script:missingPermissions | measure).Count -eq 0)
|
||||
{
|
||||
Show-GraphObjects
|
||||
Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Collapsed"
|
||||
}
|
||||
Add-XamlEvent $script:userEllipsGrid "lnkRequestConsent" "add_Click" {
|
||||
Start-MSALConsentPrompt
|
||||
}
|
||||
Write-Status ""
|
||||
})
|
||||
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdLoginAccount")
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdCachedAccounts")
|
||||
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdTenantAccounts")
|
||||
|
||||
if(($script:AccessableTenants | measure).Count -gt 1)
|
||||
{
|
||||
#########################################################################################################
|
||||
### Add switch to another tenant
|
||||
### Add cached users
|
||||
#########################################################################################################
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS><Bold>Tenants:</Bold></TextBlock>")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
foreach($tenant in $script:AccessableTenants)
|
||||
if((Get-SettingValue "SortAccountList") -eq $true)
|
||||
{
|
||||
try
|
||||
$accounts = $global:MSALAccounts | Sort -Property Username
|
||||
}
|
||||
else
|
||||
{
|
||||
$accounts = $global:MSALAccounts
|
||||
}
|
||||
|
||||
foreach($account in $accounts)
|
||||
{
|
||||
# Skip current logged on user
|
||||
if($global:MSALToken.Account.Username -eq $Account.Username -or
|
||||
$global:MSALToken.Account.HomeAccountId.ObjectId -eq $Account.HomeAccountId.ObjectId) { continue }
|
||||
|
||||
Add-CachedUser $account $otherLogins
|
||||
}
|
||||
|
||||
#########################################################################################################
|
||||
### Add login with another user
|
||||
#########################################################################################################
|
||||
$grdAccount = [System.Windows.Controls.Grid]::new()
|
||||
$cd = [System.Windows.Controls.ColumnDefinition]::new()
|
||||
$grdAccount.ColumnDefinitions.Add($cd)
|
||||
$cd = [System.Windows.Controls.ColumnDefinition]::new()
|
||||
$cd.Width = [double]::NaN
|
||||
$grdAccount.ColumnDefinitions.Add($cd)
|
||||
|
||||
$icon = Get-XamlObject ($global:AppRootFolder + "\Xaml\Icons\Logon.xaml")
|
||||
$icon.Width = 24
|
||||
$icon.Height = 24
|
||||
$icon.Margin = "0,0,5,0"
|
||||
$grdAccount.Children.Add($icon) | Out-Null
|
||||
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS>Sign in with a different account</TextBlock>")
|
||||
$lbObj.SetValue([System.Windows.Controls.Grid]::ColumnProperty,1)
|
||||
#$lbObj.Style = $window.TryFindResource("HoverUnderlineStyle")
|
||||
$grdAccount.Children.Add($lbObj) | Out-Null
|
||||
|
||||
$lnkButton = [System.Windows.Controls.Button]::new()
|
||||
$lnkButton.Content = $grdAccount
|
||||
$lnkButton.Style = $window.TryFindResource("LinkButton")
|
||||
$lnkButton.Margin = "0,5,0,0"
|
||||
$lnkButton.Cursor = "Hand"
|
||||
$lnkButton.Tag = $account
|
||||
$lnkButton.add_Click({
|
||||
Write-Status "Logging in..."
|
||||
Hide-Popup
|
||||
Connect-MSALUser -Interactive -ShowMenu
|
||||
if($global:curObjectType)
|
||||
{
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS HorizontalAlignment=`"Stretch`"><Bold>$($tenant.DisplayName)</Bold><LineBreak/>$($tenant.defaultDomain)<LineBreak/>$($tenant.tenantId)</TextBlock>")
|
||||
Show-GraphObjects
|
||||
}
|
||||
Write-Status ""
|
||||
})
|
||||
|
||||
if($tenant.tenantId -ne $global:MSALToken.TenantId)
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdLoginAccount")
|
||||
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
|
||||
$otherLogins = $global:grdProfileInfo.FindName("grdTenantAccounts")
|
||||
|
||||
if(($script:AccessableTenants | measure).Count -gt 1)
|
||||
{
|
||||
#########################################################################################################
|
||||
### Add switch to another tenant
|
||||
#########################################################################################################
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS><Bold>Tenants:</Bold></TextBlock>")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
foreach($tenant in $script:AccessableTenants)
|
||||
{
|
||||
try
|
||||
{
|
||||
$lbObj.Style = $window.TryFindResource("HoverUnderlineStyleWithBackground")
|
||||
$lbObj.HorizontalAlignment = "Stretch"
|
||||
$lnkButton = [System.Windows.Controls.Button]::new()
|
||||
$lnkButton.Content = $lbObj
|
||||
$lnkButton.HorizontalAlignment = "Stretch"
|
||||
$lnkButton.Style = $window.TryFindResource("ContentButton")
|
||||
$lnkButton.Margin = "0,5,0,0"
|
||||
$lnkButton.Cursor = "Hand"
|
||||
$lnkButton.Tag = $tenant
|
||||
$lnkButton.add_Click({
|
||||
Write-Status "Logging in to $($this.Tag.DisplayName)"
|
||||
# Set authority to selected tenant
|
||||
$global:MSALTenantId = $this.Tag.tenantId
|
||||
Hide-Popup
|
||||
Connect-MSALUser -Account ($global:MSALAccounts | Where UserName -eq $global:MSALToken.Account.Username)
|
||||
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS HorizontalAlignment=`"Stretch`"><Bold>$($tenant.DisplayName)</Bold><LineBreak/>$($tenant.defaultDomain)<LineBreak/>$($tenant.tenantId)</TextBlock>")
|
||||
|
||||
if($global:curObjectType)
|
||||
{
|
||||
Show-GraphObjects
|
||||
}
|
||||
Write-Status ""
|
||||
})
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
}
|
||||
else
|
||||
{
|
||||
$lbObj.Background = $window.TryFindResource("SelectedRowBackgroundColor")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
if($tenant.tenantId -ne $global:MSALToken.TenantId)
|
||||
{
|
||||
$lbObj.Style = $window.TryFindResource("HoverUnderlineStyleWithBackground")
|
||||
$lbObj.HorizontalAlignment = "Stretch"
|
||||
$lnkButton = [System.Windows.Controls.Button]::new()
|
||||
$lnkButton.Content = $lbObj
|
||||
$lnkButton.HorizontalAlignment = "Stretch"
|
||||
$lnkButton.Style = $window.TryFindResource("ContentButton")
|
||||
$lnkButton.Margin = "0,5,0,0"
|
||||
$lnkButton.Cursor = "Hand"
|
||||
$lnkButton.Tag = $tenant
|
||||
$lnkButton.add_Click({
|
||||
Write-Status "Logging in to $($this.Tag.DisplayName)"
|
||||
# Set authority to selected tenant
|
||||
$global:MSALTenantId = $this.Tag.tenantId
|
||||
Hide-Popup
|
||||
Connect-MSALUser -Account ($global:MSALAccounts | Where UserName -eq $global:MSALToken.Account.Username)
|
||||
|
||||
if($global:curObjectType)
|
||||
{
|
||||
Show-GraphObjects
|
||||
}
|
||||
Write-Status ""
|
||||
})
|
||||
Add-GridObject $otherLogins $lnkButton
|
||||
}
|
||||
else
|
||||
{
|
||||
$lbObj.Background = $window.TryFindResource("SelectedRowBackgroundColor")
|
||||
$lbObj.Margin = "0,5,0,0"
|
||||
Add-GridObject $otherLogins $lbObj
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1808,6 +1908,11 @@ function Get-MSALProfileEllipse
|
||||
Show-GraphObjects
|
||||
}
|
||||
}
|
||||
|
||||
if($script:jwtAccessToken.Payload.idtyp -eq "app")
|
||||
{
|
||||
Set-XamlProperty $tmpObj "lnkLogout" "Visibility" "Collapsed"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-LogError "Failed to create profile information object. Error: " $_.Exception
|
||||
@@ -1983,12 +2088,21 @@ function Get-MSALMissingScopes
|
||||
|
||||
$script:missingPermissions = @()
|
||||
|
||||
if($script:jwtAccessToken.Payload.idtyp -eq "app")
|
||||
{
|
||||
$curScopes = $script:jwtAccessToken.Payload.roles
|
||||
}
|
||||
else
|
||||
{
|
||||
$curScopes = $authToken.Scopes
|
||||
}
|
||||
|
||||
foreach($scope in $reqScopes)
|
||||
{
|
||||
$tmpScope = $scope.Split('/')[-1]
|
||||
if($tmpScope -eq ".default") { continue }
|
||||
if($authToken.Scopes -contains $tmpScope) { continue }
|
||||
if(($authToken.Scopes -like "*/$tmpScope")) { continue }
|
||||
if($curScopes -contains $tmpScope) { continue }
|
||||
if(($curScopes -like "*/$tmpScope")) { continue }
|
||||
$arrTemp = $tmpScope.Split(".")
|
||||
if($arrTemp[1] -eq "Read")
|
||||
{
|
||||
@@ -2012,6 +2126,9 @@ function Show-MSALDecodedToken {
|
||||
$tokenData,
|
||||
$title
|
||||
)
|
||||
|
||||
if(-not $tokenData.Header) { return }
|
||||
|
||||
$tokenArr = @()
|
||||
foreach($prop in ($tokenData.Header | GM | Where MemberType -eq NoteProperty))
|
||||
{
|
||||
|
||||
+159
-55
@@ -10,15 +10,19 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
|
||||
#>
|
||||
function Get-ModuleVersion
|
||||
{
|
||||
'3.9.1'
|
||||
'3.9.6'
|
||||
}
|
||||
|
||||
$global:MSGraphGlobalApps = @(
|
||||
(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
|
||||
{
|
||||
$global:graphURL = "https://graph.microsoft.com/beta"
|
||||
@@ -183,6 +187,14 @@ function Invoke-InitializeModule
|
||||
Description = "Certificate for Azure App"
|
||||
}) "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 @{
|
||||
Title = "Refresh Objects after copy"
|
||||
Key = "RefreshObjectsAfterCopy"
|
||||
@@ -214,6 +226,15 @@ function Invoke-InitializeModule
|
||||
DefaultValue = $false
|
||||
Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info"
|
||||
}) "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
|
||||
@@ -261,6 +282,7 @@ function Invoke-GraphAuthenticationUpdated
|
||||
$global:MigrationTableCacheId = $null
|
||||
$global:LoadedDependencyObjects = $null
|
||||
$global:migFileObj = $null
|
||||
$global:AADObjectCache = $null
|
||||
}
|
||||
|
||||
function Invoke-SettingsUpdated
|
||||
@@ -270,7 +292,7 @@ function Invoke-SettingsUpdated
|
||||
|
||||
function Initialize-GraphSettings
|
||||
{
|
||||
|
||||
$script:defaultVersion = ""
|
||||
}
|
||||
|
||||
function Invoke-GraphRequest
|
||||
@@ -297,7 +319,7 @@ function Invoke-GraphRequest
|
||||
$ODataMetadata = "full", # full, minimal, none or skip
|
||||
|
||||
[ValidateSet("beta","v1.0")]
|
||||
$GraphVersion = "beta",
|
||||
$GraphVersion = "",
|
||||
|
||||
[switch]
|
||||
$AllPages,
|
||||
@@ -317,6 +339,22 @@ function Invoke-GraphRequest
|
||||
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 = @{}
|
||||
|
||||
$requestId = [Guid]::NewGuid().guid
|
||||
@@ -550,7 +588,7 @@ function Get-GraphObjects
|
||||
if($SinglePage -eq $true)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
@@ -1036,13 +1074,14 @@ function Get-GraphMetaData
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$wc.Encoding = [System.Text.Encoding]::UTF8
|
||||
$proxyURI = Get-ProxyURI
|
||||
if($proxyURI)
|
||||
{
|
||||
$wc.Proxy = $proxyURI
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if($proxyURI)
|
||||
{
|
||||
$wc.Proxy = [System.Net.WebProxy]::new($proxyURI)
|
||||
}
|
||||
|
||||
[xml]$global:metaDataXML = $wc.DownloadString($url)
|
||||
# Download to string and then use Save to format the XML output
|
||||
$global:metaDataXML.Save($fi.FullName)
|
||||
@@ -1056,6 +1095,16 @@ function Get-GraphMetaData
|
||||
$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 { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,8 +1425,8 @@ function Start-GraphObjectExport
|
||||
Write-Log "Start bulk export"
|
||||
Write-Log "****************************************************************"
|
||||
|
||||
$tmpFolder = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
|
||||
Write-Log "Export root folder: $tmpFolder"
|
||||
$script:exportRoot = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
|
||||
Write-Log "Export root folder: $script:exportRoot"
|
||||
|
||||
$global:AADObjectCache = $null
|
||||
|
||||
@@ -1391,10 +1440,11 @@ function Start-GraphObjectExport
|
||||
|
||||
$txtNameFilter = $global:txtExportNameFilter.Text.Trim()
|
||||
Save-Setting "" "ExportNameFilter" $txtNameFilter
|
||||
|
||||
if($txtNameFilter) { Write-Log "Name filter: $txtNameFilter" }
|
||||
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
|
||||
|
||||
@@ -1684,6 +1734,7 @@ function Show-GraphImportForm
|
||||
|
||||
$importedObjectsCurType = 0
|
||||
$navigationPropObjects = @()
|
||||
$arrImportedObjects = @()
|
||||
foreach ($fileObj in $filesToImport)
|
||||
{
|
||||
if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObject $fileObj $global:dgObjects.ItemsSource))
|
||||
@@ -1699,9 +1750,15 @@ function Show-GraphImportForm
|
||||
ImportedObject = $importedObj
|
||||
}
|
||||
}
|
||||
$arrImportedObjects += $importedObj
|
||||
$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))
|
||||
{
|
||||
Write-Log "Remove $($global:curObjectType.Title) from dependency cache"
|
||||
@@ -1870,7 +1927,6 @@ function Show-GraphBulkImportForm
|
||||
|
||||
function Start-GraphObjectImport
|
||||
{
|
||||
|
||||
Write-Status "Import objects" -Block
|
||||
Write-Log "****************************************************************"
|
||||
Write-Log "Start bulk import"
|
||||
@@ -1920,6 +1976,8 @@ function Start-GraphObjectImport
|
||||
|
||||
$importedObjectsCurType = 0
|
||||
|
||||
$arrImportedObjects = @()
|
||||
|
||||
foreach ($fileObj in @($filesToImport))
|
||||
{
|
||||
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
|
||||
@@ -1943,11 +2001,17 @@ function Start-GraphObjectImport
|
||||
ImportedObject = $importedObj
|
||||
}
|
||||
}
|
||||
$arrImportedObjects = $importedObj
|
||||
|
||||
$importedObjects++
|
||||
$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))
|
||||
{
|
||||
Write-Log "Remove $($item.ObjectType.Title) from dependency cache"
|
||||
@@ -2243,6 +2307,11 @@ function Import-GraphFile
|
||||
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)
|
||||
{
|
||||
$newObj
|
||||
@@ -2637,7 +2706,7 @@ function Add-GroupMigrationObject
|
||||
|
||||
if(-not $groupId) { return }
|
||||
|
||||
$path = Get-GraphMigrationTableFile $global:txtExportPath.Text
|
||||
$path = Get-GraphMigrationTableFile $script:ExportRoot
|
||||
|
||||
if(-not $path) { return }
|
||||
|
||||
@@ -2678,7 +2747,7 @@ function Add-GraphMigrationObject
|
||||
|
||||
if(-not $objId) { return }
|
||||
|
||||
$path = Get-GraphMigrationTableFile $global:txtExportPath.Text
|
||||
$path = Get-GraphMigrationTableFile $script:ExportRoot
|
||||
|
||||
if(-not $path) { return }
|
||||
|
||||
@@ -2686,7 +2755,7 @@ function Add-GraphMigrationObject
|
||||
|
||||
# Check if object is already processed
|
||||
$graphObj = Get-GraphMigrationObject $objId
|
||||
if(-not $graphObj)
|
||||
if(-not $graphObj -and ($global:AADObjectCache.ContainsKey($objId) -eq $false))
|
||||
{
|
||||
# Get object info
|
||||
$graphObj = Invoke-GraphRequest "$($grapAPI)/$objId" -ODataMetadata "none" -NoError
|
||||
@@ -2712,7 +2781,8 @@ function Add-GraphMigrationObject
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Log "No $objTypeName found with ID $($groupId). It might be deleted." 2
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3018,7 +3088,7 @@ function Add-GraphDependencyObjects
|
||||
$url = "$($url.Trim())&$($depObjectType.QUERYLIST.Trim())"
|
||||
}
|
||||
|
||||
$depObjects = (Invoke-GraphRequest $url -ODataMetadata "none").Value
|
||||
$depObjects = (Invoke-GraphRequest $url -ODataMetadata "none" -AllPages).Value
|
||||
$arrDepObjects = @()
|
||||
foreach($depObject in $depObjects)
|
||||
{
|
||||
@@ -3072,8 +3142,8 @@ function Export-GraphObjects
|
||||
$objectType = $global:curObjectType
|
||||
Write-Status "Export $($objectType.Title)"
|
||||
|
||||
$global: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")
|
||||
$script:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
|
||||
$folder = Get-GraphObjectFolder $objectType $script:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked")
|
||||
|
||||
$folder = Expand-FileName $folder
|
||||
|
||||
@@ -3104,7 +3174,7 @@ function Export-GraphObjects
|
||||
}
|
||||
|
||||
Save-Setting "" "LastUsedFullPath" $folder
|
||||
Save-Setting "" "LastUsedRoot" $global:ExportRoot
|
||||
Save-Setting "" "LastUsedRoot" $script:ExportRoot
|
||||
|
||||
Write-Status ""
|
||||
}
|
||||
@@ -3146,7 +3216,7 @@ function Export-GraphObject
|
||||
[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"
|
||||
}
|
||||
@@ -3384,10 +3454,9 @@ function Get-GraphBatchObjects
|
||||
{
|
||||
param($objects, $txtNameFilter)
|
||||
|
||||
$curBatch = 1
|
||||
$batchResults = @()
|
||||
$batchArr = @()
|
||||
$batchTotal = 0
|
||||
$skipped = 0
|
||||
$objectType = $null
|
||||
|
||||
foreach($obj in $objects)
|
||||
@@ -3397,7 +3466,7 @@ function Get-GraphBatchObjects
|
||||
|
||||
if($objName -and $txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
|
||||
{
|
||||
$batchTotal++
|
||||
$skipped++
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3409,17 +3478,59 @@ function Get-GraphBatchObjects
|
||||
headers = @{"Accept"="application/json;odata.metadata=$ometadata"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($batchArr.Count -eq 20 -or ($batchTotal + $batchArr.Count -eq $objects.Count))
|
||||
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
|
||||
}
|
||||
requests = @($batchArr)
|
||||
}
|
||||
|
||||
Write-Status "Get batch $curBatch $batchType" -Force
|
||||
|
||||
Write-Status "Get batch $curBatch $($obj.ObjectType.Title)" -Force
|
||||
$batchTotal += $batchArr.Count
|
||||
$json = $batchObj | ConvertTo-Json -Depth 50
|
||||
|
||||
$maxRetryCount = 10
|
||||
$curRetry = 0
|
||||
|
||||
@@ -3428,10 +3539,11 @@ function Get-GraphBatchObjects
|
||||
$retry = $false
|
||||
$retryArr = @()
|
||||
$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))
|
||||
{
|
||||
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
|
||||
if($batchResult.Status -eq 429 -and $reqObj)
|
||||
@@ -3448,11 +3560,19 @@ function Get-GraphBatchObjects
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Log "Batch result $($batchResult.Status) for URL $($reqObj.URL). Skipping..." 2
|
||||
if($SkipWarnings -ne $true)
|
||||
{
|
||||
Write-Log "Batch result $($batchResult.Status) for URL $($reqObj.URL). Skipping..." 2
|
||||
}
|
||||
|
||||
if($IncludedFailed -eq $true)
|
||||
{
|
||||
$batchResults += $batchResult
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
$batchResults += $batchResult.body
|
||||
$batchResults += $batchResult
|
||||
}
|
||||
|
||||
if($retryArr.Count -gt 0)
|
||||
@@ -3469,7 +3589,7 @@ function Get-GraphBatchObjects
|
||||
$retry = $true
|
||||
$tmpBatchObj = [PSCustomObject]@{
|
||||
requests = $retryArr
|
||||
}
|
||||
}
|
||||
$json = $tmpBatchObj | ConvertTo-Json -Depth 50
|
||||
Start-Sleep -Seconds $retryAfter
|
||||
}
|
||||
@@ -3481,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
|
||||
}
|
||||
|
||||
@@ -4309,7 +4413,7 @@ function Save-GraphObjectToFile
|
||||
function Get-GraphObjectFile
|
||||
{
|
||||
param($obj, $objectType, $path)
|
||||
$fileName = (Get-GraphObjectName $obj $objectType)
|
||||
$fileName = (Get-GraphObjectName $obj $objectType).Trim('.')
|
||||
|
||||
if((Get-SettingValue "AddIDToExportFile") -eq $true -and $obj.Id)
|
||||
{
|
||||
|
||||
+194
@@ -1,4 +1,198 @@
|
||||
# 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 \"<TenantID>\" -appid \"<AppID>\" -secret \"<Secret>\"<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**
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
cmd /c powershell -version 5 -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -tenantId "<TenantID>" -appid "<AppID>" -secret "<Secret>"
|
||||
+22
-8
@@ -34,6 +34,8 @@
|
||||
|
||||
<Grid Grid.Row='2' VerticalAlignment="Stretch" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
@@ -44,27 +46,39 @@
|
||||
<ColumnDefinition Width="*"/>
|
||||
</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" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specifies how the export csv should be saved. One file per ObjectType or one file for all objects." />
|
||||
</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" />
|
||||
|
||||
<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" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" />
|
||||
</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" />
|
||||
|
||||
<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" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating properties in the CSV file" />
|
||||
</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>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
@@ -74,7 +88,7 @@
|
||||
</StackPanel>
|
||||
</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>
|
||||
|
||||
|
||||
+15
-1
@@ -14,6 +14,8 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -45,10 +47,22 @@
|
||||
</Grid>
|
||||
|
||||
<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" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" />
|
||||
</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" />
|
||||
|
||||
<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" />
|
||||
</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" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Filter rows" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Column='1' Grid.Row='1'>
|
||||
<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>
|
||||
<TextBox Text="" Grid.Column='1' Grid.Row='1' Margin="0,2,0,2" Name="txtIntuneAssignmentsFilter" ToolTip="Filter items" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<DataGrid Name="dgIntuneAssignments" Margin="0,5,0,0" Grid.Row="1"
|
||||
|
||||
@@ -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>
|
||||
@@ -135,7 +135,7 @@
|
||||
<Label Content="Current settings:" />
|
||||
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Current property settings. Only updated when saved" />
|
||||
</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">
|
||||
<Button Name="btnObjectColumnsReset" Content="Reset" Margin="0,0,5,0" Width="100" ToolTip="Revert all changes" />
|
||||
|
||||
@@ -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
@@ -34,9 +34,9 @@
|
||||
<LineBreak /><LineBreak />
|
||||
<Bold>Note:</Bold>
|
||||
<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 />
|
||||
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 />
|
||||
This software might use permissions not granted for the existing App.
|
||||
<LineBreak />
|
||||
|
||||
Reference in New Issue
Block a user