Merge pull request #363 from Micke-K/Development

3.10.1 Release
This commit is contained in:
Mikael Karlsson
2025-09-14 14:19:01 +10:00
committed by GitHub
82 changed files with 15557 additions and 27633 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -12,7 +12,7 @@
RootModule = 'CloudAPIPowerShellManagement.psm1'
# Version number of this module.
ModuleVersion = '3.9.8'
ModuleVersion = '3.10.1'
# Supported PSEditions
# CompatiblePSEditions = @()
+44 -1
View File
@@ -85,7 +85,12 @@ function Initialize-CloudAPIManagement
[string]
$secret,
[string]
$certificate
$certificate,
[string]
$GraphEnvironment,
[string]
$GCCType
)
$PSModuleAutoloadingPreference = "none"
@@ -102,9 +107,47 @@ function Initialize-CloudAPIManagement
if($tenantId)
{
Write-Host "Using Tenant Id: $tenantId"
$global:AzureAppId = $appId
$global:ClientSecret = $secret
$global:ClientCert = $certificate
$global:UseGraphEnvironment = $GraphEnvironment
$global:UseGCCType = $GCCType
if($global:AzureAppId)
{
Write-Host "Using Azure App Id: $($global:AzureAppId)"
}
else
{
Write-Warning "Azure App Id is missing. Use -AppId <AppID> on the command line"
}
if($global:ClientSecret -or $global:ClientCert)
{
if($global:ClientSecret)
{
Write-Host "Using Azure App Secret"
}
else
{
Write-Host "Using Azure App Certificate"
}
}
else
{
Write-Warning "Azure App Secret or Certificate is missing. Use -Secret <Secret> or -Certificate <Certificate> on the command line"
}
if($global:UseGraphEnvironment)
{
Write-Host "Using Azure Graph Environment: $($global:UseGraphEnvironment)"
}
if($global:UseGCCType)
{
Write-Host "Using Graph Environment type: $($global:UseGCCType)"
}
}
if($global:hideUI -ne $true)
+37 -4
View File
@@ -86,9 +86,13 @@ function Start-CoreApp
Write-Log "#####################################################################################"
Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())"
Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())"
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())"
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)"
if($PSVersionTable.BuildVersion) {
Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())"
}
if($PSVersionTable.CLRVersion) {
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())"
}
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)"
try
{
@@ -344,6 +348,14 @@ function Write-LogError
}
Write-Log $Text 3
if((Get-SettingValue "ShowStackTrace") -eq $true)
{
Write-Log "Stack trace:`n $($Exception.StackTrace)"
Write-Log "Script stack trace:`n $($Exception.ScriptStackTrace)"
}
}
function Write-Status
@@ -1069,7 +1081,7 @@ function Get-Folder
{
if($global:WindowsAPICodePackLoaded -eq $false)
{
$apiCodec = Join-Path $global:AppRootFolder "Microsoft.WindowsAPICodePack.Shell.dll"
$apiCodec = Join-Path $global:AppRootFolder "Bin\Microsoft.WindowsAPICodePack.Shell.dll"
if([IO.File]::Exists($apiCodec))
{
Add-Type -Path $apiCodec | Out-Null
@@ -1990,6 +2002,14 @@ function Add-DefaultSettings
DefaultValue = $true
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show stack error"
Key = "ShowStackTrace"
Type = "Boolean"
Description = "Write exception stack trace info to the log."
DefaultValue = $false
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Debug"
Key = "Debug"
@@ -2890,6 +2910,19 @@ function Get-DataGridValues
($dataGrid.ItemsSource | Select -Property $properties)
}
function Get-GUIDs
{
param($text)
$regExpGuid = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
$uniqueGuids = New-Object System.Collections.Generic.HashSet[String]
# Use regular expressions to extract the GUIDs
[regex]::Matches($text, $regExpGuid) | ForEach-Object { $uniqueGuids.Add($_.Value) | Out-Null }
$uniqueGuids
}
New-Alias -Name ?? -value Invoke-Coalesce
New-Alias -Name ?: -value Invoke-IfTrue
+2 -1
View File
@@ -151,5 +151,6 @@
"149": "WiredNetwork",
"150": "DefenderAntivirus",
"151": "CustomCompliance",
"152": "IosDefenderAtp"
"152": "IosDefenderAtp",
"153": "WSLCompliance"
}
+9
View File
@@ -314,6 +314,15 @@
]
},
{
"ObjectType": "#microsoft.graph.androidWorkProfileMigrationConfiguration",
"PolicyType": "AndroidForWorkMigrationPolicy",
"PolicyTypeLanguageId": "androidForWorkMigrationPolicy",
"PlatformLanguageId": "AndroidForWork",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.androidForWorkVpnConfiguration",
"PolicyType": "AndroidForWorkVpn",
@@ -0,0 +1,34 @@
[
{
"nameResourceKey": "TableHeaders.configurationType",
"descriptionResourceKey": "",
"entityKey": "PolicyType.hardwareConfigurations",
"dataType": 200,
"booleanActions": 0,
"category": 1000
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.hardware",
"descriptionResourceKey": "",
"entityKey": "vendor",
"dataType": 20,
"booleanActions": 0,
"category": "SettingDetails.configurations"
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.perDevicePassword",
"descriptionResourceKey": "",
"entityKey": "perDevicePasswordDisabled",
"dataType": 109,
"booleanActions": 9,
"category": "SettingDetails.configurations"
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.file",
"descriptionResourceKey": "",
"entityKey": "fileName",
"dataType": 20,
"booleanActions": 0,
"category": "SettingDetails.configurations"
}
]
@@ -11,89 +11,123 @@
"nameResourceKey": "EnrollmentStatusScreen.progressToggle",
"descriptionResourceKey": "",
"entityKey": "showInstallationProgress",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.timeout",
"descriptionResourceKey": "",
"entityKey": "installProgressTimeoutInMinutes",
"dataType": 14,
"booleanActions": 0,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageToggle",
"descriptionResourceKey": "",
"entityKey": "showCustomErrorMessage",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageTextBox",
"descriptionResourceKey": "",
"entityKey": "customErrorMessage",
"dataType": 20,
"booleanActions": 0,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.collectLogToggle",
"descriptionResourceKey": "",
"entityKey": "allowLogCollectionOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.enableForAutopilotOnlyToggle",
"descriptionResourceKey": "",
"entityKey": "trackInstallProgressForAutopilotOnly",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.blockToggle",
"descriptionResourceKey": "",
"entityKey": "blockDeviceSetupRetryByUser",
"dataType": 16,
"booleanActions": 0,
"booleanActions": 109,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "SettingDetails.no",
"value": "true"
"value": "false"
},
{
"nameResourceKey": "BooleanActions.yes",
"value": "false",
"value": "true",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.resetToggle",
"nameResourceKey": "EnrollmentStatusScreen.timeout",
"descriptionResourceKey": "",
"entityKey": "allowDeviceResetOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.allowToUseToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceUseOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.useSelectedAppsToggleLabel",
"descriptionResourceKey": "",
"entityKey": "waitForApps",
"entityKey": "InstallProgressTimeout",
"dataType": 14,
"booleanActions": 0,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageToggle",
"descriptionResourceKey": "",
"entityKey": "showCustomErrorMessage",
"dataType": 16,
"booleanActions": 109,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "SettingDetails.no",
"value": "false"
},
{
"nameResourceKey": "BooleanActions.yes",
"value": "true",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageTextBox",
"descriptionResourceKey": "",
"entityKey": "customErrorMessage",
"dataType": 20,
"booleanActions": 0,
"category": "TableHeaders.settings"
}
]
}
]
},
{
"nameResourceKey": "EnrollmentStatusScreen.collectLogToggle",
"descriptionResourceKey": "",
"entityKey": "allowLogCollectionOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.enableForAutopilotOnlyToggle",
"descriptionResourceKey": "",
"entityKey": "trackInstallProgressForAutopilotOnly",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.blockToggle",
"descriptionResourceKey": "",
"entityKey": "blockDeviceSetupRetryByUser",
"dataType": 16,
"booleanActions": 0,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "SettingDetails.no",
"value": "true"
},
{
"nameResourceKey": "BooleanActions.yes",
"value": "false",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.resetToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceResetOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.allowToUseToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceUseOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.useSelectedAppsToggleLabel",
"descriptionResourceKey": "",
"entityKey": "waitForApps",
"dataType": 14,
"booleanActions": 0,
"category": "TableHeaders.settings",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.allowNonBlockingAppInstallation",
"descriptionResourceKey": "",
"entityKey": "allowNonBlockingAppInstallation",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
}
]
}
]
}
]
}
]
}
@@ -1,14 +1,31 @@
{
"customcompliance_compliancewindows10": {
"dataType": 25,
"dataType": 0,
"category": 151,
"nameResourceKey": "AdminConfiguredComplianceSettingName",
"descriptionResourceKey": "CustomComplianceToolTip",
"childSettings": [
{
"dataType": 25,
"category": 151,
"childSettings": [
],
"options": [
],
"entityKey": "customCompliance",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"entityKey": "customComplianceRequired",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": true
}
@@ -550,7 +550,6 @@
],
"entityKey": "kioskModeScreenSaverDisplayTimeInSeconds",
"booleanActions": 0,
"defaultValue": 0,
"policyType": 2,
"enabled": true
},
@@ -568,7 +567,6 @@
],
"entityKey": "kioskModeScreenSaverStartDelayInSeconds",
"booleanActions": 0,
"defaultValue": 30,
"policyType": 2,
"enabled": true
},
@@ -734,7 +732,6 @@
],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds",
"booleanActions": 0,
"defaultValue": 300,
"policyType": 2,
"enabled": true
},
@@ -752,7 +749,6 @@
],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds",
"booleanActions": 0,
"defaultValue": 60,
"policyType": 2,
"enabled": true
}
@@ -1,5 +1,22 @@
{
"devicehealth_complianceandroiddeviceowner": [
{
"dataType": 0,
"category": 39,
"nameResourceKey": "complianceRootedAllowedName",
"descriptionResourceKey": "complianceRootedAllowedDescription",
"childSettings": [
],
"options": [
],
"entityKey": "securityBlockJailbrokenDevices",
"booleanActions": 3,
"defaultValue": false,
"policyType": 31,
"enabled": true
},
{
"dataType": 16,
"category": 39,
@@ -12,7 +12,7 @@
"dataType": 16,
"category": 42,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription",
"descriptionResourceKey": "androidEnterpriseConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
@@ -4,7 +4,7 @@
"dataType": 16,
"category": 42,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription",
"descriptionResourceKey": "aospConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
@@ -105,8 +105,8 @@
{
"dataType": 16,
"category": 44,
"nameResourceKey": "WifiTypeName",
"descriptionResourceKey": "WiFiTypeDescription",
"nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [
],
@@ -274,7 +274,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 9,
"enabled": true
},
@@ -1421,7 +1421,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 9,
"enabled": true
},
@@ -1,36 +1,64 @@
{
"importedpfx_macimportedpfx": {
"dataType": 16,
"category": 69,
"nameResourceKey": "PFXImportPolicyIntendedPurpose",
"descriptionResourceKey": "empty",
"childSettings": [
"importedpfx_macimportedpfx": [
{
"dataType": 16,
"category": 69,
"nameResourceKey": "MacOSDeploymentChannelName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeUnassigned",
"value": "unassigned",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeEncryption",
"value": "smimeEncryption",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeSigning",
"value": "smimeSigning",
"enabled": true
}
],
"entityKey": "intendedPurpose",
"booleanActions": 0,
"policyType": 62,
"enabled": true
}
],
"options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"enabled": true
},
{
"nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"value": "deviceChannel",
"enabled": true
}
],
"entityKey": "deploymentChannel",
"booleanActions": 0,
"defaultValue": "deviceChannel",
"policyType": 62,
"enabled": true
},
{
"dataType": 16,
"category": 69,
"nameResourceKey": "PFXImportPolicyIntendedPurpose",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeUnassigned",
"value": "unassigned",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeEncryption",
"value": "smimeEncryption",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeSigning",
"value": "smimeSigning",
"enabled": true
}
],
"entityKey": "intendedPurpose",
"booleanActions": 0,
"policyType": 62,
"enabled": true
}
]
}
@@ -1,36 +1,5 @@
{
"password_androidgeneral": [
{
"dataType": 0,
"category": 90,
"nameResourceKey": "requireEncryptionName",
"descriptionResourceKey": "requireEncryptionDescription",
"childSettings": [
],
"options": [
],
"entityKey": "storageRequireDeviceEncryption",
"booleanActions": 1,
"defaultValue": false,
"policyType": 20,
"enabled": true
},
{
"dataType": 10,
"category": 90,
"nameResourceKey": "androidTenDeprecationInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 20,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
@@ -62,6 +31,23 @@
"policyType": 20,
"enabled": true
},
{
"dataType": 0,
"category": 90,
"nameResourceKey": "knoxRequireEncryptionName",
"descriptionResourceKey": "requireEncryptionDescription",
"childSettings": [
],
"options": [
],
"entityKey": "storageRequireDeviceEncryption",
"booleanActions": 1,
"defaultValue": false,
"policyType": 20,
"enabled": true
},
{
"dataType": 16,
"category": 90,
@@ -203,14 +189,14 @@
"showAsSectionHeader": true,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeader",
"nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription",
"nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [
],
+615 -319
View File
@@ -1,373 +1,669 @@
{
"pkcs_macospkcs": [
{
"dataType": 14,
"category": 93,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
"pkcs_macospkcs": {
"dataType": 16,
"category": 93,
"nameResourceKey": "MacOSDeploymentChannelName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"children": [
{
"dataType": 14,
"category": 93,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
],
"entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
],
"entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
],
"entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"entityKey": "certificateTemplateName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"entityKey": "certificateTemplateName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
},
{
"columns": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
"metadata": {
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"dataType": 21,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "user",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "user",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
],
"entityKey": "allowAllAppsAccess",
"booleanActions": 2,
"policyType": 64,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"value": "deviceChannel",
"children": [
{
"dataType": 14,
"category": 93,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
],
"options": [
],
"options": [
],
"entityKey": "allowAllAppsAccess",
"booleanActions": 2,
"policyType": 64,
"enabled": true
}
]
],
"entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "certificateTemplateName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 93,
"nameResourceKey": "MacOSDeploymentChannelWarningBanner",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "machine",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
],
"options": [
],
"entityKey": "allowAllAppsAccess",
"booleanActions": 2,
"policyType": 64,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "deploymentChannel",
"booleanActions": 0,
"defaultValue": "deviceChannel",
"policyType": 64,
"enabled": true
}
}
File diff suppressed because it is too large Load Diff
@@ -187,51 +187,6 @@
"policyType": 29,
"enabled": true
},
{
"dataType": 10,
"category": 113,
"nameResourceKey": "androidTenDeprecationInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 29,
"enabled": true
},
{
"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": 29,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 29,
"enabled": true
},
{
"dataType": 16,
"category": 113,
@@ -370,14 +325,14 @@
"showAsSectionHeader": true,
"dataType": 8,
"category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeader",
"nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription",
"nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [
],
@@ -33,7 +33,7 @@
"dataType": 16,
"category": 113,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription",
"descriptionResourceKey": "androidEnterpriseComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
@@ -41,7 +41,7 @@
"dataType": 16,
"category": 113,
"nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription",
"descriptionResourceKey": "aospComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [
@@ -1,20 +1,48 @@
{
"trustedcert_mactrustedcertificate": {
"dataEntityKey": "trustedRootCertificate",
"filenameEntityKey": "certFileName",
"dataType": 1,
"category": 115,
"nameResourceKey": "trustedCertPolicySelectCertificateName",
"descriptionResourceKey": "empty",
"childSettings": [
"trustedcert_mactrustedcertificate": [
{
"dataType": 16,
"category": 115,
"nameResourceKey": "MacOSDeploymentChannelName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"enabled": true
},
{
"nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"value": "deviceChannel",
"enabled": true
}
],
"entityKey": "deploymentChannel",
"booleanActions": 0,
"defaultValue": "deviceChannel",
"policyType": 65,
"enabled": true
},
{
"dataEntityKey": "trustedRootCertificate",
"filenameEntityKey": "certFileName",
"dataType": 1,
"category": 115,
"nameResourceKey": "trustedCertPolicySelectCertificateName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"entityKey": "trustedRootCertificate",
"booleanActions": 0,
"policyType": 65,
"enabled": true
}
],
"options": [
],
"entityKey": "trustedRootCertificate",
"booleanActions": 0,
"policyType": 65,
"enabled": true
}
]
}
File diff suppressed because it is too large Load Diff
@@ -4078,6 +4078,124 @@
"defaultValue": false,
"policyType": 19,
"enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "openOption",
"value": "open",
"enabled": true
},
{
"nameResourceKey": "wEPPSKOption",
"value": "wep",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "wPAPSKOption",
"value": "wpaPersonal",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "wiFiSecurityType",
"booleanActions": 0,
"policyType": 19,
"enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicyProxySettingsName",
"descriptionResourceKey": "wiFiPolicyProxySettingsDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "noneOption",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "automaticOption",
"value": "automatic",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerURLName",
"descriptionResourceKey": "proxyServerURLDescription",
"emptyValueResourceKey": "proxyUrlExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyAutomaticConfigurationUrl",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "none",
"policyType": 19,
"enabled": true
}
],
"enabled": true
@@ -4954,7 +5072,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 19,
"enabled": true
}
@@ -105,8 +105,8 @@
{
"dataType": 16,
"category": 121,
"nameResourceKey": "WifiTypeName",
"descriptionResourceKey": "WiFiTypeDescription",
"nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [
],
@@ -274,7 +274,7 @@
"entityKey": "proxySetting",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 124,
"enabled": false
}
@@ -1106,7 +1106,7 @@
"entityKey": "proxySetting",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 124,
"enabled": false
}
+3 -3
View File
@@ -238,7 +238,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 54,
"enabled": true
},
@@ -1494,7 +1494,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 54,
"enabled": true
},
@@ -1940,7 +1940,7 @@
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "noneOption",
"unconfiguredValue": "none",
"policyType": 54,
"enabled": true
},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
{
"workprofile_androidforworkmigrationpolicy": [
{
"dataType": 10,
"category": 127,
"nameResourceKey": "migrationPolicyCannotBeUnassigned",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidForWorkMigrationPolicyDescriptionParagraph1",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidForWorkMigrationPolicyDescriptionParagraph2",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidForWorkMigrationPolicyLearnMoreText",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
}
]
}
@@ -0,0 +1,140 @@
{
"wslcompliance_compliancewindows10": [
{
"dataType": 10,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceLearnMore",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyDistributionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "distribution",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyMinOSVersionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "optionalValue",
"childSettings": [
],
"options": [
],
"entityKey": "minimumOSVersion",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyMaxOSVersionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "optionalValue",
"childSettings": [
],
"options": [
],
"entityKey": "maximumOSVersion",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
}
],
"dataType": 21,
"category": 153,
"nameResourceKey": "empty",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "wslDistributions",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+139 -23
View File
@@ -188,6 +188,12 @@ function Show-CompareBulkForm
$global:chkSkipCompareAssignments.IsChecked = (Get-Setting "Compare" "SkipCompareAssignments") -eq "true"
$global:chkSkipMissingSourcePolicies.IsChecked = (Get-Setting "Compare" "SkipMissingSourcePolicies") -eq "true"
$global:chkSkipMissingDestinationPolicies.IsChecked = (Get-Setting "Compare" "SkipMissingDestinationPolicies") -eq "true"
$global:chkBulkCompareSaveJson.IsChecked = (Get-Setting "Compare" "SaveJson") -eq "true"
$global:chkBulkCompareRemoveOData.IsChecked = (Get-Setting "Compare" "RemoveOData") -eq "true"
$objectSeparator = "[ { Name: `"New line`",Value: `"$([System.Environment]::NewLine)`" }, {Name: `";`",Value: `";`" }, {Name: `"|`",Value: `"|`" }]" | ConvertFrom-Json
$global:cbCompareMultiValueDelimiter.ItemsSource = $objectSeparator
$global:cbCompareMultiValueDelimiter.SelectedValue = (Get-Setting "Compare" "ObjectSeparator" ([System.Environment]::NewLine))
$script:compareObjects = @()
foreach($objType in $global:lstMenuItems.ItemsSource)
@@ -239,6 +245,9 @@ function Show-CompareBulkForm
Save-Setting "Compare" "SkipCompareAssignments" $global:chkSkipCompareAssignments.IsChecked
Save-Setting "Compare" "SkipMissingSourcePolicies" $global:chkSkipMissingSourcePolicies.IsChecked
Save-Setting "Compare" "SkipMissingDestinationPolicies" $global:chkSkipMissingDestinationPolicies.IsChecked
Save-Setting "Compare" "SaveJson" $global:chkBulkCompareSaveJson.IsChecked
Save-Setting "Compare" "RemoveOData" $global:chkBulkCompareRemoveOData.IsChecked
Save-Setting "Compare" "ObjectSeparator" $global:cbCompareMultiValueDelimiter.SelectedValue
if($global:cbCompareProvider.SelectedItem.BulkCompare)
{
@@ -534,6 +543,10 @@ function Invoke-BulkCompareNamedObjects
{
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.json")
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder $fileName)
}
}
}
#$fileName = Expand-FileName $fileName
@@ -546,6 +559,10 @@ function Invoke-BulkCompareNamedObjects
{
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.json")
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder $fileName)
}
}
}
@@ -689,7 +706,7 @@ function Start-BulkCompareExportObjects
$objName = Get-GraphObjectName (?? $compObj.Object1 $compObj.Object2) $item.ObjectType
foreach($compValue in $compObj.Result)
{
$compResultValues += [PSCustomObject]@{
$compValue += [PSCustomObject]@{
ObjectName = $objName
Id = $compObj.Id
Type = $compObj.ObjectType.Title
@@ -701,12 +718,34 @@ function Start-BulkCompareExportObjects
SubCategory = $compValue.SubCategory
Match = $compValue.Match
}
if($global:chkBulkCompareRemoveOData.IsChecked -and ($compValue.Value1 -like "@odata*" -or $compValue.Value2 -like "@odata*")) {
foreach($prop in $('Value1','Value2'))
{
$tmpValue1 = ""
$tmpValue2 = ""
$vauleString = $compValue.$prop
if($vauleString -is [String]) {
$vauleString = $vauleString -replace $compValue.Id, ""
$tmpObj = $compValue.$prop | ConvertFrom-Json
if($compValue.$prop -and $compValue.$prop -like "@odata*") {
Remove-GraphODataProperties $tmpObj.$prop | ConvertTo-Json -Depth 50 | Set-Variable -Name "tmp$prop"
}
}
}
$compValue.Match = $tmpValue1 -eq $tmpValue2
}
$compResultValues += $compValue
}
}
if($outputType -eq "objectType")
{
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
}
else
@@ -717,7 +756,10 @@ function Start-BulkCompareExportObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
Write-Log "****************************************************************"
@@ -726,7 +768,7 @@ function Start-BulkCompareExportObjects
Write-Status ""
if($compareObjectsResult.Count -eq 0)
{
[System.Windows.MessageBox]::Show("No objects were comparced. Verify folder and exported files", "Error", "OK", "Error")
[System.Windows.MessageBox]::Show("No objects were compared. Verify folder and exported files", "Error", "OK", "Error")
}
}
@@ -796,6 +838,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{
Write-LogDebug "Excluded based on filter. Intune object name: '$($objName)'"
continue
}
@@ -803,7 +846,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if(-not $fileObj)
{
# Add objects that are exported but deleted
# Add objects that are in Intune but no exported file found
if($global:chkSkipMissingDestinationPolicies.IsChecked -ne $true) {
Write-Log "Object '$($objName)' with id $($fileObj.Object.Id) not found in exported folder. New Object?" 2
$compareProperties = @([PSCustomObject]@{
@@ -815,7 +858,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
}
elseif(($fileObj | measure).Count -gt 1)
{
# Add objects that are exported but deleted
# Add objects where multiple files match based on name
Write-Log "Multiple exported objects found with name '$($objName)" 2
$compareProperties = @([PSCustomObject]@{
Object1Value = $objName
@@ -843,12 +886,16 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($global:chkSkipMissingSourcePolicies.IsChecked -ne $true) {
foreach ($fileObj in @($fileObjects))
{
# Add objects that are exported but not in Intune
if(($compareObjectsResult | Where { $_.FileInfo.FullName -eq $fileObj.FileInfo.FullName})) { continue }
# Skip objects if they are already processed
if(($compareObjectsResult | Where { $_.Object2 -eq $fileObj.Object})) {
Write-LogDebug "Skip already processed file '$($fileObj.FileInfo.FullName)'"
continue
}
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{
Write-LogDebug "Excluded based on filter. File: '$($fileObj.FileInfo.FullName)'"
continue
}
@@ -894,6 +941,9 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "objectType")
{
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
}
else
@@ -904,7 +954,10 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
Write-Log "****************************************************************"
@@ -1080,6 +1133,9 @@ function Start-BulkCompareExportFolders
if($outputType -eq "objectType")
{
Save-BulkCompareResults $compResultValues (Join-Path $folderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
}
else
@@ -1090,7 +1146,10 @@ function Start-BulkCompareExportFolders
if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{
Save-BulkCompareResults $compResultValues (Join-Path $rootFolderSource "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps
Save-BulkCompareResults $compResultValues (Join-Path $rootFolderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
}
Write-Log "****************************************************************"
@@ -1103,6 +1162,13 @@ function Start-BulkCompareExportFolders
}
}
function Save-BulkCompareJsonResults
{
param($CompareResults, $FileName)
$CompareResults | ConvertTo-Json -Depth 50 | Out-File $FileName -Force -Encoding UTF8
}
function Save-BulkCompareResults
{
param($compResultValues, $file, $props)
@@ -1359,7 +1425,7 @@ function Add-CompareProperty
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
$compare += [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 { "" }
@@ -1367,10 +1433,12 @@ function Add-CompareProperty
SubCategory = $subCategory
Match = ?? $match ($value1 -eq $value2)
}
if($skip -eq $true) {
$compare.Match = $null
}
Write-Host "Add property $($compare.PropertyName)"
$script:compareProperties += $compare
}
@@ -1474,17 +1542,19 @@ function Compare-ObjectsBasedonDocumentation
# ToDo: set this based on configuration value
$script:assignmentOutput = "simpleFullCompare"
$docObj1 = Invoke-ObjectDocumentation ([PSCustomObject]@{
$tmpObj1 = ([PSCustomObject]@{
Object = $obj1
ObjectType = $objectType
})
ObjectType = $objectType})
$docObj1 = Invoke-ObjectDocumentation $tmpObj1 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$docObj2 = Invoke-ObjectDocumentation ([PSCustomObject]@{
$tmpObj2 = ([PSCustomObject]@{
Object = $obj2
ObjectType = $objectType
})
$docObj2 = Invoke-ObjectDocumentation $tmpObj2 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$settingsValue = ?? $objectType.CompareValue "Value"
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
@@ -1505,8 +1575,10 @@ function Compare-ObjectsBasedonDocumentation
$addedProperties = @()
if($docObj1.InputType -eq "Settings")
if($docObj1.InputType -eq "Intent")
{
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where ParentSettingId -ne $null))
foreach ($prop in $docObj1.Settings)
{
if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue }
@@ -1580,8 +1652,48 @@ function Compare-ObjectsBasedonDocumentation
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
}
}
elseif($docObj1.InputType -eq "Settings")
{
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where SubCategory -ne $null))
foreach ($prop in $docObj1.Settings)
{
if(($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id)
$val1 = $prop.$settingsValue
$prop2 = $docObj2.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.CategoryId -eq $prop.CategoryId -and $_.SubCategoryDefinition.Id -eq $prop.SubCategoryDefinition.Id }
$val2 = $prop2.$settingsValue
if($val1 -isnot [array] -and $val2 -is [array] -and $val2.Count -gt 1)
{
Write-Log "Multiple compare results returend for $($prop.Name). Using first result" 2
$val2 = $val2[0]
}
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}
# These objects are defined only on Object 2. They will be last in the table
foreach ($prop in $docObj2.Settings)
{
if(($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id)
$val2 = $prop.$settingsValue
$prop2 = $docObj1.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.CategoryId -eq $prop.CategoryId -and $_.SubCategoryDefinition.Id -eq $prop.SubCategoryDefinition.Id }
$val1 = $prop2.$settingsValue
if($val2 -isnot [array] -and $val1 -is [array] -and $val1.Count -gt 1)
{
Write-Log "Multiple compare results returend for $($prop.Name). Using first result" 2
$val1 = $val1[0]
}
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}
}
else
{
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where SubCategory -ne $null))
foreach ($prop in $docObj1.Settings)
{
if(($prop.EntityKey + $prop.Category + $prop.SubCategory) -in $addedProperties) { continue }
@@ -1623,8 +1735,8 @@ function Compare-ObjectsBasedonDocumentation
{
$applicabilityRule2 = $docObj2.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$applicabilityRulesAdded += $applicabilityRule.Id
$val1 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value)
$val2 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value)
$val1 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val2 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
}
@@ -1634,8 +1746,8 @@ function Compare-ObjectsBasedonDocumentation
if(($applicabilityRule.Id) -in $applicabilityRulesAdded) { continue }
$applicabilityRule2 = $docObj1.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$script:applicabilityRulesAdded += $applicabilityRule.Id
$val2 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value)
$val1 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value)
$val2 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val1 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
}
@@ -1645,8 +1757,8 @@ function Compare-ObjectsBasedonDocumentation
{
$complianceAction2 = $docObj2.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr
$val1 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds)
$val2 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.EmailCCIds)
$val1 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val2 = ($complianceAction2.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.EmailCCIds)
Add-CompareProperty $complianceAction.Category $val1 $val2
}
@@ -1656,8 +1768,8 @@ function Compare-ObjectsBasedonDocumentation
if(($complianceAction.IdStr) -in $complianceActionsAdded) { continue }
$complianceAction2 = $docObj1.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr
$val2 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds)
$val1 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.EmailCCIds)
$val2 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val1 = ($complianceAction2.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.EmailCCIds)
Add-CompareProperty $complianceAction.Category $val1 $val2
}
@@ -1783,6 +1895,10 @@ function Invoke-SilentBatchJob
$global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|")
$global:cbCompareCSVDelimiter.SelectedValue = ($settingsObj.BulkCompare | Where Name -eq "cbCompareCSVDelimiter").Value
$objectSeparator = "[ { Name: `"New line`",Value: `"$([System.Environment]::NewLine)`" }, {Name: `";`",Value: `";`" }, {Name: `"|`",Value: `"|`" }]" | ConvertFrom-Json
$global:cbCompareMultiValueDelimiter.ItemsSource = $objectSeparator
$global:cbCompareMultiValueDelimiter.SelectedValue = (Get-Setting "Compare" "ObjectSeparator" ([System.Environment]::NewLine))
Set-CompareProviderOptions $global:cbCompareProvider
Set-BatchProperties $settingsObj.BulkCompare $script:cmpForm -SkipMissingControlWarning
+165 -13
View File
@@ -289,12 +289,20 @@ function Get-ObjectDocumentation
$properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description")
}
#endregion
#region Compliance Policies V2
elseif($type -eq "#microsoft.graph.deviceManagementCompliancePolicy")
{
Invoke-TranslateComplianceV2Object $obj $objectType | Out-Null
$properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description")
}
#endregion
#region Endpoint Security
elseif($type -eq "#microsoft.graph.deviceManagementIntent")
{
Invoke-TranslateIntentObject $obj $objectType | Out-Null
$properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description")
$defaultDocumentationProperties = @("Name","Value","RecommendedValue")
$inputType = "Intent"
}
#endregion
#region Administrative Templates
@@ -381,7 +389,11 @@ function Get-DocumentedSettings
function Invoke-ObjectDocumentation
{
param($documentationObj)
param($documentationObj,
$ObjectSeparator,
$PropertySeparator,
$DocumentationLanguage
)
$global:intentCategories = $null
$global:catRecommendedSettings = $null
@@ -389,10 +401,11 @@ function Invoke-ObjectDocumentation
$global:cfgCategories = $null
$script:admxCategories = $null
$script:migTable = $null
$script:offlineObjects = @{}
$script:DocumentationLanguage = "en"
$script:objectSeparator = [System.Environment]::NewLine
$script:propertySeparator = ","
$script:DocumentationLanguage = ?? $DocumentationLanguage "en"
$script:objectSeparator = ?? $ObjectSeparator ([System.Environment]::NewLine)
$script:propertySeparator = ?? $PropertySeparator ","
$loadExportedInfo = $false
@@ -691,6 +704,10 @@ function Add-BasicAdditionalValues
if($obj.createdDateTime -is [DateTime])
{
$tmpDate = $obj.createdDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
}
else
{
@@ -714,6 +731,10 @@ function Add-BasicAdditionalValues
if($obj.lastModifiedDateTime -is [DateTime])
{
$tmpDate = $obj.lastModifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
}
else
{
@@ -735,6 +756,10 @@ function Add-BasicAdditionalValues
if($obj.modifiedDateTime -is [DateTime])
{
$tmpDate = $obj.modifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
}
else
{
@@ -1037,15 +1062,26 @@ function Invoke-TranslateADMXObject
$rawValues += $rawValue
}
$status = (?: ($definitionValue.enabled -eq $true) $enabledStr $disabledStr)
$combinedValue = $status
if($values) {
$combinedValue += $script:objectSeparator + ($values -join $script:objectSeparator)
}
$combinedValueWithLabel = $status
if($valuesWithLabel) {
$combinedValueWithLabel += $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator)
}
$script:objectSettingsData += New-Object PSObject -Property @{
Name = $definitionValue.definition.displayName
Description = $definitionValue.definition.explainText
Status = $status
Value = $values -join $script:objectSeparator
CombinedValue = ($status + $script:objectSeparator + ($values -join $script:objectSeparator))
CombinedValue = $combinedValue #($status + $script:objectSeparator + ($values -join $script:objectSeparator))
ValueWithLabel = $valuesWithLabel -join $script:objectSeparator
FullValueTable = $tableValue
CombinedValueWithLabel = ($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator))
CombinedValueWithLabel = $combinedValueWithLabel #($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator))
RawValue = $rawValues -join $script:propertySeparator
Class = $definitionValue.definition.classType
DefinitionId = $definitionValue.definition.id
@@ -1109,9 +1145,9 @@ function Invoke-TranslateSettingsObject
$cfgSettings = $obj.Settings
}
if(-not $global:cfgCategories)
if(-not $global:cfgCategories -or -not ($global:cfgCategories | where { $_.settingUsage -eq "configuration" }))
{
$global:cfgCategories = (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value
$global:cfgCategories += (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value
}
if(-not $global:cachedCfgSettings)
@@ -1210,13 +1246,23 @@ function Add-SettingsSetting
$objCategory = $categoryDef
}
$settingName = ""
$settingDescription = ""
if($settingsDef.displayName) {
$settingName = $settingsDef.displayName.Trim([Environment]::NewLine).Trim("`n")
}
if($settingsDef.description) {
$settingDescription = $settingsDef.description.Trim([Environment]::NewLine).Trim("`n")
}
$settingInfo = [PSCustomObject]@{
SettingId = $settingsDef.Id
SettingKey = ""
SettingName = $settingsDef.Name
Name = $settingsDef.displayName
Description=$settingsDef.description
CategortyId = $objCategory.id
Name = $settingName
Description = $settingDescription
CategoryId = $objCategory.id
Category=$objCategory.displayName
CategoryDefinition=$objCategory
SubCategory=$subCategory.displayName
@@ -1392,6 +1438,85 @@ function Add-SettingsSetting
#endregion
#region Compliance V2 Policies - Based on Settings Catalog
function Invoke-TranslateComplianceV2Object
{
param($obj, $objectType)
$platformType = Get-LanguageString "Platform.$($obj.platforms)"
Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "ConfigurationTypes.settingsCatalog")
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.platformSupported") $platformType
Add-BasicAdditionalValues $obj $objectType
$params = @{}
## Set language
if($script:DocumentationLanguage)
{
$params.Add("AdditionalHeaders", @{"Accept-Language"=$script:DocumentationLanguage})
}
$cfgSettings = (Invoke-GraphRequest "/deviceManagement/compliancePolicies('$($obj.Id)')/settings?`$expand=settingDefinitions&top=1000" -ODataMetadata "minimal" @params).Value
if($obj.'@ObjectFromFile')
{
$cfgSettings = $obj.Settings
}
if(-not $global:cfgCategories -or -not ($global:cfgCategories | where { $_.settingUsage -eq "compliance" }))
{
$global:cfgCategories += (Invoke-GraphRequest "/deviceManagement/complianceCategories?`$templateCategory=True&`$filter=platforms has 'linux' and technologies has 'linuxMdm'" -ODataMetadata "minimal" @params).Value
}
if(-not $global:cachedCfgSettings)
{
$global:cachedCfgSettings = @{}
}
$script:settingCatalogasCategories = @{}
foreach($cfgSetting in $cfgSettings)
{
if($obj.'@ObjectFromFile' -and -not $cfgSetting.settingDefinitions)
{
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$defObj = Invoke-GraphRequest "/deviceManagement/configurationSettings/$($cfgSetting.settingInstance.settingDefinitionId)"
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
else
{
$defObj = $cfgSetting.settingDefinitions | Where id -eq $cfgSetting.settingInstance.settingDefinitionId
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
if(-not $defObj -or $script:settingCatalogasCategories.ContainsKey($defObj.categoryId)) { continue }
$catObj = $global:cfgCategories | Where Id -eq $defObj.categoryId
$rootCatObj = $global:cfgCategories | Where Id -eq $catObj.rootCategoryId
$script:settingCatalogasCategories.Add($defObj.categoryId, (New-Object PSObject -Property @{
Category=$catObj
RootCategory=$rootCatObj
}))
}
$script:curSettingsCatologPolicy = @()
$cfgSettings | % { Add-SettingsSetting $_.settingInstance $_.settingDefinitions } | Out-Null
foreach($item in ($script:curSettingsCatologPolicy | Select @{l="CategoryID";e={$_.CategoryDefinition.Id}}, @{l="SubCategoryID";e={$_.SubCategoryDefinition.Id}} -Unique))
{
$script:objectSettingsData += ($script:curSettingsCatologPolicy | Where { $_.CategoryDefinition.Id -eq $item.CategoryID -and $_.SubCategoryDefinition.Id -eq $item.SubCategoryID })
}
}
#endregion
#region Intent Objects (Endpoint Security)
function Get-IntentCategory
@@ -2166,6 +2291,7 @@ function Invoke-TranslateSection
$value = $null
$valueSet = $false
$useParentProp = $false
$payloadFile = $false
#if($prop.enabled -eq $false -and $objInfo.ShowDisabled -ne $true) { continue }
@@ -2397,6 +2523,7 @@ function Invoke-TranslateSection
if($prop.filenameEntityKey -and $obj."$($prop.filenameEntityKey)")
{
$value = $obj."$($prop.filenameEntityKey)"
$payloadFile = $true
}
else
{
@@ -2550,6 +2677,23 @@ function Invoke-TranslateSection
if($addPropertyInfo)
{
Add-PropertyInfo (?: ($useParentProp -and $parent) $parent $prop) $value $rawValue
if($payloadFile -eq $true -and $obj.payload)
{
# Add payload file conetent as a property
$tmpProp = [PSCustomObject]@{
nameResourceKey = "uploadResult"
descriptionResourceKey = ""
entityKey = "payloadData"
dataType = 20
booleanActions = 0
category = $prop.Category
}
$propValue = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($obj.payload))
Add-PropertyInfo $tmpProp $propValue -originalValue $obj.payload
}
}
}
else
@@ -4594,13 +4738,21 @@ function local:Invoke-StartDocumentatiom
{
Write-Status "Process $((Get-GraphObjectName $tmpObj.Object $tmpObj.ObjectType)) ($($obj.ObjectType.Title)) - $($global:cbDocumentationType.SelectedItem.Name)"
$hasRawValue = $false
$documentedObj.Settings | % { if(($_.PSObject.Properties | Where Name -eq "RawValue")) { $hasRawValue=$true } }
$hasRawValue
$filteredSettings = @()
foreach($item in $documentedObj.Settings)
{
if(-not ($item.PSObject.Properties | Where Name -eq "RawValue") -or $documentedObj.UpdateFilteredObject -eq $false)
{
$filteredSettings = $documentedObj.Settings
break
if($hasRawValue -eq $false) {
$filteredSettings = $documentedObj.Settings
break
}
$filteredSettings += $item
continue
}
if($item.AlwaysAddValue -eq $true)
+36 -2
View File
@@ -422,7 +422,7 @@ function Add-CDDocumentCustomProfileValue
$value = $obj.startMenuAppListVisibility
if($value.IndexOf(", ") -eq -1)
{
$value = $value -replace ",",", " # Option values in json file has space afte , but value in object don't
$value = $value -replace ",",", " # Option values in json file has space after , but value in object don't
}
Invoke-TranslateOption $obj $prop -PropValue $value
return $false
@@ -1180,6 +1180,12 @@ function Add-CDDocumentCustomProfileProperty
}
elseif($obj.'@OData.Type' -eq "#microsoft.graph.windows10EnrollmentCompletionPageConfiguration")
{
$installProgressTimeout = $obj.installProgressTimeoutInMinutes
if($installProgressTimeout -eq 0) {
$installProgressTimeout = 60
}
$obj | Add-Member Noteproperty -Name "InstallProgressTimeout" -Value $installProgressTimeout
if($obj.selectedMobileAppIds.Count -eq 0)
{
$apps = Get-LanguageString "EnrollmentStatusScreen.Apps.useSelectedAppsAll"
@@ -1329,6 +1335,17 @@ function Add-CDDocumentCustomProfileProperty
Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.remediationScriptContent
}
}
elseif($obj.'@OData.Type' -eq "#microsoft.graph.hardwareConfiguration")
{
$vendor = ?? (Get-LanguageString "HardwareConfig.Settings.Tab.HardwareDropDown.$($obj.hardwareConfigurationFormat)" -IgnoreMissing) $obj.hardwareConfigurationFormat
$obj | Add-Member Noteproperty -Name "vendor" -Value $vendor
if($obj.configurationFileContent)
{
$obj | Add-Member Noteproperty -Name "configurationFileContentString" -Value ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(($obj.configurationFileContent))))
$header = Get-LanguageString "HardwareConfig.Settings.Tab.Configurations.perDevicePassword"
Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.configurationFileContent
}
}
elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceManagementScript")
{
if($obj.ScriptContent)
@@ -2299,6 +2316,10 @@ function Invoke-CDDocumentTermsOfUse
if($obj.termsExpiration.startDateTime -is [DateTime])
{
$tmpDate = $obj.termsExpiration.startDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
}
else
{
@@ -4154,7 +4175,17 @@ function Invoke-CDDocumentWindowsKioskConfiguration
{
try
{
$startDateObj = Get-Date $obj.windowsKioskForceUpdateSchedule.startDateTime -ErrorAction Stop
if($obj.windowsKioskForceUpdateSchedule.startDateTime -is [DateTime]) {
$startDateObj = $obj.windowsKioskForceUpdateSchedule.startDateTime
if($startDateObj.Kind -eq "UTC")
{
$startDateObj = $startDateObj.ToLocalTime()
}
}
else
{
$startDateObj = Get-Date $obj.windowsKioskForceUpdateSchedule.startDateTime -ErrorAction Stop
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.kioskStartDateTime"
@@ -4608,15 +4639,18 @@ function Invoke-CDDocumentTranslateSectionFile
if($null -eq $obj.deviceCompliancePolicyScript)
{
$propValue = Get-LanguageString "BooleanActions.notConfigured"
$rawValue = "notConfigured"
}
else
{
$propValue = Get-LanguageString "BooleanActions.require"
$rawValue = "require"
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.adminConfiguredComplianceSettingName"
Value = $propValue
EntityKey = "deviceCompliancePolicyScript"
RawValue = $rawValue
Category = $category
SubCategory = $null
})
+7 -3
View File
@@ -29,6 +29,7 @@ function Add-MDOptionsControl
Set-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked" (Get-Setting "Documentation" "MDOpenFile" $true)
Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "ItemsSource" ("[ { Name: `"Single file`",Value: `"Full`" }, { Name: `"One file per object`",Value: `"Object`" }]" | ConvertFrom-Json)
Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" (Get-Setting "Documentation" "MDDocumentFileType" "Full")
Set-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked" ((Get-Setting "Documentation" "MDDocumentSkipDate" "False") -eq "True")
Add-XamlEvent $script:mdForm "browseMDDocumentName" "add_click" {
$sf = [System.Windows.Forms.SaveFileDialog]::new()
@@ -72,6 +73,7 @@ function Invoke-MDPreProcessItems
Save-Setting "Documentation" "MDCSSFile" (Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" "")
Save-Setting "Documentation" "MDOpenFile" (Get-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked")
Save-Setting "Documentation" "MDDocumentFileType" (Get-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" '')
Save-Setting "Documentation" "MDDocumentSkipDate" (Get-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked")
$defaultCSSFile = $global:AppRootFolder + "\Documentation\DefaultMDStyle.css"
$MDCssFile = Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" $defaultCSSFile
@@ -142,7 +144,9 @@ function Invoke-MDPostProcessItems
$script:mdContent.AppendLine("*Organization:* $($global:Organization.displayName)`n")
$script:mdContent.AppendLine("*Generated by:* $userName$mail`n")
$script:mdContent.AppendLine("*Generated:* $((Get-Date).ToShortDateString()) $((Get-Date).ToLongTimeString())`n")
if((Get-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked") -ne $true) {
$script:mdContent.AppendLine("*Generated:* $((Get-Date).ToShortDateString()) $((Get-Date).ToLongTimeString())`n")
}
if($script:sectionAnchors.Count -gt 0)
{
@@ -265,7 +269,7 @@ function Invoke-MDProcessItem
foreach($prop in $global:txtMDCustomProperties.Text.Split(","))
{
# This will add language support for custom columens (or replacing existing header)
# This will add language support for custom columns (or replacing existing header)
$propInfo = $prop.Split('=')
if(($propInfo | measure).Count -gt 1)
{
@@ -312,7 +316,7 @@ function Invoke-MDProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
{
Add-MDTableItems $obj $objectType $documentedObj $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
Add-MDTableItems $obj $objectType $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
}
if(($documentedObj.Assignments | measure).Count -gt 0)
+41 -2
View File
@@ -10,15 +10,32 @@ function Invoke-InitializeModule
{
if(!("Microsoft.Office.Interop.Word.Application" -as [Type]))
{
$loaded = $false
try
{
Add-Type -AssemblyName Microsoft.Office.Interop.Word
$loaded = $true
}
catch { }
try
{
$wordFile = Get-ChildItem -path "$($env:windir)\assembly\GAC_MSIL" -Filter "Microsoft.Office.Interop.Word.dll" -Recurse
if($wordFile -and $wordFile.Exists)
{
Add-Type -Path $wordFile.FullName
$loaded = $true
}
}
catch
{
Write-LogError "Failed to add Word Interop type. Cannot create word documents. Verify that Word is installed properly." $_.Exception
return
}
if(-not $loaded) {
Write-LogError "Word Interop type not found. Cannot create word documents. Verify that Word is installed properly." $_.Exception
return
}
}
Add-OutputType ([PSCustomObject]@{
@@ -46,6 +63,9 @@ function Add-WordOptionsControl
$global:spWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:txtWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:cbWordDocumentationFormat.ItemsSource = ("[ { Name: `"Docx`",Value: `"docx`" }, { Name: `"PDF`",Value: `"pdf`" }]" | ConvertFrom-Json)
$global:cbWordDocumentationFormat.SelectedValue = (Get-Setting "Documentation" "WordDocumentFormat" "docx")
$global:cbWordDocumentationLevel.ItemsSource = ("[ { Name: `"Full`",Value: `"full`" }, { Name: `"Limited`",Value: `"limited`" }, { Name: `"Basic`",Value: `"basic`" }]" | ConvertFrom-Json)
$global:cbWordDocumentationLevel.SelectedValue = (Get-Setting "Documentation" "WordDocumentationLevel" "full")
@@ -114,6 +134,7 @@ function Invoke-WordPreProcessItems
{
Save-Setting "Documentation" "WordExportProperties" $global:cbWordDocumentationProperties.SelectedValue
Save-Setting "Documentation" "WordCustomDisplayProperties" $global:txtWordCustomProperties.Text
Save-Setting "Documentation" "WordDocumentFormat" $global:cbWordDocumentationFormat.SelectedValue
Save-Setting "Documentation" "WordDocumentTemplate" $global:txtWordDocumentTemplate.Text
Save-Setting "Documentation" "WordDocumentName" $global:txtWordDocumentName.Text
@@ -384,6 +405,14 @@ function Invoke-WordPostProcessItems
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfAuthorities | ForEach-Object -Process { $_.Update() | Out-Null }
if($global:cbWordDocumentationFormat.SelectedValue -eq "pdf")
{
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatPDF
}
else {
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatDocumentDefault
}
$fileName = $global:txtWordDocumentName.Text
if(-not $fileName)
{
@@ -392,7 +421,10 @@ function Invoke-WordPostProcessItems
$fileName = Expand-FileName $fileName
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatDocumentDefault
if($format -eq [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatPDF -and $fileName -notlike "*.pdf")
{
$fileName = [IO.Path]::ChangeExtension($fileName, ".pdf")
}
try
{
@@ -575,7 +607,7 @@ function Invoke-WordProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
{
Add-DocTableItems $obj $objectType $documentedObj $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
Add-DocTableItems $obj $objectType $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
}
}
@@ -678,6 +710,10 @@ function Set-DocTableSettingsItems
$cellRow = $row
foreach($settingProp in $properties)
{
if([String]::IsNullOrEmpty($settingProp)) {
continue
}
$script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-DocTranslateColumnHeader ($settingProp.Split('.')[-1]))
$propArr = $settingProp.Split('.')
@@ -779,6 +815,9 @@ function Add-DocTableItems
$i = 1
foreach($prop in $properties)
{
if([String]::IsNullOrEmpty($prop)) {
continue
}
$script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1]))
$i++
}
+345 -13
View File
@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
#>
function Get-ModuleVersion
{
'3.9.8'
'3.10.0.6'
}
function Invoke-InitializeModule
@@ -221,7 +221,7 @@ function Invoke-InitializeModule
Id = "CompliancePoliciesV2"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/compliancePolicies"
NameProperty = "Name"
NameProperty = "name"
PropertiesToRemove = @('settingCount')
ViewProperties = @("name","description","Id")
Expand="settings"
@@ -236,9 +236,11 @@ function Invoke-InitializeModule
Id = "ComplianceScripts"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/deviceComplianceScripts"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
PostImportCommand = { Start-PostImportComplianceScripts @args }
Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "CompliancePolicies"
Icon = "Scripts"
ImportOrder = 80
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -376,7 +378,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All")
Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts"
GroupId = "Scripts"
@@ -390,7 +392,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All")
Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts"
GroupId = "Scripts"
@@ -401,7 +403,7 @@ function Invoke-InitializeModule
Id = "MacCustomAttributes"
API = "/deviceManagement/deviceCustomAttributeShellScripts"
ViewID = "IntuneGraphAPI"
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All")
Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments"
Icon="CustomAttributes"
GroupId = "CustomAttributes" # MacOS Settings
@@ -604,10 +606,11 @@ function Invoke-InitializeModule
API = "/deviceManagement/configurationPolicies"
PropertiesToRemove = @('settingCount')
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
NameProperty = "Name"
NameProperty = "name"
ViewProperties = @("name","description","Id")
Expand="Settings"
Icon="DeviceConfiguration"
PreImportCommand = { Start-PreImportSettingsCatalog @args }
PostExportCommand = { Start-PostExportSettingsCatalog @args }
PreUpdateCommand = { Start-PreUpdateSettingsCatalog @args }
PostGetCommand = { Start-PostGetSettingsCatalog @args }
@@ -615,6 +618,35 @@ function Invoke-InitializeModule
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Inventory Policies"
Id = "InventoryPolicies"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/inventoryPolicies"
PropertiesToRemove = @('settingCount')
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
NameProperty = "name"
ViewProperties = @("name","description","Id")
Expand="Settings"
Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "BIOS Configurations"
Id = "HardwareConfigurations"
ViewID = "IntuneGraphAPI"
DetailExtension = { Add-PolicyFileExtensions @args }
ExportExtension = { Add-PolicyFileExportExtensions @args }
PostExportCommand = { Start-PostExportPolicyFile @args }
PropertiesToRemoveForUpdate = @('version')
PolicyFileAttribute = "configurationFileContent"
API = "/deviceManagement/hardwareConfigurations"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Role Definitions"
Id = "RoleDefinitions"
@@ -718,7 +750,7 @@ function Invoke-InitializeModule
PreUpdateCommand = { Start-PreUpdateDeviceHealthScripts @args }
PostExportCommand = { Start-PostExportDeviceHealthScripts @args }
ExportExtension = { Add-ScriptExportExtensions @args }
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "EndpointAnalytics"
Icon = "Report"
AssignmentsType = "deviceHealthScriptAssignments"
@@ -832,6 +864,17 @@ function Invoke-InitializeModule
Icon = "UpdatePolicies"
GroupId = "WinDriverUpdatePolicies"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Device Categories"
Id = "DeviceCategories"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/deviceCategories"
QUERYLIST = "`$top=500"
Permissons = @("DeviceManagementConfiguration.ReadWrite.All")
GroupId = "DeviceConfiguration"
})
}
function Invoke-EMAuthenticateToMSAL
@@ -1010,7 +1053,7 @@ function Set-EMViewPanel
$global:btnLoadAllPages.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -AllPages
$graphObjects | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
$graphObjects | Where-Object { $_ -ne $null } | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
$global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate
@@ -1020,7 +1063,7 @@ function Set-EMViewPanel
$global:btnLoadNextPage.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage
$graphObjects | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
$graphObjects | Where-Object { $_ -ne $null } | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
$global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter
@@ -1391,6 +1434,30 @@ function Start-PreUpdateCompliancePolicies
#endregion
function Start-PostImportComplianceScripts
{
param($obj, $objectType, $file)
$endTime = (Get-Date).AddMinutes(2)
$found = $false
while($endTime -gt (Get-Date))
{
$tmpObj = Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -ErrorAction SilentlyContinue
if($tmpObj) {
$found = $true
break
}
Start-Sleep -Seconds 10
}
if(-not $found)
{
Write-LogError "Compliance script $($obj.Id) not found after import. Please check the import file."
return
}
}
#region Intune Branding functions
function Start-PreImportIntuneBranding
{
@@ -1440,7 +1507,7 @@ function Start-PreImportIntuneBranding
function Start-PostImportIntuneBranding
{
param($obj, $objectType)
param($obj, $objectType, $file)
if($obj.isDefaultProfile -or -not $global:brandingClone) { return }
@@ -1744,6 +1811,194 @@ function Invoke-EditScript
#endregion
#region Policy File functions
function Add-PolicyFileExtensions
{
param($form, $buttonPanel, $index = 0)
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Download'
$btnDownload.Name = 'btnDownload'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Invoke-DownloadPolicyFile
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Edit'
$btnDownload.Name = 'btnEdit'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Invoke-EditPolicyFile
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
}
function Add-PolicyFileExportExtensions
{
param($form, $buttonPanel, $index = 0)
$ctrl = $form.FindName("chkExportPolicyFile")
if(-not $ctrl)
{
$xaml = @"
<StackPanel $($global:wpfNS) Orientation="Horizontal" Margin="0,0,5,0">
<Label Content="Export Policy File" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Export the file associated with policies eg BIOS Configuration" />
</StackPanel>
"@
$label = [Windows.Markup.XamlReader]::Parse($xaml)
$global:chkExportPolicyFile = [System.Windows.Controls.CheckBox]::new()
$global:chkExportPolicyFile.IsChecked = $true
$global:chkExportPolicyFile.VerticalAlignment = "Center"
$global:chkExportPolicyFile.Name = "chkExportPolicyFile"
@($label, $global:chkExportPolicyFile)
}
}
function Start-PostExportPolicyFile
{
param($obj, $objectType, $exportPath)
if($objectType.PolicyFileAttribute -and $obj.$($objectType.PolicyFileAttribute) -and $global:chkExportPolicyFile.IsChecked)
{
Write-Log "Export policy file from attribute $($obj.PolicyFileAttribute)"
$fileNameOut = ?? $obj.FileName "$($obj.PolicyFileAttribute).json"
$fileName = [IO.Path]::Combine($exportPath, $fileNameOut)
[IO.File]::WriteAllBytes($fileName, ([System.Convert]::FromBase64String($obj.$($objectType.PolicyFileAttribute))))
}
}
function Invoke-DownloadPolicyFile
{
if(-not $global:dgObjects.SelectedItem.Object.id) { return }
$obj = (Get-GraphObject $global:dgObjects.SelectedItem $global:curObjectType).Object
Write-Status ""
if($global:curObjectType.PolicyFileAttribute -and $obj.$($global:curObjectType.PolicyFileAttribute))
{
$fileNameOut = ?? $obj.FileName "$($obj.PolicyFileAttribute).json"
Write-Log "Download policy file '$($fileNameOut)' from $($obj.displayName)"
$dlgSave = New-Object -Typename System.Windows.Forms.SaveFileDialog
$dlgSave.InitialDirectory = Get-SettingValue "IntuneRootFolder" $env:Temp
$dlgSave.FileName = $fileNameOut
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
# Changed to WriteAllBytes to get rid of BOM characters from Custom Attribute file
[IO.File]::WriteAllBytes($dlgSave.FileName, ([System.Convert]::FromBase64String($obj.$($global:curObjectType.PolicyFileAttribute))))
}
}
}
function Invoke-EditPolicyFile
{
if(-not $global:dgObjects.SelectedItem.Object.id) { return }
$obj = (Get-GraphObject $global:dgObjects.SelectedItem $global:curObjectType)
Write-Status ""
if(-not $global:curObjectType.PolicyFileAttribute -or -not $obj.Object.$($global:curObjectType.PolicyFileAttribute)) { return }
$script:currentScriptObject = $obj
$script:editForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\EditScriptDialog.xaml")
if(-not $script:editForm) { return }
Set-XamlProperty $script:editForm "txtEditScriptTitle" "Text" "Edit: $($obj.Object.displayName)"
$scriptText = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($obj.Object.$($global:curObjectType.PolicyFileAttribute)))
Set-XamlProperty $script:editForm "txtScriptText" "Text" $scriptText
$script:currentModal = $null
if($global:grdModal.Children.Count -gt 0)
{
$script:currentModal = $global:grdModal.Children[0]
}
Add-XamlEvent $script:editForm "btnSaveScriptEdit" "add_click" ({
$scriptText = Get-XamlProperty $script:editForm "txtScriptText" "Text"
$pre = [System.Text.Encoding]::UTF8.GetPreamble()
$utfBOM = [System.Text.Encoding]::UTF8.GetString($pre)
if($scriptText.startsWith($utfBOM))
{
# Remove UTF8 BOM bytes
$scriptText = $scriptText.Remove(0, $utfBOM.Length)
}
$bytes = [System.Text.Encoding]::UTF8.GetBytes($scriptText)
$encodedText = [Convert]::ToBase64String($bytes)
if($script:currentScriptObject.Object.scriptContent -ne $encodedText)
{
# Save script
if(([System.Windows.MessageBox]::Show("Are you sure you want to update the $($global:curObjectType.PolicyFileAttribute) attribute?`n`nObject:`n$($script:currentScriptObject.displayName)", "Update script?", "YesNo", "Warning")) -eq "Yes")
{
Write-Status "Update $($script:currentScriptObject.displayName)"
$obj = $script:currentScriptObject.Object | ConvertTo-Json -Depth 20 | ConvertFrom-Json
$obj.$($global:curObjectType.PolicyFileAttribute) = $encodedText
Start-GraphPreImport $obj $script:currentScriptObject.ObjectType
foreach($prop in $script:currentScriptObject.ObjectType.PropertiesToRemoveForUpdate)
{
Remove-Property $obj $prop
}
Remove-Property $obj "Assignments"
Remove-Property $obj "isAssigned"
$json = ConvertTo-Json $obj -Depth 15
$objectUpdated = (Invoke-GraphRequest -Url "$($script:currentScriptObject.ObjectType.API)/$($script:currentScriptObject.Object.Id)" -Content $json -HttpMethod "PATCH")
if(-not $objectUpdated)
{
Write-Log "Failed to update script" 3
[System.Windows.MessageBox]::Show("Failed to save the policy. See log for more information","Update failed!", "OK", "Error")
}
Write-Status ""
}
}
$global:grdModal.Children.Clear()
if($script:currentModal)
{
$global:grdModal.Children.Add($script:currentModal)
}
[System.Windows.Forms.Application]::DoEvents()
})
Add-XamlEvent $script:editForm "btnCancelScriptEdit" "add_click" ({
$global:grdModal.Children.Clear()
if($script:currentModal)
{
$global:grdModal.Children.Add($script:currentModal)
}
[System.Windows.Forms.Application]::DoEvents()
})
$global:grdModal.Children.Clear()
$script:editForm.SetValue([System.Windows.Controls.Grid]::RowProperty,1)
$script:editForm.SetValue([System.Windows.Controls.Grid]::ColumnProperty,1)
$global:grdModal.Children.Add($script:editForm) | Out-Null
[System.Windows.Forms.Application]::DoEvents()
}
#endregion
#region Terms and Conditions
function Start-PostExportTermsAndConditions
{
@@ -2512,7 +2767,7 @@ function Start-PostExportApplications
}
else
{
Write-Log "Cound not file encryption file"
Write-Log "Cound not find encryption file"
}
}
}
@@ -3265,6 +3520,75 @@ function Start-PostFileImportRoleDefinitions
#endregion
#region SettingsCatalog
function Start-PreImportSettingsCatalog
{
param($obj, $objectType)
$returnHT = @{}
$updated = $false
if($obj.templateReference.templateId) {
# I do not like this at all and it is a lazy but simple implementation...
# It turns out that settingInstanceTemplateId and settingValueTemplateId are case sensitive
# and there is ONE setting with a different casing in the Windows Baseline template.
# The export saves it with lowercase which causes the import to fail.
Write-Log "Get template $($obj.templateReference.templateId)"
$templateObj = Invoke-GraphRequest -Url "/deviceManagement/configurationPolicyTemplates('$($obj.templateReference.templateId)')"
if($templateObj.lifecycleState -and $templateObj.lifecycleState -ne "active") {
Write-Log "Template '$($templateObj.displayName)' '$($templateObj.displayVersion)' is in '$($templateObj.lifecycleState)' state. Current state: $($templateObj.lifecycleState). Import might fail." 2
}
#Todo: Should probably check for the latest active version and use that instead of the one in the templateReference
if(-not $script:baseLineTemplate) {
$script:baseLineTemplate = @{}
}
if($script:baseLineTemplate.ContainsKey($obj.templateReference.templateId)) {
$templateReference = $script:baseLineTemplate[$obj.templateReference.templateId]
}
else {
Write-Log "Get template settings for '$($templateObj.displayName)' '$($templateObj.displayVersion)' ($($obj.templateReference.templateId))"
$templateReference = Invoke-GraphRequest -Url "/deviceManagement/configurationPolicyTemplates('$($obj.templateReference.templateId)')/settingTemplates?`$expand=settingDefinitions&top=1000"
$script:baseLineTemplate.Add($obj.templateReference.templateId, $templateReference)
}
if($templateReference) {
$newObjJson = $obj | ConvertTo-Json -Depth 50
$templateIDs = Get-GUIDs ($templateReference | ConvertTo-Json -Depth 50)
$objectIDs = Get-GUIDs ($obj.Settings | ConvertTo-Json -Depth 50)
$diff = Compare-Object $templateIDs $objectIDs -CaseSensitive
foreach($diffItem in ($diff | where SideIndicator -eq "=>")) {
$templateID = $templateIDs | Where { $_ -eq $diffItem.InputObject }
if($templateID) {
# Found but with different casing
$newObjJson = $newObjJson -replace $diffItem.InputObject, $templateID
$updated = $true
}
}
if($updated) {
$returnHT.Add("JSON", $newObjJson)
}
}
}
return $returnHT
}
function Invoke-CheckSettingsCatalogIds
{
param($obj, $templateReference)
foreach($settingTemplate in $obj.value) {
if($settingTemplate.settingDefinitions) {
foreach($settingDefinition in $settingTemplate.settingDefinitions) {
if($settingDefinition.id -and $settingDefinition.id -ne $obj.Id) {
Write-Log "Setting definition ID $($settingDefinition.id) does not match the settings catalog ID $($obj.Id)" 2
}
}
}
}
}
function Start-PostExportSettingsCatalog
{
param($obj, $objectType, $path)
@@ -3813,11 +4137,13 @@ function Add-ConditionalAccessImportExtensions
Value = "disabled"
}
$defaultCAState = Get-SettingValue "ConditionalAccessState"
$global:cbImportCAState = [System.Windows.Controls.ComboBox]::new()
$global:cbImportCAState.DisplayMemberPath = "Name"
$global:cbImportCAState.SelectedValuePath = "Value"
$global:cbImportCAState.ItemsSource = $CAStates
$global:cbImportCAState.SelectedValue = "disabled"
$global:cbImportCAState.SelectedValue = $defaultCAState
$global:cbImportCAState.Margin="0,5,0,0"
$global:cbImportCAState.HorizontalAlignment="Left"
$global:cbImportCAState.Width=250
@@ -3855,6 +4181,12 @@ function Start-PreImportConditionalAccess
{
$obj.sessionControls.disableResilienceDefaults = $null
}
# DeviceStates property is depricated
if(($obj.conditions.PSObject.Properties | Where Name -eq "DeviceStates"))
{
$obj.conditions.PSObject.Properties.Remove('DeviceStates')
}
}
function Start-PostExportConditionalAccess
+7
View File
@@ -521,6 +521,13 @@ function Write-AzureStorageChunk
"Content-Type" = "application/octet-stream"
}
# In PowerShell (Core) 7 v7.4+, the web cmdlets (Invoke-WebRequest, Invoke-RestMethod)
# consistently encode text-based request bodies as UTF-8, unless explicitly specified otherwise.
if ($PSVersionTable.PSVersion -ge [Version]"7.4")
{
$headers["Content-Type"] += "; charset=iso-8859-1"
}
$curProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
+14 -6
View File
@@ -704,7 +704,10 @@ function Invoke-LoadADMXSettings
$tvItem | Add-Member -MemberType NoteProperty -Name "AllPolicies" -Value $true
}
$global:tvADMXCategories.Items[1].Items.Add($tvItem) | Out-Null
try {
$global:tvADMXCategories.Items[1].Items.Add($tvItem) | Out-Null
}
catch{}
}
function Set-ADMXSettingStatusText
@@ -854,6 +857,7 @@ function Get-ADMXCategoryNamePath
}
$catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($categoryId)']",$script:xmlNS)
#$catObj = $script:admxXML.policyDefinitions.categories.category | Where Name -eq "$categoryId"
$categories = @()
while($catObj)
@@ -862,6 +866,7 @@ function Get-ADMXCategoryNamePath
if($catObj.parentCategory.ref)
{
$catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($catObj.parentCategory.ref)']", $script:xmlNS)
#$catObj = $script:admxXML.policyDefinitions.categories.category | where name -eq $catObj.parentCategory.ref
}
else
{
@@ -1037,11 +1042,11 @@ function Set-ADMXElementsPanel
}
elseif($valItem.value.longDecimal)
{
$value = $valItem.value.longDecimal.'#text'
$value = ?? $valItem.value.longDecimal.'#text' $valItem.value.longDecimal
}
elseif($valItem.value.string)
{
$value = $valItem.value.string.'#text'
$value = ?? $valItem.value.string.'#text' $valItem.value.string
}
else
{
@@ -1151,7 +1156,7 @@ function Set-ADMXElementsPanel
}
elseif($valItem.value.string)
{
$value = $valItem.value.string.'#text'
$value = ?? $valItem.value.string.'#text' $valItem.value.string
}
else
{
@@ -1981,9 +1986,11 @@ function Add-ADMXRegClasses
}
$classDef = @"
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
public class ADMXRegPolicyElement : INotifyPropertyChanged
public class ADMXRegPolicyElement : System.ComponentModel.INotifyPropertyChanged
{
public string DataType { get { return _dataType; } set { _dataType = value; NotifyPropertyChanged("DataType"); NotifyPropertyChanged("DataTypeDisplayString"); } }
private string _dataType = null;
@@ -2069,8 +2076,9 @@ function Add-ADMXRegClasses
}
}
"@
[Reflection.Assembly]::LoadWithPartialName("mscorlib") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel')
Add-Type -TypeDefinition $classDef
}
#endregion
+201 -30
View File
@@ -129,6 +129,20 @@ function Invoke-InitializeModule
Description = "Sort the list of available tenants based on Tenant name. Updated at restart or account change"
}) "MSAL"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Use WAM for enhanced login methods"
Key = "UseWAM"
Type = "Boolean"
DefaultValue = $false
Description = "Use WAM for enhanced login methods"
}) "MSAL"
$script:MSALUseWAM = Get-SettingValue "UseWAM"
if($script:MSALUseWAM -and $PSVersionTable.PSVersion.Major -lt 7) {
Write-Log "WAM is only supported in PowerShell 7 and later. Disabling WAM" 2
$script:MSALUseWAM = $false
}
Add-MSALPrereq
}
@@ -200,6 +214,9 @@ function Set-MSALGraphEnvironment
{
$curAADEnv = $script:lstAADEnvironments | Where URL -eq $user.Environment
}
elseif($global:UseGraphEnvironment) {
$curAADEnv = $script:lstAADEnvironments | Where value -eq $global:UseGraphEnvironment
}
else
{
$curAADEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public")
@@ -207,7 +224,14 @@ function Set-MSALGraphEnvironment
if($curAADEnv.Value -eq "usGov")
{
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc")
if($global:UseGCCType)
{
$gccEnv = $global:UseGCCType
}
else {
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc")
}
if($gccEnv)
{
$GCCEnvObj = $script:lstGCCEnvironments | Where Value -eq $gccEnv
@@ -259,6 +283,7 @@ function Get-MSALUserInfo
if($global:Organization)
{
if($global:Organization -is [array]) { $global:Organization = $global:Organization[0]}
$global:Organization.displayName = ($global:Organization.displayName).Trim()
Save-Setting $global:Organization.Id "_Name" $global:Organization.displayName
}
Set-EnvironmentInfo $global:Organization.displayName
@@ -487,6 +512,129 @@ function Install-MSALDependencyModule
}
function Add-MSALPrereq
{
$ScriptRoot = $global:AppRootFolder
$DLLFiles = @()
if($PSVersionTable.PSVersion.Major -ge 7) {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\Microsoft.IdentityModel.Abstractions.dll")
}
else {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\6.35.0\Microsoft.IdentityModel.Abstractions.dll")
}
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\Microsoft.Identity.Client.dll")
if($script:MSALUseWAM) {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Extensions.Msal.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Broker.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Desktop.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.NativeInterop.dll")
}
$DLLFiles | ForEach-Object {
$dllFile = $_
# ToDo: Unblock files
if($_.Exists) {
try {
[void][System.Reflection.Assembly]::LoadFrom($_.FullName)
Write-Log "Loaded $($_.Name) version $($_.VersionInfo.FileVersion)"
}
catch {
$loadedFile = [Appdomain]::CurrentDomain.GetAssemblies() | Where Location -like "*\$($dllFile.Name)"
if($loadedFile) {
$loadedFI = [IO.FileInfo]($loadedFile.Location)
Write-Log "Failed to load $($dllFile.Name) version $($dllFile.VersionInfo.FileVersion). File already loaded: $($loadedFI.FullName) version $($loadedFI.VersionInfo.FileVersion)" 2
}
else {
Write-LogError "Failed to load $($dllFile.Name) version $($dllFile.VersionInfo.FileVersion)" $_.Exception
}
}
}
else {
Write-LogError "Microsoft.Identity file not found: $($_.FullName)"
}
}
if (-not ("TokenCacheHelperEx" -as [type]))
{
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
foreach($file in $DLLFiles) {
$RequiredAssemblies.Add($file.FullName)
}
$RequiredAssemblies.Add('System.Security.dll')
$RequiredAssemblies.Add('mscorlib.dll')
if($PSVersionTable.PSVersion.Major -ge 7) {
$RequiredAssemblies.Add('System.Security.Cryptography.ProtectedData.dll')
}
$RequiredAssemblies.Add('System.Threading.dll')
try
{
Add-Type -Path ($ScriptRoot + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies -IgnoreWarnings
}
catch
{
Write-LogError "Failed to compile TokenCacheHelperEx. The access token will not be cached. Check write access to the CS folder and ASR policies" $_.Exception
}
}
if($script:MSALUseWAM) {
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
foreach($file in $DLLFiles) {
$RequiredAssemblies.Add($file.FullName)
}
$RequiredAssemblies.Add('mscorlib.dll')
$RequiredAssemblies.Add('System.dll')
$RequiredAssemblies.Add('System.Windows.Forms')
# Import necessary methods from user32.dll and kernel32.dll
Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Identity.Client;
//using Microsoft.Identity.Client.Desktop;
using Microsoft.Identity.Client.Broker;
using System.Windows.Forms;
public class MSALMethods
{
enum GetAncestorFlags {
GetParent = 1,
GetRoot = 2,
GetRootOwner = 3
}
[DllImport("user32.dll", ExactSpelling = true)]
public static extern IntPtr GetAncestor(IntPtr hwnd, int flags);
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
// This is your window handle!
public static IntPtr GetConsoleOrTerminalWindow()
{
IntPtr consoleHandle = GetConsoleWindow();
IntPtr handle = GetAncestor(consoleHandle, (int)GetAncestorFlags.GetRootOwner );
return handle;
}
public static void AddParentActivirtyOrWindow(PublicClientApplicationBuilder appBuilder)
{
appBuilder.WithParentActivityOrWindow(GetConsoleOrTerminalWindow);
}
public static void AddWithBroker(PublicClientApplicationBuilder appBuilder, BrokerOptions options)
{
appBuilder.WithBroker(options);
}
}
"@ -ReferencedAssemblies $RequiredAssemblies -IgnoreWarnings
}
}
function Add-MSALPrereq_old
{
$msalPath = ""
@@ -565,7 +713,15 @@ function Add-MSALPrereq
$RequiredAssemblies.Add($msalPath)
$script:msalFile = $msalPath
}
$RequiredAssemblies.Add('System.Security.dll')
$RequiredAssemblies.Add('mscorlib.dll')
if($PSVersionTable.PSVersion.Major -ge 7)
{
$RequiredAssemblies.Add('System.Security.Cryptography.ProtectedData.dll')
}
$RequiredAssemblies.Add('System.Threading.dll')
try
{
@@ -586,6 +742,10 @@ function Connect-MSALClientApp
if(-not $script:MSALApp)
{
if($global:UseGraphEnvironment) {
Set-MSALGraphEnvironment $null $null
}
$authority = "https://login.microsoftonline.com/$tenantId"
#$redirectUri = "http://localhost"
@@ -747,7 +907,7 @@ function Get-MSALApp
{
param($appInfo, $loginHint)
$msalApp = $script:MSALAllApps | Where { $_.ClientId -eq $appInfo.ClientID -and (-not $appInfo.RedirectUri -or $_.AppConfig.RedirectUri -eq $appInfo.RedirectUri)}
$msalApp = $script:MSALAllApps | Where { $_.AppConfig.ClientId -eq $appInfo.ClientID -and (-not $appInfo.RedirectUri -or $_.AppConfig.RedirectUri -eq $appInfo.RedirectUri)}
$tenant = ?? $appInfo.TenantId "organizations"
@@ -770,14 +930,21 @@ function Get-MSALApp
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($appInfo.ClientID)
[void]$appBuilder.WithAuthority($authority)
#if($appInfo.TenantId) { [void]$appBuilder.WithAuthority("https://$((?? $loginHint.Environment (Get-MSALLoginEnvironment)))/$($appInfo.TenantId)/") }
#elseif ($appInfo.Authority) { [void]$appBuilder.WithAuthority($appInfo.Authority) }
if($appInfo.RedirectUri) { [void]$appBuilder.WithRedirectUri($appInfo.RedirectUri) }
[void] $appBuilder.WithClientName("CloudAPIPowerShellManagement")
[void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion)
if($script:MSALUseWAM) {
[MSALMethods]::AddParentActivirtyOrWindow($appBuilder)
$options = [Microsoft.Identity.Client.BrokerOptions]::new([Microsoft.Identity.Client.BrokerOptions+OperatingSystems]::Windows)
$options.Title = "Intune Manager"
[MSALMethods]::AddWithBroker($appBuilder, $options)
}
Add-MSALProxy $appBuilder
# Ceck if correct version...
@@ -908,8 +1075,6 @@ function Connect-MSALUser
Add-MSALPrereq
}
$curTicks = $global:MSALToken.ExpiresOn.LocalDateTime.Ticks
$currentLoggedInUserApp = ($global:MSALToken.Account.HomeAccountId.Identifier + $global:MSALToken.TenantId + $global:MSALApp.ClientId)
$currentLoggedInUserId = $global:MSALToken.Account.HomeAccountId.Identifier
if($Interactive -eq $true)
@@ -1015,15 +1180,6 @@ function Connect-MSALUser
return
}
if($authResult -and $authResult.ExpiresOn.LocalDateTime.Ticks -ne $curTicks)
{
Write-Log "$($authResult.Account.UserName) authenticated successfully (Silent). CorrelationId: $($global:MSALToken.CorrelationId)"
}
else
{
Write-LogDebug "$($authResult.Account.UserName) authenticated successfully (Silent). CorrelationId: $($global:MSALToken.CorrelationId)"
}
#AADSTS65001
if($script:authenticationFailure.Classification -eq "ConsentRequired")
{
@@ -1113,6 +1269,10 @@ function Connect-MSALUser
{
Write-Log "Login hint: $loginHintName"
[void]$AquireTokenObj.WithLoginHint($loginHintName)
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::NoPrompt)
}
else {
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::SelectAccount)
}
if($script:authenticationFailure.Claims)
@@ -1133,11 +1293,6 @@ function Connect-MSALUser
Write-Log "Interactive login with Consent prompt"
[void]$aquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::Consent)
}
elseif(-not $loginHintName)
{
Write-Log "Interactive login with Select account prompt"
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::SelectAccount)
}
$authResult = Get-MsalAuthenticationToken $aquireTokenObj
if($authResult)
@@ -1146,6 +1301,31 @@ function Connect-MSALUser
}
}
if($authResult) {
$telemetry = $null
$wamTelemetry = $null
if($authResult.AuthenticationResultMetadata.Telemetry) {
try {
$telemetry = $authResult.AuthenticationResultMetadata.Telemetry | ConvertFrom-Json
if($telemetry.wam_telemetry) {
$wamTelemetry = $telemetry.wam_telemetry | ConvertFrom-Json
}
}
catch {}
}
if($authResult.AuthenticationResultMetadata.TokenSource -eq "Broker" -and $telemetry.broker_app_used -eq "true") {
Write-Log "Token received from Broker. Time (ms): $($authResult.AuthenticationResultMetadata.DurationTotalInMs). CorrelationId: $($authResult.CorrelationId)"
}
elseif($authResult.AuthenticationResultMetadata.TokenSource -eq "IdentityProvider") {
Write-Log "Token received from IdentityProvider. Time (ms) $($authResult.AuthenticationResultMetadata.DurationTotalInMs)"
}
else {
# ToDo: Change to debug
Write-Log "Token received from Cache. Time (ms) $($authResult.AuthenticationResultMetadata.DurationTotalInMs)"
}
}
if($currentLoggedInUserId -ne $authResult.Account.HomeAccountId.Identifier)
{
$script:AccessableTenants = $null
@@ -1225,15 +1405,6 @@ function Connect-MSALUser
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
}
Invoke-MSALAuthenticationUpdated $authResult
<#
Write-LogDebug "User, tenant or app has changed"
Get-MSALUserInfo
if($authResult)
{
Invoke-MSALCheckObjectViewAccess $authResult
}
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
#>
}
}
@@ -2161,7 +2332,7 @@ function Show-MSALDecodedToken {
{
if($prop.Name -in @("exp","iat","nbf","xms_tcdt"))
{
$value =[datetime]::new(1970, 1, 1, 0, 0, 0, 0, "UTC").AddSeconds(($tokenData.Payload."$($prop.Name)")).ToLocalTime()
$value = [datetime]::new(1970, 1, 1, 0, 0, 0, 0, [System.DateTimeKind]::Utc).AddSeconds(($tokenData.Payload."$($prop.Name)")).ToLocalTime()
}
elseif($prop.Name -in @("acrs","amr"))
{
+139 -7
View File
@@ -53,6 +53,52 @@ function Invoke-InitializeModule
}
)
$script:lstConditionalAccessState = @(
[PSCustomObject]@{
Name = "As Exported - Change On to Report-only"
Value = "AsExportedReportOnly"
},
[PSCustomObject]@{
Name = "As Exported"
Value = "AsExported"
},
[PSCustomObject]@{
Name = "Report-only"
Value = "enabledForReportingButNotEnforced"
},
[PSCustomObject]@{
Name = "Off"
Value = "disabled"
}
)
$script:lstGraphPageSize = @(
[PSCustomObject]@{
Name = "Graph API Default"
Value = "0"
},
[PSCustomObject]@{
Name = "5"
Value = "5"
},
[PSCustomObject]@{
Name = "20"
Value = "20"
},
[PSCustomObject]@{
Name = "50"
Value = "50"
},
[PSCustomObject]@{
Name = "100"
Value = "100"
},
[PSCustomObject]@{
Name = "All"
Value = "All"
}
)
# Make sure MS Graph settings are added before exiting before App Id and Tenant Id is missing
Write-Log "Add settings and menu items"
@@ -239,6 +285,23 @@ function Invoke-InitializeModule
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"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "API Page Size"
Key = "GraphPageSize"
Type = "List"
ItemsSource = $script:lstGraphPageSize
DefaultValue = "20"
Description = "How many items load at a time"
}) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Default Conditional Access Policy State"
Key = "ConditionalAccessState"
Type = "List"
ItemsSource = $script:lstConditionalAccessState
DefaultValue = "disabled"
Description = "Define the default option of the Conditional Access policy state. It is recommended to have this to disabled to avoid accidental tenant lock out"
}) "ImportExport"
}
function Get-GraphAppInfo
@@ -558,7 +621,9 @@ function Get-GraphObjects
[switch]
$SingleObject,
[string]
$filter)
$filter,
[int]
$pageSize = -1)
$params = @{}
if($objectType.ODataMetadata)
@@ -593,6 +658,10 @@ function Get-GraphObjects
{
#Use default page size or use below for a specific page size for testing
#$params.Add("pageSize",5) #!!!
if ($pageSize -gt 0)
{
$params.Add("pageSize", $pageSize)
}
}
elseif($SingleObject -ne $true -and $SinglePage -ne $true)
{
@@ -780,7 +849,30 @@ function Show-GraphObjects
$script:nextGraphPage = $null
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage -Filter $filter
$params = @{}
$pageSize = 0
$tmpPageSize = Get-SettingValue "GraphPageSize"
if ($tmpPageSize -eq "All")
{
$params.Add("AllPages", $true)
}else
{
if($tmpPageSize) {
try {
$pageSize = [int]$tmpPageSize
}
catch {}
}
if($pageSize -gt 0)
{
$params.Add("PageSize", $pageSize)
}
$params.Add("SinglePage", $true)
}
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -Filter $filter @params
$dgObjects.AutoGenerateColumns = $false
$dgObjects.Columns.Clear()
@@ -1051,6 +1143,34 @@ function Start-GraphPreImport
}
}
function Remove-GraphODataProperties
{
param($obj)
# Remove OData properties
foreach($odataProp in ($obj.PSObject.Properties | Where { $_.Name -like "*@*" }))
{
$removeProperties += $odataProp.Name
}
foreach($prop in $removeProperties)
{
Remove-Property $obj $prop
}
foreach($prop in ($obj.PSObject.Properties))
{
if($obj."$($prop.Name)"."@odata.type")
{
foreach($childObj in ($obj."$($prop.Name)"))
{
Remove-GraphODataProperties $childObj
}
}
}
}
function Get-GraphMetaData
{
if(-not $global:metaDataXML)
@@ -3685,6 +3805,11 @@ function Import-GraphObject
{
$params.Add("AdditionalHeaders",$ret["AdditionalHeaders"])
}
if($ret.ContainsKey("JSON"))
{
$obj = $ret["JSON"] | ConvertFrom-Json
}
}
}
@@ -3985,8 +4110,8 @@ function Show-GraphObjectInfo
return
}
# Save settings here...
$nameProp = (?? $global:dgObjects.SelectedItem.Object.NameProperty "displayName")
$idProp = (?? $global:dgObjects.SelectedItem.Object.IDProperty "id")
$nameProp = (?? $global:dgObjects.SelectedItem.ObjectType.NameProperty "displayName")
$idProp = (?? $global:dgObjects.SelectedItem.ObjectType.IDProperty "id")
$updateObj = [PSCustomObject]@{
$idProp = $global:dgObjects.SelectedItem.Object."$idProp"
@@ -4148,9 +4273,10 @@ function local:Add-ObjectColumnInfoClass
}
$classDef = @"
using System;
using System.ComponentModel;
public class ObjectColumnInfo : INotifyPropertyChanged
public class ObjectColumnInfo : System.ComponentModel.INotifyPropertyChanged
{
public string Property { get { return _property; } set { _property = value; NotifyPropertyChanged("Property"); } }
private string _property = null;
@@ -4176,8 +4302,14 @@ function local:Add-ObjectColumnInfoClass
}
"@
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel')
try {
Add-Type -TypeDefinition $classDef -IgnoreWarnings #-ReferencedAssemblies @('System.ComponentModel')
}
catch
{
Write-LogError "Failed to add type ObjectColumnInfo" $_.Exception
}
}
function Local:Show-ObjectDefaultColumnsSettings
+53 -1
View File
@@ -10,7 +10,6 @@ See GitHub repository [MSAL for .Net](https://github.com/AzureAD/microsoft-authe
MSAL uses OAuth2 to authenticate to an Application in Azure. This script has two applications pre-defined in Settings:
- Microsoft Intune PowerShell (d1ddf0e4-d672-4dae-b554-9d5bdfd93547)
- Microsoft Graph PowerShell (14d82eec-204b-4c2f-b7e8-296a70dab67e)
Microsoft Intune PowerShell is the same application as the Intune PowerShell module uses and this is the default application for the script.
@@ -21,6 +20,59 @@ The script will detect if the selected app is missing permissions and prompt for
A Custom application can be specified in Settings. This could theoretically be a custom created app in Azure. However, if an App is registered in Azure, it will be single tenant only. This can be used to backup an existing environment but the Azure App cannot be used to import data in another tenant. Use Enterprise Apps and Common/Organizations authority to allow access to multiple tenants.
## Create Custom Application ##
Documentation by Microsoft: [Quickstart: Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)
Steps:
* Go to the Entra Portal
* Register a new App registration in Entra
Note Application Id
* Add Delegated permissions
* Microsoft Graph
For full support of the app requires:<br />
Application.Read.All<br />
Agreement.ReadWrite.All<br />
CloudPC.ReadWrite.All<br />
DeviceManagementApps.ReadWrite.All<br />
DeviceManagementConfiguration.ReadWrite.All<br />
DeviceManagementManagedDevices.ReadWrite.All<br />
DeviceManagementRBAC.ReadWrite.All<br />
DeviceManagementScripts.ReadWrite.All<br />
DeviceManagementServiceConfig.ReadWrite.All<br />
Organization.ReadWrite.All<br />
Policy.ReadWrite.ConditionalAccess<br /><br />
It will also need User.ReadWrite.All,Group.ReadWrite.All but you could set these to read only unless you will let the app create Groups.<br /><br />
**Note:** Change all **ReadWrite** to **Read** in the permissions above to create an Entra App with Read Only access.
* Grant permissions for the environment
* Go to Authentication
* Click **+ Add platform**
* Click on **Mobile and desktop applications**
* Check **https://login.microsoftonline.com/common/oauth2/nativeclient**<br />
msal value can also be used
* Start the Tool
* Go to Settings
* Change Application in Endpoint Manager/Intune section
* Set drop down to Empty. It will only use custom app if drop down is empty
* Specify App Id from the Entra App created earlier
* Specify Redirect URL to https://login.microsoftonline.com/common/oauth2/nativeclient<br />
This must match the setting in the Entra App.
* Save Settings
* Restart app
## Token
The MSAL authentication will create a token that is used when calling APIs in Microsoft Graph. This token is cached in an encrypted **msalcahce.bin3** file in the **%LOCALAPPDATA%\CloudAPIPowerShellManagement** folder. The file can only be decrypted by the same user. Caching the token can be disabled in Settings.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -218,7 +218,7 @@ This will replace the default columns and add new columns with specific header.
See [Change Log](ReleaseNotes.md) for more information
## Authentication
See [MSAL Info](MSALInfo.md) for more information about authentication
See [MSAL Info](MSALInfo.md) for more information about authentication and how to create a custom application in Entra.
## Settings
@@ -250,6 +250,7 @@ Start-WithJson.cmd is included as an example on how to start the script with jso
* Apple Enrolment Types - NOT fully tested
* Autopilot profiles
* Baseline Security profiles
* BIOS Configuration
* Compliance policies
* Compliance policies v2
* Compliance scripts
+123
View File
@@ -1,4 +1,127 @@
# Release Notes
## 3.10.1 - 2025-09-14
<br />
A huge thank you to:<br />
- @befra for fixing uploads with PowerShell 7.5<br />
- @MrR0bert for fixing issues with Organization name with spaces<br />
<br />
**BREAKING CHANGE**<br />
Permission requirements has changed on script policies. **DeviceManagementScripts.ReadWrite.All** is now required and Consent Request might be required to add the permissions<br />
**New features**
- **Official PowerShell 7 Support**<br />
- PowerShell 7 is now supported<br />
This is now the recommended way of using the tool.<br />
PowerShell 7 has full support for WAM authentication which is required for strong authentication like FIDO2 etc.<br />
- **Authentication**<br />
- Added documentation on how to create a custom Entra app in [MSAL Info](MSALInfo.md)
- Changed permission requiremnt to **DeviceManagementScripts.ReadWrite.All** for
- Compliance Scripts
- Custom Attributes
- Health Scripts
- Scripts (PowerShell)
- Scripts (Shell)
**Fixes**
- **Generic**<br />
- Cannot rename Settings Catalog<br />
Based on [Issue 344](https://github.com/Micke-K/IntuneManagement/issues/344)<br />
- **Compare**<br />
- Compare added letter N to the string output<br />
Based on [Issue 320](https://github.com/Micke-K/IntuneManagement/issues/320)<br />
- Wrong Category when comparing Settings Catalog objects<br />
Based on [Issue 317](https://github.com/Micke-K/IntuneManagement/issues/317)<br />
- **Import/Export**<br />
- Basline Security Policy not imported<br />
Based on [Issue 241](https://github.com/Micke-K/IntuneManagement/issues/241)<br />
- Fixed import of old exported Compliance Policies<br />
DeviceSettings property support removed and cause import failure<br />
- Custom Compliance Scripts were not imported befor the Compliance Policy<br />
Based on [Issue 353](https://github.com/Micke-K/IntuneManagement/issues/353)<br />
- Added support for BIOS Configurations<br />
Based on [Issue 350](https://github.com/Micke-K/IntuneManagement/issues/350)<br />
- Set default Conditional Access state in Settings<br />
Based on [Issue 298](https://github.com/Micke-K/IntuneManagement/issues/298)<br />
- **Documentation**<br />
- "Not configured" valued added when Uncofigured settings was selected<br />
Based on [Issue 342](https://github.com/Micke-K/IntuneManagement/issues/342)<br />
- Add file content to documentation e.g. Custom Configuration profiles for MacOS<br />
Based on [Issue 329](https://github.com/Micke-K/IntuneManagement/issues/329)<br />
- Output type for Word export - PDF is now supported<br />
Based on [Discussion 329](https://github.com/Micke-K/IntuneManagement/discussions/331)<br />
- Skip date in documentation output<br />
Based on [Issue 336](https://github.com/Micke-K/IntuneManagement/issues/336)<br />
- Added support for Compliance Policies for Linux<br />
- Language files re-generated<br />
- AppTypes file re-generated<br />
- **ADMX Tool**<br />
- Failed to import settings for some ADMX files<br />
Based on [Issue 338](https://github.com/Micke-K/IntuneManagement/issues/338)<br />
## 3.10.0 - 2025-02-22 - Beta 1 (Development branch)
<br />
A huge thank you to:<br />
- @Mykhailo-Roit for the help with the paging<br />
- @Systems-Liam for Documentation updates<br />
- @ee61r for Documentation updates - This was missed in the previous release notes. Sorry!<br />
<br />
**New features**
- **PowerShell 7 Support**<br />
- PowerShell 7 is now supported. Tested with 7.5.0<br />
- Added CMD files for PowerShell 7<br />
- Not all features and polices are tested. Please report any issues<br />
PowerShell 7 handles dates differently in Json files etc which might cause some problems<br />
- **Authentication**<br />
- Microsoft Authentication Library Updated to 4.67.2.0<br />
- Added support for automation for GCC<br />
Based on [Issue 307](https://github.com/Micke-K/IntuneManagement/issues/307)<br />
- Added support for WAM - This allows for secure login scenarios eg Windows Hello, FIDO2<br />
WAM must be enabled in Settings. This will require a restart of the app<br />
**Note** WAM is only supported in PowerShell 7<br />
Based on [Issue 310](https://github.com/Micke-K/IntuneManagement/issues/310)<br />
Based on [Issue 167](https://github.com/Micke-K/IntuneManagement/issues/167)<br />
<br />
The Authentication update has been a long battle but it's hopefully working now<br />
**Fixes**
- **Generic**<br />
- Added support for setting the page size<br />
This can help with Settings Catalog missing policies<br />
Default page size is 20. This can be changed in Settings<br />
Based on [Issue 300](https://github.com/Micke-K/IntuneManagement/issues/300)<br />
[PR 301](https://github.com/Micke-K/IntuneManagement/pull/301)<br />
- **Compare**<br />
- Lots of Bulk Compare issues fixed<br />
- Compare can now export a Json file for futher analysing<br />
Based on [Issue 281](https://github.com/Micke-K/IntuneManagement/issues/281)<br />
- **Import/Export**<br />
- Added for support for export/import Device Categories<br />
Based on [Discussion 305](https://github.com/Micke-K/IntuneManagement/discussions/305)<br />
- Added API for export/import Inventory Policies<br />
**Note** These are not working but following Microsoft documentation.<br />
- **Documentation**<br />
- App Configuration (Device) documentation updated<br />
- Fixed bug with sub tables for MD and Word<br />
Based on [Issue 246](https://github.com/Micke-K/IntuneManagement/issues/246)<br />
## 3.9.8 - 2024-10-12
**New features**
+1
View File
@@ -0,0 +1 @@
cmd /c pwsh -ex bypass -File "%~DP0Start-IntuneManagement.ps1"
+2
View File
@@ -0,0 +1,2 @@
cmd /c pwsh -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -ShowConsoleWindow
pause
+31 -8
View File
@@ -41,6 +41,9 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@@ -72,27 +75,47 @@
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='3' Name='chkSkipMissingDestinationPolicies' VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='4'>
<StackPanel Orientation="Horizontal" Grid.Row='4' Margin="0,5,5,0" >
<Label Content="Save json" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Save a json version of the compare for post-compare scripting." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='4' Name='chkBulkCompareSaveJson' VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal" Grid.Row='5' Margin="0,5,5,0" >
<Label Content="Remove OData From Compare" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skipps ID string and removes OData properties of Json strings when comparing properties." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='5' Name='chkBulkCompareRemoveOData' VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='6'>
<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='4' Grid.Column="1" HorizontalAlignment="Left"
<ComboBox Name="cbCompareSave" Margin="0,5,0,0" MinWidth="250" Grid.Row='6' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='5' >
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='7' >
<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='5' Grid.Column="1" HorizontalAlignment="Left"
<ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='7' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='6' >
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='8' >
<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='6' Grid.Column="1" HorizontalAlignment="Left" />
<ComboBox Name="cbCompareCSVDelimiter" Margin="0,5,0,0" MinWidth="250" Grid.Row='8' Grid.Column="1" HorizontalAlignment="Left" />
<Grid Margin="0,0,5,0" Grid.Row='7' >
<StackPanel Orientation="Horizontal" Margin="0,0,5,0" Grid.Row='9' >
<Label Content="Multi-Value Delimiter" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating values for properties with more than one value. New line will cause a new line in the exported CSV" />
</StackPanel>
<ComboBox Name="cbCompareMultiValueDelimiter" Margin="0,5,0,0" MinWidth="250" Grid.Row='9' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<Grid Margin="0,0,5,0" Grid.Row='10' >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
@@ -102,7 +125,7 @@
</StackPanel>
</Grid>
<DataGrid Name="dgObjectsToCompare" Margin="0,5,0,5" Grid.Row='7' Grid.Column='1' CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White" />
<DataGrid Name="dgObjectsToCompare" Margin="0,5,0,5" Grid.Row='9' Grid.Column='1' CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White" />
</Grid>
+6
View File
@@ -85,4 +85,10 @@
<ComboBox Name="cbMDDocumentOutputFile" Margin="0,5,0,0" MinWidth="250" Grid.Row='4' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Grid.Row='5' Margin="0,5,5,0" >
<Label Content="Skip date in Generated Info" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Skip the date when the documentation was generated." />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='5' Name='cbMDDocumentSkipDate' VerticalAlignment="Center" IsChecked="true" />
</Grid>
+7
View File
@@ -57,6 +57,13 @@
</StackPanel>
<TextBox Text="" Name="txtWordCustomProperties" Margin="0,5,5,5" Grid.Row="1" Grid.Column="1"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="2">
<Label Content="Document format" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the output format eg Docx or PDF" />
</StackPanel>
<ComboBox Name="cbWordDocumentationFormat" Margin="0,5,0,0" MinWidth="250" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
</Grid>
<Grid Grid.Row="1" Grid.ColumnSpan="2">
+10
View File
@@ -0,0 +1,10 @@
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas Height="50" Width="50">
<Path Data="M31.25 43.892a2.976 2.976 0 0 1-2.969 2.983H6.094a2.976 2.976 0 0 1-2.969-2.983V6.108a2.976 2.976 0 0 1 2.969-2.983H28.28a2.976 2.976 0 0 1 2.969 2.983v37.784z" Fill="#3e3e3e" />
<Path Fill="#5AB3D9" Data="M6.25 9.375h21.875v31.25H6.25z" />
<Path Fill="#E4E4E4" Data="M12.5 6.25h9.375v3.125H12.5z" />
<Path Fill="#2072B8" Data="M34.375 3.125h12.5v12.5h-12.5v-12.5z" />
<Path Fill="#F58B1F" Data="M34.375 18.75h12.5v12.5h-12.5v-12.5z" />
<Path Fill="#7FBA42" Data="M34.375 34.375h12.5v12.5h-12.5v-12.5z" />
</Canvas>
</Viewbox>