Compare commits

...
3 Commits
Author SHA1 Message Date
Mikael Karlsson ab7b062946 3.9.2 2023-10-17 20:34:44 +11:00
Mikael Karlsson ea3af64316 3.9.1 2023-08-30 20:07:18 +10:00
Mikael Karlsson e6ec048df0 3.9.0 Module
Added version in the module file
2023-05-04 23:42:37 +10:00
51 changed files with 57524 additions and 37936 deletions
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Net;
using System.Net.Http;
using Microsoft.Identity.Client;
public class HttpFactoryWithProxy : IMsalHttpClientFactory
{
private static HttpClient _httpClient;
public HttpFactoryWithProxy(string proxyURI) : this(proxyURI, null, null)
{
}
public HttpFactoryWithProxy(string proxyURI, string proxyUserName = null, string proxyPassword = null)
{
if (_httpClient == null)
{
var proxy = new WebProxy
{
Address = new Uri(proxyURI),
BypassProxyOnLocal = false,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(
userName: proxyUserName,
password: proxyPassword)
};
var httpClientHandler = new HttpClientHandler
{
Proxy = proxy,
};
_httpClient = new HttpClient(handler: httpClientHandler);
}
}
public HttpClient GetHttpClient()
{
return _httpClient;
}
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -12,7 +12,7 @@
RootModule = 'CloudAPIPowerShellManagement.psm1' RootModule = 'CloudAPIPowerShellManagement.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '3.8.1' ModuleVersion = '3.9.2'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()
@@ -27,7 +27,7 @@ Author = 'Mikael Karlsson'
# CompanyName = '' # CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = '(c) 2022 Mikael Karlsson. Software released under MIT License.' Copyright = '(c) 2023 Mikael Karlsson. Software released under MIT License.'
# Description of the functionality provided by this module # Description of the functionality provided by this module
Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Graph API' Description = 'Management of Intune and Azure via Cloud APIs like Microsoft Graph API'
+12 -4
View File
@@ -93,9 +93,18 @@ function Initialize-CloudAPIManagement
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationFramework
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$global:hideUI = ($Silent -eq $true) $global:hideUI = ($Silent -eq $true)
$global:SilentBatchFile = $SilentBatchFile $global:SilentBatchFile = $SilentBatchFile
if($tenantId)
{
$global:AzureAppId = $appId
$global:ClientSecret = $secret
$global:ClientCert = $certificate
}
if($global:hideUI -ne $true) if($global:hideUI -ne $true)
{ {
# Run with UI # Run with UI
@@ -126,12 +135,11 @@ function Initialize-CloudAPIManagement
Write-Error "Tenant Id is missing. Use -TenantId <Tenant-guid> on the command line to run silent batch jobs" Write-Error "Tenant Id is missing. Use -TenantId <Tenant-guid> on the command line to run silent batch jobs"
return return
} }
$global:TenantId = $tenantId
$global:AzureAppId = $appId
$global:ClientSecret = $secret
$global:ClientCert = $certificate
} }
$global:TenantId = $tenantId
if($ShowConsoleWindow -ne $true) if($ShowConsoleWindow -ne $true)
{ {
Hide-Console Hide-Console
+143 -6
View File
@@ -11,7 +11,7 @@ This module handles the WPF UI
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.2'
} }
function Initialize-Window function Initialize-Window
@@ -58,6 +58,7 @@ function Start-CoreApp
$global:useDefaultFolderDialog = $false $global:useDefaultFolderDialog = $false
$global:WindowsAPICodePackLoaded = $false $global:WindowsAPICodePackLoaded = $false
$script:proxyURI = $null
$global:loadedModules = @() $global:loadedModules = @()
$global:viewObjects = @() $global:viewObjects = @()
@@ -235,6 +236,8 @@ function Write-Log
if(-not $global:logFileMaxSize) { [Int64]$global:logFileMaxSize = Get-SettingValue "LogFileSize" 1024; $global:logFileMaxSize = $global:logFileMaxSize * 1kb } if(-not $global:logFileMaxSize) { [Int64]$global:logFileMaxSize = Get-SettingValue "LogFileSize" 1024; $global:logFileMaxSize = $global:logFileMaxSize * 1kb }
if($null -eq $global:logOutputError) { $global:logOutputError = Get-SettingValue "LogOutputError" }
$fi = [IO.FileInfo]$global:logFile $fi = [IO.FileInfo]$global:logFile
if($fi.Length -gt $global:logFileMaxSize) if($fi.Length -gt $global:logFileMaxSize)
@@ -286,12 +289,19 @@ function Write-Log
if($type -eq 2) if($type -eq 2)
{ {
Write-Warning $Text Write-Warning $Text
$typeStr = "Error" $typeStr = "Warning"
} }
elseif($type -eq 3) elseif($type -eq 3)
{
if($global:logOutputError -ne $false)
{ {
$host.ui.WriteErrorLine($Text) $host.ui.WriteErrorLine($Text)
$typeStr = "Warning" }
else
{
Write-Warning $Text
}
$typeStr = "Error"
} }
else else
{ {
@@ -667,8 +677,15 @@ function Show-UpdatesDialog
{ {
if($mystream) { $mystream.Dispose() } if($mystream) { $mystream.Dispose() }
} }
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" $content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" @params
if($content) if($content)
{ {
$txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content))) $txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
@@ -703,7 +720,15 @@ function Get-IsLatestVersion
$gitHubVer = $null $gitHubVer = $null
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" @params
if($content.Name) if($content.Name)
{ {
try try
@@ -715,7 +740,15 @@ function Get-IsLatestVersion
if($null -eq $gitHubVer) if($null -eq $gitHubVer)
{ {
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1" $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1" @params
$gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content))) $gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
$gitHubInfo = Get-ModuleDataTable $gitHubText $gitHubInfo = Get-ModuleDataTable $gitHubText
try try
@@ -1150,6 +1183,10 @@ function Expand-FileName
[Environment]::SetEnvironmentVariable("DateTime",$null,[System.EnvironmentVariableTarget]::Process) [Environment]::SetEnvironmentVariable("DateTime",$null,[System.EnvironmentVariableTarget]::Process)
[Environment]::SetEnvironmentVariable("Organization",$null,[System.EnvironmentVariableTarget]::Process) [Environment]::SetEnvironmentVariable("Organization",$null,[System.EnvironmentVariableTarget]::Process)
# Remove invalid path characters
$re = "[{0}]" -f [RegEx]::Escape(([IO.Path]::GetInvalidPathChars() -join ''))
$fileName = $fileName -replace $re
$fileName $fileName
} }
@@ -1168,6 +1205,8 @@ function Initialize-Settings
$global:Debug = Get-SettingValue "Debug" $global:Debug = Get-SettingValue "Debug"
$global:logFile = $null $global:logFile = $null
$global:logFileMaxSize = $null $global:logFileMaxSize = $null
$global:logOutputError = $null
$script:proxyURI = $null
if($Updated -eq $true) if($Updated -eq $true)
{ {
@@ -1943,6 +1982,14 @@ function Add-DefaultSettings
DefaultValue = 1024 DefaultValue = 1024
}) "General" }) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Add errors to PowerShell output"
Key = "LogOutputError"
Type = "Boolean"
Description = "Write errors to the Error Output of the PS Host. If disabled, errors will be written as a Warning. Eg. disable this if automation should skip logging PowerShell errors."
DefaultValue = $true
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Debug" Title = "Debug"
Key = "Debug" Key = "Debug"
@@ -1998,6 +2045,12 @@ function Add-DefaultSettings
Description = "Adds the organization name next to the login info on the menu bar" Description = "Adds the organization name next to the login info on the menu bar"
}) "General" }) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Proxy URI"
Key = "ProxyURI"
Description = "Specify the URI for the proxy eg http://&lt;server&gt;:&lt;port&gt;"
}) "General"
} }
function Add-SettingsObject function Add-SettingsObject
@@ -2435,6 +2488,15 @@ function Get-MainWindow
Show-ModalForm $window.Title $script:welcomeForm -HideButtons Show-ModalForm $window.Title $script:welcomeForm -HideButtons
} }
else
{
###!!! Force login here
if($global:currentViewObject.ViewInfo.Authenticate)
{
# Skip for now...need additional code to skip previous login and force this based on setting.
#!!!& $global:currentViewObject.ViewInfo.Authenticate -Params (@{"Interactve"=$true})
}
}
}) })
foreach($view in $global:viewObjects) foreach($view in $global:viewObjects)
@@ -2694,6 +2756,81 @@ function Get-Base64ScriptContent
} }
} }
function Get-ProxyURI
{
if($null -eq $script:proxyURI)
{
$script:proxyUri = Get-SettingValue "ProxyURI"
}
if($null -eq $script:proxyURI)
{
$script:proxyUri = ""
}
return $script:proxyURI
}
function Start-DownloadFile
{
param($sourceURL, $targetFile)
Write-Log "Download file from $sourceURL"
if(-not $sourceURL)
{
return
}
if(-not $targetFile)
{
Write-Log "Target file is missing"
return
}
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$wc = New-Object System.Net.WebClient
$wc.Encoding = [System.Text.Encoding]::UTF8
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$wc.Proxy = $proxyURI
}
try
{
Write-Status "Download file: `n$sourceURL"
$wc.DownloadFile($sourceURL, $targetFile)
Write-Log "File downloaded to $targetFile"
}
catch
{
Write-LogError "Failed to download file" $_.Exception
}
finally
{
$wc.Dispose()
}
}
function Get-ASCIIBytes
{
param($String)
$bytes = [System.Text.Encoding]::ASCII.GetBytes($String)
if ($bytes[0] -eq 0x2b -and $bytes[1] -eq 0x2f -and $bytes[2] -eq 0x76)
{ [Text.Encoding]::UTF7.GetBytes($String) }
elseif ($bytes[0] -eq 0xff -and $bytes[1] -eq 0xfe)
{ [Text.Encoding]::Unicode.GetBytes($String) }
elseif ($bytes[0] -eq 0xfe -and $bytes[1] -eq 0xff)
{ [Text.Encoding]::BigEndianUnicode.GetBytes($String) }
elseif ($bytes[0] -eq 0x00 -and $bytes[1] -eq 0x00 -and $bytes[2] -eq 0xfe -and $bytes[3] -eq 0xff)
{ [Text.Encoding]::UTF32.GetBytes($String) }
elseif ($bytes[0] -eq 0xef -and $bytes[1] -eq 0xbb -and $bytes[2] -eq 0xbf)
{ [Text.Encoding]::UTF8.GetBytes($String) }
$bytes
}
New-Alias -Name ?? -value Invoke-Coalesce New-Alias -Name ?? -value Invoke-Coalesce
New-Alias -Name ?: -value Invoke-IfTrue New-Alias -Name ?: -value Invoke-IfTrue
Export-ModuleMember -alias * -function * Export-ModuleMember -alias * -function *
+2 -2
View File
@@ -1099,12 +1099,12 @@
"category": "SettingDetails.dependencyCategory" "category": "SettingDetails.dependencyCategory"
}, },
{ {
"nameResourceKey": "supersedenceCategory", "nameResourceKey": "AppRelationshipStatus.Tabs.supersedence",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "supersededApps", "entityKey": "supersededApps",
"dataType": 20, "dataType": 20,
"booleanActions": 0, "booleanActions": 0,
"category": "SettingDetails.supersedenceCategory" "category": "AppRelationshipStatus.Tabs.supersedence"
} }
] ]
} }
@@ -0,0 +1,69 @@
[
{
"nameResourceKey": "TableHeaders.policyType",
"descriptionResourceKey": "",
"entityKey": "WindowsDriverUpdateProfile.Subtitle.automatic",
"dataType": 200,
"booleanActions": 0,
"category": 1000,
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "automatic"
}
]
}
},
{
"nameResourceKey": "TableHeaders.policyType",
"descriptionResourceKey": "",
"entityKey": "WindowsDriverUpdateProfile.Subtitle.manual",
"dataType": 200,
"booleanActions": 0,
"category": 1000,
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "manual"
}
]
}
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.Details.ApprovalMethod.label",
"descriptionResourceKey": "",
"entityKey": "approvalType",
"dataType": 16,
"booleanActions": 0,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "WindowsDriverUpdateProfile.ApprovalMethod.automatic",
"value": "automatic"
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.ApprovalMethod.manual",
"value": "manual"
}
]
},
{
"nameResourceKey": "WindowsDriverUpdateProfile.Details.DeploymentDeferralInDays.label",
"descriptionResourceKey": "",
"entityKey": "deploymentDeferralInDays",
"formatStringKey": "WindowsDriverUpdateProfile.Details.DeploymentDeferralInDays.value",
"dataType": 108,
"booleanActions": 0,
"category": "TableHeaders.settings",
"Condition": {
"Expressions": [
{
"property": "approvalType",
"value": "automatic"
}
]
}
}
]
@@ -113,6 +113,164 @@
"defaultValue": false, "defaultValue": false,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appNameName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "packageName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appId",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appUrlName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "appStoreUrl",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
},
{
"metadata": {
"dataType": 20,
"category": 2,
"nameResourceKey": "appPublisherName",
"descriptionResourceKey": "Empty",
"childSettings": [
],
"options": [
],
"entityKey": "publisher",
"booleanActions": 0,
"policyType": 2,
"enabled": false
}
}
],
"dataType": 21,
"category": 2,
"nameResourceKey": "certificateInstallTitle",
"descriptionResourceKey": "certificateInstallDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certInstallApps",
"booleanActions": 0,
"policyType": 2,
"enabled": false
},
{
"complexOptions": [
{
"dataType": 11,
"category": 2,
"nameResourceKey": "selectSecurityApp",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "securityLogAppId",
"booleanActions": 0,
"policyType": 2,
"enabled": true
}
],
"dataType": 5,
"category": 2,
"nameResourceKey": "securityLogsTitle",
"emptyValueResourceKey": "selectSecurityApp",
"childSettings": [
],
"options": [
],
"entityKey": "securityLogApp",
"booleanActions": 0,
"policyType": 2,
"enabled": false
},
{
"complexOptions": [
{
"dataType": 11,
"category": 2,
"nameResourceKey": "selectNetworkApp",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "networkLogAppId",
"booleanActions": 0,
"policyType": 2,
"enabled": true
}
],
"dataType": 5,
"category": 2,
"nameResourceKey": "networkLogsTitle",
"emptyValueResourceKey": "selectNetworkApp",
"childSettings": [
],
"options": [
],
"entityKey": "networkLogApp",
"booleanActions": 0,
"policyType": 2,
"enabled": false
} }
], ],
"options": [ "options": [
@@ -154,8 +154,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -166,17 +166,17 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified", "value": "basicIntegrityAndCertified",
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -52,8 +52,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -64,17 +64,17 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified", "value": "basicIntegrityAndCertified",
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -103,8 +103,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "safetyNetAttestationOptionsName", "nameResourceKey": "playIntegrityVerdictOptionsName",
"descriptionResourceKey": "safetyNetAttestationOptionsDescription", "descriptionResourceKey": "playIntegrityVerdictOptionsDescription",
"childSettings": [ "childSettings": [
], ],
@@ -115,25 +115,25 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetbasicIntegrity", "nameResourceKey": "androidPlayIntegrityVerdictBasicIntegrity",
"value": "basicIntegrity", "value": "basicIntegrity",
"children": [ "children": [
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeName", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidSafetyNetEvaluationTypeDescription", "descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeBasic", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic", "value": "basic",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeHardwareBacked", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "hardwareBacked", "value": "hardwareBacked",
"enabled": true "enabled": true
} }
@@ -149,25 +149,25 @@
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "androidSafetyNetBasicIntegrityAndCertified", "nameResourceKey": "androidPlayIntegrityVerdictBasicAndDeviceIntegrity",
"value": "basicIntegrityAndCertified", "value": "basicIntegrityAndCertified",
"children": [ "children": [
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeName", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeName",
"descriptionResourceKey": "requiredAndroidSafetyNetEvaluationTypeDescription", "descriptionResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeBasic", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeBasic",
"value": "basic", "value": "basic",
"enabled": true "enabled": true
}, },
{ {
"nameResourceKey": "requiredAndroidSafetyNetEvaluationTypeHardwareBacked", "nameResourceKey": "requiredAndroidPlayIntegrityVerdictEvaluationTypeHardwareBacked",
"value": "hardwareBacked", "value": "hardwareBacked",
"enabled": true "enabled": true
} }
@@ -183,7 +183,7 @@
"enabled": true "enabled": true
} }
], ],
"entityKey": "androidSafetyNetAttestationOptions", "entityKey": "androidPlayIntegrityVerdictOptions",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "notConfigured", "defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured", "unconfiguredValue": "notConfigured",
@@ -1,16 +1,32 @@
{ {
"devicehealth_compliancewindows10": { "devicehealth_compliancewindows10": [
{
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 39, "category": 39,
"nameResourceKey": "complianceWindowsDeviceHealthAttestationHeader", "nameResourceKey": "complianceWindowsDeviceHealthAttestationHeader",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 39,
"nameResourceKey": "complianceWindows10DeviceHealthAttestationHeader",
"childSettings": [ "childSettings": [
{ {
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "bitLockerEnabledName", "nameResourceKey": "bitLockerEnabledName",
"descriptionResourceKey": "bitLockerEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -27,7 +43,6 @@
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "secureBootEnabledName", "nameResourceKey": "secureBootEnabledName",
"descriptionResourceKey": "secureBootEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -44,7 +59,6 @@
"dataType": 0, "dataType": 0,
"category": 39, "category": 39,
"nameResourceKey": "codeIntegrityEnabledName", "nameResourceKey": "codeIntegrityEnabledName",
"descriptionResourceKey": "codeIntegrityEnabledDescription",
"childSettings": [ "childSettings": [
], ],
@@ -64,5 +78,101 @@
"booleanActions": 0, "booleanActions": 0,
"policyType": 35, "policyType": 35,
"enabled": true "enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 39,
"nameResourceKey": "complianceWindows11DeviceHealthAttestationHeader",
"childSettings": [
{
"dataType": 0,
"category": 39,
"nameResourceKey": "earlyLaunchAntiMalwareDriverEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "earlyLaunchAntiMalwareDriverEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "firmwareProtectionEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "firmwareProtectionEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "hvciEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "memoryIntegrityEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "memoryAccessProtectionEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "kernelDmaProtectionEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
},
{
"dataType": 0,
"category": 39,
"nameResourceKey": "virtualizationBasedSecurityEnabledName",
"childSettings": [
],
"options": [
],
"entityKey": "virtualizationBasedSecurityEnabled",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35,
"enabled": false
} }
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": false
}
]
} }
@@ -448,6 +448,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -418,6 +418,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -195,6 +195,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -418,6 +418,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -457,6 +457,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -457,6 +457,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
@@ -234,6 +234,12 @@
"displayText": "2048", "displayText": "2048",
"value": "size2048", "value": "size2048",
"enabled": true "enabled": true
},
{
"nameResourceKey": "",
"displayText": "4096",
"value": "size4096",
"enabled": false
} }
], ],
"entityKey": "keySize", "entityKey": "keySize",
+22 -22
View File
@@ -584,7 +584,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -2329,7 +2329,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -4074,7 +4074,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -5819,7 +5819,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -8052,7 +8052,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -9797,7 +9797,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -11542,7 +11542,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -13272,7 +13272,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -15390,7 +15390,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -17120,7 +17120,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -18850,7 +18850,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -20622,7 +20622,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -22367,7 +22367,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -24112,7 +24112,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -25857,7 +25857,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -28090,7 +28090,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -29835,7 +29835,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -31580,7 +31580,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -33310,7 +33310,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -35428,7 +35428,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -37158,7 +37158,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -38888,7 +38888,7 @@
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "outbound", "defaultValue": "outbound",
"policyType": 89, "policyType": 89,
"enabled": false "enabled": true
} }
}, },
{ {
@@ -613,6 +613,23 @@
"policyType": 13, "policyType": 13,
"enabled": true "enabled": true
}, },
{
"dataType": 0,
"category": 127,
"nameResourceKey": "blockUnifiedPasswordForWorkProfileName",
"descriptionResourceKey": "blockUnifiedPasswordForWorkProfileDescription",
"childSettings": [
],
"options": [
],
"entityKey": "blockUnifiedPasswordForWorkProfile",
"booleanActions": 3,
"defaultValue": false,
"policyType": 13,
"enabled": false
},
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": true, "showAsSectionHeader": true,
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2750 -1619
View File
File diff suppressed because it is too large Load Diff
+2750 -1619
View File
File diff suppressed because it is too large Load Diff
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2752 -1621
View File
File diff suppressed because it is too large Load Diff
+2753 -1622
View File
File diff suppressed because it is too large Load Diff
+2749 -1618
View File
File diff suppressed because it is too large Load Diff
+2750 -1619
View File
File diff suppressed because it is too large Load Diff
+2750 -1619
View File
File diff suppressed because it is too large Load Diff
+2752 -1621
View File
File diff suppressed because it is too large Load Diff
+2751 -1620
View File
File diff suppressed because it is too large Load Diff
+2752 -1621
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2750 -1619
View File
File diff suppressed because it is too large Load Diff
+25 -2
View File
@@ -20,7 +20,7 @@ $global:documentationProviders = @()
function Get-ModuleVersion function Get-ModuleVersion
{ {
'2.0.1' '2.0.2'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -61,6 +61,7 @@ function Invoke-InitializeModule
Settings="TableHeaders.settings" Settings="TableHeaders.settings"
returnCode='Win32ReturnCodes.Columns.returnCode' returnCode='Win32ReturnCodes.Columns.returnCode'
type='Win32ReturnCodes.Columns.codeType' type='Win32ReturnCodes.Columns.codeType'
RecommendedValue="AzureIAMCommon.Recommended"
} }
} }
@@ -290,7 +291,8 @@ function Get-ObjectDocumentation
elseif($type -eq "#microsoft.graph.deviceManagementIntent") elseif($type -eq "#microsoft.graph.deviceManagementIntent")
{ {
Invoke-TranslateIntentObject $obj $objectType | Out-Null Invoke-TranslateIntentObject $obj $objectType | Out-Null
$properties = @("Name","Value","Category","FullValueTable","RawValue","SettingId","Description") $properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description")
$defaultDocumentationProperties = @("Name","Value","RecommendedValue")
} }
#endregion #endregion
#region Administrative Templates #region Administrative Templates
@@ -541,6 +543,10 @@ function Get-ObjectTypeString
{ {
return (Get-LanguageString "Titles.windows10QualityUpdate") return (Get-LanguageString "Titles.windows10QualityUpdate")
} }
elseif($objTypeId -eq "WinDriverUpdatePolicies")
{
return (Get-LanguageString "Titles.windows10DriverUpdate")
}
elseif($objTypeId -eq "TenantAdmin") elseif($objTypeId -eq "TenantAdmin")
{ {
return (Get-LanguageString "Titles.tenantAdmin") return (Get-LanguageString "Titles.tenantAdmin")
@@ -1488,6 +1494,12 @@ function Add-IntentSettingObjectToList
$objSetting.Level = $objSetting.Level + 1 $objSetting.Level = $objSetting.Level + 1
} }
$recommendedSetting = $global:catRecommendedSettings[$objSetting.CategoryObject.Id] | Where definitionId -eq $objSetting.SettingId
if($recommendedSetting.valueJson -and ($objSetting.ValueSet -eq $false -or $recommendedSetting.valueJson -ne ($objSetting.RawValue | ConvertTo-Json -Compress))) {
$objSetting | Add-Member Noteproperty -Name "RecommendedValue" -Value ($recommendedSetting.valueJson | ConvertFrom-Json) -Force
}
$script:objectSettingsData += $objSetting $script:objectSettingsData += $objSetting
if($objSetting.ValueSet -eq $false) { return } if($objSetting.ValueSet -eq $false) { return }
@@ -2415,6 +2427,17 @@ function Invoke-TranslateSection
} }
$value = $arrTmp -join $script:objectSeparator $value = $arrTmp -join $script:objectSeparator
} }
elseif($prop.dataType -eq 108) # String with format
{
$value = $propValue
if($prop.formatStringKey) {
$str = Get-LanguageString $prop.formatStringKey
if($str)
{
$value = $str -f $propValue
}
}
}
else else
{ {
Write-Log "Unsupported property '$((Get-LanguageString "SettingDetails.$($prop.nameResourceKey)"))' ($($prop.nameResourceKey)) for object property $($prop.entityKey). Type: $($prop.dataType)" 2 Write-Log "Unsupported property '$((Get-LanguageString "SettingDetails.$($prop.nameResourceKey)"))' ($($prop.nameResourceKey)) for object property $($prop.entityKey). Type: $($prop.dataType)" 2
+111 -89
View File
@@ -10,7 +10,7 @@ This module will also document some objects based on PowerShell functions
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.6.0' '1.6.2'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -267,7 +267,7 @@ function Invoke-CDDocumentCustomPostAdd
if($prop.EntityKey -eq "featureUpdatesRollbackWindowInDays") if($prop.EntityKey -eq "featureUpdatesRollbackWindowInDays")
{ {
if($obj.businessReadyUpdatesOnly -eq "businessReadyOnly") if($obj.businessReadyUpdatesOnly -eq "businessReadyOnly" -or $obj.businessReadyUpdatesOnly -eq "all" -or $obj.businessReadyUpdatesOnly -eq "userDefined")
{ {
$propValue = Get-LanguageString "BooleanActions.notConfigured" $propValue = Get-LanguageString "BooleanActions.notConfigured"
} }
@@ -288,7 +288,7 @@ function Invoke-CDDocumentCustomPostAdd
Add-PropertyInfo $tmpProp $propValue -originalValue $obj.businessReadyUpdatesOnly Add-PropertyInfo $tmpProp $propValue -originalValue $obj.businessReadyUpdatesOnly
if($obj.businessReadyUpdatesOnly -ne "businessReadyOnly") if($obj.businessReadyUpdatesOnly -ne "businessReadyOnly" -and $obj.businessReadyUpdatesOnly -ne "all" -and $obj.businessReadyUpdatesOnly -ne "userDefined")
{ {
# Pre-release channel selected. Inject info # Pre-release channel selected. Inject info
$propValue = Get-LanguageString "SettingDetails.$($obj.businessReadyUpdatesOnly)Option" $propValue = Get-LanguageString "SettingDetails.$($obj.businessReadyUpdatesOnly)Option"
@@ -2029,17 +2029,17 @@ function Invoke-CDDocumentCountryNamedLocation
################################################### ###################################################
Add-BasicDefaultValues $obj $objectType Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.menuItemNamedNetworks") Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureCA.menuItemNamedNetworks")
Add-BasicAdditionalValues $obj $objectType Add-BasicAdditionalValues $obj $objectType
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.NamedLocation.Form.CountryLookup.ariaLabel" Name = Get-LanguageString "AzureCA.NamedLocation.Form.CountryLookup.ariaLabel"
Value = Get-LanguageString "AzureIAM.NamedLocation.Form.CountryLookup.$((?: ($obj.countryLookupMethod -eq "clientIpAddress") "ip" "gps"))" Value = Get-LanguageString "AzureCA.NamedLocation.Form.CountryLookup.$((?: ($obj.countryLookupMethod -eq "clientIpAddress") "ip" "gps"))"
EntityKey = "countryLookupMethod" EntityKey = "countryLookupMethod"
}) })
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.NamedLocation.Form.Include.label" Name = Get-LanguageString "AzureCA.NamedLocation.Form.Include.label"
Value = Get-LanguageString (?: ($obj.includeUnknownCountriesAndRegions -eq $true) "Inputs.enabled" "Inputs.disabled") Value = Get-LanguageString (?: ($obj.includeUnknownCountriesAndRegions -eq $true) "Inputs.enabled" "Inputs.disabled")
EntityKey = "includeUnknownCountriesAndRegions" EntityKey = "includeUnknownCountriesAndRegions"
}) })
@@ -2047,11 +2047,11 @@ function Invoke-CDDocumentCountryNamedLocation
$countryList = @() $countryList = @()
foreach($country in $obj.countriesAndRegions) foreach($country in $obj.countriesAndRegions)
{ {
$countryList += Get-LanguageString "AzureIAMCommon.CountryNames.countryName$($country.ToLower())" $countryList += Get-LanguageString "CountryNames.countryName$($country.ToLower())"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.NamedLocation.Type.countries" Name = Get-LanguageString "AzureCA.NamedLocation.Type.countries"
Value = $countryList -join $script:objectSeparator Value = $countryList -join $script:objectSeparator
EntityKey = "countriesAndRegions" EntityKey = "countriesAndRegions"
}) })
@@ -2072,11 +2072,11 @@ function Invoke-CDDocumentIPNamedLocation
################################################### ###################################################
Add-BasicDefaultValues $obj $objectType Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.menuItemNamedNetworks") Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureCA.menuItemNamedNetworks")
Add-BasicAdditionalValues $obj $objectType Add-BasicAdditionalValues $obj $objectType
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.NamedLocation.Form.Trusted.label" Name = Get-LanguageString "AzureCA.NamedLocation.Form.Trusted.label"
Value = Get-LanguageString (?: ($obj.isTrusted -eq $true) "Inputs.enabled" "Inputs.disabled") Value = Get-LanguageString (?: ($obj.isTrusted -eq $true) "Inputs.enabled" "Inputs.disabled")
EntityKey = "isTrusted" EntityKey = "isTrusted"
}) })
@@ -2088,7 +2088,7 @@ function Invoke-CDDocumentIPNamedLocation
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.NamedLocation.Type.ipRanges" Name = Get-LanguageString "AzureCA.NamedLocation.Type.ipRanges"
Value = $ipList -join $script:objectSeparator Value = $ipList -join $script:objectSeparator
EntityKey = "ipRanges" EntityKey = "ipRanges"
}) })
@@ -2113,7 +2113,7 @@ function Invoke-CDDocumentTermsOfUse
################################################### ###################################################
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.menuItemTermsOfUse") Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureCA.menuItemTermsOfUse")
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.agreementIsViewingBeforeAcceptanceRequiredLabel" Name = Get-LanguageString "TermsOfUse.Wizard.agreementIsViewingBeforeAcceptanceRequiredLabel"
@@ -2222,22 +2222,22 @@ function Invoke-CDDocumentConditionalAccess
#Add-BasicDefaultValues $obj $objectType #Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.conditionalAccessBladeTitle") Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureCA.conditionalAccessBladeTitle")
if($obj.state -eq "enabledForReportingButNotEnforced") if($obj.state -eq "enabledForReportingButNotEnforced")
{ {
$state = Get-LanguageString "AzureIAM.PolicyState.reportOnly" $state = Get-LanguageString "AzureCA.PolicyState.reportOnly"
} }
elseif($obj.state -eq "disabled") elseif($obj.state -eq "disabled")
{ {
$state = Get-LanguageString "AzureIAM.PolicyState.off" $state = Get-LanguageString "AzureCA.PolicyState.off"
} }
else else
{ {
$state = Get-LanguageString "AzureIAM.PolicyState.on" $state = Get-LanguageString "AzureCA.PolicyState.on"
} }
Add-BasicPropertyValue (Get-LanguageString "AzureIAM.policyEnforceLabel") $state Add-BasicPropertyValue (Get-LanguageString "AzureCA.policyEnforceLabel") $state
Add-BasicAdditionalValues $obj $objectType Add-BasicAdditionalValues $obj $objectType
@@ -2281,16 +2281,16 @@ function Invoke-CDDocumentConditionalAccess
$script:allAadRoles =(Invoke-GraphRequest -url "/directoryRoleTemplates?`$select=Id,displayName" -ODataMetadata "minimal").value $script:allAadRoles =(Invoke-GraphRequest -url "/directoryRoleTemplates?`$select=Id,displayName" -ODataMetadata "minimal").value
} }
$includeLabel = Get-LanguageString "AzureIAM.userSelectionBladeIncludeTabTitle" $includeLabel = Get-LanguageString "AzureCA.userSelectionBladeIncludeTabTitle"
$excludeLabel = Get-LanguageString "AzureIAM.userSelectionBladeExcludeTabTitle" $excludeLabel = Get-LanguageString "AzureCA.userSelectionBladeExcludeTabTitle"
$category = Get-LanguageString "AzureIAM.usersGroupsLabel" $category = Get-LanguageString "AzureCA.usersGroupsLabel"
if((($obj.conditions.users.includeUsers | Where { $_ -eq "All"}) -ne $null)) if((($obj.conditions.users.includeUsers | Where { $_ -eq "All"}) -ne $null))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.allUsersString" Value = Get-LanguageString "AzureCA.allUsersString"
Category = $category Category = $category
SubCategory = $includeLabel SubCategory = $includeLabel
EntityKey = "includeUsers" EntityKey = "includeUsers"
@@ -2300,7 +2300,7 @@ function Invoke-CDDocumentConditionalAccess
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.chooseApplicationsNone" Value = Get-LanguageString "AzureCA.chooseApplicationsNone"
Category = $category Category = $category
SubCategory = $includeLabel SubCategory = $includeLabel
EntityKey = "includeUsers" EntityKey = "includeUsers"
@@ -2310,7 +2310,7 @@ function Invoke-CDDocumentConditionalAccess
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.userSelectionBladeSelectedUsers" Value = Get-LanguageString "AzureCA.userSelectionBladeSelectedUsers"
Category = $category Category = $category
SubCategory = $includeLabel SubCategory = $includeLabel
EntityKey = "includeUsers" EntityKey = "includeUsers"
@@ -2319,7 +2319,7 @@ function Invoke-CDDocumentConditionalAccess
if((($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null)) if((($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.allGuestUserLabel" Name = Get-LanguageString "AzureCA.allGuestUserLabel"
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))" Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.includeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
Category = $category Category = $category
SubCategory = $includeLabel SubCategory = $includeLabel
@@ -2337,7 +2337,7 @@ function Invoke-CDDocumentConditionalAccess
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.directoryRolesLabel" Name = Get-LanguageString "AzureCA.directoryRolesLabel"
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = $includeLabel SubCategory = $includeLabel
@@ -2367,7 +2367,7 @@ function Invoke-CDDocumentConditionalAccess
if((($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null)) if((($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.allGuestUserLabel" Name = Get-LanguageString "AzureCA.allGuestUserLabel"
Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))" Value = Get-LanguageString "Inputs.enabled" #$((?: (($obj.conditions.users.excludeUsers | Where { $_ -eq "GuestsOrExternalUsers"}) -ne $null) "enabled" "disabled"))"
Category = $category Category = $category
SubCategory = $excludeLabel SubCategory = $excludeLabel
@@ -2385,7 +2385,7 @@ function Invoke-CDDocumentConditionalAccess
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.directoryRolesLabel" Name = Get-LanguageString "AzureCA.directoryRolesLabel"
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = $excludeLabel SubCategory = $excludeLabel
@@ -2416,8 +2416,8 @@ function Invoke-CDDocumentConditionalAccess
# Cloud apps or actions # Cloud apps or actions
################################################### ###################################################
$category = Get-LanguageString "AzureIAM.UserActions.appsOrActionsTitle" $category = Get-LanguageString "AzureCA.UserActions.appsOrActionsTitle"
$cloudAppsLabel = Get-LanguageString "AzureIAM.policyCloudAppsLabel" $cloudAppsLabel = Get-LanguageString "AzureCA.policyCloudAppsLabel"
$cloudApps = Get-CDAllCloudApps $cloudApps = Get-CDAllCloudApps
@@ -2425,7 +2425,7 @@ function Invoke-CDDocumentConditionalAccess
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.cloudappsSelectionBladeAllCloudapps" #Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "AzureCA.cloudappsSelectionBladeAllCloudapps" #Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = $cloudAppsLabel SubCategory = $cloudAppsLabel
EntityKey = "includeApplications" EntityKey = "includeApplications"
@@ -2435,7 +2435,7 @@ function Invoke-CDDocumentConditionalAccess
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.chooseApplicationsNone" #Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "AzureCA.chooseApplicationsNone" #Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = $cloudAppsLabel SubCategory = $cloudAppsLabel
EntityKey = "includeApplications" EntityKey = "includeApplications"
@@ -2477,18 +2477,18 @@ function Invoke-CDDocumentConditionalAccess
if($obj.conditions.applications.includeUserActions.Count -gt 0) if($obj.conditions.applications.includeUserActions.Count -gt 0)
{ {
$userActionsLabel = Get-LanguageString "AzureIAM.UserActions.label" $userActionsLabel = Get-LanguageString "AzureCA.UserActions.label"
if(($obj.conditions.applications.includeUserActions | Where { $_ -eq "urn:user:registersecurityinfo" })) if(($obj.conditions.applications.includeUserActions | Where { $_ -eq "urn:user:registersecurityinfo" }))
{ {
$value = Get-LanguageString "AzureIAM.UserActions.registerSecurityInfo" $value = Get-LanguageString "AzureCA.UserActions.registerSecurityInfo"
} }
else else
{ {
$value = Get-LanguageString "AzureIAM.UserActions.registerOrJoinDevices" $value = Get-LanguageString "AzureCA.UserActions.registerOrJoinDevices"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.UserActions.selectionInfo" Name = Get-LanguageString "AzureCA.UserActions.selectionInfo"
Value = $value Value = $value
Category = $category Category = $category
SubCategory = $userActionsLabel SubCategory = $userActionsLabel
@@ -2511,10 +2511,10 @@ function Invoke-CDDocumentConditionalAccess
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.AuthContext.checkBoxInfo" Name = Get-LanguageString "AzureCA.AuthContext.checkBoxInfo"
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.AuthContext.label" SubCategory = Get-LanguageString "AzureCA.AuthContext.label"
EntityKey = "includeAuthenticationContextClassReferences" EntityKey = "includeAuthenticationContextClassReferences"
}) })
} }
@@ -2523,23 +2523,23 @@ function Invoke-CDDocumentConditionalAccess
# Conditions # Conditions
################################################### ###################################################
$category = Get-LanguageString "AzureIAM.helpConditionsTitle" $category = Get-LanguageString "AzureCA.helpConditionsTitle"
#$category = Get-LanguageString "AzureIAM.policyConditionUserRisk" #$category = Get-LanguageString "AzureCA.policyConditionUserRisk"
if($obj.conditions.userRiskLevels.Count -gt 0) if($obj.conditions.userRiskLevels.Count -gt 0)
{ {
$tmpObjs = @() $tmpObjs = @()
foreach($id in ($obj.conditions.userRiskLevels)) foreach($id in ($obj.conditions.userRiskLevels))
{ {
$tmpObjs += Get-LanguageString "AzureIAM.$($id)Risk" $tmpObjs += Get-LanguageString "AzureCA.$($id)Risk"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.policyConditionUserRisk" SubCategory = Get-LanguageString "AzureCA.policyConditionUserRisk"
EntityKey = "userRiskLevels" EntityKey = "userRiskLevels"
}) })
} }
@@ -2549,14 +2549,14 @@ function Invoke-CDDocumentConditionalAccess
$tmpObjs = @() $tmpObjs = @()
foreach($id in ($obj.conditions.signInRiskLevels)) foreach($id in ($obj.conditions.signInRiskLevels))
{ {
$tmpObjs += Get-LanguageString "AzureIAM.$($id)Risk" $tmpObjs += Get-LanguageString "AzureCA.$($id)Risk"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.policyConditionSigninRisk" SubCategory = Get-LanguageString "AzureCA.policyConditionSigninRisk"
EntityKey = "signInRiskLevels" EntityKey = "signInRiskLevels"
}) })
} }
@@ -2568,11 +2568,11 @@ function Invoke-CDDocumentConditionalAccess
{ {
if($id -eq "all") if($id -eq "all")
{ {
$tmpObjs += Get-LanguageString "AzureIAM.allDevicePlatforms" $tmpObjs += Get-LanguageString "AzureCA.allDevicePlatforms"
} }
else else
{ {
$tmpObjs += Get-LanguageString "AzureIAM.$($id)DisplayName" $tmpObjs += Get-LanguageString "AzureCA.$($id)DisplayName"
} }
} }
@@ -2580,7 +2580,7 @@ function Invoke-CDDocumentConditionalAccess
Name = $includeLabel Name = $includeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.devicePlatform" SubCategory = Get-LanguageString "AzureCA.devicePlatform"
EntityKey = "includePlatforms" EntityKey = "includePlatforms"
}) })
} }
@@ -2590,14 +2590,14 @@ function Invoke-CDDocumentConditionalAccess
$tmpObjs = @() $tmpObjs = @()
foreach($id in ($obj.conditions.platforms.excludePlatforms)) foreach($id in ($obj.conditions.platforms.excludePlatforms))
{ {
$tmpObjs += Get-LanguageString "AzureIAM.$($id)DisplayName" $tmpObjs += Get-LanguageString "AzureCA.$($id)DisplayName"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $excludeLabel Name = $excludeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.devicePlatform" SubCategory = Get-LanguageString "AzureCA.devicePlatform"
EntityKey = "excludePlatforms" EntityKey = "excludePlatforms"
}) })
} }
@@ -2614,7 +2614,7 @@ function Invoke-CDDocumentConditionalAccess
elseif($script:allNamedLocations -isnot [Object[]]) { $script:allNamedLocations = @($script:allNamedLocations) } elseif($script:allNamedLocations -isnot [Object[]]) { $script:allNamedLocations = @($script:allNamedLocations) }
$script:allNamedLocations += [PSCustomObject]@{ $script:allNamedLocations += [PSCustomObject]@{
displayName = Get-LanguageString "AzureIAM.chooseLocationTrustedIpsItem" displayName = Get-LanguageString "AzureCA.chooseLocationTrustedIpsItem"
id = "00000000-0000-0000-0000-000000000000" id = "00000000-0000-0000-0000-000000000000"
} }
} }
@@ -2637,11 +2637,11 @@ function Invoke-CDDocumentConditionalAccess
{ {
if($id -eq "AllTrusted") if($id -eq "AllTrusted")
{ {
$tmpObjs += Get-LanguageString "AzureIAM.allTrustedLocationLabel" $tmpObjs += Get-LanguageString "AzureCA.allTrustedLocationLabel"
} }
elseif($id -eq "All") elseif($id -eq "All")
{ {
$tmpObjs += Get-LanguageString "AzureIAM.locationsAllLocationsLabel" $tmpObjs += Get-LanguageString "AzureCA.locationsAllLocationsLabel"
} }
else else
{ {
@@ -2654,7 +2654,7 @@ function Invoke-CDDocumentConditionalAccess
Name = $includeLabel Name = $includeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.policyConditionLocation" SubCategory = Get-LanguageString "AzureCA.policyConditionLocation"
EntityKey = "includeLocations" EntityKey = "includeLocations"
}) })
} }
@@ -2666,11 +2666,11 @@ function Invoke-CDDocumentConditionalAccess
{ {
if($id -eq "AllTrusted") if($id -eq "AllTrusted")
{ {
$tmpObjs += Get-LanguageString "AzureIAM.allTrustedLocationLabel" $tmpObjs += Get-LanguageString "AzureCA.allTrustedLocationLabel"
} }
elseif($id -eq "All") elseif($id -eq "All")
{ {
$tmpObjs += Get-LanguageString "AzureIAM.locationsAllLocationsLabel" $tmpObjs += Get-LanguageString "AzureCA.locationsAllLocationsLabel"
} }
else else
{ {
@@ -2683,7 +2683,7 @@ function Invoke-CDDocumentConditionalAccess
Name = $excludeLabel Name = $excludeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.policyConditionLocation" SubCategory = Get-LanguageString "AzureCA.policyConditionLocation"
EntityKey = "excludeLocations" EntityKey = "excludeLocations"
}) })
} }
@@ -2693,10 +2693,10 @@ function Invoke-CDDocumentConditionalAccess
$tmpObjs = @() $tmpObjs = @()
foreach($id in ($obj.conditions.clientAppTypes)) foreach($id in ($obj.conditions.clientAppTypes))
{ {
if($id -eq "browser") { $tmpObjs += Get-LanguageString "AzureIAM.clientAppWebBrowser" } if($id -eq "browser") { $tmpObjs += Get-LanguageString "AzureCA.clientAppWebBrowser" }
elseif($id -eq "mobileAppsAndDesktopClients") { $tmpObjs += Get-LanguageString "AzureIAM.clientAppMobileDesktop" } elseif($id -eq "mobileAppsAndDesktopClients") { $tmpObjs += Get-LanguageString "AzureCA.clientAppMobileDesktop" }
elseif($id -eq "exchangeActiveSync") { $tmpObjs += Get-LanguageString "AzureIAM.clientAppExchangeActiveSync" } elseif($id -eq "exchangeActiveSync") { $tmpObjs += Get-LanguageString "AzureCA.clientAppExchangeActiveSync" }
elseif($id -eq "other") { $tmpObjs += Get-LanguageString "AzureIAM.clientTypeOtherClients" } elseif($id -eq "other") { $tmpObjs += Get-LanguageString "AzureCA.clientTypeOtherClients" }
elseif($id -eq "all") { break } # Not configured elseif($id -eq "all") { break } # Not configured
else else
{ {
@@ -2711,7 +2711,7 @@ function Invoke-CDDocumentConditionalAccess
Name = $includeLabel Name = $includeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.policyConditioniClientApp" SubCategory = Get-LanguageString "AzureCA.policyConditioniClientApp"
EntityKey = "clientAppTypes" EntityKey = "clientAppTypes"
}) })
} }
@@ -2721,9 +2721,9 @@ function Invoke-CDDocumentConditionalAccess
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $includeLabel Name = $includeLabel
Value = Get-LanguageString "AzureIAM.deviceStateAll" Value = Get-LanguageString "AzureCA.deviceStateAll"
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.deviceStateConditionSelectorLabel" SubCategory = Get-LanguageString "AzureCA.deviceStateConditionSelectorLabel"
EntityKey = "includeDevices" EntityKey = "includeDevices"
}) })
} }
@@ -2733,27 +2733,49 @@ function Invoke-CDDocumentConditionalAccess
$tmpObjs = @() $tmpObjs = @()
foreach($id in ($obj.conditions.devices.excludeDevices)) foreach($id in ($obj.conditions.devices.excludeDevices))
{ {
$tmpObjs += Get-LanguageString "AzureIAM.classicPolicyControlRequire$($id)Device" $tmpObjs += Get-LanguageString "AzureCA.classicPolicyControlRequire$($id)Device"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $excludeLabel Name = $excludeLabel
Value = $tmpObjs -join $script:objectSeparator Value = $tmpObjs -join $script:objectSeparator
Category = $category Category = $category
SubCategory = Get-LanguageString "AzureIAM.deviceStateConditionSelectorLabel" SubCategory = Get-LanguageString "AzureCA.deviceStateConditionSelectorLabel"
EntityKey = "excludeDevices" EntityKey = "excludeDevices"
}) })
} }
if($obj.conditions.devices.deviceFilter)
{
if($obj.conditions.devices.deviceFilter.mode -eq "include")
{
$filterMode = "included"
}
else
{
$filterMode = "included"
}
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.AssignmentFilter.Blade
#AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.AppliesTo.$filterMode"
Value = $obj.conditions.devices.deviceFilter.rule
Category = $category
SubCategory = Get-LanguageString "AzureCA.PolicyBlade.Conditions.DeviceAttributes.Blade.title"
EntityKey = "includeDevices"
})
}
################################################### ###################################################
# Grant # Grant
################################################### ###################################################
$category = Get-LanguageString "AzureIAM.policyControlBladeTitle" $category = Get-LanguageString "AzureCA.policyControlBladeTitle"
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlContentDescription" Name = Get-LanguageString "AzureCA.policyControlContentDescription"
Value = Get-LanguageString "AzureIAM.$((?: (($obj.grantControls.builtInControls | Where { $_ -eq "block"}) -ne $null) "policyControlBlockAccessDisplayedName" "policyControlAllowAccessDisplayedName"))" Value = Get-LanguageString "AzureCA.$((?: (($obj.grantControls.builtInControls | Where { $_ -eq "block"}) -ne $null) "policyControlBlockAccessDisplayedName" "policyControlAllowAccessDisplayedName"))"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
EntityKey = "policyControl" EntityKey = "policyControl"
@@ -2766,7 +2788,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "mfa"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "mfa"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlMfaChallengeDisplayedName" Name = Get-LanguageString "AzureCA.policyControlMfaChallengeDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2777,7 +2799,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantDevice"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantDevice"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlCompliantDeviceDisplayedName" Name = Get-LanguageString "AzureCA.policyControlCompliantDeviceDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2788,7 +2810,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "domainJoinedDevice"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "domainJoinedDevice"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireDomainJoinedDisplayedName" Name = Get-LanguageString "AzureCA.policyControlRequireDomainJoinedDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2799,7 +2821,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "approvedApplication"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "approvedApplication"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireMamDisplayedName" Name = Get-LanguageString "AzureCA.policyControlRequireMamDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2810,7 +2832,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantApplication"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantApplication"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireCompliantAppDisplayedName" Name = Get-LanguageString "AzureCA.policyControlRequireCompliantAppDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2821,7 +2843,7 @@ function Invoke-CDDocumentConditionalAccess
if(($obj.grantControls.builtInControls | Where { $_ -eq "passwordChange"})) if(($obj.grantControls.builtInControls | Where { $_ -eq "passwordChange"}))
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequiredPasswordChangeDisplayedName" Name = Get-LanguageString "AzureCA.policyControlRequiredPasswordChangeDisplayedName"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2840,7 +2862,7 @@ function Invoke-CDDocumentConditionalAccess
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.menuItemTermsOfUse" Name = Get-LanguageString "AzureCA.menuItemTermsOfUse"
Value = $termsOfUse -join $script:objectSeparator Value = $termsOfUse -join $script:objectSeparator
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2849,8 +2871,8 @@ function Invoke-CDDocumentConditionalAccess
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.descriptionContentForControlsAndOr" Name = Get-LanguageString "AzureCA.descriptionContentForControlsAndOr"
Value = Get-LanguageString "AzureIAM.$((?: ($obj.grantControls.operator -eq "OR") "requireOneControlText" "requireAllControlsText"))" Value = Get-LanguageString "AzureCA.$((?: ($obj.grantControls.operator -eq "OR") "requireOneControlText" "requireAllControlsText"))"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
EntityKey = "grantOperator" EntityKey = "grantOperator"
@@ -2861,12 +2883,12 @@ function Invoke-CDDocumentConditionalAccess
# Session # Session
################################################### ###################################################
$category = Get-LanguageString "AzureIAM.sessionControlBladeTitle" $category = Get-LanguageString "AzureCA.sessionControlBladeTitle"
if($obj.sessionControls.applicationEnforcedRestrictions.isEnabled -eq $true) if($obj.sessionControls.applicationEnforcedRestrictions.isEnabled -eq $true)
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.sessionControlsAppEnforcedLabel" Name = Get-LanguageString "AzureCA.sessionControlsAppEnforcedLabel"
Value = Get-LanguageString "Inputs.enabled" Value = Get-LanguageString "Inputs.enabled"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2881,8 +2903,8 @@ function Invoke-CDDocumentConditionalAccess
elseif($obj.sessionControls.cloudAppSecurity.cloudAppSecurityType -eq "blockDownloads") { $strId = "blockDownloads" } elseif($obj.sessionControls.cloudAppSecurity.cloudAppSecurityType -eq "blockDownloads") { $strId = "blockDownloads" }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.sessionControlsCasLabel" Name = Get-LanguageString "AzureCA.sessionControlsCasLabel"
Value = Get-LanguageString "AzureIAM.CAS.BuiltinPolicy.Option.$strId" Value = Get-LanguageString "AzureCA.CAS.BuiltinPolicy.Option.$strId"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
EntityKey = "cloudAppSecurity" EntityKey = "cloudAppSecurity"
@@ -2899,27 +2921,27 @@ function Invoke-CDDocumentConditionalAccess
{ {
if($obj.sessionControls.signInFrequency.value -gt 1) if($obj.sessionControls.signInFrequency.value -gt 1)
{ {
$value = (Get-LanguageString "AzureIAM.SessionLifetime.SignInFrequency.Option.Hour.plural") -f $obj.sessionControls.signInFrequency.value $value = (Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Hour.plural") -f $obj.sessionControls.signInFrequency.value
} }
else else
{ {
$value = Get-LanguageString "AzureIAM.SessionLifetime.SignInFrequency.Option.Hour.singular" $value = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Hour.singular"
} }
} }
else else
{ {
if($obj.sessionControls.signInFrequency.value -gt 1) if($obj.sessionControls.signInFrequency.value -gt 1)
{ {
$value = (Get-LanguageString "AzureIAM.SessionLifetime.SignInFrequency.Option.Day.plural") -f $obj.sessionControls.signInFrequency.value $value = (Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Day.plural") -f $obj.sessionControls.signInFrequency.value
} }
else else
{ {
$value = Get-LanguageString "AzureIAM.SessionLifetime.SignInFrequency.Option.Day.singular" $value = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.Day.singular"
} }
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.SessionLifetime.SignInFrequency.Option.label" Name = Get-LanguageString "AzureCA.SessionLifetime.SignInFrequency.Option.label"
Value = $value Value = $value
Category = $category Category = $category
SubCategory = "" SubCategory = ""
@@ -2930,8 +2952,8 @@ function Invoke-CDDocumentConditionalAccess
if($obj.sessionControls.persistentBrowser.isEnabled -eq $true) if($obj.sessionControls.persistentBrowser.isEnabled -eq $true)
{ {
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.SessionLifetime.PersistentBrowser.Option.label" Name = Get-LanguageString "AzureCA.SessionLifetime.PersistentBrowser.Option.label"
Value = Get-LanguageString "AzureIAM.SessionLifetime.PersistentBrowser.Option.$($obj.sessionControls.persistentBrowser.mode)" Value = Get-LanguageString "AzureCA.SessionLifetime.PersistentBrowser.Option.$($obj.sessionControls.persistentBrowser.mode)"
Category = $category Category = $category
SubCategory = "" SubCategory = ""
EntityKey = "persistentBrowser" EntityKey = "persistentBrowser"
@@ -3899,7 +3921,7 @@ function Invoke-CDDocumentDeviceEnrollmentPlatformRestrictionConfiguration
if($obj.'@OData.Type' -eq '#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration') if($obj.'@OData.Type' -eq '#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration')
{ {
$platform = Get-LanguageString "AzureIAM.classicPolicyAllPlatforms" $platform = Get-LanguageString "AzureCA.classicPolicyAllPlatforms"
$properties = @("androidForWorkRestriction","androidRestriction","iosRestriction","macRestriction","windowsRestriction") $properties = @("androidForWorkRestriction","androidRestriction","iosRestriction","macRestriction","windowsRestriction")
$policyType = "all" $policyType = "all"
} }
+347 -12
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.0' '3.9.2'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -73,6 +73,21 @@ function Invoke-InitializeModule
SubPath = "EndpointManager" SubPath = "EndpointManager"
}) "EndpointManager" }) "EndpointManager"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Save Encryption File"
Key = "EMSaveEncryptionFile"
Type = "Boolean"
Description = "Save encryption file when uploading an app. This can then be used to when downloading the app file."
SubPath = "EndpointManager"
}) "EndpointManager"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "App download folder"
Key = "EMIntuneAppDownloadFolder"
Type = "Folder"
Description = "Folder where app packages will be downloaded and where encryption files will be saved"
SubPath = "EndpointManager"
}) "EndpointManager"
$viewPanel = Get-XamlObject ($global:AppRootFolder + "\Xaml\EndpointManagerPanel.xaml") -AddVariables $viewPanel = Get-XamlObject ($global:AppRootFolder + "\Xaml\EndpointManagerPanel.xaml") -AddVariables
@@ -314,7 +329,7 @@ function Invoke-InitializeModule
PostFileImportCommand = { Start-PostFileImportAdministrativeTemplate @args } PostFileImportCommand = { Start-PostFileImportAdministrativeTemplate @args }
PreImportCommand = { Start-PreImportAdministrativeTemplate @args } PreImportCommand = { Start-PreImportAdministrativeTemplate @args }
LoadObject = { Start-LoadAdministrativeTemplate @args } LoadObject = { Start-LoadAdministrativeTemplate @args }
PropertiesToRemove = @("definitionValues") PropertiesToRemove = @("definitionValues","policyConfigurationIngestionType")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="DeviceConfiguration" Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration" GroupId = "DeviceConfiguration"
@@ -454,7 +469,10 @@ function Invoke-InitializeModule
PreDeleteCommand = { Start-PreDeleteApplications @args } PreDeleteCommand = { Start-PreDeleteApplications @args }
PostExportCommand = { Start-PostExportApplications @args } PostExportCommand = { Start-PostExportApplications @args }
PostListCommand = { Start-PostListApplications @args } PostListCommand = { Start-PostListApplications @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportApplications @args }
PostGetCommand = { Start-PostGetApplications @args }
PostImportCommand = { Start-PostImportApplications @args }
PostFilesImportCommand = { Start-PostFilesImportApplications @args }
GroupId = "Apps" GroupId = "Apps"
ScopeTagsReturnedInList = $false ScopeTagsReturnedInList = $false
}) })
@@ -767,6 +785,16 @@ function Invoke-InitializeModule
Icon = "Devices" Icon = "Devices"
GroupId = "DeviceConfiguration" GroupId = "DeviceConfiguration"
}) })
Add-ViewItem (New-Object PSObject -Property @{
Title = "Driver Update Profiles"
Id = "DriverUpdateProfiles"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/windowsDriverUpdateProfiles"
Permissons = @("DeviceManagementConfiguration.ReadWrite.All")
Icon = "UpdatePolicies"
GroupId = "WinDriverUpdatePolicies"
})
} }
function Invoke-EMAuthenticateToMSAL function Invoke-EMAuthenticateToMSAL
@@ -1974,24 +2002,41 @@ function local:Start-ImportApp
if($appType -eq "microsoft.graph.win32LobApp") if($appType -eq "microsoft.graph.win32LobApp")
{ {
Copy-Win32LOBPackage $packageFile $obj $fileEncryptionInfo = Copy-Win32LOBPackage $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.windowsMobileMSI") elseif($appType -eq "microsoft.graph.windowsMobileMSI")
{ {
Copy-MSILOB $packageFile $obj $fileEncryptionInfo = Copy-MSILOB $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.iosLOBApp") elseif($appType -eq "microsoft.graph.iosLOBApp")
{ {
Copy-iOSLOB $packageFile $obj $fileEncryptionInfo = Copy-iOSLOB $packageFile $obj
} }
elseif($appType -eq "microsoft.graph.androidLOBApp") elseif($appType -eq "microsoft.graph.androidLOBApp")
{ {
Copy-AndroidLOB $packageFile $obj $fileEncryptionInfo = Copy-AndroidLOB $packageFile $obj
} }
else else
{ {
Write-Log "Unsupported application type $appType. File will not be uploaded" 2 Write-Log "Unsupported application type $appType. File will not be uploaded" 2
} }
if((Get-SettingValue "EMSaveEncryptionFile") -eq $true)
{
#$fileEncryptionInfo = $fileEncryptionInfo | where { $null -ne $_.fileEncryptionInfo }
if($fileEncryptionInfo)
{
$jsonEncryptionInfo = $fileEncryptionInfo.fileEncryptionInfo | ConvertTo-Json -Depth 10
$pkgPath = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
if($pkgPath -and [IO.Directory]::Exists($pkgPath))
{
$obj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.id)" -ODataMetadata "Minimal"
$fullPath = $pkgPath + "\$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion).json"
$jsonEncryptionInfo | Out-File -FilePath $fullPath -Force -Encoding utf8
}
}
}
} }
function Start-PreUpdateApplication function Start-PreUpdateApplication
@@ -2081,6 +2126,69 @@ function Add-DetailExtensionApplications
$tmp.Children.Insert($index, $btnUpload) $tmp.Children.Insert($index, $btnUpload)
} }
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Download'
$btnDownload.Name = 'btnDownloadAppfile'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Write-Status "Download file"
$obj = $global:dgObjects.SelectedItem.Object
#$obj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.id)"
$pkgPath = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
$dlgSave = [System.Windows.Forms.SaveFileDialog]::new()
$dlgSave.InitialDirectory = $pkgPath
$dlgSave.FileName = ($obj.FileName + ".encrypted")
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
Start-DownloadAppContent $obj $dlgSave.FileName
if([IO.File]::Exists($dlgSave.FileName))
{
$fullPath = $pkgPath + "\$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion).json"
if([IO.File]::Exists($fullPath) -eq $false)
{
if(([System.Windows.MessageBox]::Show("Could not find decryption file for $($obj.displayName)`nApp Id: $($obj.id)`nContent version $($obj.committedContentVersion)`n`nDo you want to browse for the file?", "Encryption file not found", "YesNo", "Warning")) -eq "Yes")
{
$of = [System.Windows.Forms.OpenFileDialog]::new()
$of.InitialDirectory = $pkgPath
$of.DefaultExt = "*.json"
$of.Filter = "Json (*.json)|*.*"
$of.Multiselect = $false
if($of.ShowDialog() -eq "OK")
{
$fullPath = $of.FileName
}
}
}
if([IO.File]::Exists($fullPath))
{
Write-Status "Decrypting file"
$encryptionInfo = ConvertFrom-Json (Get-Content -Path $fullPath -Raw)
$destination = $pkgPath + "\$($obj.FileName)"
Start-DecryptFile $dlgSave.Filename $destination $encryptionInfo.encryptionKey $encryptionInfo.initializationVector
}
else
{
Write-Log "Decryption file for $($obj.displayName) not found. Skipping decryption" 2
}
}
}
Write-Status ""
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
} }
function Start-PreImportAssignmentsApplications function Start-PreImportAssignmentsApplications
@@ -2166,6 +2274,42 @@ function Start-PostExportApplications
Write-LogError "Failed to export scripts" $_.Exception Write-LogError "Failed to export scripts" $_.Exception
} }
} }
Save-Setting "Intune" "ExportAppFile" $global:chkExportApplicationFile.IsChecked
if($global:chkExportApplicationFile.IsChecked)
{
$encryptioSource = Get-SettingValue "EMIntuneAppDownloadFolder" (Get-SettingValue "EMIntuneAppPackages")
$pkgPath = $path
if($pkgPath)
{
Write-Status "Download file"
$exportFile = $pkgPath + "\$($obj.FileName).encrypted"
$encryptionFile = $encryptioSource + "\$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion).json"
if($encryptionFile -and [IO.File]::Exists($encryptionFile))
{
Start-DownloadAppContent $obj $exportFile
if([IO.File]::Exists($exportFile))
{
Write-Status "Decrypting file"
$encryptionInfo = ConvertFrom-Json (Get-Content -Path $encryptionFile -Raw)
$destination = $pkgPath + "\$($obj.FileName)"
Start-DecryptFile $exportFile $destination $encryptionInfo.encryptionKey $encryptionInfo.initializationVector
}
try { [IO.File]::Delete($exportFile) }
catch {
Write-LogError "Filed to delete exported encrypted file" $_.Exception
}
}
else
{
Write-Log "Cound not file encryption file `"$($obj.displayName)_$($obj.id)_$($obj.committedContentVersion).json`""
}
}
}
} }
function Start-PostListApplications function Start-PostListApplications
@@ -2193,6 +2337,177 @@ function Start-PostListApplications
$objList $objList
} }
function Add-ScriptExportApplications
{
param($form, $buttonPanel, $index = 0)
Add-ScriptExportExtensions $form $buttonPanel $index
$ctrl = $form.FindName("chkExportApplicationFile")
if(-not $ctrl)
{
$xaml = @"
<StackPanel $($global:wpfNS) Orientation="Horizontal" Margin="0,0,5,0">
<Label Content="Export application file" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Export the application file. Note: Application file will only be exported if ecryption file is found." />
</StackPanel>
"@
$label = [Windows.Markup.XamlReader]::Parse($xaml)
$global:chkExportApplicationFile = [System.Windows.Controls.CheckBox]::new()
$global:chkExportApplicationFile.IsChecked = ((Get-Setting "Intune" "ExportAppFile" "false") -eq "true")
$global:chkExportApplicationFile.VerticalAlignment = "Center"
$global:chkExportApplicationFile.Name = "chkExportApplicationFile"
@($label, $global:chkExportApplicationFile)
}
}
function Start-PostGetApplications {
param($obj, $objectType)
if($obj.Object.dependentAppCount -is [Int] -and ($obj.Object.dependentAppCount -gt 0 -or $obj.Object.supersededAppCount -gt 0)) {
$relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value
$dependencyApps = @()
$supersededApps = @()
foreach ($rel in $relationships) {
if ($rel."@odata.type" -eq "#microsoft.graph.mobileAppDependency") {
$dependencyApps += "$($rel.targetDisplayName)|!|$($rel.targetDisplayVersion)|!|$($rel.targetId)|!|$($rel.dependencyType)"
}
elseif ($rel."@odata.type" -eq "#microsoft.graph.mobileAppSupersedence") {
$supersededApps += "$($rel.targetDisplayName)|!|$($rel.targetDisplayVersion)|!|$($rel.targetId)|!|$($rel.supersedenceType)"
}
}
if ($dependencyApps.Count -gt 0) {
$obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefDependency" -Value ($dependencyApps -join "|*|")
}
if ($supersededApps.Count -gt 0) {
$obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefSupersedence" -Value ($supersededApps -join "|*|")
}
}
}
function Start-PostImportApplications
{
param($obj, $objectType, $file)
#$tmpObj = Get-GraphObjectFromFile $file
}
function Start-PostFilesImportApplications
{
param($objType, $importedObjects, $importedFiles)
$refObjects = $importedFiles | Where { $null -ne $_.Object."#CustomRefDependency" -or $null -ne $_.Object."#CustomRefSupersedence" }
if(($refObjects | measure).Count -gt 0)
{
Write-Log "Applicetions with Depnedency or Supersedence detected"
foreach($file in $refObjects)
{
Add-ApplicationReferences $file.ImportedObject $file.Object
}
}
}
function local:Add-ApplicationReferences
{
param($obj, $fileObj)
if($fileObj."#CustomRefDependency" -or $fileObj."#CustomRefSupersedence")
{
Write-Log "Adding app references for $($obj.displayName)"
$depAppsInfo = $fileObj."#CustomRefDependency"
$supAppsInfo = $fileObj."#CustomRefSupersedence"
$releationShips = [PSCustomObject]@{
relationships = @()
}
if($depAppsInfo)
{
foreach($depApp in ($depAppsInfo -split "[|][*][|]"))
{
$appName, $appVer, $appId, $appType = $depApp -split "[|][!][|]"
if(-not $appName -or -not $appVer)
{
Write-Log "Could not get Name and Version from string: $appApp" 2
continue
}
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
if(-not $tmpApps)
{
Write-Log "No application found with name $appName" 2
continue
}
$tmpApp = $tmpApps | Where displayVersion -eq $appVer
if(-not $tmpApp)
{
Write-Log "No $appName application found with version $appVer" 2
continue
}
elseif(-not ($tmpApp | measure).Count -gt 1)
{
Write-Log "Multiple $appName application found with version $appVer" 2
continue
}
Write-Log "Add $appName ($appVer) to Dependency list"
$releationShips.relationships += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.mobileAppDependency"
targetId = $tmpApp.Id
dependencyType = $appType
}
}
}
if($supAppsInfo)
{
foreach($suppApp in ($supAppsInfo -split "[|][*][|]"))
{
$appName, $appVer, $appId, $appType = $suppApp -split "[|][!][|]"
if(-not $appName -or -not $appVer)
{
Write-Log "Could not get Name and Version from string: $appApp" 2
continue
}
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
if(-not $tmpApps)
{
Write-Log "No application found with name $appName" 2
continue
}
$tmpApp = $tmpApps | Where displayVersion -eq $appVer
if(-not $tmpApp)
{
Write-Log "No $appName application found with version $appVer" 2
continue
}
elseif(-not ($tmpApp | measure).Count -gt 1)
{
Write-Log "Multiple $appName application found with version $appVer" 2
continue
}
Write-Log "Add $appName ($appVer) to Supersedence list"
$releationShips.relationships += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.mobileAppSupersedence"
targetId = $tmpApp.Id
supersedenceType = $appType
}
}
}
if($releationShips.relationships.Count -gt 0)
{
$json = Update-JsonForEnvironment (ConvertTo-Json $releationShips -Depth 20)
Write-Log "Update app references"
Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/updateRelationships" -Method "POST" -Body $json
}
}
}
#endregion #endregion
#region Group Policy/Administrative Templates functions #region Group Policy/Administrative Templates functions
@@ -2202,6 +2517,13 @@ function Get-GPOObjectSettings
$gpoSettings = @() $gpoSettings = @()
if ($GPOObj.policyConfigurationIngestionType -eq "unknown") {
$tmpObj = (Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations?`$filter=id eq '$($GPOObj.id)'").value[0]
if ($tmpObj.policyConfigurationIngestionType) {
$GPOObj.policyConfigurationIngestionType = $tmpObj.policyConfigurationIngestionType
}
}
# Get all configured policies in the Administrative Templates profile # Get all configured policies in the Administrative Templates profile
$GPODefinitionValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues?`$expand=definition" -ODataMetadata "skip" $GPODefinitionValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues?`$expand=definition" -ODataMetadata "skip"
foreach($definitionValue in $GPODefinitionValues.value) foreach($definitionValue in $GPODefinitionValues.value)
@@ -3253,6 +3575,11 @@ function Add-ConditionalAccessImportExtensions
$label = [Windows.Markup.XamlReader]::Parse($xaml) $label = [Windows.Markup.XamlReader]::Parse($xaml)
$CAStates = @() $CAStates = @()
$CAStates += [PSCustomObject]@{
Name = "As Exported - Change On to Report-only"
Value = "AsExportedReportOnly"
}
$CAStates += [PSCustomObject]@{ $CAStates += [PSCustomObject]@{
Name = "As Exported" Name = "As Exported"
Value = "AsExported" Value = "AsExported"
@@ -3277,7 +3604,7 @@ function Add-ConditionalAccessImportExtensions
$global:cbImportCAState.DisplayMemberPath = "Name" $global:cbImportCAState.DisplayMemberPath = "Name"
$global:cbImportCAState.SelectedValuePath = "Value" $global:cbImportCAState.SelectedValuePath = "Value"
$global:cbImportCAState.ItemsSource = $CAStates $global:cbImportCAState.ItemsSource = $CAStates
$global:cbImportCAState.SelectedValue = "AsExported" $global:cbImportCAState.SelectedValue = "disabled"
$global:cbImportCAState.Margin="0,5,0,0" $global:cbImportCAState.Margin="0,5,0,0"
$global:cbImportCAState.HorizontalAlignment="Left" $global:cbImportCAState.HorizontalAlignment="Left"
$global:cbImportCAState.Width=250 $global:cbImportCAState.Width=250
@@ -3290,10 +3617,15 @@ function Start-PreImportConditionalAccess
{ {
param($obj, $objectType, $file, $assignments) param($obj, $objectType, $file, $assignments)
if($global:cbImportCAState.SelectedValue -and $global:cbImportCAState.SelectedValue -ne "AsExported") if ($global:cbImportCAState.SelectedValue -and $global:cbImportCAState.SelectedValue -ne "AsExported") {
{ if ($global:cbImportCAState.SelectedValue -eq "AsExportedReportOnly" -and $obj.state -eq "enabled") {
Write-Log "Change Enabled policy to Report-only"
$obj.state = "enabledForReportingButNotEnforced"
}
else {
$obj.state = $global:cbImportCAState.SelectedValue $obj.state = $global:cbImportCAState.SelectedValue
} }
}
if($obj.grantControls.authenticationStrength) if($obj.grantControls.authenticationStrength)
{ {
@@ -3464,10 +3796,13 @@ function Start-PreImportADMXFiles
return return
} }
$bytes = [IO.File]::ReadAllBytes($admxFile) #$bytes = [IO.File]::ReadAllBytes($admxFile)
$bytes = Get-ASCIIBytes ([IO.File]::ReadAllText($admxFile))
$obj.content = [Convert]::ToBase64String($bytes) $obj.content = [Convert]::ToBase64String($bytes)
$bytes = [IO.File]::ReadAllBytes($admlFile) #$bytes = [IO.File]::ReadAllBytes($admlFile)
$bytes = Get-ASCIIBytes ([IO.File]::ReadAllText($admlFile))
$obj.groupPolicyUploadedLanguageFiles += [PSCustomObject]@{ $obj.groupPolicyUploadedLanguageFiles += [PSCustomObject]@{
fileName = [io.path]::GetFileName($admlFile) fileName = [io.path]::GetFileName($admlFile)
content = [Convert]::ToBase64String($bytes) content = [Convert]::ToBase64String($bytes)
+152 -16
View File
@@ -10,7 +10,7 @@ This module manages Application objects in Intune e.g. uploading application fil
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.9.0' '3.9.2'
} }
######################################################################################### #########################################################################################
@@ -94,14 +94,18 @@ function Copy-MSILOB
$tmpFile = [IO.Path]::GetTempFileName() $tmpFile = [IO.Path]::GetTempFileName()
$msiInfo = Get-MSIFileInformation $msiFile @("ProductName", "ProductCode", "ProductVersion", "ProductLanguage") $msiInfo = Get-MSIFileInformation $msiFile @("ProductName", "ProductCode", "ProductVersion", "ProductLanguage", "UpgradeCode", "ALLUSERS")
if(-not $msiInfo) { return } if(-not $msiInfo) { return }
$fileEncryptionInfo = New-IntuneEncryptedFile $msiFile $tmpFile $fileEncryptionInfo = New-IntuneEncryptedFile $msiFile $tmpFile
[xml]$manifestXML = '<MobileMsiData MsiExecutionContext="Any" MsiRequiresReboot="false" MsiUpgradeCode="" MsiIsMachineInstall="true" MsiIsUserInstall="false" MsiIncludesServices="false" MsiContainsSystemRegistryKeys="false" MsiContainsSystemFolders="false"></MobileMsiData>' [xml]$manifestXML = '<MobileMsiData MsiExecutionContext="Any" MsiRequiresReboot="false" MsiUpgradeCode="" MsiIsMachineInstall="true" MsiIsUserInstall="false" MsiIncludesServices="false" MsiContainsSystemRegistryKeys="false" MsiContainsSystemFolders="false"></MobileMsiData>'
$manifestXML.MobileMsiData.MsiUpgradeCode = $msiInfo["ProductCode"] $manifestXML.MobileMsiData.MsiUpgradeCode = $msiInfo["UpgradeCode"]
if($msiInfo["ALLUSERS"] -eq 1)
{
$manifestXML.MobileMsiData.MsiExecutionContext = "System"
}
$appFileBody = @{ $appFileBody = @{
"@odata.type" = "#microsoft.graph.mobileAppContentFile" "@odata.type" = "#microsoft.graph.mobileAppContentFile"
@@ -109,11 +113,14 @@ function Copy-MSILOB
size = (Get-Item $msiFile).Length size = (Get-Item $msiFile).Length
sizeEncrypted = (Get-Item $tmpFile).Length sizeEncrypted = (Get-Item $tmpFile).Length
manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifestXML.OuterXml)) manifest = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($manifestXML.OuterXml))
isDependency = $false
} }
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-iOSLOB function Copy-iOSLOB
@@ -149,6 +156,8 @@ function Copy-iOSLOB
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-AndroidLOB function Copy-AndroidLOB
@@ -185,6 +194,8 @@ function Copy-AndroidLOB
Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody Add-FileToIntuneApp $appId $appType $tmpFile $appFileBody
Remove-Item $tmpFile -Force Remove-Item $tmpFile -Force
$fileEncryptionInfo
} }
function Copy-Win32LOBPackage function Copy-Win32LOBPackage
@@ -235,7 +246,7 @@ function Copy-Win32LOBPackage
$fileBody = @{ $fileBody = @{
"@odata.type" = "#microsoft.graph.mobileAppContentFile" "@odata.type" = "#microsoft.graph.mobileAppContentFile"
name = $DetectionXML.ApplicationInfo.FileName name = "IntunePackage.intunewin"
size = [int64]$DetectionXML.ApplicationInfo.UnencryptedContentSize size = [int64]$DetectionXML.ApplicationInfo.UnencryptedContentSize
sizeEncrypted = (Get-Item $tmpIntunewinFile).Length sizeEncrypted = (Get-Item $tmpIntunewinFile).Length
manifest = $null manifest = $null
@@ -246,45 +257,58 @@ function Copy-Win32LOBPackage
# Remove extracted inintunewin file # Remove extracted inintunewin file
Remove-Item $tmpIntunewinPath -Force -Recurse Remove-Item $tmpIntunewinPath -Force -Recurse
$fileEncryptionInfo
} }
function Add-FileToIntuneApp function Add-FileToIntuneApp
{ {
param($appId, $appType, $appFile, $fileBody) param($appId, $appType, $appFile, $fileBody)
$contentVersion = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions" -HttpMethod POST -Content "{}" $contentVersion = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions" -HttpMethod POST -Content "{}" -ODataMetadata "Minimal"
$contentVersionId = $contentVersion.id $contentVersionId = $contentVersion.id
$fileObj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files" -HttpMethod POST -Content (ConvertTo-Json $fileBody -Depth 5) $fileObj = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files" -HttpMethod POST -Content (ConvertTo-Json $fileBody -Depth 5) -ODataMetadata "Minimal"
if(-not $fileObj) if(-not $fileObj)
{ {
return return
} }
Write-Log "File object created. ID: $($fileObj.id)"
# Wait for Azure storage URI # Wait for Azure storage URI
$fileObj = Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "AzureStorageUriRequest" $fileObj = Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "AzureStorageUriRequest"
if(-not $fileObj) if(-not $fileObj)
{ {
Write-Log "No File Object returned from commit. Upload failed" 3
return return
} }
# Upload file # Upload file
Send-IntuneFileToAzureStorage $fileObj.azureStorageUri $appFile "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" Send-IntuneFileToAzureStorage $fileObj.azureStorageUri $appFile "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" | Out-Null
# Commit the file # Commit the file
$reponse = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)/commit" -HttpMethod POST -Content (ConvertTo-Json $fileEncryptionInfo -Depth 5) Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)/commit" -HttpMethod POST -Content (ConvertTo-Json $fileEncryptionInfo -Depth 5) | Out-Null
Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "CommitFile" Wait-IntuneFileState "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVersionId/files/$($fileObj.Id)" "CommitFile" | Out-Null
$fiUpload = [IO.FileInfo]$appFile
# Commit the content version # Commit the content version
$commitAppBody = @{ $commitAppBody = @{
"@odata.type" = "#$appType" "@odata.type" = "#$appType"
committedContentVersion = $contentVersionId committedContentVersion = $contentVersionId
fileName = $fiUpload.Name
} }
$reponse = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId" -HttpMethod PATCH -Content (ConvertTo-Json $commitAppBody -Depth 5) # if($fileBody.Name) {
# $fileUploadName = $fileBody.Name
# }
# else {
$fiUpload = [IO.FileInfo]$appFile
$fileUploadName = $fiUpload.Name
# }
$commitAppBody.Add("fileName",$fileUploadName)
Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId" -HttpMethod PATCH -Content (ConvertTo-Json $commitAppBody -Depth 5) | Out-Null
Write-Log "Upload finished for file $fileUploadName version $contentVersionId"
} }
function Wait-IntuneFileState function Wait-IntuneFileState
@@ -318,7 +342,7 @@ function Wait-IntuneFileState
return return
} }
Start-Sleep -s 5 Start-Sleep -Seconds 1
} }
if($succes -eq $false) if($succes -eq $false)
@@ -423,9 +447,17 @@ function Set-FinalizeAzureStorageUpload
} }
$xml += '</BlockList>' $xml += '</BlockList>'
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
try try
{ {
Invoke-RestMethod $uri -Method Put -Body $xml Invoke-RestMethod $uri -Method Put -Body $xml @params
} }
catch catch
{ {
@@ -457,12 +489,18 @@ function Write-AzureStorageChunk
$success = $false $success = $false
$retryCount = 0 $retryCount = 0
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
}
while($true) while($true)
{ {
try try
{ {
$response = Invoke-WebRequest $uri -Method Put -Headers $headers -Body $encodedBody -UseBasicParsing $response = Invoke-WebRequest $uri -Method Put -Headers $headers -Body $encodedBody -UseBasicParsing @params
if($retryCount -gt 0) if($retryCount -gt 0)
{ {
Write-Log "Chunk uploaded successfully" Write-Log "Chunk uploaded successfully"
@@ -622,3 +660,101 @@ function New-IntuneEncryptedFile
$fileEncryptionInfo $fileEncryptionInfo
} }
function Start-DecryptFile
{
param($sourceFile, $targetFile, $encryptionKey, $initializationVector)
if([IO.File]::Exists($targetFile))
{
$fi = [IO.FileInfo]$targetFile
$newName = $fi.Name + "_$((Get-Date).ToString("yyyyMMdd_HHmm"))" + $fi.Extension
$targetFile = $fi.DirectoryName + "\$newName"
Write-Log "Target file exists. Changing target file to $targetFile" 2
}
$bufferBlockSize = 1024 * 4
try
{
$aes = [System.Security.Cryptography.Aes]::Create()
$buffer = New-Object byte[] $bufferBlockSize
$bytesRead = 0
$targetStream = [System.IO.File]::Open($targetFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
try
{
$sourceStream = [System.IO.File]::Open($sourceFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::None)
$decryptor = $aes.CreateDecryptor([Convert]::FromBase64String($encryptionKey), [Convert]::FromBase64String($initializationVector))
$decryptoStream = New-Object System.Security.Cryptography.CryptoStream -ArgumentList @($targetStream, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Write)
$sourceStream.Seek(48L, [System.IO.SeekOrigin]::Begin)
while (($bytesRead = $sourceStream.Read($buffer, 0, $bufferBlockSize)) -gt 0)
{
$decryptoStream.Write($buffer, 0, $bytesRead)
$decryptoStream.Flush()
}
$decryptoStream.FlushFinalBlock()
}
finally
{
if ($null -ne $decryptoStream) { $decryptoStream.Dispose() }
if ($null -ne $targetStream) { $targetStream.Dispose() }
if ($null -ne $decryptor) { $decryptor.Dispose() }
if ($null -ne $sourceStream) { $sourceStream.Dispose() }
}
}
finally
{
if ($null -ne $sourceStream) { $sourceStream.Dispose() }
if ($null -ne $aes) { $aes.Dispose() }
}
}
function Start-DownloadAppContent
{
param($obj, $destinationFile)
# Not use but kept for reference. File can be download but it will be encrypted
if([IO.File]::Exists($destinationFile))
{
try { [IO.File]::Delete($encryptionFile) }
catch {}
}
$appId = $obj.Id
$appInfo = Invoke-GraphRequest -Url "$($global:graphURL)/deviceAppManagement/mobileApps/$appId"
$appType = $appInfo.'@odata.type'.Trim('#')
#$contentVersions = Invoke-GraphRequest -Url "$($global:graphURL)/deviceAppManagement/mobileApps/$appId/$appType/contentVersions"
#$contentVerId = $contentVersions.Value[0].id
$contentVerId = $appInfo.committedContentVersion
$contentFiles = Invoke-GraphRequest "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files"
$contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($contentFiles.value[-1].Id)" -NoError
if(-not $contentFile)
{
foreach($file in $contentFiles.value)
{
if($contentFiles.value[-1].Id -eq $file.id) { continune }
# NOT happy about this. file objects are not always returned in the order of upload.
$contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($file.Id)" -NoError
if($contentFile)
{
break
}
}
}
Start-DownloadFile $contentFile.azureStorageUri $destinationFile
}
+2 -2
View File
@@ -22,7 +22,7 @@ $global:EMToolsViewObject = $null
function Get-ModuleVersion function Get-ModuleVersion
{ {
'1.0.3' '1.0.4'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -82,7 +82,7 @@ function Add-EMToolsViewItem
Activating = { Invoke-EMToolsActivatingView } Activating = { Invoke-EMToolsActivatingView }
Authentication = (Get-MSALAuthenticationObject) Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMToolsAuthenticateToMSAL } Authenticate = { Invoke-EMToolsAuthenticateToMSAL }
AppInfo = (Get-GraphAppInfo "EM" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547") AppInfo = (Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547")
SaveSettings = { Invoke-EMSaveSettings } SaveSettings = { Invoke-EMSaveSettings }
Permissions = @() Permissions = @()
}) })
+177 -8
View File
@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.8.1' '3.9.2'
} }
$global:msalAuthenticator = $null $global:msalAuthenticator = $null
@@ -158,6 +158,10 @@ function Clear-MSALCurentUserVaiables
{ {
$global:MSALTenantId = $null $global:MSALTenantId = $null
$global:MSALGraphEnvironment = $null $global:MSALGraphEnvironment = $null
$script:jwtAccessToken = $null
$script:jwtIdToken = $null
} }
function Get-MSALCurrentApp function Get-MSALCurrentApp
@@ -223,6 +227,9 @@ function Get-MSALUserInfo
if($global:MSALToken) if($global:MSALToken)
{ {
Write-Log "Get current user" Write-Log "Get current user"
if($script:jwtAccessToken.Payload.idtyp -ne "app")
{
$tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip" $tmpMe = MSGraph\Invoke-GraphRequest -Url "ME" -SkipAuthentication -ODataMetadata "Skip"
if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation") if($null -ne $tmpMe -and $tmpMe.creationType -ne "Invitation")
{ {
@@ -232,6 +239,12 @@ function Get-MSALUserInfo
$global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg" $global:profilePhoto = "$($env:LOCALAPPDATA)\CloudAPIPowerShellManagement\$($global:Me.Id).jpeg"
MSGraph\Invoke-GraphRequest "me/photos/48x48/`$value" -OutFile $global:profilePhoto -SkipAuthentication -NoError | Out-Null MSGraph\Invoke-GraphRequest "me/photos/48x48/`$value" -OutFile $global:profilePhoto -SkipAuthentication -NoError | Out-Null
} }
}
else
{
$global:profilePhoto = $null
$global:me = $script:jwtAccessToken.Payload.app_displayname
}
Write-Log "Get organization info" Write-Log "Get organization info"
$global:Organization = (MSGraph\Invoke-GraphRequest -Url "Organization" -SkipAuthentication -ODataMetadata "Skip").Value $global:Organization = (MSGraph\Invoke-GraphRequest -Url "Organization" -SkipAuthentication -ODataMetadata "Skip").Value
@@ -535,12 +548,14 @@ function Add-MSALPrereq
Write-Log "Some MSAL features might not work!" 3 Write-Log "Some MSAL features might not work!" 3
Write-Log "This could happen if another version of MSAL.DLL was loaded beforethe script tried to load it" 3 Write-Log "This could happen if another version of MSAL.DLL was loaded beforethe script tried to load it" 3
$RequiredAssemblies.Add($fiLoaded.FullName) $RequiredAssemblies.Add($fiLoaded.FullName)
$script:msalFile = $fiLoaded.FullName
} }
else else
{ {
Write-Log "Using MSAL file $msalPath. Version: $($fi.VersionInfo.FileVersion)" Write-Log "Using MSAL file $msalPath. Version: $($fi.VersionInfo.FileVersion)"
[void][System.Reflection.Assembly]::LoadFile($msalPath) [void][System.Reflection.Assembly]::LoadFile($msalPath)
$RequiredAssemblies.Add($msalPath) $RequiredAssemblies.Add($msalPath)
$script:msalFile = $msalPath
} }
$RequiredAssemblies.Add('System.Security.dll') $RequiredAssemblies.Add('System.Security.dll')
@@ -598,6 +613,7 @@ function Connect-MSALClientApp
{ {
return return
} }
Add-MSALProxy $ClientApplicationBuilder
$script:MSALApp = $ClientApplicationBuilder.Build() $script:MSALApp = $ClientApplicationBuilder.Build()
} }
@@ -677,6 +693,43 @@ function Get-MsalAuthenticationToken
$authResult $authResult
} }
function Add-MSALProxy
{
param($appBuilder)
$proxy = Get-SettingValue "ProxyURI"
if($proxy)
{
Write-Log "Use proxy $proxy"
if(-not ("HttpFactoryWithProxy" -as [type]))
{
try
{
Write-Log "Add type HttpFactoryWithProxy"
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
$RequiredAssemblies.Add($script:msalFile)
$RequiredAssemblies.Add('System.Net.Http.dll')
$RequiredAssemblies.Add('System.Net.Primitives.dll')
Add-Type -Path ($global:AppRootFolder + "\CS\HttpFactoryWithProxy.cs") -ReferencedAssemblies $RequiredAssemblies
}
catch
{
Write-LogError "Failed to compile HttpFactoryWithProxy" $_.Exception
}
}
try
{
$hcf = [HttpFactoryWithProxy]::new($proxy)
[void] $appBuilder.WithHttpClientFactory($hcf)
}
catch
{
Write-LogError "Failed to set proxy for MSAL" $_.Exception
}
}
}
function Get-MSALLoginEnvironment function Get-MSALLoginEnvironment
{ {
$loginEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public") $loginEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public")
@@ -717,6 +770,8 @@ function Get-MSALApp
[void] $appBuilder.WithClientName("CloudAPIPowerShellManagement") [void] $appBuilder.WithClientName("CloudAPIPowerShellManagement")
[void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion) [void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion)
Add-MSALProxy $appBuilder
# Ceck if correct version... # Ceck if correct version...
#$appBuilder.WithMultiCloudSupport($true) #$appBuilder.WithMultiCloudSupport($true)
@@ -792,6 +847,42 @@ function Connect-MSALUser
Write-LogDebug "Authenticate" Write-LogDebug "Authenticate"
if($global:MainAppStarted -eq $false)
{
$script:AppLogin = (Get-SettingValue "GraphAzureAppLogin") -or ($global:TenantId -and $global:AzureAppId -and ($global:ClientSecret -or $global:ClientCert))
}
if($script:AppLogin)
{
if($global:MSALToken -and $global:MSALToken.ExpiresOn.LocalDateTime.Ticks -gt ((Get-Date).AddMinutes(-5)).Ticks)
{
return
}
# Get login info for silent job from settings
if(-not $global:AzureAppId) { $global:AzureAppId = Get-SettingValue "GraphAzureAppId" -TenantID $global:TenantId }
if(-not $global:ClientSecret -and -not $global:ClientCert) { $global:ClientSecret = Get-SettingValue "GraphAzureAppSecret" -TenantID $global:TenantId }
if(-not $global:ClientSecret -and -not $global:ClientCert) { $global:ClientCert = Get-SettingValue "GraphAzureAppCert" -TenantID $global:TenantId }
if($global:AzureAppId -and $global:ClientSecret -and $global:TenantId)
{
Connect-MSALClientApp $global:AzureAppId $global:TenantId -secret $global:ClientSecret
}
elseif($global:AzureAppId -and $global:ClientCert -and $global:TenantId)
{
Connect-MSALClientApp $global:AzureAppId $global:TenantId -certificate $global:ClientCert
}
else
{
Write-Log "Azure AppId, Tenant Id and Sercret/Cert must be specified for App logins" 3
}
Invoke-MSALAuthenticationUpdated $global:MSALToken
return
}
if($ShowMenu -eq $true -and ((Get-SettingValue "AzureADLoginMenu") -eq $true)) if($ShowMenu -eq $true -and ((Get-SettingValue "AzureADLoginMenu") -eq $true))
{ {
if((Show-MSALLoginMenu) -eq $false) { return } if((Show-MSALLoginMenu) -eq $false) { return }
@@ -1065,6 +1156,8 @@ function Connect-MSALUser
else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) } else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) }
if($global:appObj.RedirectUri) { [void]$appBuilder.WithRedirectUri($global:appObj.RedirectUri) } if($global:appObj.RedirectUri) { [void]$appBuilder.WithRedirectUri($global:appObj.RedirectUri) }
Add-MSALProxy $appBuilder
$app = $appBuilder.Build() $app = $appBuilder.Build()
if((Get-SettingValue "CacheMSALToken")) if((Get-SettingValue "CacheMSALToken"))
@@ -1093,7 +1186,15 @@ function Connect-MSALUser
'ExpiresOn' = $tmpResults.ExpiresOn 'ExpiresOn' = $tmpResults.ExpiresOn
} }
$ret = Invoke-RestMethod "https://management.azure.com/tenants?api-version=2020-01-01" -Headers $Headers $params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$ret = Invoke-RestMethod "https://management.azure.com/tenants?api-version=2020-01-01" -Headers $Headers @params
if($ret) if($ret)
{ {
$script:AccessableTenants = $ret.Value $script:AccessableTenants = $ret.Value
@@ -1115,7 +1216,8 @@ function Connect-MSALUser
Save-Setting "" "LastLoggedOnUser" $authResult.Account.UserName Save-Setting "" "LastLoggedOnUser" $authResult.Account.UserName
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
} }
Invoke-MSALAuthenticationUpdated $authResult
<#
Write-LogDebug "User, tenant or app has changed" Write-LogDebug "User, tenant or app has changed"
Get-MSALUserInfo Get-MSALUserInfo
if($authResult) if($authResult)
@@ -1123,9 +1225,26 @@ function Connect-MSALUser
Invoke-MSALCheckObjectViewAccess $authResult Invoke-MSALCheckObjectViewAccess $authResult
} }
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated" Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
#>
} }
} }
function local:Invoke-MSALAuthenticationUpdated
{
param($authResult)
Write-LogDebug "User, tenant or app has changed"
$script:jwtAccessToken = Get-JWTtoken $global:MSALToken.AccessToken
$script:jwtIdToken = Get-JWTtoken $global:MSALToken.IdToken
Get-MSALUserInfo
if($authResult)
{
Invoke-MSALCheckObjectViewAccess $authResult
}
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
}
function Start-MSALConsentPrompt function Start-MSALConsentPrompt
{ {
param([switch]$PassThru, $authToken) param([switch]$PassThru, $authToken)
@@ -1202,6 +1321,22 @@ function Invoke-MSALCheckObjectViewAccess
Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Visible" Set-XamlProperty $script:userEllipsGrid "lnkRequestConsent" "Visibility" "Visible"
} }
$accessToken = $null
if($authToken)
{
$accessToken = Get-JWTtoken $authToken.AccessToken
}
$curPermissions = $null
if($accessToken.Payload.idtyp -eq "app")
{
$curPermissions = $accessToken.Payload.roles
}
elseif($accessToken.Payload.scp)
{
$curPermissions = $accessToken.Payload.scp.Split(" ")
}
foreach($viewObjInfo in ($global:viewObjects | Where { $_.ViewInfo.AuthenticationID -eq "MSAL" })) foreach($viewObjInfo in ($global:viewObjects | Where { $_.ViewInfo.AuthenticationID -eq "MSAL" }))
{ {
$viewObjInfo = $global:viewObjects | Where { $_.ViewInfo.Id -eq $global:EMViewObject.Id } $viewObjInfo = $global:viewObjects | Where { $_.ViewInfo.Id -eq $global:EMViewObject.Id }
@@ -1210,10 +1345,8 @@ function Invoke-MSALCheckObjectViewAccess
{ {
if($authToken) if($authToken)
{ {
$accessToken = Get-JWTtoken $authToken.AccessToken if($curPermissions)
if($accessToken.Payload.scp)
{ {
$curPermissions = $accessToken.Payload.scp.Split(" ")
foreach($viewItem in $viewObjInfo.ViewItems) foreach($viewItem in $viewObjInfo.ViewItems)
{ {
$full = 0 $full = 0
@@ -1511,6 +1644,10 @@ function Get-MSALProfileEllipse
{ {
$initials = "$($global:me.userPrincipalName[0])".ToUpper() $initials = "$($global:me.userPrincipalName[0])".ToUpper()
} }
elseif($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$initials = "APP"
}
$grd = Get-MSALUserPhotoEllips -size $size -fontSize $fontSize -Color $Color $grd = Get-MSALUserPhotoEllips -size $size -fontSize $fontSize -Color $Color
@@ -1534,8 +1671,15 @@ function Get-MSALProfileEllipse
$global:grdProfileInfo.Tag = $grd $global:grdProfileInfo.Tag = $grd
$grd.Tag = $global:grdProfileInfo $grd.Tag = $global:grdProfileInfo
Set-XamlProperty $global:grdProfileInfo "txtOrganization" "Text" $global:Organization.displayName Set-XamlProperty $global:grdProfileInfo "txtOrganization" "Text" $global:Organization.displayName
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" "App Login"
}
else
{
Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" $global:me.displayName Set-XamlProperty $global:grdProfileInfo "txtUsername" "Text" $global:me.displayName
Set-XamlProperty $global:grdProfileInfo "txtLogonName" "Text" $global:me.userPrincipalName Set-XamlProperty $global:grdProfileInfo "txtLogonName" "Text" $global:me.userPrincipalName
}
$global:tokenInfo = Get-JWTtoken $global:MSALToken.AccessToken $global:tokenInfo = Get-JWTtoken $global:MSALToken.AccessToken
if($global:tokenInfo) if($global:tokenInfo)
@@ -1560,12 +1704,19 @@ function Get-MSALProfileEllipse
$profileGrid.Children.Add($tmpObj) | Out-Null $profileGrid.Children.Add($tmpObj) | Out-Null
} }
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$tmpObj.Visibility = "Collapsed"
}
$global:grdProfileInfo.Add_Loaded({param($obj, $e) $global:grdProfileInfo.Add_Loaded({param($obj, $e)
$point = $obj.Tag.TransformToAncestor($window).Transform([System.Windows.Point]::new(0,0)); $point = $obj.Tag.TransformToAncestor($window).Transform([System.Windows.Point]::new(0,0));
[System.Windows.Controls.Canvas]::SetLeft($obj,($point.X - $obj.ActualWidth + $obj.Tag.ActualWidth)) [System.Windows.Controls.Canvas]::SetLeft($obj,($point.X - $obj.ActualWidth + $obj.Tag.ActualWidth))
[System.Windows.Controls.Canvas]::SetTop($obj,($point.Y + $obj.Tag.ActualHeight)) [System.Windows.Controls.Canvas]::SetTop($obj,($point.Y + $obj.Tag.ActualHeight))
}) })
if($script:jwtAccessToken.Payload.idtyp -ne "app")
{
######################################################################################################### #########################################################################################################
### Show / Hide consent button ### Show / Hide consent button
######################################################################################################### #########################################################################################################
@@ -1696,6 +1847,7 @@ function Get-MSALProfileEllipse
catch {} catch {}
} }
} }
}
######################################################################################################### #########################################################################################################
### Add event handling ### Add event handling
@@ -1756,6 +1908,11 @@ function Get-MSALProfileEllipse
Show-GraphObjects Show-GraphObjects
} }
} }
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
Set-XamlProperty $tmpObj "lnkLogout" "Visibility" "Collapsed"
}
} }
catch { catch {
Write-LogError "Failed to create profile information object. Error: " $_.Exception Write-LogError "Failed to create profile information object. Error: " $_.Exception
@@ -1931,12 +2088,21 @@ function Get-MSALMissingScopes
$script:missingPermissions = @() $script:missingPermissions = @()
if($script:jwtAccessToken.Payload.idtyp -eq "app")
{
$curScopes = $script:jwtAccessToken.Payload.roles
}
else
{
$curScopes = $authToken.Scopes
}
foreach($scope in $reqScopes) foreach($scope in $reqScopes)
{ {
$tmpScope = $scope.Split('/')[-1] $tmpScope = $scope.Split('/')[-1]
if($tmpScope -eq ".default") { continue } if($tmpScope -eq ".default") { continue }
if($authToken.Scopes -contains $tmpScope) { continue } if($curScopes -contains $tmpScope) { continue }
if(($authToken.Scopes -like "*/$tmpScope")) { continue } if(($curScopes -like "*/$tmpScope")) { continue }
$arrTemp = $tmpScope.Split(".") $arrTemp = $tmpScope.Split(".")
if($arrTemp[1] -eq "Read") if($arrTemp[1] -eq "Read")
{ {
@@ -1960,6 +2126,9 @@ function Show-MSALDecodedToken {
$tokenData, $tokenData,
$title $title
) )
if(-not $tokenData.Header) { return }
$tokenArr = @() $tokenArr = @()
foreach($prop in ($tokenData.Header | GM | Where MemberType -eq NoteProperty)) foreach($prop in ($tokenData.Header | GM | Where MemberType -eq NoteProperty))
{ {
+81 -5
View File
@@ -10,7 +10,7 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.9.0' '3.9.2'
} }
$global:MSGraphGlobalApps = @( $global:MSGraphGlobalApps = @(
@@ -183,6 +183,14 @@ function Invoke-InitializeModule
Description = "Certificate for Azure App" Description = "Certificate for Azure App"
}) "GraphSilent" }) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Login with App in UI (Preview)"
Key = "GraphAzureAppLogin"
Type = "Boolean"
DefaultValue = $false
Description = "Login with specified app in the UI. Note: Change will require app restart"
}) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Refresh Objects after copy" Title = "Refresh Objects after copy"
Key = "RefreshObjectsAfterCopy" Key = "RefreshObjectsAfterCopy"
@@ -214,6 +222,15 @@ function Invoke-InitializeModule
DefaultValue = $false DefaultValue = $false
Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info" Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info"
}) "GraphGeneral" }) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Use Graph 1.0 (Not Recommended)"
Key = "UseGraphV1"
Type = "Boolean"
DefaultValue = $false
Description = "This will use production verionof graph, v1.0. Note: Thot officially supported since this can have unpredicted results. Some parts will require Beta version of Graph."
}) "GraphGeneral"
} }
function Get-GraphAppInfo function Get-GraphAppInfo
@@ -270,7 +287,7 @@ function Invoke-SettingsUpdated
function Initialize-GraphSettings function Initialize-GraphSettings
{ {
$script:defaultVersion = ""
} }
function Invoke-GraphRequest function Invoke-GraphRequest
@@ -297,7 +314,7 @@ function Invoke-GraphRequest
$ODataMetadata = "full", # full, minimal, none or skip $ODataMetadata = "full", # full, minimal, none or skip
[ValidateSet("beta","v1.0")] [ValidateSet("beta","v1.0")]
$GraphVersion = "beta", $GraphVersion = "",
[switch] [switch]
$AllPages, $AllPages,
@@ -317,6 +334,22 @@ function Invoke-GraphRequest
Connect-MSALUser Connect-MSALUser
} }
if(-not $GraphVersion)
{
if(-not $script:defaultVersion)
{
if((Get-SettingValue "UseGraphV1") -eq $true)
{
$script:defaultVersion = "v1.0"
}
else
{
$script:defaultVersion = "beta"
}
}
$GraphVersion = $script:defaultVersion
}
$params = @{} $params = @{}
$requestId = [Guid]::NewGuid().guid $requestId = [Guid]::NewGuid().guid
@@ -394,6 +427,13 @@ function Invoke-GraphRequest
$url = "$($url.Trim())`$top=$($PageSize)" $url = "$($url.Trim())`$top=$($PageSize)"
} }
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$ret = $null $ret = $null
$retryCount = 0 $retryCount = 0
@@ -1028,6 +1068,12 @@ function Get-GraphMetaData
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$wc = New-Object System.Net.WebClient $wc = New-Object System.Net.WebClient
$wc.Encoding = [System.Text.Encoding]::UTF8 $wc.Encoding = [System.Text.Encoding]::UTF8
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$wc.Proxy = $proxyURI
}
try try
{ {
[xml]$global:metaDataXML = $wc.DownloadString($url) [xml]$global:metaDataXML = $wc.DownloadString($url)
@@ -1671,6 +1717,7 @@ function Show-GraphImportForm
$importedObjectsCurType = 0 $importedObjectsCurType = 0
$navigationPropObjects = @() $navigationPropObjects = @()
$arrImportedObjects = @()
foreach ($fileObj in $filesToImport) foreach ($fileObj in $filesToImport)
{ {
if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObject $fileObj $global:dgObjects.ItemsSource)) if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObject $fileObj $global:dgObjects.ItemsSource))
@@ -1686,9 +1733,15 @@ function Show-GraphImportForm
ImportedObject = $importedObj ImportedObject = $importedObj
} }
} }
$arrImportedObjects += $importedObj
$importedObjectsCurType++ $importedObjectsCurType++
} }
if($global:curObjectType.PostFilesImportCommand)
{
& $global:curObjectType.PostFilesImportCommand $global:curObjectType $arrImportedObjects $filesToImport
}
if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($global:curObjectType.Id)) if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($global:curObjectType.Id))
{ {
Write-Log "Remove $($global:curObjectType.Title) from dependency cache" Write-Log "Remove $($global:curObjectType.Title) from dependency cache"
@@ -1857,7 +1910,6 @@ function Show-GraphBulkImportForm
function Start-GraphObjectImport function Start-GraphObjectImport
{ {
Write-Status "Import objects" -Block Write-Status "Import objects" -Block
Write-Log "****************************************************************" Write-Log "****************************************************************"
Write-Log "Start bulk import" Write-Log "Start bulk import"
@@ -1907,6 +1959,8 @@ function Start-GraphObjectImport
$importedObjectsCurType = 0 $importedObjectsCurType = 0
$arrImportedObjects = @()
foreach ($fileObj in @($filesToImport)) foreach ($fileObj in @($filesToImport))
{ {
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType $objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
@@ -1930,11 +1984,17 @@ function Start-GraphObjectImport
ImportedObject = $importedObj ImportedObject = $importedObj
} }
} }
$arrImportedObjects = $importedObj
$importedObjects++ $importedObjects++
$importedObjectsCurType++ $importedObjectsCurType++
} }
if($item.ObjectType.PostFilesImportCommand)
{
& $item.ObjectType.PostFilesImportCommand $item.ObjectType $arrImportedObjects $filesToImport
}
if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($item.ObjectType.Id)) if($importedObjectsCurType -gt 0 -and $global:LoadedDependencyObjects -is [HashTable] -and $global:LoadedDependencyObjects.ContainsKey($item.ObjectType.Id))
{ {
Write-Log "Remove $($item.ObjectType.Title) from dependency cache" Write-Log "Remove $($item.ObjectType.Title) from dependency cache"
@@ -2230,6 +2290,11 @@ function Import-GraphFile
Import-GraphObjectAssignment $newObj $file.ObjectType $objClone.Assignments $file.FileInfo.FullName | Out-Null Import-GraphObjectAssignment $newObj $file.ObjectType $objClone.Assignments $file.FileInfo.FullName | Out-Null
} }
if($newObj)
{
$file | Add-Member -NotePropertyName "ImportedObject" -NotePropertyValue $newObj
}
if($PassThru -eq $true -and $newObj) if($PassThru -eq $true -and $newObj)
{ {
$newObj $newObj
@@ -2497,6 +2562,15 @@ function Set-ScopeTags
else { return } else { return }
$scopesIds = @() $scopesIds = @()
if($global:chkReplaceDependencyIDs.IsChecked -eq $false -and $global:chkReplaceDependencyIDs.IsEnabled -eq $false)
{
if($global:chkImportScopes.IsChecked -eq $true)
{
$scopesIds += $obj.$scopeTagProperty
}
}
else
{
$loadedScopeTags = $global:LoadedDependencyObjects["ScopeTags"] $loadedScopeTags = $global:LoadedDependencyObjects["ScopeTags"]
$usingDefault = (($obj."$scopeTagProperty" | measure).Count -eq 1 -and ($obj."$scopeTagProperty")[0] -eq "0") $usingDefault = (($obj."$scopeTagProperty" | measure).Count -eq 1 -and ($obj."$scopeTagProperty")[0] -eq "0")
if($loadedScopeTags -and $global:chkImportScopes.IsChecked -eq $true -and $usingDefault -eq $false -and $loadedScopeTags) if($loadedScopeTags -and $global:chkImportScopes.IsChecked -eq $true -and $usingDefault -eq $false -and $loadedScopeTags)
@@ -2516,6 +2590,8 @@ function Set-ScopeTags
} }
} }
} }
}
if($scopesIds.Count -eq 0) if($scopesIds.Count -eq 0)
{ {
$scopesIds += "0" # Import with Default ScopeTag as default. $scopesIds += "0" # Import with Default ScopeTag as default.
@@ -2961,7 +3037,7 @@ function Add-GraphDependencyObjects
{ {
if($global:LoadedDependencyObjects.ContainsKey($dep)) { continue } if($global:LoadedDependencyObjects.ContainsKey($dep)) { continue }
$depObjectType = $global:currentViewObject.ViewItems | Where Id -eq $Dep $depObjectType = $global:viewObjects.ViewItems | Where Id -eq $Dep
if(-not $depObjectType) if(-not $depObjectType)
{ {
+94
View File
@@ -1,4 +1,98 @@
# Release Notes # Release Notes
## 3.9.2 - 2023-10-17
**New features**
- **Application Content Export - Experimental**<br />
- Added support for Exporting Appliction with decrypted content<br />
App file can be downloaded during export or from the detail view of the Application<br />
Enable "Save Encryption File" and specify "App download folder" in Settings<br />
"App download folder" is used for encryption file and manual download<br />
File content will be downloaded to the export foler during export<br />
Files will be downloaded with .encrypted extension and then decrypted to original file name<br />
Please report any issue or any suggestions<br />
**NOTE:** This will ONLY work if the encryption file is exported and available<br />
- **Authentication**<br />
- Login with application<br />
This will login with specified Azure App ID and Secret/Certificate that is used for Batch processes<br />
NOTE: This will require a restart of the app<br />
Start with app **must** use -TenantID on command line. AppID and Secret/Certificate can be specified in Settings or command line<br />
Example: Start-IntuneManagement.ps1 -tenantId \"&lt;TenantID&gt;\" -appid \"&lt;AppID&gt;\" -secret \"&lt;Secret&gt;\"<br />
See *Start-WithApp.cmd* for samle file<br />
Based on [Issue 122](https://github.com/Micke-K/IntuneManagement/issues/122) and [Issue 134](https://github.com/Micke-K/IntuneManagement/issues/134)<br />
- **Support for new Settings**<br />
- Save encryption file - Saves a json file with encryption data when an application file is uploaded eg created or uploaded in details view<br />
- App download folder - Folder where application files should be downloaded and decrypted<br />
- Login with App in UI (Preview) - Use app batch login in UI<br />
- Use Graph 1.0 (Not Recommended) - Use Graph v1.0 instead of Beta. **Note:** Some features will NOT work in v1.0<br />
Based on [Issue 170](https://github.com/Micke-K/IntuneManagement/issues/170)<br />
**Fixes**
- **Documentation**<br />
- Language files re-generated eg Supersedence (preview) -> Supersedence<br />
- Added support for documenting "Filter for devices" info for Conditional Access policies<br />
Based on [Issue 168](https://github.com/Micke-K/IntuneManagement/issues/168)<br />
- **Custom ADMX Files**<br />
- Fixed issues with migrating custom policies between environments (3rd time)<br />
Based on [Issue 124](https://github.com/Micke-K/IntuneManagement/issues/124)<br />
- Fixed issue when importing ADMX files - Encoding issue eg ADMX/ADML file was UTF8<br />
Based on [Issue 169](https://github.com/Micke-K/IntuneManagement/issues/169)<br />
- **Importing Windows LoB Apps**<br />
- Fixed issue when importing LoB Apps that was only targeted to System context<br />
Available Assignment option was missing after import<br />
Based on [Discussion 164](https://github.com/Micke-K/IntuneManagement/discussions/164)<br />
- Added support for Depnedency and Supersedence reations at import<br />
Application will need to be re-exported since additinal data is added to the export file<br />
Based on [Discussion 159](https://github.com/Micke-K/IntuneManagement/discussions/159)<br />
- **Generic**<br />
- Fixed issue when compiling Procxy CS file<br />
- Tls 1.2 is now enforced.<br />
Based on [Discussion 166](https://github.com/Micke-K/IntuneManagement/discussions/166)<br />
<br />
## 3.9.1 - 2023-08-30
**New features**
- **Added support for Windows Update Driver Policies**<br />
- **Support for new Settings**<br />
- Proxy configuration - If configured, Proxy will be used for authentication, APIs and upload<br />
- Disable Write-Error output - Skip PowerShell errors in output<br />
**Default Settings Value Changes**
- Conditional Access policies will now be imported as Disabled by default<br />
- New import option added: As Exported - Change On to Report-only<br />
- This is to avoid being locked out from the tenant when importing Conditional Access policies<br />
- Based on [Discussion 139](https://github.com/Micke-K/IntuneManagement/discussions/139)<br />
**Fixes**
- **Documentation**<br />
- Fixed issues with some Feature Updates properties<br />
- Added missing strings on Windows Update polices<br />
- Regenerated Language files and Translation tables for Template policies<br />
Note: Conditional Access string has changed file in background. Please report if there is anything missing<br />
- **Custom ADMX Files**<br />
- Fixed issues with migrating custom policies between environments<br />
- Case reopened due to something broke the initial functionality<br />
- Only custom ADMX policies with #Definition properties can be imported into a new environment<br />
- Based on [Issue 124](https://github.com/Micke-K/IntuneManagement/issues/124)<br />
- **Scope Tags**<br />
- Fixed issues with importing policies with Scope Tags but they were not set<br />
- Based on [Issue 133](https://github.com/Micke-K/IntuneManagement/issues/133)<br />
**Generic**<br />
- Remove invalid characters from path.<br />
- Based on [Issue 150](https://github.com/Micke-K/IntuneManagement/issues/150)<br />
<br />
## 3.9.0 - 2023-05-04 ## 3.9.0 - 2023-05-04
**New features** **New features**
+1
View File
@@ -0,0 +1 @@
cmd /c powershell -version 5 -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -tenantId "<TenantID>" -appid "<AppID>" -secret "<Secret>"
+1 -1
View File
@@ -135,7 +135,7 @@
<Label Content="Current settings:" /> <Label Content="Current settings:" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Current property settings. Only updated when saved" /> <Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Current property settings. Only updated when saved" />
</StackPanel> </StackPanel>
<Label Name="lblObjectColumnsConfig" Content="" Margin="0,0,5,0" Grid.Row="3" /> <Label Name="lblObjectColumnsConfig" Content="" Margin="0,0,5,0" Grid.Row="3" Grid.ColumnSpan="2" />
<StackPanel Orientation="Horizontal" Grid.Column="1" Margin="5,5,5,0" Grid.Row="4" Grid.ColumnSpan="2" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" Grid.Column="1" Margin="5,5,5,0" Grid.Row="4" Grid.ColumnSpan="2" HorizontalAlignment="Right">
<Button Name="btnObjectColumnsReset" Content="Reset" Margin="0,0,5,0" Width="100" ToolTip="Revert all changes" /> <Button Name="btnObjectColumnsReset" Content="Reset" Margin="0,0,5,0" Width="100" ToolTip="Revert all changes" />