This commit is contained in:
Mikael Karlsson
2022-04-26 21:49:54 +10:00
parent 46435b5717
commit 4571341763
56 changed files with 101162 additions and 79376 deletions

Binary file not shown.

199
Core.psm1
View File

@@ -11,7 +11,40 @@ This module handles the WPF UI
function Get-ModuleVersion
{
'3.4.0'
'3.5.0'
}
function Initialize-Window
{
param($xamlFile)
try
{
[xml]$xaml = Get-Content $xamlFile
[xml]$styles = Get-Content ($global:AppRootFolder + "\Themes\Styles.xaml")
### Update relative path to full path for ResourceDictionary
[System.Xml.XmlNamespaceManager] $nsm = $xaml.NameTable;
$nsm.AddNamespace("s", 'http://schemas.microsoft.com/winfx/2006/xaml/presentation');
foreach($rsdNode in ($xaml.SelectNodes("//s:ResourceDictionary[@Source]", $nsm)))
{
$rsdNode.Source = (Join-Path ($global:AppRootFolder) ($rsdNode.Source)).ToString()
}
# Add Styles
foreach($node in $styles.DocumentElement.ChildNodes)
{
$tmpNode = $xaml.CreateElement("Temp")
$tmpNode.InnerXml = $node.OuterXml
$xaml.Window.'Window.Resources'.ResourceDictionary.AppendChild($tmpNode.Style) | Out-Null
}
return ([Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml)))
}
catch
{
Write-LogError "Failed to initialize window" $_.Exception
return
}
}
function Start-CoreApp
@@ -51,6 +84,23 @@ function Start-CoreApp
Write-Log "Application started"
Write-Log "#####################################################################################"
Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())"
Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())"
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())"
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)"
try
{
$osName = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "ProductName" -ErrorAction Stop
$patchLevel = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "UBR" -ErrorAction Stop
$ver = [Version]::new([Environment]::OSVersion.Version.Major,[Environment]::OSVersion.Version.Minor, [Environment]::OSVersion.Version.Build, $patchLevel)
Write-Log "OS: $osName $ver"
}
catch
{
Write-Log "OS version: $([environment]::OSVersion.VersionString)"
}
if(Test-Path $global:modulesPath)
{
Import-AllModules
@@ -98,6 +148,8 @@ function Start-CoreApp
Show-View $View
if((Get-SettingValue "CheckForUpdates") -eq $true) { Get-IsLatestVersion }
Invoke-ModuleFunction "Invoke-ShowMainWindow"
$global:txtSplashText.Text = "Open main window"
@@ -600,7 +652,6 @@ function Show-UpdatesDialog
Show-ModalObject
}
#Get-Module | Where Name -eq "Core"
$fileContent = Get-Content -Raw -Path ($global:AppRootFolder + "\ReleaseNotes.md")
try
{
@@ -614,14 +665,6 @@ function Show-UpdatesDialog
if($mystream) { $mystream.Dispose() }
}
<#
$latest = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest"
if($latest)
{
}
#>
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md"
if($content)
{
@@ -647,6 +690,102 @@ function Show-UpdatesDialog
Show-ModalForm "Release Notes" $script:dlgUpdates -HideButtons
}
function Get-IsLatestVersion
{
if($global:MainAppStarted -ne $true)
{
$global:txtSplashText.Text = "Check for updates"
[System.Windows.Forms.Application]::DoEvents()
}
$gitHubVer = $null
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest"
if($content.Name)
{
try
{
$gitHubVer = [version]$content.Name
}
catch {}
}
if($null -eq $gitHubVer)
{
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1"
$gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
$gitHubInfo = Get-ModuleDataTable $gitHubText
try
{
$gitHubVer = [version]$gitHubInfo.ModuleVersion
}
catch {}
}
if(-not $gitHubVer)
{
Write-log "Failed to get version info in GitHub" 2
return
}
$LocalInfo = $null
$localVer = $null
try
{
Import-LocalizedData -BindingVariable LocalInfo -BaseDirectory $global:AppRootFolder -FileName "CloudAPIPowerShellManagement.psd1" -ErrorAction Stop
$localVer = [version]$LocalInfo.ModuleVersion
}
catch { }
if(-not $localVer)
{
Write-log "Failed to get version info from local file" 2
return
}
if($localVer -lt $gitHubVer)
{
Write-Log "Local version and GitHub version does not match" 2
Write-Log "Local version: $($localVer.ToString())"
Write-Log "GitHub version: $($gitHubVer.ToString())"
[System.Windows.MessageBox]::Show("There is a new version available on GitHub $($gitHubVer.ToString())`n`nCurrent version is $($localVer.ToString())", "Old version!", "OK", "Warning")
}
else
{
Write-Log "Running latest version: $($localVer.ToString())"
}
}
function Get-ModuleDataTable
{
param($moduleText)
$result = $null
if(-not $moduleText) { return }
try
{
$Path = [IO.path]::ChangeExtension([IO.Path]::GetTempFileName(), "psd1")
$FI = [io.FileInfo]$path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($FI.FullName, $moduleText, $Utf8NoBomEncoding)
$Result = $null
Import-LocalizedData -BindingVariable Result -BaseDirectory $FI.DirectoryName -FileName $fi.Name
}
catch
{
}
finally
{
try { [IO.File]::Delete(([IO.path]::ChangeExtension($FI.FullName, "tmp"))) } catch {}
try { $FI.Delete() } catch{}
}
$Result
}
function Show-InputDialog
{
param(
@@ -654,7 +793,7 @@ function Show-InputDialog
$FormText,
$DefaultValue)
$script:inputBox = Get-XamlObject ($global:AppRootFolder + "\Xaml\InputDialog.xaml")
$script:inputBox = Initialize-Window ($global:AppRootFolder + "\Xaml\InputDialog.xaml")
if(-not $script:inputBox) { return }
$script:inputBox.Title = $FormTitle
@@ -672,6 +811,9 @@ function Show-InputDialog
$script:txtValue.Focus();
})
$inputBox.Owner = $global:window
$inputBox.Icon = $global:Window.Icon
$inputBox.ShowDialog() | Out-null
return $script:txtValue.Text
@@ -1674,7 +1816,7 @@ function Show-SettingsForm
}
}
foreach($section in $global:appSettingSections)
foreach($settingObj in $global:appSettingSections)
{
if(-not ($settingObj | Get-Member -MemberType NoteProperty -Name "Priority"))
{
@@ -1738,8 +1880,16 @@ function Add-DefaultSettings
Key = "PreviewFeatures"
Type = "Boolean"
DefaultValue = $false
Description = "Enable featurs that are marked as Preview. This might require a restart and prompt for consent"
Description = "Enable features that are marked as Preview. This might require a restart and prompt for consent"
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Check for updates"
Key = "CheckForUpdates"
Type = "Boolean"
DefaultValue = $true
Description = "Check GitHub if there is a later version available"
}) "General"
}
function Add-SettingsObject
@@ -1752,7 +1902,12 @@ function Add-SettingsObject
Write-Log "Could not find section $section" 3
return
}
$section.Values += $obj
try
{
$section.Values += $obj
}
catch { }
}
function Save-AllSettings
@@ -2168,10 +2323,10 @@ function Get-MainWindow
{
$window.Close()
}
}
}
Show-ModalForm $window.Title $script:welcomeForm -HideButtons
}
Show-ModalForm $window.Title $script:welcomeForm -HideButtons
}
})
foreach($view in $global:viewObjects)
@@ -2186,7 +2341,8 @@ function Get-MainWindow
}
})
$global:mnuViews.AddChild($subItem) | Out-Null
}
}
}
#endregion
@@ -2229,7 +2385,12 @@ function Get-JWTtoken
{
param($token)
if(-not $token -or -not $token.StartsWith("eyJ")) { Write-Log "Invalid token" 3; return }
if(-not $token) { return }
if(-not $token.StartsWith("eyJ"))
{
Write-Log "Invalid JWT token" 3; return
}
# First part is the header. Second part is the payload. Third part is the signature
$arr = $token.Split(".")

View File

@@ -413,6 +413,42 @@
"DeviceRestrictions"
]
},
{
"ObjectType": "#microsoft.graph.aospDeviceOwnerEnterpriseWiFiConfiguration",
"PolicyType": "AOSPDeviceOwnerWiFi",
"PolicyTypeLanguageId": "wiFi",
"PlatformLanguageId": "AndroidAOSP",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.aospDeviceOwnerTrustedRootCertificate",
"PolicyType": "AOSPDeviceOwnerTrustedCertificate",
"PolicyTypeLanguageId": "trustedCertificate",
"PlatformLanguageId": "AndroidAOSP",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.aospDeviceOwnerPkcsCertificateProfile",
"PolicyType": "AOSPDeviceOwnerPKCS",
"PolicyTypeLanguageId": "pkcsCertificate",
"PlatformLanguageId": "AndroidAOSP",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.aospDeviceOwnerScepCertificateProfile",
"PolicyType": "AOSPDeviceOwnerSCEP",
"PolicyTypeLanguageId": "scepCertificate",
"PlatformLanguageId": "AndroidAOSP",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.editionUpgradeConfiguration",
"PolicyType": "WindowsEditionUpgrade",
@@ -1114,6 +1150,15 @@
"Win10Wifi"
]
},
{
"ObjectType": "#microsoft.graph.windowsWiredNetworkConfiguration",
"PolicyType": "Windows10WiredNetwork",
"PolicyTypeLanguageId": "wiredNetwork",
"PlatformLanguageId": "Windows10",
"Categories": [
]
},
{
"ObjectType": "#microsoft.graph.windowsWifiEnterpriseEAPConfiguration",
"PolicyType": "Windows10WiFi",
@@ -1320,5 +1365,23 @@
"Categories": [
]
},
{
"ObjectType": "settingsCatalogLinux",
"PolicyType": "SettingsCatalogLinux",
"PolicyTypeLanguageId": "settingsCatalog",
"PlatformLanguageId": "Linux",
"Categories": [
]
},
{
"ObjectType": "settingsCatalogIOS",
"PolicyType": "SettingsCatalogIOS",
"PolicyTypeLanguageId": "settingsCatalog",
"PlatformLanguageId": "Ios",
"Categories": [
]
}
]

View File

@@ -244,7 +244,7 @@
"enabled": true
}
],
"entityKey": "frontCameras",
"entityKey": "frontCamera",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -276,7 +276,7 @@
"enabled": true
}
],
"entityKey": "rearCameras",
"entityKey": "rearCamera",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -308,7 +308,7 @@
"enabled": true
}
],
"entityKey": "infraredCameras",
"entityKey": "infraredCamera",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -372,7 +372,7 @@
"enabled": true
}
],
"entityKey": "microphones",
"entityKey": "microphone",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -484,7 +484,7 @@
"enabled": true
}
],
"entityKey": "wwan",
"entityKey": "wirelessWideAreaNetwork",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -516,7 +516,7 @@
"enabled": true
}
],
"entityKey": "nfc",
"entityKey": "nearFieldCommunication",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",
@@ -548,7 +548,7 @@
"enabled": true
}
],
"entityKey": "wifi",
"entityKey": "wiFi",
"booleanActions": 0,
"defaultValue": "notConfigured",
"unconfiguredValue": "notConfigured",

View File

@@ -198,6 +198,32 @@
"policyType": 9,
"enabled": true
},
{
"dataType": 19,
"category": 41,
"nameResourceKey": "wiFiPolicyConnectAutomaticallyName",
"descriptionResourceKey": "wiFiPolicyConnectAutomaticallyDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "enableOption",
"value": true,
"enabled": true
},
{
"nameResourceKey": "disableOption",
"value": false,
"enabled": true
}
],
"entityKey": "connectAutomatically",
"booleanActions": 0,
"defaultValue": false,
"policyType": 9,
"enabled": true
},
{
"dataType": 19,
"category": 41,

View File

@@ -0,0 +1,471 @@
{
"pkcs_aospdeviceownerpkcs": [
{
"dataType": 14,
"category": 88,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
],
"options": [
],
"entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 88,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"dataType": 20,
"category": 88,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 121,
"enabled": true
},
{
"dataType": 20,
"category": 88,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 121,
"enabled": true
},
{
"dataType": 20,
"category": 88,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "certificateTemplateName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 121,
"enabled": true
},
{
"dataType": 16,
"category": 88,
"nameResourceKey": "pKCSPolicyCertificationAuthorityType",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "1",
"childSettings": [
],
"options": [
{
"nameResourceKey": "MicrosoftCA",
"value": "Microsoft",
"enabled": true
},
{
"nameResourceKey": "DigiCertCA",
"value": "DigiCert",
"enabled": true
}
],
"entityKey": "certificationAuthorityType",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"dataType": 16,
"category": 88,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 88,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"dataType": 20,
"category": 88,
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 121,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 88,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 88,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
}
],
"dataType": 21,
"category": 88,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 88,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"dataType": 20,
"category": 88,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 121,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 88,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 88,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
}
],
"dataType": 21,
"category": 88,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "user",
"policyType": 121,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 88,
"nameResourceKey": "eDPPolicyAppsListNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 88,
"nameResourceKey": "sCEPPolicyObjectIdentifierColumnName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "objectIdentifier",
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
}
],
"dataType": 21,
"category": 88,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageName",
"descriptionResourceKey": "sCEPPolicyExtendedKeyUsageDescription",
"childSettings": [
],
"options": [
],
"entityKey": "extendedKeyUsages",
"booleanActions": 0,
"policyType": 121,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 88,
"nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificate",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 121,
"enabled": true
}
],
"dataType": 5,
"category": 88,
"nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 121,
"enabled": true
}
]
}

View File

@@ -0,0 +1,612 @@
{
"scepproperties_aospdeviceownerscep": [
{
"dataType": 16,
"category": 96,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 96,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 20,
"category": 96,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 122,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 96,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 96,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
}
],
"dataType": 21,
"category": 96,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 96,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 20,
"category": 96,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 122,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 96,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 96,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
}
],
"dataType": 21,
"category": 96,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "user",
"policyType": 122,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 96,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 16,
"category": 96,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCommonName",
"value": "commonName",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCommonNameAndEmailAddress",
"value": "commonNameIncludingEmail",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCommonNameAsEmail",
"value": "commonNameAsEmail",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCommonNameAsIMEI",
"value": "commonNameAsIMEI",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCommonNameAsSerialNumber",
"value": "commonNameAsSerialNumber",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicySubjectNameFormatCustom",
"value": "custom",
"children": [
{
"dataType": 20,
"category": 96,
"nameResourceKey": "sCEPPolicySubjectNameFormatCustom",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 122,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 13,
"category": 96,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"emptyValueResourceKey": "notConfigured",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
}
],
"entityKey": "subjectAlternativeNameType",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 13,
"category": 96,
"nameResourceKey": "sCEPPolicyKeyUsageName",
"descriptionResourceKey": "sCEPPolicyKeyUsageDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "sCEPPolicyUseAsDigitialSignature",
"value": "digitalSignature",
"enabled": true
},
{
"nameResourceKey": "sCEPPolicyUseForKeyEncipherment",
"value": "keyEncipherment",
"enabled": true
}
],
"entityKey": "keyUsage",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 16,
"category": 96,
"nameResourceKey": "sCEPPolicyKeySizeName",
"descriptionResourceKey": "sCEPPolicyKeySizeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "",
"displayText": "1024",
"value": "size1024",
"enabled": true
},
{
"nameResourceKey": "",
"displayText": "2048",
"value": "size2048",
"enabled": true
}
],
"entityKey": "keySize",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 13,
"category": 96,
"nameResourceKey": "sCEPPolicyHashAlgorithmName",
"descriptionResourceKey": "sCEPPolicyHashAlgorithmDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "sCEPPPolicySHA1",
"value": "sha1",
"enabled": true
},
{
"nameResourceKey": "sCEPPPolicySHA2",
"value": "sha2",
"enabled": true
}
],
"entityKey": "hashAlgorithm",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 96,
"nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificate",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 122,
"enabled": true
}
],
"dataType": 5,
"category": 96,
"nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 96,
"nameResourceKey": "eDPPolicyAppsListNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 96,
"nameResourceKey": "sCEPPolicyObjectIdentifierColumnName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "objectIdentifier",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
}
],
"dataType": 21,
"category": 96,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageName",
"descriptionResourceKey": "sCEPPolicyExtendedKeyUsageDescription",
"childSettings": [
],
"options": [
],
"entityKey": "extendedKeyUsages",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 96,
"nameResourceKey": "enrollmentSettingsHeading",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"dataType": 14,
"category": 96,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
],
"options": [
],
"entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 122,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 96,
"nameResourceKey": "sCEPPolicyServerURLName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "sCEPPolicyServerURLSExample",
"childSettings": [
],
"options": [
],
"entityKey": "sCEPPolicyServerURLName",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
}
],
"dataType": 21,
"category": 96,
"nameResourceKey": "sCEPPolicyServerURLSName",
"descriptionResourceKey": "sCEPPolicyServerURLSDescription",
"childSettings": [
],
"options": [
],
"entityKey": "scepServerUrls",
"booleanActions": 0,
"policyType": 122,
"enabled": true
}
]
}

View File

@@ -31,57 +31,57 @@
"enabled": true
},
{
"displayText": "Never timeout",
"nameResourceKey": "timeoutNever",
"value": 0,
"enabled": true
},
{
"displayText": "1 minute",
"nameResourceKey": "timeoutOneMinute",
"value": 1,
"enabled": true
},
{
"displayText": "2 minutes",
"nameResourceKey": "timeoutTwoMinutes",
"value": 2,
"enabled": true
},
{
"displayText": "3 minutes",
"nameResourceKey": "timeoutThreeMinutes",
"value": 3,
"enabled": true
},
{
"displayText": "5 minutes",
"nameResourceKey": "timeoutFiveMinutes",
"value": 5,
"enabled": true
},
{
"displayText": "10 minutes",
"nameResourceKey": "timeoutTenMinutes",
"value": 10,
"enabled": true
},
{
"displayText": "15 minutes",
"nameResourceKey": "timeoutFifteenMinutes",
"value": 15,
"enabled": true
},
{
"displayText": "30 minutes",
"nameResourceKey": "timeoutThirtyMinutes",
"value": 30,
"enabled": true
},
{
"displayText": "1 hour",
"nameResourceKey": "timeoutOneHour",
"value": 60,
"enabled": true
},
{
"displayText": "2 hours",
"nameResourceKey": "timeoutTwoHours",
"value": 120,
"enabled": true
},
{
"displayText": "4 hours",
"nameResourceKey": "timeoutFourHours",
"value": 240,
"enabled": true
}
@@ -105,57 +105,57 @@
"enabled": true
},
{
"displayText": "Never timeout",
"nameResourceKey": "timeoutNever",
"value": 0,
"enabled": true
},
{
"displayText": "1 minute",
"nameResourceKey": "timeoutOneMinute",
"value": 1,
"enabled": true
},
{
"displayText": "2 minutes",
"nameResourceKey": "timeoutTwoMinutes",
"value": 2,
"enabled": true
},
{
"displayText": "3 minutes",
"nameResourceKey": "timeoutThreeMinutes",
"value": 3,
"enabled": true
},
{
"displayText": "5 minutes",
"nameResourceKey": "timeoutFiveMinutes",
"value": 5,
"enabled": true
},
{
"displayText": "10 minutes",
"nameResourceKey": "timeoutTenMinutes",
"value": 10,
"enabled": true
},
{
"displayText": "15 minutes",
"nameResourceKey": "timeoutFifteenMinutes",
"value": 15,
"enabled": true
},
{
"displayText": "30 minutes",
"nameResourceKey": "timeoutThirtyMinutes",
"value": 30,
"enabled": true
},
{
"displayText": "1 hour",
"nameResourceKey": "timeoutOneHour",
"value": 60,
"enabled": true
},
{
"displayText": "2 hours",
"nameResourceKey": "timeoutTwoHours",
"value": 120,
"enabled": true
},
{
"displayText": "4 hours",
"nameResourceKey": "timeoutFourHours",
"value": 240,
"enabled": true
}
@@ -179,57 +179,57 @@
"enabled": true
},
{
"displayText": "Never timeout",
"nameResourceKey": "timeoutNever",
"value": 0,
"enabled": true
},
{
"displayText": "1 minute",
"nameResourceKey": "timeoutOneMinute",
"value": 1,
"enabled": true
},
{
"displayText": "2 minutes",
"nameResourceKey": "timeoutTwoMinutes",
"value": 2,
"enabled": true
},
{
"displayText": "3 minutes",
"nameResourceKey": "timeoutThreeMinutes",
"value": 3,
"enabled": true
},
{
"displayText": "5 minutes",
"nameResourceKey": "timeoutFiveMinutes",
"value": 5,
"enabled": true
},
{
"displayText": "10 minutes",
"nameResourceKey": "timeoutTenMinutes",
"value": 10,
"enabled": true
},
{
"displayText": "15 minutes",
"nameResourceKey": "timeoutFifteenMinutes",
"value": 15,
"enabled": true
},
{
"displayText": "30 minutes",
"nameResourceKey": "timeoutThirtyMinutes",
"value": 30,
"enabled": true
},
{
"displayText": "1 hour",
"nameResourceKey": "timeoutOneHour",
"value": 60,
"enabled": true
},
{
"displayText": "2 hours",
"nameResourceKey": "timeoutTwoHours",
"value": 120,
"enabled": true
},
{
"displayText": "4 hours",
"nameResourceKey": "timeoutFourHours",
"value": 240,
"enabled": true
}

View File

@@ -0,0 +1,20 @@
{
"trustedcert_aospdeviceownertrustedcertificate": {
"dataEntityKey": "trustedRootCertificate",
"filenameEntityKey": "certFileName",
"dataType": 1,
"category": 108,
"nameResourceKey": "trustedCertPolicySelectCertificateName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "trustedRootCertificate",
"booleanActions": 0,
"policyType": 123,
"enabled": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -167,7 +167,7 @@
"dataType": 20,
"category": 121,
"nameResourceKey": "domainsInList",
"descriptionResourceKey": "empty",
"descriptionResourceKey": "searchDomainsDescriptionWithHint",
"emptyValueResourceKey": "vPNPolicyTrustedNetworkDomainExample",
"childSettings": [
@@ -350,7 +350,7 @@
"dataType": 20,
"category": 121,
"nameResourceKey": "domainsInList",
"descriptionResourceKey": "empty",
"descriptionResourceKey": "searchDomainsDescription",
"emptyValueResourceKey": "vPNPolicyTrustedNetworkDomainExample",
"childSettings": [
@@ -474,7 +474,7 @@
"dataType": 20,
"category": 121,
"nameResourceKey": "domainsOptional",
"descriptionResourceKey": "empty",
"descriptionResourceKey": "connectIfNeededDomainsDescription",
"emptyValueResourceKey": "vPNPolicyTrustedNetworkDomainExample",
"childSettings": [
@@ -508,8 +508,8 @@
"metadata": {
"dataType": 20,
"category": 121,
"nameResourceKey": "dNSSearchDomainsName",
"descriptionResourceKey": "empty",
"nameResourceKey": "anyDNSAddressesInList",
"descriptionResourceKey": "connectIfNeededDNSListDescription",
"emptyValueResourceKey": "proxyAddressExample",
"childSettings": [
@@ -540,7 +540,7 @@
{
"dataType": 20,
"category": 121,
"nameResourceKey": "probeUrlOptionalDescription",
"nameResourceKey": "probeUrlOptionalName",
"descriptionResourceKey": "probeUrlOptionalDescription",
"emptyValueResourceKey": "probeUrlOptionalExample",
"childSettings": [
@@ -695,7 +695,7 @@
"dataType": 20,
"category": 121,
"nameResourceKey": "domainsInList",
"descriptionResourceKey": "empty",
"descriptionResourceKey": "searchDomainsDescription",
"emptyValueResourceKey": "vPNPolicyTrustedNetworkDomainExample",
"childSettings": [

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -20,11 +20,13 @@ $global:documentationProviders = @()
function Get-ModuleVersion
{
'1.1.0'
'1.2.0'
}
function Invoke-InitializeModule
{
$script:alwaysUseMigTableForTranslation = $false
# Make sure we add the default Output types
Add-OutputType
@@ -43,14 +45,20 @@ function Invoke-InitializeModule
Schedule="ScheduledAction.List.schedule"
MessageTemplate="ScheduledAction.Notification.messageTemplate"
EmailCC="ScheduledAction.Notification.additionalRecipients"
Filter="AssignmentFilters.assignmentFilterColumnHeader"
Rule="ApplicabilityRules.GridLabel.Rule"
ValueWithLabel="TableHeaders.value"
Status="TableHeaders.status"
CombinedValueWithLabel="TableHeaders.value"
CombinedValue="TableHeaders.value"
useDeviceLicensing="TableHeaders.licenseType"
#filterMode="Filter mode" # Not in any string file yet
Filter="AppResources.AppSettingsUx.assignmentFilterColumnHeader"
filterMode="AppResources.AppSettingsUx.assignmentFilterTypeColumnHeader"
deliveryOptimizationPriority="AppResources.AppSettingsUx.deliveryOptimizationPriorityHeader"
startTimeColumnLabel="AppResources.AppSettingsUx.startTimeColumnLabel"
installTimeSettings="AppResources.AppSettingsUx.deadlineTimeColumnLabel"
restartSettings="AppResources.AppSettingsUx.restartGracePeriodHeader"
notifications="AppResources.AppSettingsUx.assignmentToast"
Settings="TableHeaders.settings"
}
}
@@ -199,7 +207,7 @@ function Get-ObjectDocumentation
$status = $null
$inputType = "Settings"
if(-not $script:scopeTags)
if(-not $script:scopeTags -and $script:offlineDocumentation -ne $true)
{
$script:scopeTags = (Invoke-GraphRequest -Url "/deviceManagement/roleScopeTags").Value
}
@@ -209,7 +217,7 @@ function Get-ObjectDocumentation
$script:currentObject = $obj
$script:languageStrings = $null
$script:CurrentSubCategory = $null
$script:objectBasicInfo = @()
$script:objectSettingsData = @()
@@ -587,19 +595,68 @@ function Add-BasicAdditionalValues
if($obj.createdDateTime)
{
$tmpDate = ([DateTime]::Parse($obj.createdDateTime))
Add-BasicPropertyValue (Get-LanguageString "Inputs.createdDateTime") "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
try
{
if($obj.createdDateTime -is [DateTime])
{
$tmpDate = $obj.createdDateTime
}
else
{
$tmpDate = ([DateTime]::Parse($obj.createdDateTime))
}
$tmpDateStr = "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
}
catch
{
Write-Log "Failed to parse date from $($obj.createdDateTime) (Object type: $($obj.createdDateTime.GetType().Name))" 2
$tmpDateStr = $obj.createdDateTime
}
Add-BasicPropertyValue (Get-LanguageString "Inputs.createdDateTime") $tmpDateStr
}
if($obj.lastModifiedDateTime)
{
$tmpDate = ([DateTime]::Parse($obj.lastModifiedDateTime))
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.lastModified") "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
try
{
if($obj.lastModifiedDateTime -is [DateTime])
{
$tmpDate = $obj.lastModifiedDateTime
}
else
{
$tmpDate = ([DateTime]::Parse($obj.lastModifiedDateTime))
}
$tmpDateStr = "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
}
catch
{
Write-Log "Failed to parse date from $($obj.lastModifiedDateTime) (Object type: $($obj.lastModifiedDateTime.GetType().Name))" 2
$tmpDateStr = $obj.lastModifiedDateTime
}
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.lastModified") $tmpDateStr
}
elseif($obj.modifiedDateTime)
{
$tmpDate = ([DateTime]::Parse($obj.modifiedDateTime))
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.lastModified") "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
try
{
if($obj.modifiedDateTime -is [DateTime])
{
$tmpDate = $obj.modifiedDateTime
}
else
{
$tmpDate = ([DateTime]::Parse($obj.modifiedDateTime))
}
$tmpDateStr = "$($tmpDate.ToLongDateString()) $($tmpDate.ToLongTimeString())"
}
catch
{
Write-Log "Failed to parse date from $($obj.modifiedDateTime) (Object type: $($obj.modifiedDateTime.GetType().Name))" 2
$tmpDateStr = $obj.modifiedDateTime
}
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.lastModified") $tmpDateStr
}
if($obj.version)
@@ -1829,7 +1886,11 @@ function Invoke-TranslateSection
$useParentProp = $true
# Use $script:currentObject since $obj could be a property on the original object
# Cert links are always specified on the main object
$cert = Invoke-GraphRequest -URL $script:currentObject."$($prop.entityKey)@odata.navigationLink" -ODataMetadata "minimal" -NoError
$cert = $null
if($script:offlineDocumentation -ne $true)
{
$cert = Invoke-GraphRequest -URL $script:currentObject."$($prop.entityKey)@odata.navigationLink" -ODataMetadata "minimal" -NoError
}
if($cert)
{
if($cert.value -is [Object[]])
@@ -1849,7 +1910,22 @@ function Invoke-TranslateSection
}
elseif($script:currentObject.'@ObjectFromFile' -eq $true)
{
$value = "##TBD - Linked Certificate"
if($script:currentObject."#CustomRef_$($prop.entityKey)")
{
$idx = $script:currentObject."#CustomRef_$($prop.entityKey)".IndexOf("|:|")
if($idx -gt -1)
{
$value = $script:currentObject."#CustomRef_$($prop.entityKey)".SubString(0,$idx)
}
else
{
$value = $script:currentObject."#CustomRef_$($prop.entityKey)"
}
}
else
{
$value = "##TBD - Linked Certificate"
}
$rawValue = $value
}
}
@@ -2242,6 +2318,17 @@ function Get-CustomChildObject
return $obj
}
function Invoke-InitDocumentation
{
foreach($docProvider in ($global:documentationProviders | Sort -Property Priority))
{
if($docProvider.InitializeDocumentation)
{
& $docProvider.InitializeDocumentation
}
}
}
function Add-CustomProfileProperties
{
param($obj)
@@ -2900,7 +2987,7 @@ function Invoke-TranslateAssignments
$groupInfo = $null
if($groupIds.Count -gt 0)
if($groupIds.Count -gt 0 -and $script:offlineDocumentation -ne $true)
{
$ht = @{}
$ht.Add("ids", @($groupIds | Unique))
@@ -2913,26 +3000,40 @@ function Invoke-TranslateAssignments
if(($null -eq $groupInfo -or ($groupInfo | measure).Count -eq 0) -and $obj."@ObjectFromFile" -eq $true -and $script:migTable)
{
### Get group info from mig table when documenting from file if there's no access to the environment
$groupInfo = $script:migTable.Objects | Where Type -eq "Group"
$groupInfo = $script:migTable.Objects | Where Type -eq "Group"
}
if($filterIds.Count -gt 0)
{
$batchInfo = @{}
$requests = @()
#{"requests":[{"id":"<FilterID>","method":"GET","url":"deviceManagement/assignmentFilters/<FilterID>?$select=displayName"}]}
foreach($filterId in $filterIds)
{
if($script:offlineDocumentation -eq $true)
{
$requests += [PSCustomObject]@{
id = $filterIds
method = "GET"
"url" = "deviceManagement/assignmentFilters/$($filterId)?`$select=displayName"
if($script:offlineObjects["AssignmentFilters"])
{
$filtersInfo = $script:offlineObjects["AssignmentFilters"] | Where { $_.Id -in $filterIds }
}
else
{
Write-Log "No assignment filters loaded for Offline documentation. Check export folder" 2
}
}
$batchInfo = @{"requests"=$requests}
$jsonBody = $batchInfo | ConvertTo-Json
else
{
$batchInfo = @{}
$requests = @()
#{"requests":[{"id":"<FilterID>","method":"GET","url":"deviceManagement/assignmentFilters/<FilterID>?$select=displayName"}]}
foreach($filterId in $filterIds)
{
$requests += [PSCustomObject]@{
id = $filterId
method = "GET"
"url" = "deviceManagement/assignmentFilters/$($filterId)?`$select=displayName"
}
}
$batchInfo = @{"requests"=$requests}
$jsonBody = $batchInfo | ConvertTo-Json
$filtersInfo = Invoke-GraphRequest -Url "/`$batch" -Content $jsonBody -Method "Post"
$filtersInfo = (Invoke-GraphRequest -Url "/`$batch" -Content $jsonBody -Method "Post").responses.body
}
}
foreach($assignment in $obj.assignments)
@@ -2987,12 +3088,12 @@ function Invoke-TranslateAssignments
$filterName = $noFilter
$filterMode = $noFilter
if($assignment.target.deviceAndAppManagementAssignmentFilterId -and $filtersInfo.responses)
if($assignment.target.deviceAndAppManagementAssignmentFilterId -and $filtersInfo)
{
$filtersObj = $filtersInfo.responses | Where Id -eq $assignment.target.deviceAndAppManagementAssignmentFilterId
if($filtersObj.body.displayName)
$filtersObj = $filtersInfo | Where Id -eq $assignment.target.deviceAndAppManagementAssignmentFilterId
if($filtersObj.displayName)
{
$filterName = $filtersObj.body.displayName
$filterName = $filtersObj.displayName
}
if($assignment.target.deviceAndAppManagementAssignmentFilterType -eq "include")
@@ -3037,6 +3138,66 @@ function Invoke-TranslateAssignments
$value = Get-LanguageString "SettingDetails.licenseTypeUser"
}
}
elseif($settingProp -eq "restartSettings" -and $null -eq $assignment.settings.$settingProp)
{
$value = Get-LanguageString "SettingDetails.disabledOption"
}
elseif($settingProp -eq "notifications")
{
$value = ?? (Get-LanguageString "AppResources.AssignmentToast.$($assignment.settings.$settingProp)") $assignment.settings.$settingProp
}
elseif($settingProp -eq "installTimeSettings")
{
$asap = Get-LanguageString "Assignment.SoftwareInstallationTime.defaultTime"
$startValue = $asap
$value = $asap
if($assignment.settings.installTimeSettings)
{
if($assignment.settings.installTimeSettings.startDateTime)
{
$instTime = Get-Date $assignment.settings.installTimeSettings.startDateTime
if($assignment.settings.installTimeSettings.useLocalTime -eq $false)
{
$hours = ($instTime.ToUniversalTime() - $instTime).Hours
$instTime = $instTime.AddHours($hours)
}
$startValue = "$($instTime.ToShortDateString()) $($instTime.ToShortTimeString())"
}
if($assignment.settings.installTimeSettings.deadlineDateTime)
{
$endTime = Get-Date $assignment.settings.installTimeSettings.deadlineDateTime
if($assignment.settings.installTimeSettings.useLocalTime -eq $false)
{
$hours = ($endTime.ToUniversalTime() - $endTime).Hours
$endTime = $endTime.AddHours($hours)
}
$value = "$($instTime.ToShortDateString()) $($instTime.ToShortTimeString())"
}
}
$assignmentSettingProps.Add("startTimeColumnLabel", $startValue)
}
elseif($settingProp -eq "deliveryOptimizationPriority")
{
$tmpStr = Get-LanguageString "AppResources.DeliveryOptimizationPriority.displayText"
if($assignment.settings.$settingProp -ne "foreground")
{
$tmpType = Get-LanguageString "AppResources.DeliveryOptimizationPriority.backgroundNormal"
}
else
{
$tmpType = Get-LanguageString "AppResources.DeliveryOptimizationPriority.foreground"
}
$value = $tmpStr -f $tmpType
}
elseif($assignment.settings.$settingProp -eq "notConfigured")
{
$value = Get-LanguageString "BooleanActions.notConfigured"
}
else
{
$value = $assignment.settings.$settingProp
@@ -3389,6 +3550,9 @@ function Show-DocumentationForm
$txtDocumentationRawData.Text = ""
$script:offlineDocumentation = $false
$script:offlineObjects = @{}
$loadExportedInfo = $true
$script:migTable = $null
$script:scopeTags = $null
@@ -3421,6 +3585,8 @@ function Show-DocumentationForm
Get-CustomIgnoredCategories $obj
Invoke-InitDocumentation
if($global:grdDocumentObjects.Tag -eq "Objects")
{
$sourceList = @()
@@ -3532,21 +3698,20 @@ function Show-DocumentationForm
$script:migTable = ConvertFrom-Json (Get-Content $migFileName -Raw)
}
$scopeTagObjectType = $global:currentViewObject.ViewItems | Where Id -eq "ScopeTags"
if($scopeTagObjectType)
if($script:migTable.TenantId -and $script:migTable.TenantId -ne $global:organization.id)
{
$scopePath = [IO.Path]::Combine($diSource.FullName,$scopeTagObjectType.Id)
if([IO.Directory]::Exists($scopePath) -eq $false)
$script:offlineDocumentation = $true
}
if($script:offlineDocumentation -eq $true)
{
Add-DocOfflineDependecies "ScopeTags" $diSource.FullName
Add-DocOfflineDependecies "AssignmentFilters" $diSource.FullName
Add-DocOfflineObjectTypeDependecies $diSource.FullName
if($script:offlineObjects.ContainsKey("ScopeTags"))
{
Write-Log "Object path for Scope (Tags) ($($scopePath)) not found" 2
}
else
{
$scopeTagObjects = Get-GraphFileObjects $scopePath -ObjectType $scopeTagObjectType
$script:scopeTags = @(($scopeTagObjects | Select Object))
}
$script:scopeTags = @($script:offlineObjects["ScopeTags"])
}
}
}
@@ -3723,7 +3888,7 @@ function Show-DocumentationForm
}
}
}
}
}
}
if($allObjectTypeObjects.Count -gt 0)
@@ -3745,7 +3910,13 @@ function Show-DocumentationForm
Write-Status "Run PostProcess for $($global:cbDocumentationType.SelectedItem.Name)"
& $global:cbDocumentationType.SelectedItem.PostProcess
}
if($script:offlineDocumentation -eq $true)
{
# Clear the dependecy objects loaded for Offline documentation
$global:LoadedDependencyObjects = $null
}
$script:offlineDocumentation = $false
Write-Status ""
}
@@ -3797,6 +3968,18 @@ function Show-DocumentationForm
Show-ModalForm "Intune Documentation" $script:docForm -HideButtons
}
function Get-DocOfflineObjects
{
param($objectName)
if($script:offlineDocumentation -eq $false) { return }
if($script:offlineObjects.ContainsKey($objectName))
{
$script:offlineObjects[$objectName]
}
}
function Set-OutputOptionsTabStatus
{
param($control)
@@ -3828,6 +4011,42 @@ function Invoke-DocumentSelectedObjects
Show-DocumentationForm -objects $script:selectedObjects -SelectedDocuments
}
function Add-DocOfflineObjectTypeDependecies
{
param($fromFolder)
foreacH($viewItem in $global:currentViewObject.ViewItems)
{
foreach($dep in $viewItem.Dependencies)
{
Add-DocOfflineDependecies $dep $fromFolder
}
}
}
function Add-DocOfflineDependecies
{
param($objectTypeName, $fromFolder)
if($script:offlineObjects.ContainsKey($objectTypeName)) { return }
$tmpObjType = $global:currentViewObject.ViewItems | Where Id -eq $objectTypeName
if($tmpObjType)
{
$objPath = [IO.Path]::Combine($fromFolder,$tmpObjType.Id)
if([IO.Directory]::Exists($objPath) -eq $false)
{
Write-Log "Object path for $($tmpObjType.Title) ($($objPath)) not found" 2
}
else
{
$tmpObjects = Get-GraphFileObjects $objPath -ObjectType $tmpObjType
$script:offlineObjects.Add($tmpObjType.Id, @(($tmpObjects | Select Object).Object))
}
}
}
function Add-DocumentationObjects
{
param($objects)

View File

@@ -10,7 +10,7 @@ This module will also document some objects based on PowerShell functions
function Get-ModuleVersion
{
'1.1.0'
'1.2.0'
}
function Invoke-InitializeModule
@@ -18,6 +18,7 @@ function Invoke-InitializeModule
Add-DocumentationProvicer ([PSCustomObject]@{
Name="Custom"
Priority = 1000 # The priority of the Provider. Lower number has higher priority.
InitializeDocumentation = { Initialize-CDDocumentation @args }
DocumentObject = { Invoke-CDDocumentObject @args }
GetCustomProfileValue = { Add-CDDocumentCustomProfileValue @args }
GetCustomChildObject = { Get-CDDocumentCustomChildObjet @args }
@@ -27,6 +28,12 @@ function Invoke-InitializeModule
})
}
function Initialize-CDDocumentation
{
$script:allTenantApps = $null
$script:allTermsOfUse = $null
}
function Invoke-CDDocumentObject
{
param($documentationObj)
@@ -42,6 +49,13 @@ function Invoke-CDDocumentObject
Properties = @("Name","Value","Category","SubCategory") #,"RawValue","Description"
}
}
elseif($type -eq '#microsoft.graph.agreement')
{
Invoke-CDDocumentTermsOfUse $documentationObj
return [PSCustomObject]@{
Properties = @("Name","Value") #,"RawValue","Description"
}
}
elseif($type -eq '#microsoft.graph.countryNamedLocation')
{
Invoke-CDDocumentCountryNamedLocation $documentationObj
@@ -116,7 +130,7 @@ function Get-CDAllCloudApps
{
if(-not $script:allCloudApps)
{
$script:allCloudApps =(Invoke-GraphRequest -url "/servicePrincipals?`$select=displayName,appId&top=999" -ODataMetadata "minimal").value
$script:allCloudApps = (Invoke-GraphRequest -url "/servicePrincipals?`$select=displayName,appId&top=999" -ODataMetadata "minimal").value
}
$script:allCloudApps
}
@@ -125,7 +139,11 @@ function Get-CDAllTenantApps
{
if(-not $script:allTenantApps)
{
$script:allTenantApps =(Invoke-GraphRequest -url "/deviceAppManagement/mobileApps?`$select=displayName,id&top=999" -ODataMetadata "minimal").value
$script:allTenantApps = Get-DocOfflineObjects "Applications"
if(-not $script:allTenantApps)
{
$script:allTenantApps =(Invoke-GraphRequest -url "/deviceAppManagement/mobileApps?`$select=displayName,id&top=999" -ODataMetadata "minimal").value
}
}
$script:allTenantApps
}
@@ -750,13 +768,26 @@ function Add-CDDocumentCustomProfileProperty
{
if($obj.authenticationMethod -ne "derivedCredential")
{
$idCert = Invoke-GraphRequest -URL $obj."identityCertificateForClientAuthentication@odata.navigationLink" -ODataMetadata "minimal" -NoError
if($obj."#CustomRef_identityCertificateForClientAuthentication" -and $obj.'@ObjectFromFile' -eq $true)
{
$idCert = $obj."#CustomRef_identityCertificateForClientAuthentication"
$idx = $idCert.IndexOf("|:|")
if($idx -gt -1)
{
$idCertType = $idCert.SubString($idx + 3)
}
}
else
{
$idCert = Invoke-GraphRequest -URL $obj."identityCertificateForClientAuthentication@odata.navigationLink" -ODataMetadata "minimal" -NoError
$idCertType = $idCert.'@OData.Type'
}
if($idCert.'@OData.Type' -like "*Pkcs*")
if($idCertType -like "*Pkcs*")
{
$clientCertType = "PKCS certificate"
}
elseif($idCert.'@OData.Type' -like "*SCEP*")
elseif($idCertType -like "*SCEP*")
{
$clientCertType = "SCEP certificate"
}
@@ -1102,6 +1133,7 @@ function Add-CDDocumentCustomProfileProperty
$supersededApps = @()
if($obj.dependentAppCount -gt 0 -or $obj.supersededAppCount -gt 0)
{
# ToDo: Add support for Offline documentation
$relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value
foreach($rel in $relationships)
{
@@ -1187,6 +1219,11 @@ function Add-CDDocumentCustomProfileProperty
}
}
elseif($obj.'@OData.Type' -eq "#microsoft.graph.windows10TeamGeneralConfiguration")
{
$obj | Add-Member Noteproperty -Name "syntheticAzureOperationalInsightsEnabled" -Value ($obj.azureOperationalInsightsBlockTelemetry -eq $false)
$obj | Add-Member Noteproperty -Name "syntheticMaintenanceWindowEnabled" -Value ($obj.maintenanceWindowBlocked -eq $false)
}
if(($obj.PSObject.Properties | where Name -eq "securityRequireSafetyNetAttestationBasicIntegrity") -and
($obj.PSObject.Properties | where Name -eq "securityRequireSafetyNetAttestationCertifiedDevice"))
@@ -1478,7 +1515,7 @@ function Invoke-CDDocumentCountryNamedLocation
$countryList = @()
foreach($country in $obj.countriesAndRegions)
{
$countryList += Get-LanguageString "Countries.$($country.ToLower())"
$countryList += Get-LanguageString "AzureIAMCommon.CountryNames.countryName$($country.ToLower())"
}
Add-CustomSettingObject ([PSCustomObject]@{
@@ -1525,6 +1562,117 @@ function Invoke-CDDocumentIPNamedLocation
})
}
# Document Terms of Use
function Invoke-CDDocumentTermsOfUse
{
param($documentationObj)
$obj = $documentationObj.Object
$objectType = $documentationObj.ObjectType
$script:objectSeparator = ?? $global:cbDocumentationObjectSeparator.SelectedValue ([System.Environment]::NewLine)
$script:propertySeparator = ?? $global:cbDocumentationPropertySeparator.SelectedValue ","
$offLabel = Get-LanguageString "SettingDetails.offOption"
$onLabel = Get-LanguageString "SettingDetails.onOption"
###################################################
# Basic info
###################################################
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.menuItemTermsOfUse")
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.agreementIsViewingBeforeAcceptanceRequiredLabel"
Value = ?: $obj.isViewingBeforeAcceptanceRequired $onLabel $offLabel
Category = $null
SubCategory = $null
EntityKey = "isViewingBeforeAcceptanceRequired"
})
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.agreementIsPerDeviceAcceptanceRequiredLabel"
Value = ?: $obj.isPerDeviceAcceptanceRequired $onLabel $offLabel
Category = $null
SubCategory = $null
EntityKey = "isPerDeviceAcceptanceRequired"
})
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.isAcceptanceExpirationEnabledLabel"
Value = ?: $obj.termsExpiration $onLabel $offLabel
Category = $null
SubCategory = $null
EntityKey = "isAcceptanceExpirationEnabledLabel"
})
if($obj.termsExpiration.startDateTime)
{
try
{
if($obj.termsExpiration.startDateTime -is [DateTime])
{
$tmpDate = $obj.termsExpiration.startDateTime
}
else
{
$tmpDate = ([DateTime]::Parse($obj.termsExpiration.startDateTime))
}
$tmpDateStr = ($tmpDate).ToShortDateString()
}
catch
{
Write-Log "Failed to parse date from string $($obj.termsExpiration.startDateTime)" 2
$tmpDateStr = $obj.termsExpiration.startDateTime
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.acceptanceExpirationStartDateTimeLabel"
Value = $tmpDateStr
Category = $null
SubCategory = $null
EntityKey = "startDateTime"
})
if($obj.termsExpiration.frequency -eq "P365D")
{
$value = Get-LanguageString "TermsOfUse.AcceptanceExpirationFrequency.annually"
}
elseif($obj.termsExpiration.frequency -eq "P180D")
{
$value = Get-LanguageString "TermsOfUse.AcceptanceExpirationFrequency.biannually"
}
elseif($obj.termsExpiration.frequency -eq "P30D")
{
$value = Get-LanguageString "TermsOfUse.AcceptanceExpirationFrequency.monthly"
}
elseif($obj.termsExpiration.frequency -eq "P90D")
{
$value = Get-LanguageString "TermsOfUse.AcceptanceExpirationFrequency.quarterly"
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.acceptanceExpirationFrequencyLabel"
Value = $value
Category = $null
SubCategory = $null
EntityKey = "frequency"
})
}
if($null -ne $obj.userReacceptRequiredFrequency)
{
$days = Get-DurationValue $obj.userReacceptRequiredFrequency
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "TermsOfUse.Wizard.acceptanceDurationLabel"
Value = $days
Category = $null
SubCategory = $null
EntityKey = "userReacceptRequiredFrequency"
})
}
}
# Document Conditional Access policy
function Invoke-CDDocumentConditionalAccess
{
@@ -1540,7 +1688,9 @@ function Invoke-CDDocumentConditionalAccess
# Basic info
###################################################
Add-BasicDefaultValues $obj $objectType
#Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") $obj.displayName
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "AzureIAM.conditionalAccessBladeTitle")
if($obj.state -eq "enabledForReportingButNotEnforced")
{
@@ -1590,6 +1740,7 @@ function Invoke-CDDocumentConditionalAccess
$body = $ht | ConvertTo-Json
# ToDo: Get from MigFile for Offline
$idInfo = (Invoke-GraphRequest -Url "/directoryObjects/getByIds?`$select=displayName,id" -Content $body -Method "Post").Value
}
@@ -1719,6 +1870,7 @@ function Invoke-CDDocumentConditionalAccess
$idObj = $idInfo | Where Id -eq $id
$tmpObjs += ?? $idObj.displayName $id
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = $category
Value = $tmpObjs -join $script:objectSeparator
@@ -1916,8 +2068,12 @@ function Invoke-CDDocumentConditionalAccess
if(-not $script:allNamedLocations -and ($obj.conditions.locations.includeLocations.Count -gt 0 -or $obj.conditions.locations.excludeLocations.Count))
{
# Might be better to get them one by one
$script:allNamedLocations = (Invoke-GraphRequest -url "/identity/conditionalAccess/namedLocations?`$select=displayName,Id&top=999" -ODataMetadata "minimal").value
$script:allNamedLocations = Get-DocOfflineObjects "NamedLocations"
if(-not $script:allNamedLocations)
{
# Might be better to get them one by one
$script:allNamedLocations = (Invoke-GraphRequest -url "/identity/conditionalAccess/namedLocations?`$select=displayName,Id&top=999" -ODataMetadata "minimal").value
}
if(-not $script:allNamedLocations) { $script:allNamedLocations = @()}
elseif($script:allNamedLocations -isnot [Object[]]) { $script:allNamedLocations = @($script:allNamedLocations) }
@@ -1927,6 +2083,17 @@ function Invoke-CDDocumentConditionalAccess
}
}
if(-not $script:allTermsOfUse -and (($obj.grantControls.termsOfUse | measure).Count -gt 0))
{
$script:allTermsOfUse = Get-DocOfflineObjects "TermsOfUse"
if(-not $script:allTermsOfUse)
{
$script:allTermsOfUse = (Invoke-GraphRequest -url "/identityGovernance/termsOfUse/agreements?`$select=displayName,Id&top=999" -ODataMetadata "minimal").value
}
if(-not $script:allTermsOfUse ) { $script:allTermsOfUse = @()}
elseif($script:allTermsOfUse -isnot [Object[]]) { $script:allTermsOfUse = @($script:allTermsOfUse ) }
}
if($obj.conditions.locations.includeLocations.Count -gt 0)
{
$tmpObjs = @()
@@ -2056,82 +2223,103 @@ function Invoke-CDDocumentConditionalAccess
EntityKey = "policyControl"
})
if(($obj.grantControls.builtInControls | Where { $_ -eq "block"}))
if($null -eq (($obj.grantControls.builtInControls | Where { $_ -eq "block"}) ))
{
if(($obj.grantControls.builtInControls | Where { $_ -eq "mfa"}))
if(($obj.grantControls.builtInControls | measure).Count -gt 0)
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlMfaChallengeDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "mfa"
})
if(($obj.grantControls.builtInControls | Where { $_ -eq "mfa"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlMfaChallengeDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "mfa"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantDevice"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlCompliantDeviceDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "compliantDevice"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "domainJoinedDevice"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireDomainJoinedDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "domainJoinedDevice"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "approvedApplication"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireMamDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "approvedApplication"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantApplication"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireCompliantAppDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "compliantApplication"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "passwordChange"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequiredPasswordChangeDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "passwordChange"
})
}
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantDevice"}))
if(($obj.grantControls.termsOfUse | measure).Count -gt 0)
{
$termsOfUse = @()
foreach($tmpId in $obj.grantControls.termsOfUse)
{
$touObj = $script:allTermsOfUse | Where Id -eq $tmpId
$termsOfUse += ?? $touObj.displayName $tmpId
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlCompliantDeviceDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Name = Get-LanguageString "AzureIAM.menuItemTermsOfUse"
Value = $termsOfUse -join $script:objectSeparator
Category = $category
SubCategory = ""
EntityKey = "compliantDevice"
})
EntityKey = "termsOfUse"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "domainJoinedDevice"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireDomainJoinedDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "domainJoinedDevice"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "approvedApplication"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireMamDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "approvedApplication"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "compliantApplication"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequireCompliantAppDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "compliantApplication"
})
}
if(($obj.grantControls.builtInControls | Where { $_ -eq "passwordChange"}))
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.policyControlRequiredPasswordChangeDisplayedName"
Value = Get-LanguageString "Inputs.enabled"
Category = $category
SubCategory = ""
EntityKey = "passwordChange"
})
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "AzureIAM.descriptionContentForControlsAndOr"
Value = Get-LanguageString "AzureIAM.$((?: ($obj.grantControls.operator -eq "OR") "requireOneControlText" "requireAllControlsText"))"
Category = $category
SubCategory = ""
EntityKey = "grantOperator"
})
}
})
}
###################################################
# Session
@@ -2644,12 +2832,11 @@ function Invoke-CDDocumentAssignmentFilter
$label = Get-LanguageString "ApplicabilityRules.GridLabel.rule"
# "Rules" is not in the translation file
$category = "Rules"
$category = Get-LanguageString "SettingDetails.rules"
Add-CustomSettingObject ([PSCustomObject]@{
Name = $label
Value = $obj.rule
Value = $obj.rule
EntityKey = "rule"
Category = $category
SubCategory = $null

View File

@@ -3,7 +3,7 @@
#https://docs.microsoft.com/en-us/office/vba/api/overview/word
function Get-ModuleVersion
{
'1.1.0'
'1.2.0'
}
function Invoke-InitializeModule
@@ -31,32 +31,7 @@ function Invoke-InitializeModule
Process = { Invoke-WordProcessItem @args }
PostProcess = { Invoke-WordPostProcessItems @args }
ProcessAllObjects = { Invoke-WordProcessAllObjects @args }
})
$script:columnHeaders = @{
Name="Inputs.displayNameLabel"
Value="TableHeaders.value"
Description="TableHeaders.description"
GroupMode="SettingDetails.modeTableHeader" #assignmentTypeSelectionLabel?
Group="TableHeaders.assignedGroups"
Groups="TableHeaders.groups"
useDeviceContext="SettingDetails.installContextLabel"
uninstallOnDeviceRemoval="SettingDetails.UninstallOnRemoval"
isRemovable="SettingDetails.installAsRemovable"
vpnConfigurationId="PolicyType.vpn"
Action="SettingDetails.actionColumnName"
Schedule="ScheduledAction.List.schedule"
MessageTemplate="ScheduledAction.Notification.messageTemplate"
EmailCC="ScheduledAction.Notification.additionalRecipients"
Filter="AssignmentFilters.assignmentFilterColumnHeader"
Rule="ApplicabilityRules.GridLabel.Rule"
ValueWithLabel="TableHeaders.value"
Status="TableHeaders.status"
CombinedValueWithLabel="TableHeaders.value"
CombinedValue="TableHeaders.value"
useDeviceLicensing="TableHeaders.licenseType"
#filterMode="Filter mode" # Not in any string file yet
}
})
}
function Add-WordOptionsControl
@@ -90,6 +65,11 @@ function Add-WordOptionsControl
$global:txtWordTableHeaderStyle.Text = Get-Setting "Documentation" "WordTableHeaderStyle" ""
$global:txtWordCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordCategoryHeaderStyle" ""
$global:txtWordSubCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordSubCategoryHeaderStyle" ""
$global:txtWordTableTextStyle.Text = Get-Setting "Documentation" "WordTableTextStyle" ""
$global:cbWordTableCaptionPosition.ItemsSource = ("[ { Name: `"Above`",Value: `"above`" }, { Name: `"Below`",Value: `"below`" }]" | ConvertFrom-Json)
$global:cbWordTableCaptionPosition.SelectedValue = (Get-Setting "Documentation" "WordTableCaptionPosition" "below")
$global:txtWordContentControls.Text = Get-Setting "Documentation" "WordContentControls" "Year=;Address="
$global:txtWordTitleProperty.Text = Get-Setting "Documentation" "WordTitleProperty" "Intune documentation"
$global:txtWordSubjectProperty.Text = Get-Setting "Documentation" "WordSubjectProperty" "Intune documentation"
@@ -152,6 +132,9 @@ function Invoke-WordPreProcessItems
Save-Setting "Documentation" "WordTableHeaderStyle" $global:txtWordTableHeaderStyle.Text
Save-Setting "Documentation" "WordCategoryHeaderStyle" $global:txtWordCategoryHeaderStyle.Text
Save-Setting "Documentation" "WordSubCategoryHeaderStyle" $global:txtWordSubCategoryHeaderStyle.Text
Save-Setting "Documentation" "WordTableTextStyle" $global:txtWordTableTextStyle.Text
Save-Setting "Documentation" "WordTableCaptionPosition" $global:cbWordTableCaptionPosition.SelectedValue
Save-Setting "Documentation" "WordContentControls" $global:txtWordContentControls.Text
Save-Setting "Documentation" "WordTitleProperty" $global:txtWordTitleProperty.Text
Save-Setting "Documentation" "WordSubjectProperty" $global:txtWordSubjectProperty.Text
@@ -470,7 +453,7 @@ function Set-WordContentControlText
}
else
{
Write-Log "No ContentControl found with name $controlName" 2
#Write-Log "No ContentControl found with name $controlName" 2
}
}
catch
@@ -521,12 +504,12 @@ function Invoke-WordProcessItem
foreach($prop in $global:txtWordCustomProperties.Text.Split(","))
{
# This will add language support for custom columens (or replacing existing header)
# This will add language support for custom columns (or replacing existing header)
$propInfo = $prop.Split('=')
if(($propInfo | measure).Count -gt 1)
{
$properties += $propInfo[0]
Set-WordColumnHeaderLanguageId $propInfo[0] $propInfo[1]
Set-DocColumnHeaderLanguageId $propInfo[0] $propInfo[1]
}
else
{
@@ -574,9 +557,12 @@ function Invoke-WordProcessItem
if(($documentedObj.Assignments | measure).Count -gt 0)
{
$params = @{}
$settingProps = $null
if($documentedObj.Assignments[0].RawIntent)
{
$properties = @("GroupMode","Group","Filter","FilterMode")
$settingProps = @("Filter","FilterMode")
$settingsObj = $documentedObj.Assignments | Where { $_.Settings -ne $null } | Select -First 1
@@ -586,7 +572,7 @@ function Invoke-WordProcessItem
{
if($objProp -in $properties) { continue }
if($objProp -in @("Category","RawIntent")) { continue }
$properties += ("Settings." + $objProp)
$settingProps += ("Settings." + $objProp)
}
}
}
@@ -609,7 +595,14 @@ function Invoke-WordProcessItem
$params.Add("AddCategories", $true)
}
# Creates a standard assignments table
Add-DocTableItems $obj $objectType $documentedObj.Assignments $properties "TableHeaders.assignments" @params
if($null -ne $settingProps)
{
# Adds additional values to the assignments table for Apps assignments
Set-DocTableSettingsItems $obj $objectType $documentedObj.Assignments $settingProps 3
}
}
if($global:chkWordAttatchJsonFile.IsChecked -eq $true)
@@ -632,6 +625,44 @@ function Invoke-WordProcessItem
}
}
function Set-DocTableSettingsItems
{
param($obj, $objectType, $items, $properties, $firstColumn)
$secondColumn = $firstColumn + 1
$script:docTable.Cell(1, $firstColumn).Range.Text = (Invoke-WordTranslateColumnHeader "Settings")
$script:docTable.Cell(1, $secondColumn).Range.Text = ""
$row = 2
foreach($itemObj in $items)
{
$script:docTable.Cell($row, $firstColumn).Range.Text = ""
$script:docTable.Cell($row, $secondColumn).Range.Text = ""
$script:docTable.Cell($row, $firstColumn).Split($properties.Count,1)
$script:docTable.Cell($row, $secondColumn).Split($properties.Count,1)
$cellRow = $row
foreach($settingProp in $properties)
{
$script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-WordTranslateColumnHeader ($settingProp.Split('.')[-1]))
$propArr = $settingProp.Split('.')
$tmpObj = $itemObj
$propName = $propArr[-1]
for($x = 0; $x -lt ($propArr.Count - 1);$x++)
{
$tmpObj = $tmpObj."$($propArr[$x])"
}
$script:docTable.Cell($cellRow, $secondColumn).Column.Cells($cellRow).Range.Text = "$($tmpObj.$propName)"
$cellRow++
}
$row = $row + $properties.Count
}
}
function Invoke-WordProcessAllObjects
{
param($allObjectTypeObjects)
@@ -671,54 +702,32 @@ function Invoke-WordProcessAllObjects
}
}
function Invoke-WordTranslateColumnHeader
{
param($columnName)
$lngText = ""
if($script:columnHeaders.ContainsKey($columnName))
{
$lngText = Get-LanguageString $script:columnHeaders[$columnName]
}
(?? $lngText $columnName)
}
function Invoke-WordCustomProcessItems
{
param($obj, $documentedObj)
}
function Set-WordColumnHeaderLanguageId
{
param($columnName, $lngId)
if(-not $script:columnHeaders -or -not $lngId) { return }
if($script:columnHeaders.ContainsKey($columnName))
{
$script:columnHeaders[$columnName] = $lngId
}
else
{
$script:columnHeaders.Add($columnName, $lngId)
}
}
function Add-DocTableItems
{
param($obj, $objectType, $items, $properties, $lngId, [switch]$AddCategories, [switch]$AddSubcategories, $captionOverride, [switch]$forceFullValue)
if(($items | measure).Count -eq 0)
{
return
}
$tblHeaderStyle = $global:txtWordTableHeaderStyle.Text
$tblCategoryStyle = $global:txtWordCategoryHeaderStyle.Text
$tblSubCategoryStyle = $global:txtWordSubCategoryHeaderStyle.Text
$tblTextStyle = $global:txtWordTableTextStyle.Text
$txtTableCaptionPosition = $global:cbWordTableCaptionPosition.SelectedValue
$range = $script:doc.application.selection.range
$script:docTable = $script:doc.Tables.Add($range, ($items.Count + 1), $properties.Count, [Microsoft.Office.Interop.Word.WdDefaultTableBehavior]::wdWord9TableBehavior, [Microsoft.Office.Interop.Word.WdAutoFitBehavior]::wdAutoFitWindow)
$script:docTable.ApplyStyleHeadingRows = $true
Set-DocObjectStyle $script:docTable $global:txtWordTableStyle.Text
Set-DocObjectStyle $script:docTable $global:txtWordTableStyle.Text | Out-null
if($captionOverride)
{
@@ -736,7 +745,7 @@ function Add-DocTableItems
$i = 1
foreach($prop in $properties)
{
$script:docTable.Cell(1, $i).Range.Text = (Invoke-WordTranslateColumnHeader ($prop.Split(".")[-1]))
$script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1]))
$i++
}
@@ -816,6 +825,8 @@ function Add-DocTableItems
}
$i++
}
Set-DocObjectStyle $script:docTable.Rows($row).Range $tblTextStyle
if($itemObj.Category -and $curCategory -ne $itemObj.Category -and $AddCategories -eq $true)
{
@@ -857,13 +868,22 @@ function Add-DocTableItems
$row++
}
# -2 = Table, 1 = Below
$script:docTable.Application.Selection.InsertCaption(-2, ". $caption", $null, 1)
# -2 = Table caption, 1 = Below / 0 = Above
if($txtTableCaptionPosition -eq "above")
{
$capPos = 0
}
else
{
$capPos = 1
}
$script:docTable.Application.Selection.InsertCaption(-2, ". $caption", $null, $capPos)
Invoke-DocGoToEnd
# Add new row after the table
#$script:doc.Application.Selection.InsertParagraphAfter()
$script:doc.Application.Selection.TypeParagraph()
#$script:doc.Application.Selection.TypeParagraph()
}
function Add-DocTableScript

View File

@@ -11,7 +11,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
#>
function Get-ModuleVersion
{
'3.4.0'
'3.5.0'
}
function Invoke-InitializeModule
@@ -86,7 +86,7 @@ function Invoke-InitializeModule
ID="IntuneGraphAPI"
ViewPanel = $viewPanel
AuthenticationID = "MSAL"
ItemChanged = { Show-GraphObjects; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""}
ItemChanged = { Show-GraphObjects -ObjectTypeChanged; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""}
Deactivating = { Invoke-EMDeactivateView }
Activating = { Invoke-EMActivatingView }
Authentication = (Get-MSALAuthenticationObject)
@@ -112,6 +112,7 @@ function Invoke-InitializeModule
PostCopyCommand = { Start-PostCopyDeviceConfiguration @args }
PostGetCommand = { Start-PostGetDeviceConfiguration @args }
GroupId = "DeviceConfiguration"
NavigationProperties=$true
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -124,6 +125,8 @@ function Invoke-InitializeModule
GroupId = "ConditionalAccess"
ImportExtension = { Add-ConditionalAccessImportExtensions @args }
PreImportCommand = { Start-PreImportConditionalAccess @args }
PostExportCommand = { Start-PostExportConditionalAccess @args }
ExpandAssignmentsList = $false
})
if((Get-SettingValue "PreviewFeatures" $false) -eq $true)
@@ -150,6 +153,7 @@ function Invoke-InitializeModule
Permissons=@("Policy.ReadWrite.ConditionalAccess")
ImportOrder = 50
GroupId = "ConditionalAccess"
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -226,6 +230,7 @@ function Invoke-InitializeModule
SkipRemoveProperties = @('Id')
GroupId = "Azure"
SkipAddIDOnExport = $true
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -340,6 +345,7 @@ function Invoke-InitializeModule
PostExportCommand = { Start-PostExportTermsAndConditions @args }
PreImportAssignmentsCommand = { Start-PreImportAssignmentsTermsAndConditions @args }
GroupId = "TenantAdmin"
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -359,6 +365,7 @@ function Invoke-InitializeModule
Permissons=@("DeviceManagementApps.ReadWrite.All")
Dependencies = @("Applications")
GroupId = "AppProtection"
ExpandAssignmentsList = $false
})
# These are also included in the managedAppPolicies API
@@ -377,6 +384,7 @@ function Invoke-InitializeModule
Dependencies = @("Applications")
Icon = "AppConfiguration"
GroupId = "AppConfiguration"
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -400,6 +408,7 @@ function Invoke-InitializeModule
ViewID = "IntuneGraphAPI"
PropertiesToRemove = @('uploadState','publishingState','isAssigned','dependentAppCount','supersedingAppCount','supersededAppCount','committedContentVersion','isFeatured','size','categories')
QUERYLIST = "`$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName"
QuerySearch=$true
Permissons=@("DeviceManagementApps.ReadWrite.All")
AssignmentsType="mobileAppAssignments"
AssignmentProperties = @("@odata.type","target","settings","intent")
@@ -437,10 +446,12 @@ function Invoke-InitializeModule
PreImportAssignmentsCommand = { Start-PreImportAssignmentsPolicySets @args }
PreImportCommand = { Start-PreImportPolicySets @args }
PreUpdateCommand = { Start-PreUpdatePolicySets @args }
PostListCommand = { Start-PostListPolicySets @args }
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
ImportOrder = 2000 # Policy Sets reference other objects so make sure it is imported last
Dependencies = @("Applications","AppConfiguration","AppProtection","AutoPilot","EnrollmentRestrictions","EnrollmentStatusPage","DeviceConfiguration","AdministrativeTemplates","SettingsCatalog","CompliancePolicies")
GroupId = "PolicySets"
ExpandAssignmentsList = $false # expand is not allowed, IsAssigned is set in PostListCommand
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -485,6 +496,8 @@ function Invoke-InitializeModule
# Property that needs to be updated on the Compliance Policy
# deviceManagement/managementConditionStatements/$obj.conditionStatementId
# Location objects support removed from Intune
<#
Add-ViewItem (New-Object PSObject -Property @{
Title = "Locations"
Id = "Locations"
@@ -495,6 +508,7 @@ function Invoke-InitializeModule
ImportOrder = 30
GroupId = "CompliancePolicies"
})
#>
Add-ViewItem (New-Object PSObject -Property @{
Title = "Settings Catalog"
@@ -526,6 +540,8 @@ function Invoke-InitializeModule
#expand=roleassignments
PropertiesToRemoveForUpdate = @('isBuiltInRoleDefinition','isBuiltIn','roleAssignments') ### !!! ToDo: Add support for roleAssignments
GroupId = "TenantAdmin"
ExpandAssignments = $false
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -539,6 +555,7 @@ function Invoke-InitializeModule
ImportOrder = 10
DocumentAll = $true
GroupId = "TenantAdmin"
ExpandAssignmentsList = $false # Adds the assignmnets property but always empty
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -554,6 +571,7 @@ function Invoke-InitializeModule
PostCopyCommand = { Start-PostCopyNotifications @args }
PropertiesToRemoveForUpdate = @('defaultLocale','localizedNotificationMessages') ### !!! ToDo: Add support for localizedNotificationMessages
GroupId = "CompliancePolicies"
ExpandAssignmentsList = $false
})
# This has some pre-reqs for working!
@@ -593,6 +611,7 @@ function Invoke-InitializeModule
ImportOrder = 15
GroupId = "TenantAdmin"
PropertiesToRemoveForUpdate = @('platform')
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -749,19 +768,34 @@ function Set-EMViewPanel
$btnRefresh.SetValue([System.Windows.Controls.Grid]::ColumnProperty,$grdTitle.ColumnDefinitions.Count - 1)
$btnRefresh.Margin = "0,0,5,3"
$btnRefresh.Cursor = "Hand"
$btnRefresh.Name = "btnRefresh"
$btnRefresh.Focusable = $false
$grdTitle.Children.Add($btnRefresh) | Out-Null
$tooltip = [System.Windows.Controls.ToolTip]::new()
$tooltip.Content = "Refresh"
$tooltip.Content = "Refresh all objects"
[System.Windows.Controls.ToolTipService]::SetToolTip($btnRefresh, $tooltip)
$panel.RegisterName($btnRefresh.Name, $btnRefresh)
$tooltip = [System.Windows.Controls.ToolTip]::new()
$tooltip.Content = "Refresh objects"
[System.Windows.Controls.ToolTipService]::SetToolTip($btnRefresh, $tooltip)
$btnRefresh.Add_Click({
# ToDo: Move this to view view object
$txtFilterText = $null
$txtFilter = $this.Parent.FindName("txtFilter")
if($txtFilter) { $txtFilter.Text = "" }
if($txtFilter) { $txtFilterText = $txtFilter.Text } #= "" }
Show-GraphObjects
Show-GraphObjects $txtFilterText
if($txtFilterText -and $txtFilter)
{
$txtFilter.Text = $txtFilterText
Invoke-FilterBoxChanged $txtFilter
}
Write-Status ""
})
}
@@ -782,11 +816,29 @@ function Set-EMViewPanel
$graphObjects | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
$global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate
Invoke-FilterBoxChanged $global:txtFilter
Write-Status ""
})
}
function Invoke-GraphObjectsChanged
{
$btnRefresh = $global:EMViewObject.ViewPanel.FindName("btnRefresh")
if($btnRefresh)
{
$tooltip = [System.Windows.Controls.ToolTipService]::GetToolTip($btnRefresh)
if($global:lstMenuItems.SelectedItem.QuerySearch -eq $true)
{
$tooltip.Content = "Refresh objects based on filter. Note: Only filtered objects will be returned. Clear filter and press refresh to reload other objects"
}
else
{
$tooltip.Content = "Refresh all objects"
}
}
}
function Invoke-EMSelectedItemsChanged
{
$hasSelectedItems = ($global:dgObjects.ItemsSource | Where IsSelected -eq $true) -or ($null -ne $global:dgObjects.SelectedItem)
@@ -2132,6 +2184,16 @@ function Update-EMPolicySetAssignment
Invoke-GraphRequest -Url $api -HttpMethod "POST" -Content $json
}
function Start-PostListPolicySets
{
param($objList, $objectType)
foreach($obj in $objList)
{
$obj | Add-Member -MemberType NoteProperty -Name "IsAssigned" -Value ($obj.Object.status -ne "notAssigned")
}
$objList
}
#endregion
#endregion Locations
@@ -2710,6 +2772,43 @@ function Start-PreImportConditionalAccess
$obj.state = $global:cbImportCAState.SelectedValue
}
}
function Start-PostExportConditionalAccess
{
param($obj, $objectType, $path)
$ids = @()
foreach($id in ($obj.conditions.users.includeGroups + $obj.conditions.users.excludeGroups))
{
if($id -in $ids) { continue }
elseif($id -eq "GuestsOrExternalUsers") { continue }
elseif($id -eq "All") { continue }
elseif($id -eq "None") { continue }
$ids += $id
Add-GraphMigrationObject $id "/groups" "Group"
}
foreach($id in ($obj.conditions.users.includeUsers +$obj.conditions.users.excludeUsers))
{
if($id -in $ids) { continue }
elseif($id -eq "GuestsOrExternalUsers") { continue }
elseif($id -eq "All") { continue }
elseif($id -eq "None") { continue }
$ids += $id
Add-GraphMigrationObject $id "/users" "User"
}
<#
$roleIds = @()
foreach($id in ($obj.conditions.users.includeRoles + $obj.conditions.users.excludeRoles))
{
if($id -in $ids) { continue }
$roleIds += $id
}
#>
}
#endregion
#region Terms of use

View File

@@ -10,7 +10,7 @@ This module is for the Endpoint Info View. It shows read-only objects in Intune
#>
function Get-ModuleVersion
{
'3.1.4'
'3.5.0'
}
function Invoke-InitializeModule
@@ -22,7 +22,7 @@ function Invoke-InitializeModule
ID = "EMInfoGraphAPI"
ViewPanel = $viewPanel
AuthenticationID = "MSAL"
ItemChanged = { Show-GraphObjects; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""}
ItemChanged = { Show-GraphObjects -ObjectTypeChanged; Invoke-ModuleFunction "Invoke-GraphObjectsChanged"; Write-Status ""}
Activating = { Invoke-EMInfoActivatingView }
Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMInfoAuthenticateToMSAL }
@@ -40,7 +40,8 @@ function Invoke-InitializeModule
API = "/deviceManagement/templates"
ShowButtons = @("Export","View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="EndpointSecurity"
Icon="EndpointSecurity"
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -50,7 +51,8 @@ function Invoke-InitializeModule
ViewProperties = @("bindStatus", "lastAppSyncDateTime", "ownerUserPrincipalName")
API = "/deviceManagement/androidManagedStoreAccountEnterpriseSettings"
ShowButtons = @("Export","View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -61,6 +63,7 @@ function Invoke-InitializeModule
ShowButtons = @("Export","View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon = "AndroidCOWP"
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -70,7 +73,8 @@ function Invoke-InitializeModule
ViewProperties = @("appleId", "state", "appleId", "id")
API = "/deviceAppManagement/vppTokens"
ShowButtons = @("Export","View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
ExpandAssignmentsList = $false
})
Add-ViewItem (New-Object PSObject -Property @{
@@ -80,9 +84,9 @@ function Invoke-InitializeModule
ViewProperties = @("tokenName", "appleIdentifier", "tokenExpirationDateTime", "id")
API = "/deviceManagement/depOnboardingSettings/?`$top=100"
ShowButtons = @("Export","View")
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
ExpandAssignmentsList = $false
})
}
function Invoke-EMInfoActivatingView

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
#>
function Get-ModuleVersion
{
'3.4.0'
'3.5.0'
}
$global:MSGraphGlobalApps = @(
@@ -61,6 +61,12 @@ function Invoke-InitializeModule
Values = @()
})
$global:appSettingSections += (New-Object PSObject -Property @{
Title = "MS Graph General"
Id = "GraphGeneral"
Values = @()
})
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Root folder"
Key = "RootFolder"
@@ -132,23 +138,6 @@ function Invoke-InitializeModule
Description = "Default value for Import Scope (Tags) when importing objects"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show Delete button"
Key = "EMAllowDelete"
Type = "Boolean"
DefaultValue = $false
Description = "Allow deleting individual objectes"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show Bulk Delete "
Key = "EMAllowBulkDelete"
Type = "Boolean"
DefaultValue = $false
Description = "Allow using bulk delete to delete all objects of selected types"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Allow update on import (Preview)"
Key = "AllowUpdate"
@@ -157,7 +146,6 @@ function Invoke-InitializeModule
Description = "This will enable the option to update/replace an existing object during import"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Add ID to export file"
Key = "AddIDToExportFile"
@@ -171,17 +159,17 @@ function Invoke-InitializeModule
Key = "UseBatchAPI"
Type = "Boolean"
DefaultValue = $false
Description = "This will use batch API to call up to extport 20 objects on each API call"
Description = "This will use batch API to export up to 20 objects on each API call"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Refresh Objects after copy"
Key = "RefreshObjectsAfterCopy"
Title = "Resolve reference info"
Key = "ResolveReferenceInfo"
Type = "Boolean"
DefaultValue = $true
Description = "This will refresh all objects when after a copy. If this is disabled, the list must be refreshed manually to see the new objects. Default is true"
Description = "This will export/import info for referenced/navigation properties eg certificates in VPN profiles etc."
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "ApplicationId"
Key = "GraphAzureAppId"
@@ -202,6 +190,38 @@ function Invoke-InitializeModule
Type = "String"
Description = "Certificate for Azure App"
}) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Refresh Objects after copy"
Key = "RefreshObjectsAfterCopy"
Type = "Boolean"
DefaultValue = $true
Description = "This will refresh all objects when after a copy. If this is disabled, the list must be refreshed manually to see the new objects. Default is true"
}) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show Delete button"
Key = "EMAllowDelete"
Type = "Boolean"
DefaultValue = $false
Description = "Allow deleting individual objectes"
}) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show Bulk Delete "
Key = "EMAllowBulkDelete"
Type = "Boolean"
DefaultValue = $false
Description = "Allow using bulk delete to delete all objects of selected types"
}) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Expand assignments"
Key = "ExpandAssignments"
Type = "Boolean"
DefaultValue = $false
Description = "Expand assignments when listing objects. This can be used in custom columns based on assignment info"
}) "GraphGeneral"
}
function Get-GraphAppInfo
@@ -210,13 +230,8 @@ function Get-GraphAppInfo
if($global:hideUI -eq $true)
{
# Set app info from custom settings
$appObj = New-Object PSObject -Property @{
ClientId = Get-SettingValue "$($PreFix)CustomAppId"
TenantId = $global:silentTenantId
RedirectUri = Get-SettingValue "$($PreFix)CustomAppRedirect"
Authority = Get-SettingValue "$($PreFix)CustomAuthority"
}
# Taken care of by authentication function
return
}
$graphAppId = Get-SettingValue $settingId
@@ -288,8 +303,8 @@ function Invoke-GraphRequest
$ODataMetadata = "full", # full, minimal, none or skip
[ValidateSet("BETA","v1.0")]
$GraphVersion = "BETA",
[ValidateSet("beta","v1.0")]
$GraphVersion = "beta",
[switch]
$AllPages,
@@ -452,7 +467,9 @@ function Get-GraphObjects
[switch]
$AllPages,
[switch]
$SingleObject)
$SingleObject,
[string]
$filter)
$params = @{}
if($objectType.ODataMetadata)
@@ -486,7 +503,7 @@ function Get-GraphObjects
if($SinglePage -eq $true)
{
#Use default page size or use below for a specific page size for testing
#$params.Add("pageSize",100)
#$params.Add("pageSize",10) #!!!
}
elseif($SingleObject -ne $true -and $SinglePage -ne $true)
{
@@ -498,14 +515,36 @@ function Get-GraphObjects
$url = $script:nextGraphPage
}
if($SingleObject -ne $true -and (Get-SettingValue "ExpandAssignments") -eq $true -and $objectType.ExpandAssignmentsList -ne $false)
{
# Expand assignments so they can be used in custom columns
if(($url.IndexOf('expand',[System.StringComparison]::InvariantCultureIgnoreCase)) -eq -1)
{
$url += (?: (($url.IndexOf('?')) -eq -1) "?" "&")
$url = "$($url)`$expand=assignments"
}
}
if($script:multipleGraphPages -eq $true -and $SingleObject -ne $true -and $filter -and $objectType.QuerySearch -eq $true)
{
# QuerySearch is only reqired when there are more pages to load
if(($url.IndexOf('search',[System.StringComparison]::InvariantCultureIgnoreCase)) -eq -1)
{
$url += (?: (($url.IndexOf('?')) -eq -1) "?" "&")
$url = "$($url)`$search=`"$($filter)`""
}
}
$graphObjects = Invoke-GraphRequest -Url $url @params
if($SinglePage -eq $true -or $AllPages -eq $true)
{
$script:nextGraphPage = $graphObjects.'@odata.nextLink'
}
if($null -eq $script:multipleGraphPages)
{
$script:multipleGraphPages = $null -ne $script:nextGraphPage
}
}
if($graphObjects -and ($graphObjects | GM -Name Value -MemberType NoteProperty))
{
$retObjects = $graphObjects.Value
@@ -515,7 +554,7 @@ function Get-GraphObjects
$retObjects = $graphObjects
}
$graphObjects = Add-GraphObectProperties $retObjects $objectType $property $exclude $SortProperty
$graphObjects = Add-GraphObjectProperties $retObjects $objectType $property $exclude $SortProperty
if($SingleObject -ne $true -and $objectType.PostListCommand)
{
@@ -525,7 +564,7 @@ function Get-GraphObjects
$graphObjects
}
function Add-GraphObectProperties
function Add-GraphObjectProperties
{
param($graphObjects,
$objectType,
@@ -548,6 +587,8 @@ function Add-GraphObectProperties
$retObjects = $graphObjects
}
$getAssignmentInfo = ((Get-SettingValue "ExpandAssignments") -eq $true -and $objectType.ExpandAssignmentsList -ne $false)
foreach($graphObject in $retObjects)
{
$params = @{}
@@ -559,7 +600,16 @@ function Add-GraphObectProperties
$objTmp | Add-Member -NotePropertyName "Object" -NotePropertyValue $graphObject
$objTmp | Add-Member -NotePropertyName "ObjectType" -NotePropertyValue $objectType
$objects += $objTmp
}
}
if($null -ne $graphObject.isAssigned)
{
$objTmp | Add-Member -NotePropertyName "IsAssigned" -NotePropertyValue $graphObject.isAssigned
}
elseif($getAssignmentInfo)
{
$objTmp | Add-Member -NotePropertyName "IsAssigned" -NotePropertyValue (($graphObject.assignments | measure).Count -gt 0)
}
}
if($objects.Count -gt 0 -and $SortProperty -and ($objects[0] | GM -MemberType NoteProperty -Name $SortProperty))
@@ -572,8 +622,15 @@ function Add-GraphObectProperties
function Show-GraphObjects
{
param($filter, [switch]$ObjectTypeChanged)
$global:curObjectType = $global:lstMenuItems.SelectedItem
if($ObjectTypeChanged -eq $true)
{
$script:multipleGraphPages = $null
}
Clear-GraphObjects
if(-not $global:MSALToken)
@@ -585,7 +642,17 @@ function Show-GraphObjects
}
elseif($global:curObjectType.'@AccessType' -eq "None")
{
$global:txtNotLoggedIn.Content = "You don't have the required permissons to access $($global:curObjectType.Title).`n`nRequired perimssons: $($global:curObjectType.Permissons)"
$requiredPermissions = ($global:curObjectType.Permissons -join ",")
$missingScopes = ?? $global:curObjectType.'@MissingScopes' $requiredPermissions
if($requiredPermissions -ne $missingScopes)
{
$requiredPermissions = "`nRequired permissions: $requiredPermissions"
}
else
{
$requiredPermissions = ""
}
$global:txtNotLoggedIn.Content = "You don't have the required permissons to access $($global:curObjectType.Title).$($requiredPermissions)`n`Missing perimssons: $missingScopes`n`nRequest consent from the 'Request Consent' link in the user login info`nor`nDisable the 'Use Default Permissions' setting to trigger consent prompt.`nNote: Changing the 'Use Default Permissions' setting will require a restart of the app`nand a 'manual' login"
$global:grdNotLoggedIn.Visibility = "Visible"
$global:grdData.Visibility = "Collapsed"
return
@@ -593,7 +660,7 @@ function Show-GraphObjects
$global:grdNotLoggedIn.Visibility = "Collapsed"
$global:grdData.Visibility = "Visible"
# Always show Import is an item is selected
# Always show Import if an item is selected
$global:btnImport.IsEnabled = $global:lstMenuItems.SelectedItem -ne $null
if(-not $global:lstMenuItems.SelectedItem) { return }
@@ -612,9 +679,9 @@ function Show-GraphObjects
$global:grdTitle.Visibility = "Visible"
}
$script:nextGraphPage = $null
$script:nextGraphPage = $null
$graphObjects = @(Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage)
$graphObjects = @(Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage -Filter $filter)
$dgObjects.AutoGenerateColumns = $false
$dgObjects.Columns.Clear()
@@ -857,7 +924,7 @@ function Start-GraphPreImport
}
# Remove OData properties
foreach($odataProp in ($obj.PSObject.Properties | Where { $_.Name -like "*@Odata*Link" -or $_.Name -like "*@odata.context" -or $_.Name -like "*@odata.id" -or ($_.Name -like "*@odata.type" -and $_.Name -ne "@odata.type")}))
foreach($odataProp in ($obj.PSObject.Properties | Where { $_.Name -like "*@Odata*Link" -or $_.Name -like "*@odata.context" -or $_.Name -like "*@odata.id" -or ($_.Name -like "*@odata.type" -and $_.Name -ne "@odata.type")})) # -or $_.Name -like "#CustomRef*"
{
$removeProperties += $odataProp.Name
}
@@ -890,10 +957,11 @@ function Get-GraphMetaData
{
# Graph metadata does not support Content-Length in response so size can not be used to check if it is updated
# There also no other version information in response headers. Use file date to update every week
Write-Log "Load Graph MetaData file"
$url = "https://graph.microsoft.com/beta/`$metadata"
$fileFullPath = [Environment]::ExpandEnvironmentVariables("%LOCALAPPDATA%\CloudAPIPowerShellManagement\GraphMetaData.xml")
$fi = [IO.FileInfo]$fileFullPath
$maxAge = (Get-Date).AddDays(-7)
$maxAge = (Get-Date).AddDays(-14)
if($fi.Exists -and ($fi.LastWriteTime -gt $maxAge -or $fi.CreationTime -gt $maxAge))
{
try
@@ -905,6 +973,7 @@ function Get-GraphMetaData
if(-not $global:metaDataXML)
{
Write-Log "Download Graph MetaData file"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$wc = New-Object System.Net.WebClient
$wc.Encoding = [System.Text.Encoding]::UTF8
@@ -1538,6 +1607,7 @@ function Show-GraphImportForm
$filesToImport = & $global:curObjectType.PreFilesImportCommand $global:curObjectType $filesToImport
}
$navigationPropObjects = @()
foreach ($fileObj in $filesToImport)
{
if($allowUpdate -and $global:cbImportType.SelectedValue -ne "alwaysImport" -and (Reset-GraphObjet $fileObj $global:dgObjects.ItemsSource))
@@ -1545,7 +1615,22 @@ function Show-GraphImportForm
continue
}
Import-GraphFile $fileObj
$importedObj = Import-GraphFile $fileObj -PassThru
if($importedObj -and $global:curObjectType.NavigationProperties -eq $true)
{
$navigationPropObjects += [PSCustomObject]@{
File = $fileObj
ImportedObject = $importedObj
}
}
}
if($navigationPropObjects)
{
foreach($navPropObj in $navigationPropObjects)
{
Set-GraphNavigationPropertiesFromFile $navPropObj
}
}
Show-GraphObjects
Show-ModalObject
@@ -1554,8 +1639,9 @@ function Show-GraphImportForm
Add-XamlEvent $script:importForm "btnGetFiles" "add_click" {
# Used when the user manually updates the path and the press Get Files
$global:dgObjectsToImport.ItemsSource = @(Get-GraphFileObjects $global:txtImportPath.Text)
if([IO.Directory]::Exists($global:txtImportPath.Text))
$path = Expand-FileName $global:txtImportPath.Text
$global:dgObjectsToImport.ItemsSource = @(Get-GraphFileObjects $path)
if([IO.Directory]::Exists($path))
{
Save-Setting "" "LastUsedFullPath" $global:txtImportPath.Text
Set-XamlProperty $script:importForm "lblMigrationTableInfo" "Content" (Get-MigrationTableInfo)
@@ -1566,7 +1652,8 @@ function Show-GraphImportForm
if($global:txtImportPath.Text)
{
$global:dgObjectsToImport.ItemsSource = @(Get-GraphFileObjects $global:txtImportPath.Text)
$path = Expand-FileName $global:txtImportPath.Text
$global:dgObjectsToImport.ItemsSource = @(Get-GraphFileObjects $path)
Set-XamlProperty $script:importForm "lblMigrationTableInfo" "Content" (Get-MigrationTableInfo)
}
@@ -1750,7 +1837,8 @@ function Start-GraphObjectImport
{
$filesToImport = & $item.ObjectType.PreFilesImportCommand $item.ObjectType $filesToImport
}
$navigationPropObjects = @()
foreach ($fileObj in @($filesToImport))
{
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
@@ -1766,10 +1854,25 @@ function Start-GraphObjectImport
continue
}
Import-GraphFile $fileObj
$importedObj = Import-GraphFile $fileObj -PassThru
if($importedObj -and $item.ObjectType.NavigationProperties -eq $true)
{
$navigationPropObjects += [PSCustomObject]@{
File = $fileObj
ImportedObject = $importedObj
}
}
$importedObjects++
}
Save-Setting "" "LastUsedFullPath" $folder
if($navigationPropObjects)
{
foreach($navPropObj in $navigationPropObjects)
{
Set-GraphNavigationPropertiesFromFile $navPropObj
}
}
}
else
{
@@ -2010,7 +2113,7 @@ function Get-GraphFileObjects
function Import-GraphFile
{
param($file, $objectType)
param($file, $objectType, [switch]$PassThru)
if([IO.File]::Exists($file.FileInfo.FullName) -eq $false)
{
@@ -2050,7 +2153,12 @@ function Import-GraphFile
if($newObj -and $objClone.Assignments -and $global:chkImportAssignments.IsChecked -eq $true)
{
Import-GraphObjectAssignment $newObj $file.ObjectType $objClone.Assignments $file.FileInfo.FullName | Out-Null
}
}
if($PassThru -eq $true -and $newObj)
{
$newObj
}
}
catch
{
@@ -2347,7 +2455,8 @@ function Add-GraphMigrationInfo
if($objType -eq "#microsoft.graph.groupAssignmentTarget" -or
$objType -eq "#microsoft.graph.exclusionGroupAssignmentTarget")
{
Add-GroupMigrationObject $objInfo.groupid
#Add-GroupMigrationObject $objInfo.groupid
Add-GraphMigrationObject $objInfo.groupid "/groups" "Group"
}
elseif($objType -eq "#microsoft.graph.allLicensedUsersAssignmentTarget" -or
$objType -eq "#microsoft.graph.allDevicesAssignmentTarget")
@@ -2420,6 +2529,8 @@ function Add-GroupMigrationObject
if(-not $path) { return }
$path = Expand-FileName $path
# Check if group is already processed
$groupObj = Get-GraphMigrationObject $groupId
if(-not $groupObj)
@@ -2434,7 +2545,7 @@ function Add-GroupMigrationObject
if($global:AADObjectCache.ContainsKey($groupId) -eq $false) { $global:AADObjectCache.Add($groupId, $groupObj) }
# Add group to migration file
if((Add-GraphMigrationObject $groupObj $path "Group"))
if((Add-GraphMigrationObjectToFile $groupObj $path "Group"))
{
# Export group info to json file for possible import
$grouspPath = Join-Path $path "Groups"
@@ -2445,6 +2556,46 @@ function Add-GroupMigrationObject
}
}
function Add-GraphMigrationObject
{
param($objId, $grapAPI, $objTypeName)
if(-not $objId) { return }
$path = Get-GraphMigrationTableFile $global:txtExportPath.Text
if(-not $path) { return }
$path = Expand-FileName $path
# Check if object is already processed
$graphObj = Get-GraphMigrationObject $objId
if(-not $graphObj)
{
# Get object info
$graphObj = Invoke-GraphRequest "$($grapAPI)/$objId" -ODataMetadata "none"
}
if($graphObj)
{
# Add object to cache
if($global:AADObjectCache.ContainsKey($objId) -eq $false) { $global:AADObjectCache.Add($objId, $ugraphObjserObj) }
# Add object to migration file
if((Add-GraphMigrationObjectToFile $graphObj $path $objTypeName))
{
if($objTypeName -eq "Group")
{
# Export group info to json file for possible import
$grouspPath = Join-Path $path "Groups"
if(-not (Test-Path $grouspPath)) { mkdir -Path $grouspPath -Force -ErrorAction SilentlyContinue | Out-Null }
$fileName = "$grouspPath\$((Remove-InvalidFileNameChars $graphObj.displayName)).json"
ConvertTo-Json $graphObj -Depth 10 | Out-File $fileName -Force
}
}
}
}
function Get-GraphMigrationObject
{
param($objId)
@@ -2458,7 +2609,7 @@ function Get-GraphMigrationObject
}
# Adds an object to migration file if not added previously
function Add-GraphMigrationObject
function Add-GraphMigrationObjectToFile
{
param($obj, $path, $objType)
@@ -2517,6 +2668,7 @@ function Get-GraphMigrationTableForImport
$global:GraphMigrationTable = $null
# Migration table must be located in the root of the import path
$path = $global:txtImportPath.Text
$path = Expand-FileName $path
for($i = 0;$i -lt 2;$i++)
{
@@ -2659,7 +2811,7 @@ function Update-JsonForEnvironment
#region Dependency Functions
function Get-GraphDependencyDefaultObjects
{
Add-GraphDependencyObjects @("ScopeTags")
Add-GraphDependencyObjects @("ScopeTags","AssignmentFilters")
}
function Get-GraphDependencyObjects
@@ -2771,6 +2923,8 @@ function Export-GraphObjects
$global:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
$folder = Get-GraphObjectFolder $objectType $global:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked")
$folder = Expand-FileName $folder
$objectsToExport = @()
if($Selected -ne $true)
@@ -2831,6 +2985,8 @@ function Export-GraphObject
Write-Log "No object to export" 3
return
}
Add-GraphNavigationProperties $obj $objectType
try
{
@@ -2871,6 +3027,177 @@ function Export-GraphObject
}
}
<#
Update the navigation references for an object
#>
function Set-GraphNavigationPropertiesFromFile
{
param($navPropObject)
if(-not $navPropObject.File -or -not $navPropObject.ImportedObject)
{
return
}
# Reload data from file. Some object properties was removed before import...
$objFileInfo = (ConvertFrom-Json (Get-Content -LiteralPath $navPropObject.File.FileInfo.FullName -Raw))
if(-not ($objFileInfo.PSObject.Properties | Where { $_.Name -like "#CustomRef_*" })) { return }
Set-GraphNavigationProperties $navPropObject.ImportedObject $objFileInfo $navPropObject.File.ObjectType
}
function Set-GraphNavigationProperties
{
param($newObj, $oldObj, $objectType, [switch]$FromOldObject)
if($objectType.NavigationProperties -ne $true) { return }
if(-not $newObj -or -not $oldObj -or -not $objectType)
{
return
}
if((Get-SettingValue "ResolveReferenceInfo") -ne $true) { return }
$entityName = $oldObj.'@odata.type'.Split('.')[-1]
$nameProp = ?? $objectType.NameProperty "displayName"
$props = Get-GraphEntityTypeProperties $entityName
foreach($prop in ($props | Where LocalName -eq "NavigationProperty" ))
{
# Is this the correct way of filter out Assignments, summaries etc.?
if($prop.ContainsTarget -eq $true) { continue }
if(-not ($oldObj."$($prop.Name)@odata.associationLink")) { continue }
$associationLink = $oldObj."$($prop.Name)@odata.associationLink" -replace $oldObj.Id,$newObj.Id
$refBodyObjs = $null #@()
$refObjName = $null
$refObjId = $null
if($FromOldObject -eq $true)
{
$navProp = Invoke-GraphRequest -URL $oldObj."$($prop.Name)@odata.navigationLink" -ODataMetadata "minimal" -NoError
if(-not $navProp) { continue }
$refObjName = Get-GraphObjectName $navProp $navProp
$refObjId = $navProp.Id
$refBodyObjs = ([PSCustomObject]@{
"@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($navProp.Id)')")
})
}
else
{
if(-not ($oldObj."#CustomRef_$($prop.Name)")) { continue } # Not included in the export file
$idx = $oldObj."#CustomRef_$($prop.Name)".IndexOf("|:|")
if($idx -gt -1)
{
$refObjName = $oldObj."#CustomRef_$($prop.Name)".SubString(0,$idx)
}
else
{
$refObjName = $oldObj."#CustomRef_$($prop.Name)"
}
$refObjects = Invoke-GraphRequest -URL "$($objectType.API)?`$filter=$($nameProp) eq '$($refObjName)'" -NoError
$objectsFound = ($refObjects.value | measure).Count
if($objectsFound -eq 1)
{
# Are there any references that allows multiple ref objects?
foreach($refObj in $refObjects.value)
{
$refBodyObjs = ([PSCustomObject]@{
"@odata.id" = ("https://$global:MSALGraphEnvironment/beta/$($objectType.API)('$($refObj.Id)')")
})
$refObjId = $refObj.Id
}
}
elseif($objectsFound -gt 1)
{
Write-Log "Multiple objects ($objectsFound) found with $nameProp $refObjName. Skipping reference." 2
continue
}
else
{
Write-Log "No object found with $nameProp $refObjName" 2
continue
}
}
Write-Log "Add $refObjName ($refObjId) to navigation property $($prop.Name)"
$body = $refBodyObjs | ConvertTo-Json -Depth 10
Invoke-GraphRequest -URL $associationLink -HttpMethod "PUT" -Content $body | Out-Null
}
}
<#
Add Navigation Property data to the object so it included in the exported json file
#>
function Add-GraphNavigationProperties
{
param($obj, $objType)
if($objectType.NavigationProperties -ne $true) { return }
if(-not $obj.'@odata.type') { return }
if((Get-SettingValue "ResolveReferenceInfo") -ne $true) { return }
$entityName = $obj.'@odata.type'.Split('.')[-1]
$props = Get-GraphEntityTypeProperties $entityName
foreach($prop in ($props | Where LocalName -eq "NavigationProperty" ))
{
# Is this the correct way of filter out Assignments, summaries etc.?
if($prop.ContainsTarget -eq $true) { continue }
if(-not ($obj."$($prop.Name)@odata.navigationLink")) { continue }
$navProp = Invoke-GraphRequest -URL $obj."$($prop.Name)@odata.navigationLink" -ODataMetadata "minimal" -NoError
if($navProp)
{
$value = $null
$refType = ""
if($navProp.value -is [Object[]])
{
if($navProp.value.Count -gt 0 -and $navProp.value[0].'@odata.type') { $refType = $navProp.value[0].'@odata.type' }
$refValues = @()
$navProp.value | ForEach-Object { $refValues += (Get-GraphObjectName $_ $objType) }
if($refValues.Count -gt 0)
{
if(($refValues -join "") -like "*,*")
{
Write-Log "One or mor referenced objects has the comma (,) character in the name. Cannot add navigation property $($prop.Name)" 3
}
$value = ($refValues -join ",")
}
}
else
{
if($navProp.'@odata.type') { $refType = $navProp.'@odata.type' }
$value = (Get-GraphObjectName $navProp $objType)
}
if($refType -and $value)
{
$value = ($value + "|:|" + $refType)
}
$obj | Add-Member -NotePropertyName "#CustomRef_$($prop.Name)" -NotePropertyValue $value
}
}
}
function Get-GraphBatchObjects
{
param($objects, $txtNameFilter)
@@ -2932,7 +3259,7 @@ function Get-GraphBatchObjects
if($objectType -and $batchResults.Count -gt 0)
{
$batchResultsTmp = $batchResults
$batchResults = Add-GraphObectProperties $batchResultsTmp $objectType -property $objectType.ViewProperties
$batchResults = Add-GraphObjectProperties $batchResultsTmp $objectType -property $objectType.ViewProperties
$curObj = 1
foreach($obj in $batchResults)
@@ -3120,6 +3447,8 @@ function Copy-GraphObject
[System.Windows.MessageBox]::Show("No object selected`n`nSelect the $($global:curObjectType.Title) item you want to copy", "Error", "OK", "Error")
return
}
$script:copyForm = Initialize-Window ($global:AppRootFolder + "\Xaml\CopyDialog.xaml")
if(-not $script:copyForm) { return }
$newName = "$((Get-GraphObjectName $dgObjects.SelectedItem $global:curObjectType)) - Copy"
if($global:curObjectType.CopyDefaultName)
@@ -3127,10 +3456,44 @@ function Copy-GraphObject
$newName = $global:curObjectType.CopyDefaultName
$dgObjects.SelectedItem.PSObject.Properties | foreach { $newName = $newName -replace "%$($_.Name)%", $dgObjects.SelectedItem."$($_.Name)" }
}
$ret = Show-InputDialog "Copy $($global:curObjectType.Title)" "Select name for the new object" $newName
Set-XamlProperty $script:copyForm "txtObjectName" "Text" $newName
$descriptionProperty = $global:dgObjects.SelectedItem.Object | gm | Where { $_.Name -eq "Description" }
if($descriptionProperty)
{
Set-XamlProperty $script:copyForm "txtObjectDescription" "Text" $global:dgObjects.SelectedItem.Object.Description
}
else
{
Set-XamlProperty $script:copyForm "txtObjectDescription" "IsEnabled" $false
}
$script:copyForm.Add_ContentRendered({
$txtName = $script:copyForm.FindName("txtObjectName")
if($txtName)
{
$txtName.SelectAll();
}
})
Add-XamlEvent $script:copyForm "btnOk" "Add_Click" -scriptBlock ([scriptblock]{
$script:copyForm.DialogResult = $true;
})
$script:copyForm.Owner = $global:window
$script:copyForm.Icon = $global:Window.Icon
$ret = $script:copyForm.ShowDialog()
if($ret)
{
$newName = Get-XamlProperty $script:copyForm "txtObjectName" "Text"
if(-not $newName)
{
Write-Log "New name cannot be empty. Copy object skipped" 2
Write-Status ""
return
}
# Export profile
Write-Status "Export $((Get-GraphObjectName $dgObjects.SelectedItem $global:curObjectType))"
@@ -3138,7 +3501,7 @@ function Copy-GraphObject
if($global:curObjectType.PreCopyCommand)
{
if((& $global:curObjectType.PreCopyCommand $exportObj $global:curObjectType $ret))
if((& $global:curObjectType.PreCopyCommand $exportObj $global:curObjectType $newName))
{
if((Get-SettingValue "RefreshObjectsAfterCopy") -eq $true)
{
@@ -3154,15 +3517,22 @@ function Copy-GraphObject
if($obj)
{
# Import new profile
Set-GraphObjectName $obj $global:curObjectType $ret
Set-GraphObjectName $obj $global:curObjectType $newName
if((Get-XamlProperty $script:copyForm "txtObjectDescription" "IsEnabled" $false) -eq $true)
{
$obj.Description = Get-XamlProperty $script:copyForm "txtObjectDescription" "Text"
}
$newObj = Import-GraphObject $obj $global:curObjectType
if($newObj)
{
Set-GraphNavigationProperties $newObj $exportObj $global:curObjectType -FromOldObject
if($global:curObjectType.PostCopyCommand)
{
& $global:curObjectType.PostCopyCommand $exportObj $newObj $global:curObjectType
}
if((Get-SettingValue "RefreshObjectsAfterCopy") -eq $true)
{
Show-GraphObjects
@@ -3236,7 +3606,7 @@ function Show-GraphObjectInfo
$descriptionProperty = $global:dgObjects.SelectedItem.Object | gm | Where { $_.Name -eq "Description" }
if($descriptionProperty)
{
Set-XamlProperty $script:detailsForm "txtObjectDescription" "Text" $descriptionProperty.Value
Set-XamlProperty $script:detailsForm "txtObjectDescription" "Text" $global:dgObjects.SelectedItem.Object.Description
}
else
{
@@ -3612,6 +3982,11 @@ function Get-GraphEntityTypeProperties
{
param($entityType, $xml)
Get-GraphMetaData
if(-not $xml) { $xml = $global:metaDataXML }
if(-not $xml) { return }
$tmpEntity = $xml.SelectSingleNode("//*[name()='EntityType' and @Name='$entityType']")
if(-not $tmpEntity) { return }
@@ -3631,7 +4006,7 @@ function Get-GraphEntityTypeProperties
[array]::Reverse($entities)
foreach($enitiy in $entities)
{
$properties += $enitiy.SelectNodes("*[name()='Property']")
$properties += $enitiy.SelectNodes("*[name()='Property' or name()='NavigationProperty']")
}
$properties

View File

@@ -1,6 +1,6 @@
# Microsoft Authentication Library (MSAL)
Microsoft Authentication Library (MSAL) is used for authenticating to Microsoft Graph and other APIs used by the script. Microsoft.Identity.Client.dll** is the library file that contains the authentication functions. This script is depending on the file to be able to authenticate to Microsoft Graph.
Microsoft Authentication Library (MSAL) is used for authenticating to Microsoft Graph and other APIs used by the script. **Microsoft.Identity.Client.dll** is the library file that contains the authentication functions. This script is depending on the file to be able to authenticate to Microsoft Graph.
See the GitHub repository [MSAL.PS](https://github.com/AzureAD/MSAL.PS) for more information on using MSAL with PowerShell. This script does not use the module directly for various reasons but the MSAL.PS repository is a great source of information and the best place to start for using MSAL with PowerShell.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@ Before starting the app:
Before logging on:
* The app will use the Intune PowerShell Azure Enterprise Application by default and only use the permissions granted to that appliction. Disable **Use Default Permissions** in Settings to request additional permissions. The will cause a consent prompt if one or more permissions are missing for the app.
**Note:** If the app has not been approved for the organization, a consent prompt will be disablyed.
**Note:** If the app has not been approved for the organization, a consent prompt will be displayed.
* Enable **Get Tenant List** in Settings if accessing multiple environments with the same account e.g. a guest account in other tenants. This might cause a Consent prompt
Start the script by running **Start.cmd**, **Start-WithJson.cmd**, **Start-WithConsole.cmd** or **Start-IntuneManagement.ps1**. **Start-WithConsole.cmd** will leave the command prompt window open so you can see the log while running the app.
@@ -282,7 +282,7 @@ Start-WithJson.cmd is included as an example on how to start the script with jso
* .Net 4.7
* PowerShell 5.1
* MSAL
* Microsoft.Identity.Client.dll version 4.29.0.0 is included in this version
* Microsoft.Identity.Client.dll version 4.42.1.0 is included in this version
* License and permissions in Azure to manage objects in Intune and Azure
## References

View File

@@ -1,4 +1,78 @@
# Release Notes
## 3.5.0 - 2022-04-26
**New features**
- **Automatic update check**<br />
The app will check GitHub at start-up if there is a new version available<br />
This can be disabled in settings<br />
- **Use PowerShell 5**<br />
Command files will now use PowerShell 5 (-version 5 in the command line)<br />
This is based on [Issue 44](https://github.com/Micke-K/IntuneManagement/issues/44)<br />
- **Documentation**<br />
- New Word settings: Table text style and table caption location<br />
This is based on an additional request in [Issue 37](https://github.com/Micke-K/IntuneManagement/issues/37)<br />
- Terms of Use info when documenting Conditional Access<br />
- Added documentation support for Terms of Use<br />
- Added additional support for offline documentation<br />
**Note:** Offline is defined as documenting an exported folder while logged in to another tenant.<br />
If logged in to the same tenant as the exported folder, "online" documentation will be used<br />
- Changed the layout for the assignment table on Win32 Applications. There were too many columns so additional info is changed to a table in the value column<br />
- Filter / Filter Mode column headers are now set from language files<br />
<br />
- **Export/Import**<br />
- Users in Conditional Access are now added to the Migration Table<br />
This is so the user IDs can be translated during Offline documentation<br />
- Referenced settings are now included in the export<br />
This is to support referenced settings during import, copy and offline documentation (Certs on VPN profiles etc.)<br />
These properties are named #CustomRef_*PropertyName* in the json file<br />
**Note:** This might cause export/copy to take longer once every second week since it requires the MetaData XML for Graph to be downloaded.<br />
This feature can be turned off by unchecking 'Resolve reference info' in Settings<br />
<br />
- **Copy**<br />
- New dialog when copying an object. Description can now be changed during the copy<br />
<br />
- **Authentication**<br />
- Full authentication support for US Government and China clouds<br />
This requires that 'Show Azure AD login menu' is enabled in Settings<br />
- Consent can be requested for missing permissions. This can be triggered via the 'Request Consent' link in the user profile info<br />
- New version of MSAL.DLL, version 4.42.1<br />
- Object types with only Read permissions are now supported. These will be orange in the menu<br />
Buttons like Import and Delete will still be available but they will not work<br />
<br />
- **List objects**<br />
- IsAssigned column is added to objects that supports it (property on the Graph object)<br />
- Enable 'Expand assignments' in Settings to include Assignments when getting a full list of objects from Graph<br />
This can be used for adding Custom columns based on assignment info<br />
It is also used for setting the IsAssigned column for objects that doesn't have the info in Graph<br />
This is based on [Issue 30](https://github.com/Micke-K/IntuneManagement/issues/30)<br />
- Apps can be filtered in the request<br />
If there are more than 1000 applications in the environment, the filter box can be used to return only matched items<br />
Enter the filter in the text box and press the Refresh button. Clear the filter box and click Refresh to reload other objects<br />
This is based on [Issue 28](https://github.com/Micke-K/IntuneManagement/issues/28)<br />
<br />
**Fixes**
- **Documentation**<br />
- Fixed bug in *Conditional Access* documentation that caused some Grant information to be excluded from documentation
- Fixed missing properties when documenting *Device restrictions (Windows 10 Team)* profiles
- Fixed some Offline Documentation issues<br />
Get dependency info from exported folders instead of Graph<br />
Offline documentation is not 100% fully supported yet. Dependency applications for Win32 apps are not included in this version<br />
and there might be more properties missing. Please report anything missing for offline documentation to [Issue 37](https://github.com/Micke-K/IntuneManagement/issues/37)<br />
**Note** Offline documentation will always require online access. Some information like language text, Azure roles, Mobile apps etc. will use Graph API<br /><br />
- **Authentication**<br />
- First login with last used account could fail if the user domain was changed after the initial token was cached<br />
<br />
## 3.4.0 - 2022-03-01

View File

@@ -1,2 +1,2 @@
cmd /c powershell -ex bypass -file "%~DP0Start-IntuneManagement.ps1" -ShowConsoleWindow
cmd /c powershell -version 5 -ex bypass -file "%~DP0Start-IntuneManagement.ps1" -ShowConsoleWindow
pause

View File

@@ -1 +1 @@
cmd /c powershell -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -JSonSettings
cmd /c powershell -version 5 -ex bypass -File "%~DP0Start-IntuneManagement.ps1" -JSonSettings

View File

@@ -1 +1 @@
cmd /c powershell -ex bypass -File "%~DP0Start-IntuneManagement.ps1"
cmd /c powershell -version 5 -ex bypass -File "%~DP0Start-IntuneManagement.ps1"

View File

@@ -16,7 +16,7 @@
<TextBlock Height="20" Name="txtTitle" FontWeight="Bold" Margin="0,5,0,0" />
<TextBlock Grid.Row="1" Text="(c) 2021 Mikael Karlsson - MIT License" Margin="0,5,0,0" />
<TextBlock Grid.Row="1" Text="(c) 2022 Mikael Karlsson - MIT License" Margin="0,5,0,0" />
<TextBlock Grid.Row="2">
See

47
Xaml/CopyDialog.xaml Normal file
View File

@@ -0,0 +1,47 @@
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Copy object"
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=txtObjectName}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="0" HorizontalAlignment="Left">
<Label Content="New Name" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Name of the object" />
</StackPanel>
<TextBox Name="txtObjectName" Margin="0,5,5,0" Grid.Row="0" Grid.Column="1" Width="250"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" >
<Label Content="Description" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Description for the object" Margin="0,2,0,0" />
</StackPanel>
<TextBox Name="txtObjectDescription" Margin="0,5,5,0" Grid.Row="1" Grid.Column="1" AcceptsReturn="True" Width="250" Height="100" />
<WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
<Button IsDefault="True" Name="btnOk" MinWidth="60" Margin="0,0,10,0">_OK</Button>
<Button IsCancel="True" Name="btnCancel" MinWidth="60" >_Cancel</Button>
</WrapPanel>
</Grid>
</Window>

View File

@@ -24,6 +24,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@@ -190,63 +191,76 @@
<TextBox Grid.Column='2' Grid.Row='12' Name='txtWordSubCategoryHeaderStyle' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="13">
<Label Content="Table text style" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Style of the text in a table. Default is current font" />
</StackPanel>
<TextBox Grid.Column='2' Grid.Row='13' Name='txtWordTableTextStyle' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="14">
<Label Content="Table caption position" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify where the table captions should be. Above or below the table" />
</StackPanel>
<ComboBox Name="cbWordTableCaptionPosition" Margin="0,5,0,0" MinWidth="250" Grid.Row="14" Grid.Column="1" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="15">
<Label Content="Cover Page" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Cover page to use if the template property is not specified. Ion (Dark) is used if not specified" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='13' Name='txtWordCoverPage' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='15' Name='txtWordCoverPage' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="14">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="16">
<Label Content="Title" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the title property for the document" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='14' Name='txtWordTitleProperty' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='16' Name='txtWordTitleProperty' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="15">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="17">
<Label Content="Subject" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the subject property for the document" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='15' Name='txtWordSubjectProperty' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='17' Name='txtWordSubjectProperty' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="16">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="18">
<Label Content="Content controls" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify content control values e.g. prop1=value;prop2=value;prop3=value" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='16' Name='txtWordContentControls' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='18' Name='txtWordContentControls' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Grid.Row='17' Margin="0,0,5,0">
<StackPanel Orientation="Horizontal" Grid.Row='19' Margin="0,0,5,0">
<Label Content="Open document" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="This will open the document and activate Word when finished" />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='17' Name='chkWordOpenDocument' VerticalAlignment="Center" IsChecked="true" />
<CheckBox Grid.Column='1' Grid.Row='19' Name='chkWordOpenDocument' VerticalAlignment="Center" IsChecked="true" />
<StackPanel Orientation="Horizontal" Grid.Row='18' Margin="0,0,5,0">
<StackPanel Orientation="Horizontal" Grid.Row='20' Margin="0,0,5,0">
<Label Content="Document scripts" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Include scripts in the documentation" />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='18' Name='chkWordIncludeScripts' VerticalAlignment="Center" IsChecked="true" />
<CheckBox Grid.Column='1' Grid.Row='20' Name='chkWordIncludeScripts' VerticalAlignment="Center" IsChecked="true" />
<StackPanel Orientation="Horizontal" Grid.Row='19' Margin="0,0,5,0">
<StackPanel Orientation="Horizontal" Grid.Row='21' Margin="0,0,5,0">
<Label Content="Remove script signature" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Remove signature block from PowerShell scripts to reduce script documentation size" />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='19' Name='chkWordExcludeScriptSignature' VerticalAlignment="Center" IsChecked="true" />
<CheckBox Grid.Column='1' Grid.Row='21' Name='chkWordExcludeScriptSignature' VerticalAlignment="Center" IsChecked="true" />
<StackPanel Orientation="Horizontal" Grid.Row='20' Margin="0,0,5,0">
<StackPanel Orientation="Horizontal" Grid.Row='22' Margin="0,0,5,0">
<Label Content="Attatch Json file" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Attatch the Json file to the documentation" />
</StackPanel>
<CheckBox Grid.Column='1' Grid.Row='20' Name='chkWordAttatchJsonFile' VerticalAlignment="Center" IsChecked="false" />
<CheckBox Grid.Column='1' Grid.Row='22' Name='chkWordAttatchJsonFile' VerticalAlignment="Center" IsChecked="false" />
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="21">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="23">
<Label Content="Script table style" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the table style to use for scripts. Ducument table style will be use as default" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='21' Name='txtWordScriptTableStyle' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='23' Name='txtWordScriptTableStyle' Margin="0,5,5,5"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="22">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="24">
<Label Content="Script font style" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Specify the font style to use for documenting scripts. HTML Code is used as default" />
</StackPanel>
<TextBox Grid.Column='1' Grid.Row='22' Name='txtWordScriptStyle' Margin="0,5,5,5"/>
<TextBox Grid.Column='1' Grid.Row='24' Name='txtWordScriptStyle' Margin="0,5,5,5"/>
</Grid>

View File

@@ -0,0 +1,33 @@
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Grid.IsSharedSizeScope='True'>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Margin="5,5,0,0" FontWeight="Bold" />
<TextBlock Text="{Binding Description}" Grid.Row="1" Margin="5,5,0,0" />
<Separator Grid.Row="2" />
<ContentControl Name="ccEMIntuneAppPage" Grid.Row="3" Margin="5,5,5,0" Content="{Binding PanelView}" />
<Separator Grid.Row="4" />
<TextBlock Grid.Row="5" Name="txtIntuneAppsPageStatus" HorizontalAlignment="Left" Margin="0,5,0,0" />
<StackPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0" >
<Button Name="btnIntuneApplicationPrevious" Content="Previous" MinWidth="100" Margin="0,0,5,0" IsEnabled="False" />
<Button Name="btnIntuneApplicationNext" Content="Next" MinWidth="100" Margin="0,0,5,0" />
<Button Name="btnIntuneApplicationFinish" Content="Finish" ToolTip="Create application in intune" MinWidth="100" Visibility="Collapsed" Margin="0,0,5,0" />
<Button Name="btnIntuneApplicationNew" Content="New" ToolTip="Create a new application" MinWidth="100" Visibility="Collapsed" Margin="0,0,5,0" />
</StackPanel>
</Grid>

View File

@@ -1,5 +1,19 @@
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen">
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title=""
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -15,7 +29,7 @@
<TextBox Name="txtValue" Grid.Column="1" Grid.Row="1" MinWidth="250"></TextBox>
<WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
<Button IsDefault="True" Name="btnOk" MinWidth="60" Margin="0,0,10,0">_Ok</Button>
<Button IsDefault="True" Name="btnOk" MinWidth="60" Margin="0,0,10,0">_OK</Button>
<Button IsCancel="True" Name="btnCancel" MinWidth="60">_Cancel</Button>
</WrapPanel>
</Grid>

69
Xaml/MSALLoginMenu.xaml Normal file
View File

@@ -0,0 +1,69 @@
<!-- x:Class="Dialogs.Margins" <Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> -->
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Login"
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=cbMSALCloudType}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Width="350" HorizontalAlignment="Stretch" Name="grdModalContainer" VerticalAlignment="Stretch" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--
<Border Background="{DynamicResource TitleBackgroundColor}" BorderThickness="0">
<TextBlock Margin="5" FontWeight="Bold" Text="Login" />
</Border>
-->
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TitleColumn" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="0">
<Label Content="Cloud" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Select the target cloud to login to" />
</StackPanel>
<ComboBox Name="cbMSALCloudType" Margin="0,5,5,0" Grid.Row="0" Grid.Column="1"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="1">
<Label Content="GCC Environment" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Select the GCC environment. Only valid if 'Azure AD US Government' cloud is selected." />
</StackPanel>
<ComboBox Name="cbMSALGCCType" Margin="0,5,5,0" Grid.Row="1" Grid.Column="1"
DisplayMemberPath="Name" SelectedValuePath="Value" />
<StackPanel Grid.Row='2' Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,5,5">
<Button Name="btnLogin" Content="Login" Width='100' Margin="5,0,0,0" VerticalAlignment="Center" />
<Button Name="btnCancel" Content="Cancel" Width='100' Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Grid>
</Window>

View File

@@ -32,7 +32,7 @@
</Grid.ColumnDefinitions>
<Menu Name="mnuMain" Padding="0,5,0,5" Grid.ColumnSpan="2" >
<MenuItem Header="_File" >
<MenuItem Header="_File" Name="mnuFile">
<MenuItem Header="_Settings" Name="mnuSettings" />
<MenuItem Header="_Tenant Settings" Name="mnuTenantSettings" />
<Separator />

View File

@@ -44,9 +44,9 @@
</StackPanel>
<TextBox Name="txtObjectName" Margin="0,5,5,0" Grid.Row="0" Grid.Column="1" />
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="1" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<Label Content="Description" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Name of the object" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Description for the object" Margin="0,2,0,0" />
</StackPanel>
<TextBox Name="txtObjectDescription" Margin="0,5,5,0" Grid.Row="1" Grid.Column="1" AcceptsReturn="True" Height="100" />

View File

@@ -41,6 +41,8 @@
<TextBlock Name="txtAppId" />
</StackPanel>
<Button Margin="5" Grid.Row="4" Grid.ColumnSpan="2" Name="lnkRequestConsent" Content="Request Consent" ToolTip="Request consent for missing scopes" Cursor="Hand" Style="{DynamicResource LinkButton}" />
<StackPanel Grid.Row="5" Grid.ColumnSpan="2" Orientation="Horizontal">
<Button Margin="5" Name="lnkTokeninfo" Content="MSAL Token" Cursor="Hand" Style="{DynamicResource LinkButton}" />
<Button Margin="5" Name="lnkAccessTokenInfo" ToolTip="Show the decoded JWT info of the AccessToken" Content="Access Token" Cursor="Hand" Style="{DynamicResource LinkButton}" />