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' RootModule = 'CloudAPIPowerShellManagement.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '3.9.8' ModuleVersion = '3.10.1'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()
+44 -1
View File
@@ -85,7 +85,12 @@ function Initialize-CloudAPIManagement
[string] [string]
$secret, $secret,
[string] [string]
$certificate $certificate,
[string]
$GraphEnvironment,
[string]
$GCCType
) )
$PSModuleAutoloadingPreference = "none" $PSModuleAutoloadingPreference = "none"
@@ -102,9 +107,47 @@ function Initialize-CloudAPIManagement
if($tenantId) if($tenantId)
{ {
Write-Host "Using Tenant Id: $tenantId"
$global:AzureAppId = $appId $global:AzureAppId = $appId
$global:ClientSecret = $secret $global:ClientSecret = $secret
$global:ClientCert = $certificate $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) if($global:hideUI -ne $true)
+37 -4
View File
@@ -86,9 +86,13 @@ function Start-CoreApp
Write-Log "#####################################################################################" Write-Log "#####################################################################################"
Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())" Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())"
Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())" if($PSVersionTable.BuildVersion) {
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())" Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())"
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)" }
if($PSVersionTable.CLRVersion) {
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())"
}
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)"
try try
{ {
@@ -344,6 +348,14 @@ function Write-LogError
} }
Write-Log $Text 3 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 function Write-Status
@@ -1069,7 +1081,7 @@ function Get-Folder
{ {
if($global:WindowsAPICodePackLoaded -eq $false) 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)) if([IO.File]::Exists($apiCodec))
{ {
Add-Type -Path $apiCodec | Out-Null Add-Type -Path $apiCodec | Out-Null
@@ -1990,6 +2002,14 @@ function Add-DefaultSettings
DefaultValue = $true DefaultValue = $true
}) "General" }) "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 @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Debug" Title = "Debug"
Key = "Debug" Key = "Debug"
@@ -2890,6 +2910,19 @@ function Get-DataGridValues
($dataGrid.ItemsSource | Select -Property $properties) ($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-Coalesce
New-Alias -Name ?: -value Invoke-IfTrue New-Alias -Name ?: -value Invoke-IfTrue
+2 -1
View File
@@ -151,5 +151,6 @@
"149": "WiredNetwork", "149": "WiredNetwork",
"150": "DefenderAntivirus", "150": "DefenderAntivirus",
"151": "CustomCompliance", "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", "ObjectType": "#microsoft.graph.androidForWorkVpnConfiguration",
"PolicyType": "AndroidForWorkVpn", "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", "nameResourceKey": "EnrollmentStatusScreen.progressToggle",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "showInstallationProgress", "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, "dataType": 16,
"booleanActions": 0, "booleanActions": 109,
"category": "TableHeaders.settings", "category": "TableHeaders.settings",
"options": [ "options": [
{ {
"nameResourceKey": "SettingDetails.no", "nameResourceKey": "SettingDetails.no",
"value": "true" "value": "false"
}, },
{ {
"nameResourceKey": "BooleanActions.yes", "nameResourceKey": "BooleanActions.yes",
"value": "false", "value": "true",
"Children": [ "Children": [
{ {
"nameResourceKey": "EnrollmentStatusScreen.resetToggle", "nameResourceKey": "EnrollmentStatusScreen.timeout",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "allowDeviceResetOnInstallFailure", "entityKey": "InstallProgressTimeout",
"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, "dataType": 14,
"booleanActions": 0, "booleanActions": 0,
"category": "TableHeaders.settings" "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": { "customcompliance_compliancewindows10": {
"dataType": 25, "dataType": 0,
"category": 151, "category": 151,
"nameResourceKey": "AdminConfiguredComplianceSettingName",
"descriptionResourceKey": "CustomComplianceToolTip",
"childSettings": [ "childSettings": [
{
"dataType": 25,
"category": 151,
"childSettings": [
],
"options": [
],
"entityKey": "customCompliance",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
], ],
"options": [ "options": [
], ],
"booleanActions": 0, "entityKey": "customComplianceRequired",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35, "policyType": 35,
"enabled": true "enabled": true
} }
@@ -550,7 +550,6 @@
], ],
"entityKey": "kioskModeScreenSaverDisplayTimeInSeconds", "entityKey": "kioskModeScreenSaverDisplayTimeInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 0,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -568,7 +567,6 @@
], ],
"entityKey": "kioskModeScreenSaverStartDelayInSeconds", "entityKey": "kioskModeScreenSaverStartDelayInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 30,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -734,7 +732,6 @@
], ],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds", "entityKey": "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 300,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -752,7 +749,6 @@
], ],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds", "entityKey": "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 60,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
} }
@@ -1,5 +1,22 @@
{ {
"devicehealth_complianceandroiddeviceowner": [ "devicehealth_complianceandroiddeviceowner": [
{
"dataType": 0,
"category": 39,
"nameResourceKey": "complianceRootedAllowedName",
"descriptionResourceKey": "complianceRootedAllowedDescription",
"childSettings": [
],
"options": [
],
"entityKey": "securityBlockJailbrokenDevices",
"booleanActions": 3,
"defaultValue": false,
"policyType": 31,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
@@ -12,7 +12,7 @@
"dataType": 16, "dataType": 16,
"category": 42, "category": 42,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "androidEnterpriseConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -4,7 +4,7 @@
"dataType": 16, "dataType": 16,
"category": 42, "category": 42,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "aospConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -105,8 +105,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 44, "category": 44,
"nameResourceKey": "WifiTypeName", "nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "WiFiTypeDescription", "descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [ "childSettings": [
], ],
@@ -274,7 +274,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
}, },
@@ -1421,7 +1421,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
}, },
@@ -1,36 +1,64 @@
{ {
"importedpfx_macimportedpfx": { "importedpfx_macimportedpfx": [
"dataType": 16, {
"category": 69, "dataType": 16,
"nameResourceKey": "PFXImportPolicyIntendedPurpose", "category": 69,
"descriptionResourceKey": "empty", "nameResourceKey": "MacOSDeploymentChannelName",
"childSettings": [ "descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "notConfigured", "nameResourceKey": "MacOSDeploymentChannelUserChannel",
"enabled": true "value": "userChannel",
}, "enabled": true
{ },
"nameResourceKey": "PFXImportPolicyIntendedPurposeUnassigned", {
"value": "unassigned", "nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"enabled": true "value": "deviceChannel",
}, "enabled": true
{ }
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeEncryption", ],
"value": "smimeEncryption", "entityKey": "deploymentChannel",
"enabled": true "booleanActions": 0,
}, "defaultValue": "deviceChannel",
{ "policyType": 62,
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeSigning", "enabled": true
"value": "smimeSigning", },
"enabled": true {
} "dataType": 16,
], "category": 69,
"entityKey": "intendedPurpose", "nameResourceKey": "PFXImportPolicyIntendedPurpose",
"booleanActions": 0, "descriptionResourceKey": "empty",
"policyType": 62, "childSettings": [
"enabled": true
} ],
"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": [ "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, "isSettingDescription": false,
"showAsSectionHeader": true, "showAsSectionHeader": true,
@@ -62,6 +31,23 @@
"policyType": 20, "policyType": 20,
"enabled": true "enabled": true
}, },
{
"dataType": 0,
"category": 90,
"nameResourceKey": "knoxRequireEncryptionName",
"descriptionResourceKey": "requireEncryptionDescription",
"childSettings": [
],
"options": [
],
"entityKey": "storageRequireDeviceEncryption",
"booleanActions": 1,
"defaultValue": false,
"policyType": 20,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 90, "category": 90,
@@ -203,14 +189,14 @@
"showAsSectionHeader": true, "showAsSectionHeader": true,
"dataType": 8, "dataType": 8,
"category": 90, "category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeader", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [ "childSettings": [
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 90, "category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [ "childSettings": [
], ],
+615 -319
View File
@@ -1,373 +1,669 @@
{ {
"pkcs_macospkcs": [ "pkcs_macospkcs": {
{ "dataType": 16,
"dataType": 14, "category": 93,
"category": 93, "nameResourceKey": "MacOSDeploymentChannelName",
"nameResourceKey": "sCEPPolicyRenewalThresholdName", "descriptionResourceKey": "empty",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription", "childSettings": [
"childSettings": [
], ],
"options": [ "options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"children": [
{
"dataType": 14,
"category": 93,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
], ],
"entityKey": "renewalThresholdPercentage", "options": [
"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": "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", "options": [
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
], ],
"options": [ "entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
], ],
"entityKey": "certificationAuthority", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
], ],
"options": [ "entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
], ],
"entityKey": "certificationAuthorityName", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"entityKey": "certificateTemplateName", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "entityKey": "certificateTemplateName",
{ "booleanActions": 0,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser", "defaultValue": "",
"value": "user", "policyType": 64,
"children": [ "enabled": true
{ },
"value": "custom", {
"dataType": 9, "dataType": 16,
"category": 93, "category": 93,
"childSettings": [ "nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "options": [
{
], "nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"entityKey": "subjectNameFormat", "value": "user",
"booleanActions": 0, "children": [
"policyType": 64, {
"enabled": true "value": "custom",
}, "dataType": 9,
{
"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, "category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [ "childSettings": [
], ],
"options": [ "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, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} },
}, {
{
"metadata": {
"dataType": 20, "dataType": 20,
"category": 93, "category": 93,
"nameResourceKey": "value", "nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "name", "entityKey": "subjectNameFormatString",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} },
} {
], "columns": [
"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", "metadata": {
"value": "emailAddress", "dataType": 16,
"enabled": true "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", "metadata": {
"value": "userPrincipalName", "dataType": 20,
"enabled": true "category": 93,
}, "nameResourceKey": "value",
{ "descriptionResourceKey": "empty",
"nameResourceKey": "PolicyDomainNameService", "childSettings": [
"value": "domainNameService",
"enabled": true ],
}, "options": [
{
"nameResourceKey": "PolicyUniversalResourceIdentifier", ],
"value": "universalResourceIdentifier", "entityKey": "name",
"enabled": true "booleanActions": 0,
}, "policyType": 64,
{ "enabled": true
"nameResourceKey": "SCEPPolicyCustomAADAttribute", }
"value": "customAzureADAttribute",
"enabled": true
} }
], ],
"entityKey": "sanType", "dataType": 21,
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93, "category": 93,
"nameResourceKey": "value", "nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "name", "entityKey": "customSubjectAlternativeNames",
"booleanActions": 0, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} }
} ],
], "enabled": true
"dataType": 21, }
"category": 93, ],
"nameResourceKey": "PolicySubjectAlternativeName", "entityKey": "certificateStore",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription", "booleanActions": 0,
"childSettings": [ "defaultValue": "user",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "customSubjectAlternativeNames", "entityKey": "allowAllAppsAccess",
"booleanActions": 0, "booleanActions": 2,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} }
], ],
"enabled": true "enabled": true
} },
], {
"entityKey": "certificateStore", "nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"booleanActions": 0, "value": "deviceChannel",
"defaultValue": "user", "children": [
"policyType": 64, {
"enabled": true "dataType": 14,
}, "category": 93,
{ "nameResourceKey": "sCEPPolicyRenewalThresholdName",
"dataType": 0, "descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"category": 93, "childSettings": [
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "allowAllAppsAccess", "entityKey": "renewalThresholdPercentage",
"booleanActions": 2, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "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, "policyType": 29,
"enabled": true "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, "dataType": 16,
"category": 113, "category": 113,
@@ -370,14 +325,14 @@
"showAsSectionHeader": true, "showAsSectionHeader": true,
"dataType": 8, "dataType": 8,
"category": 113, "category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeader", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [ "childSettings": [
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 113, "category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [ "childSettings": [
], ],
@@ -33,7 +33,7 @@
"dataType": 16, "dataType": 16,
"category": 113, "category": 113,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "androidEnterpriseComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -41,7 +41,7 @@
"dataType": 16, "dataType": 16,
"category": 113, "category": 113,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "aospComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -1,20 +1,48 @@
{ {
"trustedcert_mactrustedcertificate": { "trustedcert_mactrustedcertificate": [
"dataEntityKey": "trustedRootCertificate", {
"filenameEntityKey": "certFileName", "dataType": 16,
"dataType": 1, "category": 115,
"category": 115, "nameResourceKey": "MacOSDeploymentChannelName",
"nameResourceKey": "trustedCertPolicySelectCertificateName", "descriptionResourceKey": "empty",
"descriptionResourceKey": "empty", "childSettings": [
"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", "options": [
"booleanActions": 0,
"policyType": 65, ],
"enabled": true "entityKey": "trustedRootCertificate",
} "booleanActions": 0,
"policyType": 65,
"enabled": true
}
]
} }
File diff suppressed because it is too large Load Diff
@@ -4078,6 +4078,124 @@
"defaultValue": false, "defaultValue": false,
"policyType": 19, "policyType": 19,
"enabled": true "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 "enabled": true
@@ -4954,7 +5072,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 19, "policyType": 19,
"enabled": true "enabled": true
} }
@@ -105,8 +105,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 121, "category": 121,
"nameResourceKey": "WifiTypeName", "nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "WiFiTypeDescription", "descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [ "childSettings": [
], ],
@@ -274,7 +274,7 @@
"entityKey": "proxySetting", "entityKey": "proxySetting",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 124, "policyType": 124,
"enabled": false "enabled": false
} }
@@ -1106,7 +1106,7 @@
"entityKey": "proxySetting", "entityKey": "proxySetting",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 124, "policyType": 124,
"enabled": false "enabled": false
} }
+3 -3
View File
@@ -238,7 +238,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "enabled": true
}, },
@@ -1494,7 +1494,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "enabled": true
}, },
@@ -1940,7 +1940,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "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:chkSkipCompareAssignments.IsChecked = (Get-Setting "Compare" "SkipCompareAssignments") -eq "true"
$global:chkSkipMissingSourcePolicies.IsChecked = (Get-Setting "Compare" "SkipMissingSourcePolicies") -eq "true" $global:chkSkipMissingSourcePolicies.IsChecked = (Get-Setting "Compare" "SkipMissingSourcePolicies") -eq "true"
$global:chkSkipMissingDestinationPolicies.IsChecked = (Get-Setting "Compare" "SkipMissingDestinationPolicies") -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 = @() $script:compareObjects = @()
foreach($objType in $global:lstMenuItems.ItemsSource) foreach($objType in $global:lstMenuItems.ItemsSource)
@@ -239,6 +245,9 @@ function Show-CompareBulkForm
Save-Setting "Compare" "SkipCompareAssignments" $global:chkSkipCompareAssignments.IsChecked Save-Setting "Compare" "SkipCompareAssignments" $global:chkSkipCompareAssignments.IsChecked
Save-Setting "Compare" "SkipMissingSourcePolicies" $global:chkSkipMissingSourcePolicies.IsChecked Save-Setting "Compare" "SkipMissingSourcePolicies" $global:chkSkipMissingSourcePolicies.IsChecked
Save-Setting "Compare" "SkipMissingDestinationPolicies" $global:chkSkipMissingDestinationPolicies.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) 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") $fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps 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 #$fileName = Expand-FileName $fileName
@@ -546,6 +559,10 @@ function Invoke-BulkCompareNamedObjects
{ {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$sourcePattern-$comparePattern-%DateTime%.csv") $fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps 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 $objName = Get-GraphObjectName (?? $compObj.Object1 $compObj.Object2) $item.ObjectType
foreach($compValue in $compObj.Result) foreach($compValue in $compObj.Result)
{ {
$compResultValues += [PSCustomObject]@{ $compValue += [PSCustomObject]@{
ObjectName = $objName ObjectName = $objName
Id = $compObj.Id Id = $compObj.Id
Type = $compObj.ObjectType.Title Type = $compObj.ObjectType.Title
@@ -701,12 +718,34 @@ function Start-BulkCompareExportObjects
SubCategory = $compValue.SubCategory SubCategory = $compValue.SubCategory
Match = $compValue.Match 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") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps 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 else
@@ -717,7 +756,10 @@ function Start-BulkCompareExportObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0) 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 "****************************************************************" Write-Log "****************************************************************"
@@ -726,7 +768,7 @@ function Start-BulkCompareExportObjects
Write-Status "" Write-Status ""
if($compareObjectsResult.Count -eq 0) 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)) if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{ {
Write-LogDebug "Excluded based on filter. Intune object name: '$($objName)'"
continue continue
} }
@@ -803,7 +846,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if(-not $fileObj) 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) { if($global:chkSkipMissingDestinationPolicies.IsChecked -ne $true) {
Write-Log "Object '$($objName)' with id $($fileObj.Object.Id) not found in exported folder. New Object?" 2 Write-Log "Object '$($objName)' with id $($fileObj.Object.Id) not found in exported folder. New Object?" 2
$compareProperties = @([PSCustomObject]@{ $compareProperties = @([PSCustomObject]@{
@@ -815,7 +858,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
} }
elseif(($fileObj | measure).Count -gt 1) 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 Write-Log "Multiple exported objects found with name '$($objName)" 2
$compareProperties = @([PSCustomObject]@{ $compareProperties = @([PSCustomObject]@{
Object1Value = $objName Object1Value = $objName
@@ -843,12 +886,16 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($global:chkSkipMissingSourcePolicies.IsChecked -ne $true) { if($global:chkSkipMissingSourcePolicies.IsChecked -ne $true) {
foreach ($fileObj in @($fileObjects)) foreach ($fileObj in @($fileObjects))
{ {
# Add objects that are exported but not in Intune # Skip objects if they are already processed
if(($compareObjectsResult | Where { $_.FileInfo.FullName -eq $fileObj.FileInfo.FullName})) { continue } if(($compareObjectsResult | Where { $_.Object2 -eq $fileObj.Object})) {
Write-LogDebug "Skip already processed file '$($fileObj.FileInfo.FullName)'"
continue
}
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType $objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter)) if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{ {
Write-LogDebug "Excluded based on filter. File: '$($fileObj.FileInfo.FullName)'"
continue continue
} }
@@ -894,6 +941,9 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "objectType") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps 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 else
@@ -904,7 +954,10 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0) 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 "****************************************************************" Write-Log "****************************************************************"
@@ -1080,6 +1133,9 @@ function Start-BulkCompareExportFolders
if($outputType -eq "objectType") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps 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 else
@@ -1090,7 +1146,10 @@ function Start-BulkCompareExportFolders
if($outputType -eq "all" -and $compResultValues.Count -gt 0) 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 "****************************************************************" 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 function Save-BulkCompareResults
{ {
param($compResultValues, $file, $props) param($compResultValues, $file, $props)
@@ -1359,7 +1425,7 @@ function Add-CompareProperty
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") } $value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") } $value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
$compare += [PSCustomObject]@{ $compare = [PSCustomObject]@{
PropertyName = $name PropertyName = $name
Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" } Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" }
Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" } Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" }
@@ -1367,10 +1433,12 @@ function Add-CompareProperty
SubCategory = $subCategory SubCategory = $subCategory
Match = ?? $match ($value1 -eq $value2) Match = ?? $match ($value1 -eq $value2)
} }
if($skip -eq $true) { if($skip -eq $true) {
$compare.Match = $null $compare.Match = $null
} }
Write-Host "Add property $($compare.PropertyName)"
$script:compareProperties += $compare $script:compareProperties += $compare
} }
@@ -1474,17 +1542,19 @@ function Compare-ObjectsBasedonDocumentation
# ToDo: set this based on configuration value # ToDo: set this based on configuration value
$script:assignmentOutput = "simpleFullCompare" $script:assignmentOutput = "simpleFullCompare"
$docObj1 = Invoke-ObjectDocumentation ([PSCustomObject]@{ $tmpObj1 = ([PSCustomObject]@{
Object = $obj1 Object = $obj1
ObjectType = $objectType ObjectType = $objectType})
})
$docObj1 = Invoke-ObjectDocumentation $tmpObj1 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$docObj2 = Invoke-ObjectDocumentation ([PSCustomObject]@{ $tmpObj2 = ([PSCustomObject]@{
Object = $obj2 Object = $obj2
ObjectType = $objectType ObjectType = $objectType
}) })
$docObj2 = Invoke-ObjectDocumentation $tmpObj2 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$settingsValue = ?? $objectType.CompareValue "Value" $settingsValue = ?? $objectType.CompareValue "Value"
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked" $skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
@@ -1505,8 +1575,10 @@ function Compare-ObjectsBasedonDocumentation
$addedProperties = @() $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) foreach ($prop in $docObj1.Settings)
{ {
if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue } 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 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 else
{ {
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where SubCategory -ne $null))
foreach ($prop in $docObj1.Settings) foreach ($prop in $docObj1.Settings)
{ {
if(($prop.EntityKey + $prop.Category + $prop.SubCategory) -in $addedProperties) { continue } 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 } $applicabilityRule2 = $docObj2.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$applicabilityRulesAdded += $applicabilityRule.Id $applicabilityRulesAdded += $applicabilityRule.Id
$val1 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value) $val1 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val2 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value) $val2 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
} }
@@ -1634,8 +1746,8 @@ function Compare-ObjectsBasedonDocumentation
if(($applicabilityRule.Id) -in $applicabilityRulesAdded) { continue } if(($applicabilityRule.Id) -in $applicabilityRulesAdded) { continue }
$applicabilityRule2 = $docObj1.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id } $applicabilityRule2 = $docObj1.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$script:applicabilityRulesAdded += $applicabilityRule.Id $script:applicabilityRulesAdded += $applicabilityRule.Id
$val2 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value) $val2 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val1 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value) $val1 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
} }
@@ -1645,8 +1757,8 @@ function Compare-ObjectsBasedonDocumentation
{ {
$complianceAction2 = $docObj2.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr } $complianceAction2 = $docObj2.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr $complianceActionsAdded += $complianceAction.IdStr
$val1 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds) $val1 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val2 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.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 Add-CompareProperty $complianceAction.Category $val1 $val2
} }
@@ -1656,8 +1768,8 @@ function Compare-ObjectsBasedonDocumentation
if(($complianceAction.IdStr) -in $complianceActionsAdded) { continue } if(($complianceAction.IdStr) -in $complianceActionsAdded) { continue }
$complianceAction2 = $docObj1.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr } $complianceAction2 = $docObj1.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr $complianceActionsAdded += $complianceAction.IdStr
$val2 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds) $val2 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val1 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.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 Add-CompareProperty $complianceAction.Category $val1 $val2
} }
@@ -1783,6 +1895,10 @@ function Invoke-SilentBatchJob
$global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|") $global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|")
$global:cbCompareCSVDelimiter.SelectedValue = ($settingsObj.BulkCompare | Where Name -eq "cbCompareCSVDelimiter").Value $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-CompareProviderOptions $global:cbCompareProvider
Set-BatchProperties $settingsObj.BulkCompare $script:cmpForm -SkipMissingControlWarning 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") $properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description")
} }
#endregion #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 #region Endpoint Security
elseif($type -eq "#microsoft.graph.deviceManagementIntent") elseif($type -eq "#microsoft.graph.deviceManagementIntent")
{ {
Invoke-TranslateIntentObject $obj $objectType | Out-Null Invoke-TranslateIntentObject $obj $objectType | Out-Null
$properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description") $properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description")
$defaultDocumentationProperties = @("Name","Value","RecommendedValue") $defaultDocumentationProperties = @("Name","Value","RecommendedValue")
$inputType = "Intent"
} }
#endregion #endregion
#region Administrative Templates #region Administrative Templates
@@ -381,7 +389,11 @@ function Get-DocumentedSettings
function Invoke-ObjectDocumentation function Invoke-ObjectDocumentation
{ {
param($documentationObj) param($documentationObj,
$ObjectSeparator,
$PropertySeparator,
$DocumentationLanguage
)
$global:intentCategories = $null $global:intentCategories = $null
$global:catRecommendedSettings = $null $global:catRecommendedSettings = $null
@@ -389,10 +401,11 @@ function Invoke-ObjectDocumentation
$global:cfgCategories = $null $global:cfgCategories = $null
$script:admxCategories = $null $script:admxCategories = $null
$script:migTable = $null $script:migTable = $null
$script:offlineObjects = @{}
$script:DocumentationLanguage = "en" $script:DocumentationLanguage = ?? $DocumentationLanguage "en"
$script:objectSeparator = [System.Environment]::NewLine $script:objectSeparator = ?? $ObjectSeparator ([System.Environment]::NewLine)
$script:propertySeparator = "," $script:propertySeparator = ?? $PropertySeparator ","
$loadExportedInfo = $false $loadExportedInfo = $false
@@ -691,6 +704,10 @@ function Add-BasicAdditionalValues
if($obj.createdDateTime -is [DateTime]) if($obj.createdDateTime -is [DateTime])
{ {
$tmpDate = $obj.createdDateTime $tmpDate = $obj.createdDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -714,6 +731,10 @@ function Add-BasicAdditionalValues
if($obj.lastModifiedDateTime -is [DateTime]) if($obj.lastModifiedDateTime -is [DateTime])
{ {
$tmpDate = $obj.lastModifiedDateTime $tmpDate = $obj.lastModifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -735,6 +756,10 @@ function Add-BasicAdditionalValues
if($obj.modifiedDateTime -is [DateTime]) if($obj.modifiedDateTime -is [DateTime])
{ {
$tmpDate = $obj.modifiedDateTime $tmpDate = $obj.modifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -1037,15 +1062,26 @@ function Invoke-TranslateADMXObject
$rawValues += $rawValue $rawValues += $rawValue
} }
$status = (?: ($definitionValue.enabled -eq $true) $enabledStr $disabledStr) $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 @{ $script:objectSettingsData += New-Object PSObject -Property @{
Name = $definitionValue.definition.displayName Name = $definitionValue.definition.displayName
Description = $definitionValue.definition.explainText Description = $definitionValue.definition.explainText
Status = $status Status = $status
Value = $values -join $script:objectSeparator 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 ValueWithLabel = $valuesWithLabel -join $script:objectSeparator
FullValueTable = $tableValue FullValueTable = $tableValue
CombinedValueWithLabel = ($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator)) CombinedValueWithLabel = $combinedValueWithLabel #($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator))
RawValue = $rawValues -join $script:propertySeparator RawValue = $rawValues -join $script:propertySeparator
Class = $definitionValue.definition.classType Class = $definitionValue.definition.classType
DefinitionId = $definitionValue.definition.id DefinitionId = $definitionValue.definition.id
@@ -1109,9 +1145,9 @@ function Invoke-TranslateSettingsObject
$cfgSettings = $obj.Settings $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) if(-not $global:cachedCfgSettings)
@@ -1210,13 +1246,23 @@ function Add-SettingsSetting
$objCategory = $categoryDef $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]@{ $settingInfo = [PSCustomObject]@{
SettingId = $settingsDef.Id SettingId = $settingsDef.Id
SettingKey = "" SettingKey = ""
SettingName = $settingsDef.Name SettingName = $settingsDef.Name
Name = $settingsDef.displayName Name = $settingName
Description=$settingsDef.description Description = $settingDescription
CategortyId = $objCategory.id CategoryId = $objCategory.id
Category=$objCategory.displayName Category=$objCategory.displayName
CategoryDefinition=$objCategory CategoryDefinition=$objCategory
SubCategory=$subCategory.displayName SubCategory=$subCategory.displayName
@@ -1392,6 +1438,85 @@ function Add-SettingsSetting
#endregion #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) #region Intent Objects (Endpoint Security)
function Get-IntentCategory function Get-IntentCategory
@@ -2166,6 +2291,7 @@ function Invoke-TranslateSection
$value = $null $value = $null
$valueSet = $false $valueSet = $false
$useParentProp = $false $useParentProp = $false
$payloadFile = $false
#if($prop.enabled -eq $false -and $objInfo.ShowDisabled -ne $true) { continue } #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)") if($prop.filenameEntityKey -and $obj."$($prop.filenameEntityKey)")
{ {
$value = $obj."$($prop.filenameEntityKey)" $value = $obj."$($prop.filenameEntityKey)"
$payloadFile = $true
} }
else else
{ {
@@ -2550,6 +2677,23 @@ function Invoke-TranslateSection
if($addPropertyInfo) if($addPropertyInfo)
{ {
Add-PropertyInfo (?: ($useParentProp -and $parent) $parent $prop) $value $rawValue 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 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)" 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 = @() $filteredSettings = @()
foreach($item in $documentedObj.Settings) foreach($item in $documentedObj.Settings)
{ {
if(-not ($item.PSObject.Properties | Where Name -eq "RawValue") -or $documentedObj.UpdateFilteredObject -eq $false) if(-not ($item.PSObject.Properties | Where Name -eq "RawValue") -or $documentedObj.UpdateFilteredObject -eq $false)
{ {
$filteredSettings = $documentedObj.Settings if($hasRawValue -eq $false) {
break $filteredSettings = $documentedObj.Settings
break
}
$filteredSettings += $item
continue
} }
if($item.AlwaysAddValue -eq $true) if($item.AlwaysAddValue -eq $true)
+36 -2
View File
@@ -422,7 +422,7 @@ function Add-CDDocumentCustomProfileValue
$value = $obj.startMenuAppListVisibility $value = $obj.startMenuAppListVisibility
if($value.IndexOf(", ") -eq -1) 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 Invoke-TranslateOption $obj $prop -PropValue $value
return $false return $false
@@ -1180,6 +1180,12 @@ function Add-CDDocumentCustomProfileProperty
} }
elseif($obj.'@OData.Type' -eq "#microsoft.graph.windows10EnrollmentCompletionPageConfiguration") 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) if($obj.selectedMobileAppIds.Count -eq 0)
{ {
$apps = Get-LanguageString "EnrollmentStatusScreen.Apps.useSelectedAppsAll" $apps = Get-LanguageString "EnrollmentStatusScreen.Apps.useSelectedAppsAll"
@@ -1329,6 +1335,17 @@ function Add-CDDocumentCustomProfileProperty
Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.remediationScriptContent 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") elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceManagementScript")
{ {
if($obj.ScriptContent) if($obj.ScriptContent)
@@ -2299,6 +2316,10 @@ function Invoke-CDDocumentTermsOfUse
if($obj.termsExpiration.startDateTime -is [DateTime]) if($obj.termsExpiration.startDateTime -is [DateTime])
{ {
$tmpDate = $obj.termsExpiration.startDateTime $tmpDate = $obj.termsExpiration.startDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -4154,7 +4175,17 @@ function Invoke-CDDocumentWindowsKioskConfiguration
{ {
try 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]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.kioskStartDateTime" Name = Get-LanguageString "SettingDetails.kioskStartDateTime"
@@ -4608,15 +4639,18 @@ function Invoke-CDDocumentTranslateSectionFile
if($null -eq $obj.deviceCompliancePolicyScript) if($null -eq $obj.deviceCompliancePolicyScript)
{ {
$propValue = Get-LanguageString "BooleanActions.notConfigured" $propValue = Get-LanguageString "BooleanActions.notConfigured"
$rawValue = "notConfigured"
} }
else else
{ {
$propValue = Get-LanguageString "BooleanActions.require" $propValue = Get-LanguageString "BooleanActions.require"
$rawValue = "require"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.adminConfiguredComplianceSettingName" Name = Get-LanguageString "SettingDetails.adminConfiguredComplianceSettingName"
Value = $propValue Value = $propValue
EntityKey = "deviceCompliancePolicyScript" EntityKey = "deviceCompliancePolicyScript"
RawValue = $rawValue
Category = $category Category = $category
SubCategory = $null 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 "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" "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 "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" { Add-XamlEvent $script:mdForm "browseMDDocumentName" "add_click" {
$sf = [System.Windows.Forms.SaveFileDialog]::new() $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" "MDCSSFile" (Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" "")
Save-Setting "Documentation" "MDOpenFile" (Get-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked") Save-Setting "Documentation" "MDOpenFile" (Get-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked")
Save-Setting "Documentation" "MDDocumentFileType" (Get-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" '') 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" $defaultCSSFile = $global:AppRootFolder + "\Documentation\DefaultMDStyle.css"
$MDCssFile = Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" $defaultCSSFile $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("*Organization:* $($global:Organization.displayName)`n")
$script:mdContent.AppendLine("*Generated by:* $userName$mail`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) if($script:sectionAnchors.Count -gt 0)
{ {
@@ -265,7 +269,7 @@ function Invoke-MDProcessItem
foreach($prop in $global:txtMDCustomProperties.Text.Split(",")) 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('=') $propInfo = $prop.Split('=')
if(($propInfo | measure).Count -gt 1) if(($propInfo | measure).Count -gt 1)
{ {
@@ -312,7 +316,7 @@ function Invoke-MDProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order)) 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) 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])) if(!("Microsoft.Office.Interop.Word.Application" -as [Type]))
{ {
$loaded = $false
try try
{ {
Add-Type -AssemblyName Microsoft.Office.Interop.Word 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 catch
{ {
Write-LogError "Failed to add Word Interop type. Cannot create word documents. Verify that Word is installed properly." $_.Exception Write-LogError "Failed to add Word Interop type. Cannot create word documents. Verify that Word is installed properly." $_.Exception
return 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]@{ Add-OutputType ([PSCustomObject]@{
@@ -46,6 +63,9 @@ function Add-WordOptionsControl
$global:spWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible") $global:spWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:txtWordCustomProperties.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.ItemsSource = ("[ { Name: `"Full`",Value: `"full`" }, { Name: `"Limited`",Value: `"limited`" }, { Name: `"Basic`",Value: `"basic`" }]" | ConvertFrom-Json)
$global:cbWordDocumentationLevel.SelectedValue = (Get-Setting "Documentation" "WordDocumentationLevel" "full") $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" "WordExportProperties" $global:cbWordDocumentationProperties.SelectedValue
Save-Setting "Documentation" "WordCustomDisplayProperties" $global:txtWordCustomProperties.Text Save-Setting "Documentation" "WordCustomDisplayProperties" $global:txtWordCustomProperties.Text
Save-Setting "Documentation" "WordDocumentFormat" $global:cbWordDocumentationFormat.SelectedValue
Save-Setting "Documentation" "WordDocumentTemplate" $global:txtWordDocumentTemplate.Text Save-Setting "Documentation" "WordDocumentTemplate" $global:txtWordDocumentTemplate.Text
Save-Setting "Documentation" "WordDocumentName" $global:txtWordDocumentName.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.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfAuthorities | 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 $fileName = $global:txtWordDocumentName.Text
if(-not $fileName) if(-not $fileName)
{ {
@@ -392,7 +421,10 @@ function Invoke-WordPostProcessItems
$fileName = Expand-FileName $fileName $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 try
{ {
@@ -575,7 +607,7 @@ function Invoke-WordProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order)) 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 $cellRow = $row
foreach($settingProp in $properties) foreach($settingProp in $properties)
{ {
if([String]::IsNullOrEmpty($settingProp)) {
continue
}
$script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-DocTranslateColumnHeader ($settingProp.Split('.')[-1])) $script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-DocTranslateColumnHeader ($settingProp.Split('.')[-1]))
$propArr = $settingProp.Split('.') $propArr = $settingProp.Split('.')
@@ -779,6 +815,9 @@ function Add-DocTableItems
$i = 1 $i = 1
foreach($prop in $properties) foreach($prop in $properties)
{ {
if([String]::IsNullOrEmpty($prop)) {
continue
}
$script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1])) $script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1]))
$i++ $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 function Get-ModuleVersion
{ {
'3.9.8' '3.10.0.6'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -221,7 +221,7 @@ function Invoke-InitializeModule
Id = "CompliancePoliciesV2" Id = "CompliancePoliciesV2"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/deviceManagement/compliancePolicies" API = "/deviceManagement/compliancePolicies"
NameProperty = "Name" NameProperty = "name"
PropertiesToRemove = @('settingCount') PropertiesToRemove = @('settingCount')
ViewProperties = @("name","description","Id") ViewProperties = @("name","description","Id")
Expand="settings" Expand="settings"
@@ -236,9 +236,11 @@ function Invoke-InitializeModule
Id = "ComplianceScripts" Id = "ComplianceScripts"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/deviceManagement/deviceComplianceScripts" API = "/deviceManagement/deviceComplianceScripts"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") PostImportCommand = { Start-PostImportComplianceScripts @args }
Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "CompliancePolicies" GroupId = "CompliancePolicies"
Icon = "Scripts" Icon = "Scripts"
ImportOrder = 80
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -376,7 +378,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args } DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args } PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts" Icon="Scripts"
GroupId = "Scripts" GroupId = "Scripts"
@@ -390,7 +392,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args } DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args } PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts" Icon="Scripts"
GroupId = "Scripts" GroupId = "Scripts"
@@ -401,7 +403,7 @@ function Invoke-InitializeModule
Id = "MacCustomAttributes" Id = "MacCustomAttributes"
API = "/deviceManagement/deviceCustomAttributeShellScripts" API = "/deviceManagement/deviceCustomAttributeShellScripts"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="CustomAttributes" Icon="CustomAttributes"
GroupId = "CustomAttributes" # MacOS Settings GroupId = "CustomAttributes" # MacOS Settings
@@ -604,10 +606,11 @@ function Invoke-InitializeModule
API = "/deviceManagement/configurationPolicies" API = "/deviceManagement/configurationPolicies"
PropertiesToRemove = @('settingCount') PropertiesToRemove = @('settingCount')
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
NameProperty = "Name" NameProperty = "name"
ViewProperties = @("name","description","Id") ViewProperties = @("name","description","Id")
Expand="Settings" Expand="Settings"
Icon="DeviceConfiguration" Icon="DeviceConfiguration"
PreImportCommand = { Start-PreImportSettingsCatalog @args }
PostExportCommand = { Start-PostExportSettingsCatalog @args } PostExportCommand = { Start-PostExportSettingsCatalog @args }
PreUpdateCommand = { Start-PreUpdateSettingsCatalog @args } PreUpdateCommand = { Start-PreUpdateSettingsCatalog @args }
PostGetCommand = { Start-PostGetSettingsCatalog @args } PostGetCommand = { Start-PostGetSettingsCatalog @args }
@@ -615,6 +618,35 @@ function Invoke-InitializeModule
GroupId = "DeviceConfiguration" 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 @{ Add-ViewItem (New-Object PSObject -Property @{
Title = "Role Definitions" Title = "Role Definitions"
Id = "RoleDefinitions" Id = "RoleDefinitions"
@@ -718,7 +750,7 @@ function Invoke-InitializeModule
PreUpdateCommand = { Start-PreUpdateDeviceHealthScripts @args } PreUpdateCommand = { Start-PreUpdateDeviceHealthScripts @args }
PostExportCommand = { Start-PostExportDeviceHealthScripts @args } PostExportCommand = { Start-PostExportDeviceHealthScripts @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "EndpointAnalytics" GroupId = "EndpointAnalytics"
Icon = "Report" Icon = "Report"
AssignmentsType = "deviceHealthScriptAssignments" AssignmentsType = "deviceHealthScriptAssignments"
@@ -832,6 +864,17 @@ function Invoke-InitializeModule
Icon = "UpdatePolicies" Icon = "UpdatePolicies"
GroupId = "WinDriverUpdatePolicies" 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 function Invoke-EMAuthenticateToMSAL
@@ -1010,7 +1053,7 @@ function Set-EMViewPanel
$global:btnLoadAllPages.add_click({ $global:btnLoadAllPages.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects" Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -AllPages [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() $global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate
@@ -1020,7 +1063,7 @@ function Set-EMViewPanel
$global:btnLoadNextPage.add_click({ $global:btnLoadNextPage.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects" Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage [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() $global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter Invoke-FilterBoxChanged $global:txtFilter
@@ -1391,6 +1434,30 @@ function Start-PreUpdateCompliancePolicies
#endregion #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 #region Intune Branding functions
function Start-PreImportIntuneBranding function Start-PreImportIntuneBranding
{ {
@@ -1440,7 +1507,7 @@ function Start-PreImportIntuneBranding
function Start-PostImportIntuneBranding function Start-PostImportIntuneBranding
{ {
param($obj, $objectType) param($obj, $objectType, $file)
if($obj.isDefaultProfile -or -not $global:brandingClone) { return } if($obj.isDefaultProfile -or -not $global:brandingClone) { return }
@@ -1744,6 +1811,194 @@ function Invoke-EditScript
#endregion #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 #region Terms and Conditions
function Start-PostExportTermsAndConditions function Start-PostExportTermsAndConditions
{ {
@@ -2512,7 +2767,7 @@ function Start-PostExportApplications
} }
else else
{ {
Write-Log "Cound not file encryption file" Write-Log "Cound not find encryption file"
} }
} }
} }
@@ -3265,6 +3520,75 @@ function Start-PostFileImportRoleDefinitions
#endregion #endregion
#region SettingsCatalog #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 function Start-PostExportSettingsCatalog
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
@@ -3813,11 +4137,13 @@ function Add-ConditionalAccessImportExtensions
Value = "disabled" Value = "disabled"
} }
$defaultCAState = Get-SettingValue "ConditionalAccessState"
$global:cbImportCAState = [System.Windows.Controls.ComboBox]::new() $global:cbImportCAState = [System.Windows.Controls.ComboBox]::new()
$global:cbImportCAState.DisplayMemberPath = "Name" $global:cbImportCAState.DisplayMemberPath = "Name"
$global:cbImportCAState.SelectedValuePath = "Value" $global:cbImportCAState.SelectedValuePath = "Value"
$global:cbImportCAState.ItemsSource = $CAStates $global:cbImportCAState.ItemsSource = $CAStates
$global:cbImportCAState.SelectedValue = "disabled" $global:cbImportCAState.SelectedValue = $defaultCAState
$global:cbImportCAState.Margin="0,5,0,0" $global:cbImportCAState.Margin="0,5,0,0"
$global:cbImportCAState.HorizontalAlignment="Left" $global:cbImportCAState.HorizontalAlignment="Left"
$global:cbImportCAState.Width=250 $global:cbImportCAState.Width=250
@@ -3855,6 +4181,12 @@ function Start-PreImportConditionalAccess
{ {
$obj.sessionControls.disableResilienceDefaults = $null $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 function Start-PostExportConditionalAccess
+7
View File
@@ -521,6 +521,13 @@ function Write-AzureStorageChunk
"Content-Type" = "application/octet-stream" "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 $curProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
+14 -6
View File
@@ -704,7 +704,10 @@ function Invoke-LoadADMXSettings
$tvItem | Add-Member -MemberType NoteProperty -Name "AllPolicies" -Value $true $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 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.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($categoryId)']",$script:xmlNS)
#$catObj = $script:admxXML.policyDefinitions.categories.category | Where Name -eq "$categoryId"
$categories = @() $categories = @()
while($catObj) while($catObj)
@@ -862,6 +866,7 @@ function Get-ADMXCategoryNamePath
if($catObj.parentCategory.ref) if($catObj.parentCategory.ref)
{ {
$catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($catObj.parentCategory.ref)']", $script:xmlNS) $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 else
{ {
@@ -1037,11 +1042,11 @@ function Set-ADMXElementsPanel
} }
elseif($valItem.value.longDecimal) elseif($valItem.value.longDecimal)
{ {
$value = $valItem.value.longDecimal.'#text' $value = ?? $valItem.value.longDecimal.'#text' $valItem.value.longDecimal
} }
elseif($valItem.value.string) elseif($valItem.value.string)
{ {
$value = $valItem.value.string.'#text' $value = ?? $valItem.value.string.'#text' $valItem.value.string
} }
else else
{ {
@@ -1151,7 +1156,7 @@ function Set-ADMXElementsPanel
} }
elseif($valItem.value.string) elseif($valItem.value.string)
{ {
$value = $valItem.value.string.'#text' $value = ?? $valItem.value.string.'#text' $valItem.value.string
} }
else else
{ {
@@ -1981,9 +1986,11 @@ function Add-ADMXRegClasses
} }
$classDef = @" $classDef = @"
using System;
using System.ComponentModel; 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"); } } public string DataType { get { return _dataType; } set { _dataType = value; NotifyPropertyChanged("DataType"); NotifyPropertyChanged("DataTypeDisplayString"); } }
private string _dataType = null; private string _dataType = null;
@@ -2069,8 +2076,9 @@ function Add-ADMXRegClasses
} }
} }
"@ "@
[Reflection.Assembly]::LoadWithPartialName("mscorlib") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null [Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel') Add-Type -TypeDefinition $classDef
} }
#endregion #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" Description = "Sort the list of available tenants based on Tenant name. Updated at restart or account change"
}) "MSAL" }) "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 Add-MSALPrereq
} }
@@ -200,6 +214,9 @@ function Set-MSALGraphEnvironment
{ {
$curAADEnv = $script:lstAADEnvironments | Where URL -eq $user.Environment $curAADEnv = $script:lstAADEnvironments | Where URL -eq $user.Environment
} }
elseif($global:UseGraphEnvironment) {
$curAADEnv = $script:lstAADEnvironments | Where value -eq $global:UseGraphEnvironment
}
else else
{ {
$curAADEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public") $curAADEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public")
@@ -207,7 +224,14 @@ function Set-MSALGraphEnvironment
if($curAADEnv.Value -eq "usGov") if($curAADEnv.Value -eq "usGov")
{ {
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc") if($global:UseGCCType)
{
$gccEnv = $global:UseGCCType
}
else {
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc")
}
if($gccEnv) if($gccEnv)
{ {
$GCCEnvObj = $script:lstGCCEnvironments | Where Value -eq $gccEnv $GCCEnvObj = $script:lstGCCEnvironments | Where Value -eq $gccEnv
@@ -259,6 +283,7 @@ function Get-MSALUserInfo
if($global:Organization) if($global:Organization)
{ {
if($global:Organization -is [array]) { $global:Organization = $global:Organization[0]} 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 Save-Setting $global:Organization.Id "_Name" $global:Organization.displayName
} }
Set-EnvironmentInfo $global:Organization.displayName Set-EnvironmentInfo $global:Organization.displayName
@@ -487,6 +512,129 @@ function Install-MSALDependencyModule
} }
function Add-MSALPrereq 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 = "" $msalPath = ""
@@ -565,7 +713,15 @@ function Add-MSALPrereq
$RequiredAssemblies.Add($msalPath) $RequiredAssemblies.Add($msalPath)
$script:msalFile = $msalPath $script:msalFile = $msalPath
} }
$RequiredAssemblies.Add('System.Security.dll') $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 try
{ {
@@ -586,6 +742,10 @@ function Connect-MSALClientApp
if(-not $script:MSALApp) if(-not $script:MSALApp)
{ {
if($global:UseGraphEnvironment) {
Set-MSALGraphEnvironment $null $null
}
$authority = "https://login.microsoftonline.com/$tenantId" $authority = "https://login.microsoftonline.com/$tenantId"
#$redirectUri = "http://localhost" #$redirectUri = "http://localhost"
@@ -747,7 +907,7 @@ function Get-MSALApp
{ {
param($appInfo, $loginHint) 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" $tenant = ?? $appInfo.TenantId "organizations"
@@ -770,14 +930,21 @@ function Get-MSALApp
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($appInfo.ClientID) $appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($appInfo.ClientID)
[void]$appBuilder.WithAuthority($authority) [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) } if($appInfo.RedirectUri) { [void]$appBuilder.WithRedirectUri($appInfo.RedirectUri) }
[void] $appBuilder.WithClientName("CloudAPIPowerShellManagement") [void] $appBuilder.WithClientName("CloudAPIPowerShellManagement")
[void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion) [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 Add-MSALProxy $appBuilder
# Ceck if correct version... # Ceck if correct version...
@@ -908,8 +1075,6 @@ function Connect-MSALUser
Add-MSALPrereq Add-MSALPrereq
} }
$curTicks = $global:MSALToken.ExpiresOn.LocalDateTime.Ticks
$currentLoggedInUserApp = ($global:MSALToken.Account.HomeAccountId.Identifier + $global:MSALToken.TenantId + $global:MSALApp.ClientId) $currentLoggedInUserApp = ($global:MSALToken.Account.HomeAccountId.Identifier + $global:MSALToken.TenantId + $global:MSALApp.ClientId)
$currentLoggedInUserId = $global:MSALToken.Account.HomeAccountId.Identifier $currentLoggedInUserId = $global:MSALToken.Account.HomeAccountId.Identifier
if($Interactive -eq $true) if($Interactive -eq $true)
@@ -1015,15 +1180,6 @@ function Connect-MSALUser
return 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 #AADSTS65001
if($script:authenticationFailure.Classification -eq "ConsentRequired") if($script:authenticationFailure.Classification -eq "ConsentRequired")
{ {
@@ -1113,6 +1269,10 @@ function Connect-MSALUser
{ {
Write-Log "Login hint: $loginHintName" Write-Log "Login hint: $loginHintName"
[void]$AquireTokenObj.WithLoginHint($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) if($script:authenticationFailure.Claims)
@@ -1133,11 +1293,6 @@ function Connect-MSALUser
Write-Log "Interactive login with Consent prompt" Write-Log "Interactive login with Consent prompt"
[void]$aquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::Consent) [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 $authResult = Get-MsalAuthenticationToken $aquireTokenObj
if($authResult) 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) if($currentLoggedInUserId -ne $authResult.Account.HomeAccountId.Identifier)
{ {
$script:AccessableTenants = $null $script:AccessableTenants = $null
@@ -1225,15 +1405,6 @@ function Connect-MSALUser
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
} }
Invoke-MSALAuthenticationUpdated $authResult 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")) 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")) 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 # Make sure MS Graph settings are added before exiting before App Id and Tenant Id is missing
Write-Log "Add settings and menu items" 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." 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" }) "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 function Get-GraphAppInfo
@@ -558,7 +621,9 @@ function Get-GraphObjects
[switch] [switch]
$SingleObject, $SingleObject,
[string] [string]
$filter) $filter,
[int]
$pageSize = -1)
$params = @{} $params = @{}
if($objectType.ODataMetadata) if($objectType.ODataMetadata)
@@ -593,6 +658,10 @@ function Get-GraphObjects
{ {
#Use default page size or use below for a specific page size for testing #Use default page size or use below for a specific page size for testing
#$params.Add("pageSize",5) #!!! #$params.Add("pageSize",5) #!!!
if ($pageSize -gt 0)
{
$params.Add("pageSize", $pageSize)
}
} }
elseif($SingleObject -ne $true -and $SinglePage -ne $true) elseif($SingleObject -ne $true -and $SinglePage -ne $true)
{ {
@@ -780,7 +849,30 @@ function Show-GraphObjects
$script:nextGraphPage = $null $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.AutoGenerateColumns = $false
$dgObjects.Columns.Clear() $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 function Get-GraphMetaData
{ {
if(-not $global:metaDataXML) if(-not $global:metaDataXML)
@@ -3685,6 +3805,11 @@ function Import-GraphObject
{ {
$params.Add("AdditionalHeaders",$ret["AdditionalHeaders"]) $params.Add("AdditionalHeaders",$ret["AdditionalHeaders"])
} }
if($ret.ContainsKey("JSON"))
{
$obj = $ret["JSON"] | ConvertFrom-Json
}
} }
} }
@@ -3985,8 +4110,8 @@ function Show-GraphObjectInfo
return return
} }
# Save settings here... # Save settings here...
$nameProp = (?? $global:dgObjects.SelectedItem.Object.NameProperty "displayName") $nameProp = (?? $global:dgObjects.SelectedItem.ObjectType.NameProperty "displayName")
$idProp = (?? $global:dgObjects.SelectedItem.Object.IDProperty "id") $idProp = (?? $global:dgObjects.SelectedItem.ObjectType.IDProperty "id")
$updateObj = [PSCustomObject]@{ $updateObj = [PSCustomObject]@{
$idProp = $global:dgObjects.SelectedItem.Object."$idProp" $idProp = $global:dgObjects.SelectedItem.Object."$idProp"
@@ -4148,9 +4273,10 @@ function local:Add-ObjectColumnInfoClass
} }
$classDef = @" $classDef = @"
using System;
using System.ComponentModel; using System.ComponentModel;
public class ObjectColumnInfo : INotifyPropertyChanged public class ObjectColumnInfo : System.ComponentModel.INotifyPropertyChanged
{ {
public string Property { get { return _property; } set { _property = value; NotifyPropertyChanged("Property"); } } public string Property { get { return _property; } set { _property = value; NotifyPropertyChanged("Property"); } }
private string _property = null; private string _property = null;
@@ -4176,8 +4302,14 @@ function local:Add-ObjectColumnInfoClass
} }
"@ "@
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null try {
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel') Add-Type -TypeDefinition $classDef -IgnoreWarnings #-ReferencedAssemblies @('System.ComponentModel')
}
catch
{
Write-LogError "Failed to add type ObjectColumnInfo" $_.Exception
}
} }
function Local:Show-ObjectDefaultColumnsSettings 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: 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 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. 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. 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 ## 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. 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 See [Change Log](ReleaseNotes.md) for more information
## Authentication ## 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 ## 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 * Apple Enrolment Types - NOT fully tested
* Autopilot profiles * Autopilot profiles
* Baseline Security profiles * Baseline Security profiles
* BIOS Configuration
* Compliance policies * Compliance policies
* Compliance policies v2 * Compliance policies v2
* Compliance scripts * Compliance scripts
+123
View File
@@ -1,4 +1,127 @@
# Release Notes # 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 ## 3.9.8 - 2024-10-12
**New features** **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="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -72,27 +75,47 @@
</StackPanel> </StackPanel>
<CheckBox Grid.Column='1' Grid.Row='3' Name='chkSkipMissingDestinationPolicies' VerticalAlignment="Center" /> <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" /> <Label Content="Save as" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specifies how the export csv should be saved. One file per ObjectType or one file for all objects." /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specifies how the export csv should be saved. One file per ObjectType or one file for all objects." />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareSave" Margin="0,5,0,0" MinWidth="250" Grid.Row='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" /> 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" /> <Label Content="Comparison Type" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify how objects should be compared" />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareType" Margin="0,5,0,0" MinWidth="250" Grid.Row='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" /> 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" /> <Label Content="CSV Delimiter" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating properties in the CSV file" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the character to use for separating properties in the CSV file" />
</StackPanel> </StackPanel>
<ComboBox Name="cbCompareCSVDelimiter" Margin="0,5,0,0" MinWidth="250" Grid.Row='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> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
@@ -102,7 +125,7 @@
</StackPanel> </StackPanel>
</Grid> </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> </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" <ComboBox Name="cbMDDocumentOutputFile" Margin="0,5,0,0" MinWidth="250" Grid.Row='4' Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" /> 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> </Grid>
+7
View File
@@ -57,6 +57,13 @@
</StackPanel> </StackPanel>
<TextBox Text="" Name="txtWordCustomProperties" Margin="0,5,5,5" Grid.Row="1" Grid.Column="1"/> <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 Grid.Row="1" Grid.ColumnSpan="2"> <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>