Compare commits

..
61 Commits
Author SHA1 Message Date
Mikael Karlsson 1bd2151358 Merge Development for 3.11.0 2026-09-23 19:53:35 +10:00
Mikael Karlsson fb819949f5 Restore LF line endings in Core.psm1 and EndpointManager.psm1
The commit for issue #428 re-saved both files with CRLF, so every line showed
as changed against master, which stores them with LF like the rest of the
repository. Content is untouched; only the line endings return to LF.
2026-09-23 19:53:35 +10:00
Mikael Karlsson f96037a9d0 3.11.0: system browser sign-in, update check limited to 3.x, GitHub templates 2026-09-23 19:48:02 +10:00
Mikael Karlsson 0492b784a1 Added support for System Broswer login 2026-08-14 21:56:06 +10:00
Mikael Karlsson 65ef411e20 Fixed Issue #428 2026-08-14 21:40:48 +10:00
Mikael Karlsson ed45693344 Merge pull request #429 from McKenzieCo/fix/silent-bulk-compare-op-addition
Fix silent bulk compare crash: op_Addition on PSObject
2026-08-06 21:30:15 +10:00
Mikael Karlsson f036c64d74 Refactor comparison logic to use compResultValue 2026-07-23 19:41:47 +10:00
Mikael Karlsson c3db7edb6e Merge pull request #424 from BuggyAl/patch-1
Fix typo in permissions error message
2026-07-23 19:25:07 +10:00
McKenzieCoandClaude Fable 5 51e5966fa7 Fix silent bulk compare crash: op_Addition on PSObject
In Start-BulkCompareExportObjects the flat CSV row was built with
'$compValue +=' where $compValue is a single PSCustomObject element of
the result array. PowerShell has no op_Addition for PSObject, so every
silent batch compare using the 'Exported Files with Intune Objects (Id)'
provider threw 'Method invocation failed because [PSObject] does not
contain a method named op_Addition' before Save-BulkCompareResults ran,
and no CSV was produced.

All other compare providers assign the row object directly; this aligns
the export provider with them. Verified against a live tenant: the
silent BulkCompare job now completes and writes the result CSV.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 18:02:23 -04:00
BuggyAl 7cd93038da Fix typo in permissions error message 2026-06-30 13:49:04 -05:00
Mikael Karlsson 5bb84c8561 Merge Development with Master 2026-05-12 19:50:19 +10:00
Mikael Karlsson b6b9e9e34c 3.10.3.1 2026-05-12 19:40:20 +10:00
Mikael Karlsson bd84a61522 3.10.3 2026-05-12 19:39:29 +10:00
Mikael Karlsson e09b3f71fa 3.10.1.19
Added support for importing Win32 app with Install/Uninstall script.
2026-04-11 15:09:39 +10:00
Mikael Karlsson 836c8a0c2e 3.10.1.18
Fixed issues: 402, 403 and 404
Added support for Install/Uninstall Script on Win32 apps
Rebuilt Strings
2026-03-07 14:01:52 +11:00
Mikael Karlsson b6c94e78d5 3.10.1.17
Issue 400 - Country names when documenting named locations
2026-02-22 20:40:45 +11:00
Mikael Karlsson e242865ef4 3.10.1.16
Issue 378 - Fixed issue when "Sort Json Properties" is enabled. Arrays were broken e.g. empty array ended up as null and single item ended up as string. This broke export/import of Conditional Access policies.
2026-01-26 22:08:24 +11:00
Mikael Karlsson f7043ae4a2 3.10.1.15
Issue 306 - Add additional support for clearing cache during Export/Import
2025-12-14 19:15:17 +11:00
Mikael Karlsson 71bb111a00 3.10.1.14
Issue 387 - Add support for Windows Update Profiles
2025-12-13 17:06:17 +11:00
Mikael Karlsson 9ca756bfed 3.10.1.13
Issue 383 - Fixed issue with document bool values in App Config with XML settings.
2025-12-07 21:23:01 +11:00
Mikael Karlsson 4053b5c672 3.10.1.12
Issue 380 - XML formatting
2025-11-25 21:25:26 +11:00
Mikael Karlsson 469408d29f 3.10.1.11
Issue 380 - Additional format of XML for ADMX and Reg value
2025-11-25 20:14:00 +11:00
Mikael Karlsson 7b87325776 3.10.1.10
Issue 380 - ADMX Import / Reg Values fails because of XML format.
2025-11-24 21:56:42 +11:00
Mikael Karlsson 7657fac645 3.10.1.9
Issue 378 - Add support for sorting exported json files.
2025-11-23 17:08:27 +11:00
Mikael Karlsson 37700847b5 3.10.1.8
Issue 381 - Fix issue with Device Categories and Expand Assignments enabled.
2025-11-20 22:32:54 +11:00
Mikael Karlsson e37a44dd87 3.10.1.7
Issue 375 - Additional error handling in the Word output provider.
2025-11-13 20:24:03 +11:00
Mikael Karlsson cd26450a10 3.10.1.6
Issues 375 - Add support for Strict Open XML document
2025-11-11 18:59:35 +11:00
Mikael Karlsson f1fdf5c078 3.10.1.5
Issue 367
2025-10-15 09:54:33 +11:00
Mikael Karlsson 03b27b1775 3.10.1.4
Issue 364 - Paging issues
Issue 367 - Login with App in UI
2025-10-11 13:40:24 +11:00
Mikael Karlsson 9bb966015e 3.10.1.3
Issue 364 - Conditional Access policies does not support paging.
2025-09-28 14:20:28 +10:00
Mikael Karlsson 286f238fde 3.10.1.1
Issue 364 - Failed to create group caused by wrong mailNickname
2025-09-23 20:18:22 +10:00
Mikael Karlsson 8368af379f 3.10.1.1
Fix Issue 364 - Conditional Access does not return Next page. Fall back to default for now.
2025-09-14 18:57:39 +10:00
Mikael Karlsson faffa95d8a Merge pull request #363 from Micke-K/Development
3.10.1 Release
2025-09-14 14:19:01 +10:00
Mikael Karlsson 485a9de855 3.10.1 2025-09-14 14:15:15 +10:00
Mikael Karlsson 951b583dd2 3.10.0.11
Added full support for BIOS Config polices eg export and edit file + documentation
2025-08-09 13:30:51 +10:00
Mikael Karlsson f27175d543 3.10.0.10
Added support for BIOS Confiuration policies
2025-08-06 20:19:13 +10:00
Mikael Karlsson 1ab13bf2dd 3.10.0.9
Fixed issue with Not Configured for Custom Compliance script.
Added option to skip date when generating MD document.
2025-08-03 20:42:46 +10:00
Mikael Karlsson 8952e2894a 3.10.0.8
Fix renaming Settings Catalog policies
2025-08-03 20:12:34 +10:00
Mikael Karlsson a0bac61ba4 Merge pull request #339 from MrR0bert/FixExportDirectoryNaming
Add Trim() to sanitize the organization displayName property
2025-08-03 19:12:08 +10:00
Mikael Karlsson 8fab983b25 Merge pull request #347 from brefra/Fix-Upload
Fix .intunewin uploads when using powershell 7.4+
2025-08-03 19:06:36 +10:00
Frank 6f6eba6959 Fix content upload at powershell 7.4+ 2025-07-29 21:08:56 +02:00
Mikael Karlsson b69cc227a4 3.10.0.7
Fixed issue with ADMX import and different enum format
Fixed issue with skipping Not Configured for Compliance Policies
Added support for documenting Compliance Policy V2 (Linux)
2025-07-28 21:11:17 +10:00
Mikael Karlsson 4253901249 3.10.0.6
Fixed import order for Compliance Scripts
2025-07-16 04:23:32 +10:00
Robert Kooistra cfb0e5f6e4 Moved trim of org displayName to the moment it is loaded instead of where it's used 2025-06-24 10:07:17 +02:00
MrR0b3rt 125d2e2b44 Forgot brackets before calling Trim() 2025-06-23 15:10:33 +02:00
MrR0b3rt 95c38a2b3d Add Trim() to sanitize the organization displayName property 2025-06-23 14:29:07 +02:00
Mikael Karlsson 9586ffb3fa 3.10.0.5
Removed deviceStates property for Conditional Access policy import. The property is depricated
2025-06-17 02:04:35 +10:00
Mikael Karlsson 5984acfca0 3.10.0.4
Fixed issue with Word Interop not loading
Added support for PDF output
2025-05-25 21:07:57 +10:00
Mikael Karlsson e1328ac7dd 3.10.0.3
Added documenting for file content eg MacOS Custom Settings
2025-05-03 15:42:03 +10:00
Mikael Karlsson 968fb4866c 3.10.0.2
Fixed issue with importing Security Baseline 24H2.
2025-04-19 14:53:57 +10:00
Mikael Karlsson 2169e91c9c 3.10.0
Fixed bad trimming
2025-03-16 20:59:19 +11:00
Mikael Karlsson ad5d6df95e 3.10.0
Added additional logging
2025-03-16 20:59:01 +11:00
Mikael Karlsson 9232769d5b Fixed Compare Issues
Fixed issues with Compare and Settings Catalog
2025-03-09 19:57:41 +11:00
Mikael Karlsson 06ab2c2023 Paging issues
Device settings does not return next page so get top 500
Found a rare issue where Settings Catalog could return next page after all items were returned. This caused the app to crash when scrolling the list.
2025-03-01 12:08:16 +11:00
Mikael Karlsson 8601a5b38e Initial 3.10.0 upload 2025-02-22 21:52:13 +11:00
Mikael Karlsson 17e9b786be Merge pull request #296 from Mykhailo-Roit/master
feat: replace_with_assignments import type
2025-01-12 17:20:36 +11:00
Mikael Karlsson e2c40b0a67 Merge pull request #290 from Systems-Liam/patch-1
Update DocumentationWordOptions.xaml
2025-01-12 17:17:14 +11:00
Mykhailo-Roit 381967c8cf fix conditions 2025-01-09 15:40:21 +02:00
Mykhailo-Roit 28022615a1 feat: add tooltip description for 'Replace with assignments' option in import forms 2025-01-08 18:58:36 +02:00
Mykhailo-Roit ff539f9ec1 feat: replace_with_assignments import type 2025-01-08 18:45:48 +02:00
Liam 7bab923a1f Update DocumentationWordOptions.xaml
Update typo on line 251.  Ducument to Document
2025-01-04 21:36:09 +00:00
119 changed files with 22699 additions and 28123 deletions
+39
View File
@@ -0,0 +1,39 @@
title: ""
body:
- type: markdown
attributes:
value: |
Ideas is for shaping something before it becomes a request. Say what you
are trying to achieve rather than the control you picture, and it will be
clear whether the application should grow a feature or already has one.
- type: dropdown
id: version
attributes:
label: Which version are you using?
options:
- 4.0 beta
- 3.x
- Neither yet, just looking
validations:
required: true
- type: textarea
id: goal
attributes:
label: What are you trying to achieve?
validations:
required: true
- type: textarea
id: idea
attributes:
label: How do you picture it working?
- type: textarea
id: scale
attributes:
label: How often, and at what scale?
description: >
How many tenants, how many policies, how often you do it. Scale changes
the answer more than anything else here.
+64
View File
@@ -0,0 +1,64 @@
title: "[Question] "
labels: ["needs-triage"]
body:
- type: markdown
attributes:
value: |
Most questions here turn out to be one of four things: a sign-in method
the embedded window cannot complete, a list that looks short because the
version you are on stops paging, a permission the app registration does
not hold, or an object type that has no public Graph endpoint. The fields
below let that be spotted straight away.
- type: dropdown
id: version
attributes:
label: Version
options:
- 4.0 beta
- 3.x
validations:
required: true
- type: dropdown
id: signin
attributes:
label: How do you sign in?
options:
- Interactive, embedded window (the default in v3)
- Interactive, Web Account Manager (WAM)
- Interactive, system browser (the default in v4)
- Device code
- Application and secret
- Application and certificate
- Managed identity or federated credential
- Bring your own token
validations:
required: true
- type: dropdown
id: cloud
attributes:
label: Cloud
options:
- Public (commercial)
- US Government (GCC High)
- US Government (DoD)
- China (21Vianet)
validations:
required: true
- type: textarea
id: question
attributes:
label: What are you trying to do?
validations:
required: true
- type: textarea
id: tried
attributes:
label: What have you tried, and what happened?
description: >
Paste any error text here. **Remove tenant identifiers, user names and
tokens first.**
+4
View File
@@ -0,0 +1,4 @@
# GitHub renders this as the "Sponsor" button on the repository page
# (public repositories, default branch). Buy Me a Coffee takes the
# username, not the URL: https://buymeacoffee.com/MickeK
buy_me_a_coffee: MickeK
+116
View File
@@ -0,0 +1,116 @@
name: Bug report (version 3.x)
description: Something is wrong in the current release. Windows only.
title: "[3.x] "
labels: ["bug", "v3", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Version 3 stays supported until 4.0 leaves beta.
Before filing, check whether 4.0 already fixes it. Several long-standing
reports here are addressed there: sign-in with passkeys and other
phishing-resistant methods, lists that stopped at 20, 100 or a few
hundred objects, sovereign cloud sign-in, and running without a user
present. The 4.0 beta lives on the `v4` branch.
- type: checkboxes
id: preflight
attributes:
label: Before reporting
options:
- label: >
If my sign-in involves a passkey, security key, Windows Hello or a
phishing-resistant policy: I know the embedded sign-in window cannot
complete those, and I have said so below rather than reporting it as
a broken login.
required: true
- label: >
I searched existing issues and discussions, including closed ones.
required: true
- type: input
id: version
attributes:
label: Version
placeholder: 3.10.3
validations:
required: true
- type: dropdown
id: signin
attributes:
label: How did you sign in?
options:
- Interactive, embedded window (the default)
- Interactive, other
- Application and secret
- Application and certificate
- Not signed in / sign-in is the problem
validations:
required: true
- type: dropdown
id: cloud
attributes:
label: Cloud
options:
- Public (commercial)
- US Government (GCC High)
- US Government (DoD)
- China (21Vianet)
validations:
required: true
- type: input
id: powershell
attributes:
label: PowerShell version
description: Run `$PSVersionTable.PSVersion`.
placeholder: "5.1.22621.4391"
validations:
required: true
- type: dropdown
id: area
attributes:
label: Which part of the application?
options:
- Sign-in and authentication
- Export
- Import
- Copy
- Compare
- Documentation output
- Assignments, groups or filters
- Bulk or silent operations
- ADMX or tools
- The user interface itself
- Something else
validations:
required: true
- type: textarea
id: what
attributes:
label: What happened, and what did you expect instead?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
validations:
required: true
- type: textarea
id: log
attributes:
label: Log
description: >
The relevant lines, or the error text. **Remove tenant identifiers, user
names, access tokens and secrets before pasting.**
render: text
validations:
required: true
+154
View File
@@ -0,0 +1,154 @@
name: Bug report (version 4.0 beta)
description: Something is wrong in 4.0. Runs on Windows, macOS and Linux.
title: "[4.0] "
labels: ["bug", "v4", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for testing the beta. Four fields below do most of the work:
**how you signed in**, **which cloud**, **which operating system** and
**the log**. Reports without them usually need a round trip before
anything can happen.
- type: checkboxes
id: preflight
attributes:
label: Before reporting
description: These three cover the majority of beta reports so far.
options:
- label: >
I read the release notes for this beta, including the breaking changes.
required: true
- label: >
If my sign-in involves a passkey, security key, Windows Hello or any
phishing-resistant policy: I enabled **Use Web Account Manager (WAM)
for login** or **Use system browser for login** in Settings, and tried
again. The embedded window cannot complete those methods.
required: true
- label: >
My problem is not Inventory Policies returning 403. That endpoint is
not published on the public Graph API, so the application cannot read
it with a normal sign-in. It is a Microsoft limitation, not a bug.
A bring-your-own-token sign-in can reach it.
required: true
- type: input
id: version
attributes:
label: Version
description: The About dialog, or the ModuleVersion in IntuneManagement.psd1.
placeholder: 4.0.0-beta1
validations:
required: true
- type: dropdown
id: signin
attributes:
label: How did you sign in?
description: >
The single most useful field in this form. Roughly a third of all reports
on this project have turned out to be sign-in behaviour rather than the
feature being reported.
options:
- Interactive, embedded window
- Interactive, Web Account Manager (WAM)
- Interactive, system browser (the default)
- Device code
- Application and secret
- Application and certificate
- Managed identity or federated credential
- Bring your own token
- Not signed in / sign-in is the problem
validations:
required: true
- type: dropdown
id: cloud
attributes:
label: Cloud
options:
- Public (commercial)
- US Government (GCC High)
- US Government (DoD)
- China (21Vianet)
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating system
description: 4.0 runs the full application outside Windows, so this now matters.
options:
- Windows
- macOS (Apple Silicon)
- macOS (Intel)
- Linux
validations:
required: true
- type: input
id: powershell
attributes:
label: PowerShell edition and version
description: Run `$PSVersionTable.PSVersion` and `$PSVersionTable.PSEdition`.
placeholder: "7.4.6, Core"
validations:
required: true
- type: dropdown
id: area
attributes:
label: Which part of the application?
options:
- Sign-in and authentication
- Export
- Import
- Copy
- Compare
- Documentation output
- Assignments, groups or filters
- Bulk operations
- ADMX or tools
- The user interface itself
- Automation through the PowerShell commands
- Something else
validations:
required: true
- type: input
id: objecttype
attributes:
label: Which object type, if it is specific to one
placeholder: Settings Catalog, Conditional Access, Win32 app, ...
- type: textarea
id: what
attributes:
label: What happened, and what did you expect instead?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
placeholder: |
1. Sign in to ...
2. Open ...
3. Click ...
validations:
required: true
- type: textarea
id: log
attributes:
label: Log
description: >
The relevant lines from the log file, or the error text. **Remove tenant
identifiers, user names, access tokens and secrets before pasting.** If
an exported policy file is needed, redact it or use one from a lab tenant.
render: text
validations:
required: true
+17
View File
@@ -0,0 +1,17 @@
# Turns off the "open a blank issue" escape hatch, so every report arrives
# through a form with the fields that make it answerable. Questions go to
# Discussions, which is where most of them already end up.
blank_issues_enabled: false
contact_links:
- name: Question, or not sure it is a bug
url: https://github.com/Micke-K/IntuneManagement/discussions/categories/q-a
about: Ask in Q&A. Most "it does not show my policies" reports are answered there in a day.
- name: Feature idea worth discussing first
url: https://github.com/Micke-K/IntuneManagement/discussions/categories/ideas
about: Ideas that are still taking shape belong here. A concrete request can go straight to an issue.
- name: Version 4.0 beta feedback
url: https://github.com/Micke-K/IntuneManagement/discussions/categories/announcements
about: Testing the 4.0 beta? Start at the pinned announcement, which lists what to try first.
- name: Security vulnerability
url: https://github.com/Micke-K/IntuneManagement/security/advisories/new
about: Never report a security problem in a public issue. Use private reporting.
+71
View File
@@ -0,0 +1,71 @@
name: Feature request
description: Something the application should do and does not.
title: "[Request] "
labels: ["enhancement", "needs-triage"]
body:
- type: markdown
attributes:
value: |
If the idea is still taking shape, [Ideas in
Discussions](https://github.com/Micke-K/IntuneManagement/discussions/categories/ideas)
is the better room. Use this form when you can describe the outcome you
want.
- type: dropdown
id: version
attributes:
label: Which version is this for?
description: >
This one is read by a human, not by automation, so say what you mean.
A request that 4.0 already covers is worth checking against the release
notes first.
options:
- Version 4.0
- Version 3.x
- Either
validations:
required: true
- type: textarea
id: problem
attributes:
label: What are you trying to do?
description: >
The situation, not the solution. "I move policies between two tenants
every month and have to redo the assignments by hand" tells more than
"add a button".
validations:
required: true
- type: textarea
id: proposal
attributes:
label: What would you like it to do?
validations:
required: true
- type: textarea
id: workaround
attributes:
label: How do you handle it today?
description: Including "not at all", which is useful to know.
- type: dropdown
id: area
attributes:
label: Which part of the application?
options:
- Export
- Import
- Copy
- Compare
- Documentation output
- Assignments, groups or filters
- Bulk operations
- ADMX or tools
- The user interface
- Automation through the PowerShell commands
- A policy type that is not supported yet
- Something else
validations:
required: true
+47
View File
@@ -0,0 +1,47 @@
<!--
Target branch
Fixing version 3? target Development
Fixing version 4? target v4
A pull request opened against the default branch is retargeted to
Development before review. Use the Edit button next to the title.
-->
<!--
How version 4 changes are applied during the beta
Version 4 is developed elsewhere and the v4 branch is published as one
snapshot per release, not as a running history. An accepted change is
applied upstream and appears in the next release, so your commit will not
show up in this branch. You are credited in the release notes instead.
Nothing is lost, and nothing needs doing on your side.
-->
## What does this change?
<!-- One or two sentences. What was wrong, or what is now possible. -->
## Related issue
<!-- "Fixes #123", or "none" if there isn't one. -->
## How was it tested?
<!--
Which version, which cloud, and which operating system, since 4.0 runs on
three. If it touches sign-in, say which method you used: embedded window,
Web Account Manager, system browser, device code, or an application identity.
-->
- Version:
- Cloud:
- Operating system and PowerShell version:
- Tests run:
## Anything a reviewer should know
<!--
Behaviour that changes for existing users, a setting that moves, a file format
that shifts. Say so here rather than leaving it to be discovered.
-->
+3
View File
@@ -8,5 +8,8 @@
/*.new /*.new
/*.old /*.old
/Extensions/*.zip /Extensions/*.zip
Extensions_dev/
.gitignore .gitignore
CloudAPIPowerShellManagement.log CloudAPIPowerShellManagement.log
AGENTS.md
CLAUDE.md
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -12,7 +12,7 @@
RootModule = 'CloudAPIPowerShellManagement.psm1' RootModule = 'CloudAPIPowerShellManagement.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '3.9.8' ModuleVersion = '3.11.0'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()
+53 -1
View File
@@ -85,7 +85,12 @@ function Initialize-CloudAPIManagement
[string] [string]
$secret, $secret,
[string] [string]
$certificate $certificate,
[string]
$GraphEnvironment,
[string]
$GCCType
) )
$PSModuleAutoloadingPreference = "none" $PSModuleAutoloadingPreference = "none"
@@ -102,10 +107,57 @@ function Initialize-CloudAPIManagement
if($tenantId) if($tenantId)
{ {
Write-Host "Using Tenant Id: $tenantId"
$global:AzureAppId = $appId $global:AzureAppId = $appId
$global:ClientSecret = $secret $global:ClientSecret = $secret
$global:ClientCert = $certificate $global:ClientCert = $certificate
$global:UseGraphEnvironment = $GraphEnvironment
$global:UseGCCType = $GCCType
if($global:AzureAppId)
{
Write-Host "Using Azure App Id: $($global:AzureAppId)"
}
else
{
Write-Warning "Azure App Id is missing. Use -AppId <AppID> on the command line"
}
if($global:ClientSecret -or $global:ClientCert)
{
if($global:ClientSecret)
{
Write-Host "Using Azure App Secret"
}
else
{
Write-Host "Using Azure App Certificate"
}
}
else
{
Write-Warning "Azure App Secret or Certificate is missing. Use -Secret <Secret> or -Certificate <Certificate> on the command line"
}
if($global:UseGraphEnvironment)
{
Write-Host "Using Azure Graph Environment: $($global:UseGraphEnvironment)"
}
if($global:UseGCCType)
{
Write-Host "Using Graph Environment type: $($global:UseGCCType)"
}
} }
elseif($secret)
{
$global:ClientSecret = $secret
}
if($certificate)
{
$global:ClientCert = $certificate
}
if($global:hideUI -ne $true) if($global:hideUI -ne $true)
{ {
+111 -44
View File
@@ -86,9 +86,13 @@ function Start-CoreApp
Write-Log "#####################################################################################" Write-Log "#####################################################################################"
Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())" Write-Log "PowerShell version: $($PSVersionTable.PSVersion.ToString())"
Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())" if($PSVersionTable.BuildVersion) {
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())" Write-Log "PowerShell build: $($PSVersionTable.BuildVersion.ToString())"
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)" }
if($PSVersionTable.CLRVersion) {
Write-Log "PowerShell CLR: $($PSVersionTable.CLRVersion.ToString())"
}
Write-Log "PowerShell edition: $($PSVersionTable.PSEdition)"
try try
{ {
@@ -344,6 +348,14 @@ function Write-LogError
} }
Write-Log $Text 3 Write-Log $Text 3
if((Get-SettingValue "ShowStackTrace") -eq $true)
{
Write-Log "Stack trace:`n $($Exception.StackTrace)"
Write-Log "Script stack trace:`n $($Exception.ScriptStackTrace)"
}
} }
function Write-Status function Write-Status
@@ -648,7 +660,7 @@ function Show-AboutDialog
Set-XamlProperty $script:dlgAbout "lstModules" "ItemsSource" $loadedItems Set-XamlProperty $script:dlgAbout "lstModules" "ItemsSource" $loadedItems
Add-XamlEvent $script:dlgAbout "linkSource" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:dlgAbout "linkSource" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
Show-ModalForm "About" $script:dlgAbout Show-ModalForm "About" $script:dlgAbout
} }
@@ -665,6 +677,8 @@ function Show-UpdatesDialog
Show-ModalObject Show-ModalObject
} }
Add-XamlEvent $script:dlgUpdates "linkSource" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
$fileContent = Get-Content -Raw -Path ($global:AppRootFolder + "\ReleaseNotes.md") $fileContent = Get-Content -Raw -Path ($global:AppRootFolder + "\ReleaseNotes.md")
try try
{ {
@@ -685,7 +699,11 @@ function Show-UpdatesDialog
$params.Add("UseBasicParsing", $true) $params.Add("UseBasicParsing", $true)
} }
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" @params # The notes at the newest 3.x release tag, never at the default branch: that
# branch will carry version 4 once the branches are renamed.
$latestVer = Get-LatestGitHubVersion $params
$notesRef = if($latestVer) { "?ref=$($latestVer.ToString())" } else { "" }
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md$notesRef" @params
if($content) if($content)
{ {
$txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content))) $txt = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
@@ -710,6 +728,37 @@ function Show-UpdatesDialog
Show-ModalForm "Release Notes" $script:dlgUpdates -HideButtons Show-ModalForm "Release Notes" $script:dlgUpdates -HideButtons
} }
# Newest published 3.x release on GitHub, or $null.
#
# releases/latest answers the newest release of ANY version. The day 4.0.0 is
# published it would tell every 3.x installation to upgrade to a breaking
# change, and reading the manifest on the default branch stops working once the
# branches are renamed for version 4. The releases list filtered to this major
# is the one source that survives both. Pre-releases and drafts are skipped.
function Get-LatestGitHubVersion
{
param($Params = @{})
$latest = $null
try
{
$releases = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases?per_page=100" @Params
foreach($release in @($releases))
{
if($release.draft -or $release.prerelease) { continue }
$ver = $null
try { $ver = [version](([string]$release.tag_name) -replace '^v','') } catch { continue }
if($ver.Major -ne 3) { continue }
if($null -eq $latest -or $ver -gt $latest) { $latest = $ver }
}
}
catch
{
Write-Log "Failed to list GitHub releases: $($_.Exception.Message)" 2
}
return $latest
}
function Get-IsLatestVersion function Get-IsLatestVersion
{ {
if($global:MainAppStarted -ne $true) if($global:MainAppStarted -ne $true)
@@ -728,35 +777,7 @@ function Get-IsLatestVersion
$params.Add("UseBasicParsing", $true) $params.Add("UseBasicParsing", $true)
} }
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" @params $gitHubVer = Get-LatestGitHubVersion $params
if($content.Name)
{
try
{
$gitHubVer = [version]$content.Name
}
catch {}
}
if($null -eq $gitHubVer)
{
$params = @{}
$proxyURI = Get-ProxyURI
if($proxyURI)
{
$params.Add("proxy", $proxyURI)
$params.Add("UseBasicParsing", $true)
}
$content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/CloudAPIPowerShellManagement.psd1" @params
$gitHubText = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($content.content)))
$gitHubInfo = Get-ModuleDataTable $gitHubText
try
{
$gitHubVer = [version]$gitHubInfo.ModuleVersion
}
catch {}
}
if(-not $gitHubVer) if(-not $gitHubVer)
{ {
@@ -1069,7 +1090,7 @@ function Get-Folder
{ {
if($global:WindowsAPICodePackLoaded -eq $false) if($global:WindowsAPICodePackLoaded -eq $false)
{ {
$apiCodec = Join-Path $global:AppRootFolder "Microsoft.WindowsAPICodePack.Shell.dll" $apiCodec = Join-Path $global:AppRootFolder "Bin\Microsoft.WindowsAPICodePack.Shell.dll"
if([IO.File]::Exists($apiCodec)) if([IO.File]::Exists($apiCodec))
{ {
Add-Type -Path $apiCodec | Out-Null Add-Type -Path $apiCodec | Out-Null
@@ -1100,7 +1121,7 @@ function Get-Folder
{ {
$dlgCOFD.InitialDirectory = $path $dlgCOFD.InitialDirectory = $path
} }
if($dlgCOFD.ShowDialog($window) = [Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult]::Ok) if($dlgCOFD.ShowDialog($window) -eq [Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult]::Ok)
{ {
$dlgCofd.FileName $dlgCofd.FileName
} }
@@ -1398,7 +1419,7 @@ function Remove-Setting
try try
{ {
$temp = Get-Item -LiteralPath $regPath -ErrorAction SilentlyContinue $temp = Get-Item -LiteralPath $regPath -ErrorAction SilentlyContinue
if(($temp.Property -contains $Key)) if(($temp -and $temp.Property -contains $Key))
{ {
Remove-ItemProperty -Path $regPath -Name $Key -Force -ErrorAction Stop Remove-ItemProperty -Path $regPath -Name $Key -Force -ErrorAction Stop
} }
@@ -1412,7 +1433,7 @@ function Remove-Setting
function Get-Setting function Get-Setting
{ {
param($SubPath = "", $Key = "", $defautValue) param($SubPath = "", $Key = "", $defaultValue)
if(-not $key) if(-not $key)
{ {
@@ -1477,7 +1498,7 @@ function Get-Setting
if(-not $val) if(-not $val)
{ {
$defautValue $defaultValue
} }
else else
{ {
@@ -1700,7 +1721,11 @@ function Add-SettingsItem
{ {
if($settingValue.Description) if($settingValue.Description)
{ {
$descriptionInfo = "<Rectangle Style=`"{DynamicResource InfoIcon}`" ToolTip=`"$($settingValue.Description)`" Margin=`"5,0,0,0`" />" $descriptionInfo = "<Rectangle Style=`"{DynamicResource InfoIcon}`" Margin=`"5,0,0,0`">" +
"<Rectangle.ToolTip><TextBlock>" +
$settingValue.Description +
"</TextBlock></Rectangle.ToolTip>" +
"</Rectangle>"
} }
$xaml = @" $xaml = @"
@@ -1990,6 +2015,14 @@ function Add-DefaultSettings
DefaultValue = $true DefaultValue = $true
}) "General" }) "General"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Show stack error"
Key = "ShowStackTrace"
Type = "Boolean"
Description = "Write exception stack trace info to the log."
DefaultValue = $false
}) "General"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Debug" Title = "Debug"
Key = "Debug" Key = "Debug"
@@ -2461,9 +2494,9 @@ function Get-MainWindow
{ {
$script:welcomeForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\Welcome.xaml") -AddVariables $script:welcomeForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\Welcome.xaml") -AddVariables
Add-XamlEvent $script:welcomeForm "gitHubLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "gitHubLink" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "licenseLink" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "licenseLink" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "addCustomApp" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
Add-XamlEvent $script:welcomeForm "chkAcceptConditions" "add_click" { Add-XamlEvent $script:welcomeForm "chkAcceptConditions" "add_click" {
$global:btnAcceptConditions.IsEnabled = ($this.IsChecked -eq $true) $global:btnAcceptConditions.IsEnabled = ($this.IsChecked -eq $true)
@@ -2498,7 +2531,7 @@ function Get-MainWindow
if($appIdChangeInformed -ne "true") { if($appIdChangeInformed -ne "true") {
$script:oldAzureAppForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\OldAzureApp.xaml") $script:oldAzureAppForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\OldAzureApp.xaml")
Add-XamlEvent $script:oldAzureAppForm "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true }) Add-XamlEvent $script:oldAzureAppForm "addCustomApp" "Add_RequestNavigate" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true })
Add-XamlEvent $script:oldAzureAppForm "btnOK" "add_click" { Add-XamlEvent $script:oldAzureAppForm "btnOK" "add_click" {
if((Get-XamlProperty $script:oldAzureAppForm "chkChangeApp" "IsChecked") -eq $true) { if((Get-XamlProperty $script:oldAzureAppForm "chkChangeApp" "IsChecked") -eq $true) {
@@ -2737,6 +2770,27 @@ function Format-XML
$StringWriter.ToString() $StringWriter.ToString()
} }
function Update-XmlFormatting {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string]$Xml
)
process {
$Xml = $Xml -replace '<([^\s/>]+)([^>]*)\s/>' , '<$1$2/>'
$Xml = ($Xml -split "`r?`n") |
Where-Object { $_.Trim().Length -gt 0 } |
ForEach-Object { $_ } |
Out-String
$Xml = $Xml -replace "`r`n", "`n"
return $Xml.Trim()
}
}
function Show-LogView function Show-LogView
{ {
if($script:LogViewObject -and -not $script:LogViewObject.ViewPanel) if($script:LogViewObject -and -not $script:LogViewObject.ViewPanel)
@@ -2890,6 +2944,19 @@ function Get-DataGridValues
($dataGrid.ItemsSource | Select -Property $properties) ($dataGrid.ItemsSource | Select -Property $properties)
} }
function Get-GUIDs
{
param($text)
$regExpGuid = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
$uniqueGuids = New-Object System.Collections.Generic.HashSet[String]
# Use regular expressions to extract the GUIDs
[regex]::Matches($text, $regExpGuid) | ForEach-Object { $uniqueGuids.Add($_.Value) | Out-Null }
$uniqueGuids
}
New-Alias -Name ?? -value Invoke-Coalesce New-Alias -Name ?? -value Invoke-Coalesce
New-Alias -Name ?: -value Invoke-IfTrue New-Alias -Name ?: -value Invoke-IfTrue
+69
View File
@@ -101,6 +101,75 @@ The json files contains a definition of each property to document. This includes
The `DocumentationCustom.psm1` file also takes care of custom documentation for some object types e.g. Conditional Access. App Configuration policies etc. These objects are documented via a PowerShell function in the script. The `DocumentationCustom.psm1` file also takes care of custom documentation for some object types e.g. Conditional Access. App Configuration policies etc. These objects are documented via a PowerShell function in the script.
**dataTypes Reference**
The following `dataType` values are supported in property-based ObjectInfo json files:
| Value | Name | Description |
|---|---|---|
| `0` | Boolean | Translated via the `booleanActions` field |
| `1` | Base64 | Certificate or binary data decoded to a UTF-8 string; filename used if `filenameEntityKey` is set |
| `2` | Multiline String | Multiline text or XML decoded from Base64 if needed; stored to a payload file if `filenameEntityKey` is set |
| `3` | Image | Binary image; outputs "Image file" when a value is present |
| `4` | Linked Certificate | Certificate resolved via OData navigation link |
| `5` | Complex Options | Iterates child `complexOptions` as a sub-section |
| `6` | Complex Option (sub-property) | Iterates `complexOptions` resolved via `entityKey` sub-property |
| `7` | OMA DateTime | Raw OMA DateTime string |
| `8` | Sub-category | Sets the current sub-category label from `nameResourceKey` |
| `9` | Label / OData Type | Skipped — UI label or `@odata.type` property |
| `10` | Information Box | Skipped — UI-only information box |
| `11` | App Picker | Application picker |
| `12` | Multiline String Array | Array of strings joined with the object separator |
| `13` | Multi Option | Multiple selection; translated via `Invoke-TranslateMultiOption` |
| `14` | Int32 | 32-bit integer |
| `15` | Int64 | 64-bit integer |
| `16` | Option | Single-select option; translated via `Invoke-TranslateOption` |
| `19` | Option (variant) | Single-select option; translated via `Invoke-TranslateOption` |
| `20` | String | Plain string |
| `21` | Table | Sub-table; translated via `Invoke-TranslateTable` |
| `22` | Scale Value | Numeric value combined with a unit from `scaleOptions` (e.g. "4 Years") |
| `99` | Reserved | No-op placeholder |
| `100` | Duration | Custom `Edm.Duration` formatting via `Invoke-TranslateDuration` |
| `101` | Static Label | Language string taken from the `value` field |
| `102` | Culture Name | Language/culture name string |
| `103` | Boolean (hide on false) | Boolean via `booleanActions`; hides child properties when `false` |
| `104` | Multi Option Boolean | Multi-option via boolean; hides children when `false` |
| `105` | Multi Option Boolean (inverted) | Like `104` but treats `false` as the selected state |
| `106` | Language Array | Array of culture/language names joined with the object separator |
| `107` | Static Value | Literal string taken directly from the `value` field |
| `108` | String with Format | String formatted using the `formatStringKey` language template |
| `200` | Multi Option (language key) | Translated string looked up via `entityKey` as a language string ID |
**booleanActions Reference**
The `booleanActions` field controls the text shown for `true`/`false` values when `dataType` is `0`, `103`, `104`, or `105`.
Values `0`–`9` and `107`–`108` only display a custom label when `true`; a `false` value falls through to *Not Configured*.
| Value | `true` → | `false` → |
|---|---|---|
| `0` | Allow | *(Not Configured)* |
| `1` | Require | *(Not Configured)* |
| `2` | Enable | *(Not Configured)* |
| `3` | Block | *(Not Configured)* |
| `4` | Configured | *(Not Configured)* |
| `5` | Disable | *(Not Configured)* |
| `6` | Limit | *(Not Configured)* |
| `7` | Show | *(Not Configured)* |
| `8` | Hide | *(Not Configured)* |
| `9` | Yes | *(Not Configured)* |
| `100` | Block | Allow |
| `101` | Require | Not Required |
| `102` | Enable | Disable |
| `107` | Show | *(Not Configured)* |
| `108` | Hide | *(Not Configured)* |
| `109` | Yes | No |
| `110` | No | Yes |
| `120` | On | Off |
| `200` | Allow | Block |
| `201` | Not Required | Require |
| `220` | Off | On |
**Language Support** **Language Support**
The Settings based objects get their language strings from Graph APIs with a few exceptions. The Settings based objects get their language strings from Graph APIs with a few exceptions.
+3 -1
View File
@@ -151,5 +151,7 @@
"149": "WiredNetwork", "149": "WiredNetwork",
"150": "DefenderAntivirus", "150": "DefenderAntivirus",
"151": "CustomCompliance", "151": "CustomCompliance",
"152": "IosDefenderAtp" "152": "IosDefenderAtp",
"153": "WSLCompliance",
"154": "WindowsZtdns"
} }
+27
View File
@@ -314,6 +314,15 @@
] ]
}, },
{
"ObjectType": "#microsoft.graph.androidWorkProfileMigrationConfiguration",
"PolicyType": "AndroidForWorkMigrationPolicy",
"PolicyTypeLanguageId": "androidForWorkMigrationPolicy",
"PlatformLanguageId": "AndroidForWork",
"Categories": [
]
},
{ {
"ObjectType": "#microsoft.graph.androidForWorkVpnConfiguration", "ObjectType": "#microsoft.graph.androidForWorkVpnConfiguration",
"PolicyType": "AndroidForWorkVpn", "PolicyType": "AndroidForWorkVpn",
@@ -625,6 +634,15 @@
] ]
}, },
{
"ObjectType": "#microsoft.graph.iosWiredNetworkConfiguration",
"PolicyType": "IosWiredNetwork",
"PolicyTypeLanguageId": "wiredNetwork",
"PlatformLanguageId": "Ios",
"Categories": [
]
},
{ {
"ObjectType": "#microsoft.graph.iosEnterpriseWiFiConfiguration", "ObjectType": "#microsoft.graph.iosEnterpriseWiFiConfiguration",
"PolicyType": "IosWiFi", "PolicyType": "IosWiFi",
@@ -1197,6 +1215,15 @@
"HealthMonitoring" "HealthMonitoring"
] ]
}, },
{
"ObjectType": "#microsoft.graph.windowsZtdnsConfiguration",
"PolicyType": "Windows10Ztdns",
"PolicyTypeLanguageId": "windowsZeroTrustDns",
"PlatformLanguageId": "Windows10",
"Categories": [
]
},
{ {
"ObjectType": "#microsoft.graph.windows10XWifiConfiguration", "ObjectType": "#microsoft.graph.windows10XWifiConfiguration",
"PolicyType": "Windows10XWifi", "PolicyType": "Windows10XWifi",
+108 -6
View File
@@ -856,20 +856,122 @@
}, },
"complexOptions": [ "complexOptions": [
{ {
"nameResourceKey": "Win32Program.installCommand", "nameResourceKey": "Win32Program.installerTypeText",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "installCommandLine", "entityKey": "installerType",
"dataType": 20, "dataType": 20,
"booleanActions": 0, "booleanActions": 0,
"category": "Win32Program.selectorLabel" "category": "Win32Program.selectorLabel",
"Children": [
{
"nameResourceKey": "Win32Program.installCommand",
"descriptionResourceKey": "",
"entityKey": "installCommandLine",
"dataType": 20,
"booleanActions": 0,
"category": "Win32Program.selectorLabel",
"Condition": {
"Expressions": [
{
"property": "installCommandLine"
}
]
}
},
{
"nameResourceKey": "Win32Program.installScript",
"descriptionResourceKey": "",
"entityKey": "activeInstallScript",
"dataType": 6,
"booleanActions": 0,
"category": "Win32Program.selectorLabel",
"complexOptions": [
{
"nameResourceKey": "TableHeaders.scriptName",
"descriptionResourceKey": "",
"entityKey": "scriptName",
"dataType": 20,
"booleanActions": 0,
"category": "Win32Program.selectorLabel"
},
{
"nameResourceKey": "Win32Requirements.AdditionalRequirements.Script.enforceSignatureCheck",
"descriptionResourceKey": "Win32Requirements.AdditionalRequirements.Script.enforceSignatureCheckTooltip",
"entityKey": "enforceSignatureCheck",
"dataType": 0,
"booleanActions": 109,
"category": "Win32Program.selectorLabel"
},
{
"nameResourceKey": "DetectionRules.CustomScript.runAs32Bit",
"descriptionResourceKey": "DetectionRules.CustomScript.runAs32BitTooltip",
"entityKey": "runAs32Bit",
"dataType": 0,
"booleanActions": 109,
"category": "Win32Program.selectorLabel"
}
]
}
]
}, },
{ {
"nameResourceKey": "Win32Program.uninstallCommand", "nameResourceKey": "Win32Program.uninstallerTypeText",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "uninstallCommandLine", "entityKey": "uninstallerType",
"dataType": 20, "dataType": 20,
"booleanActions": 0, "booleanActions": 0,
"category": "Win32Program.selectorLabel" "category": "Win32Program.selectorLabel",
"Children": [
{
"nameResourceKey": "Win32Program.uninstallCommand",
"descriptionResourceKey": "",
"entityKey": "uninstallCommandLine",
"dataType": 20,
"booleanActions": 0,
"category": "Win32Program.selectorLabel",
"Condition": {
"Expressions": [
{
"property": "uninstallCommandLine"
}
]
}
},
{
"nameResourceKey": "Win32Program.uninstallScript",
"descriptionResourceKey": "",
"entityKey": "activeUninstallScript",
"dataType": 6,
"booleanActions": 0,
"category": "Win32Program.selectorLabel",
"complexOptions": [
{
"nameResourceKey": "TableHeaders.scriptName",
"descriptionResourceKey": "",
"entityKey": "scriptName",
"dataType": 20,
"booleanActions": 0,
"category": "Win32Program.selectorLabel"
},
{
"nameResourceKey": "Win32Requirements.AdditionalRequirements.Script.enforceSignatureCheck",
"descriptionResourceKey": "Win32Requirements.AdditionalRequirements.Script.enforceSignatureCheckTooltip",
"entityKey": "enforceSignatureCheck",
"dataType": 0,
"booleanActions": 109,
"category": "Win32Program.selectorLabel"
},
{
"nameResourceKey": "DetectionRules.CustomScript.runAs32Bit",
"descriptionResourceKey": "DetectionRules.CustomScript.runAs32BitTooltip",
"entityKey": "runAs32Bit",
"dataType": 0,
"booleanActions": 109,
"category": "Win32Program.selectorLabel"
}
]
}
]
}, },
{ {
"nameResourceKey": "", "nameResourceKey": "",
@@ -0,0 +1,34 @@
[
{
"nameResourceKey": "TableHeaders.configurationType",
"descriptionResourceKey": "",
"entityKey": "PolicyType.hardwareConfigurations",
"dataType": 200,
"booleanActions": 0,
"category": 1000
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.hardware",
"descriptionResourceKey": "",
"entityKey": "vendor",
"dataType": 20,
"booleanActions": 0,
"category": "SettingDetails.configurations"
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.perDevicePassword",
"descriptionResourceKey": "",
"entityKey": "perDevicePasswordDisabled",
"dataType": 109,
"booleanActions": 9,
"category": "SettingDetails.configurations"
},
{
"nameResourceKey": "HardwareConfig.Settings.Tab.Configurations.file",
"descriptionResourceKey": "",
"entityKey": "fileName",
"dataType": 20,
"booleanActions": 0,
"category": "SettingDetails.configurations"
}
]
@@ -11,89 +11,123 @@
"nameResourceKey": "EnrollmentStatusScreen.progressToggle", "nameResourceKey": "EnrollmentStatusScreen.progressToggle",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "showInstallationProgress", "entityKey": "showInstallationProgress",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.timeout",
"descriptionResourceKey": "",
"entityKey": "installProgressTimeoutInMinutes",
"dataType": 14,
"booleanActions": 0,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageToggle",
"descriptionResourceKey": "",
"entityKey": "showCustomErrorMessage",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageTextBox",
"descriptionResourceKey": "",
"entityKey": "customErrorMessage",
"dataType": 20,
"booleanActions": 0,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.collectLogToggle",
"descriptionResourceKey": "",
"entityKey": "allowLogCollectionOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.enableForAutopilotOnlyToggle",
"descriptionResourceKey": "",
"entityKey": "trackInstallProgressForAutopilotOnly",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.blockToggle",
"descriptionResourceKey": "",
"entityKey": "blockDeviceSetupRetryByUser",
"dataType": 16, "dataType": 16,
"booleanActions": 0, "booleanActions": 109,
"category": "TableHeaders.settings", "category": "TableHeaders.settings",
"options": [ "options": [
{ {
"nameResourceKey": "SettingDetails.no", "nameResourceKey": "SettingDetails.no",
"value": "true" "value": "false"
}, },
{ {
"nameResourceKey": "BooleanActions.yes", "nameResourceKey": "BooleanActions.yes",
"value": "false", "value": "true",
"Children": [ "Children": [
{ {
"nameResourceKey": "EnrollmentStatusScreen.resetToggle", "nameResourceKey": "EnrollmentStatusScreen.timeout",
"descriptionResourceKey": "", "descriptionResourceKey": "",
"entityKey": "allowDeviceResetOnInstallFailure", "entityKey": "InstallProgressTimeout",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.allowToUseToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceUseOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.useSelectedAppsToggleLabel",
"descriptionResourceKey": "",
"entityKey": "waitForApps",
"dataType": 14, "dataType": 14,
"booleanActions": 0, "booleanActions": 0,
"category": "TableHeaders.settings" "category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageToggle",
"descriptionResourceKey": "",
"entityKey": "showCustomErrorMessage",
"dataType": 16,
"booleanActions": 109,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "SettingDetails.no",
"value": "false"
},
{
"nameResourceKey": "BooleanActions.yes",
"value": "true",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.customMessageTextBox",
"descriptionResourceKey": "",
"entityKey": "customErrorMessage",
"dataType": 20,
"booleanActions": 0,
"category": "TableHeaders.settings"
}
]
}
]
},
{
"nameResourceKey": "EnrollmentStatusScreen.collectLogToggle",
"descriptionResourceKey": "",
"entityKey": "allowLogCollectionOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.enableForAutopilotOnlyToggle",
"descriptionResourceKey": "",
"entityKey": "trackInstallProgressForAutopilotOnly",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.blockToggle",
"descriptionResourceKey": "",
"entityKey": "blockDeviceSetupRetryByUser",
"dataType": 16,
"booleanActions": 0,
"category": "TableHeaders.settings",
"options": [
{
"nameResourceKey": "SettingDetails.no",
"value": "true"
},
{
"nameResourceKey": "BooleanActions.yes",
"value": "false",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.resetToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceResetOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.allowToUseToggle",
"descriptionResourceKey": "",
"entityKey": "allowDeviceUseOnInstallFailure",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
},
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.useSelectedAppsToggleLabel",
"descriptionResourceKey": "",
"entityKey": "waitForApps",
"dataType": 14,
"booleanActions": 0,
"category": "TableHeaders.settings",
"Children": [
{
"nameResourceKey": "EnrollmentStatusScreen.Apps.allowNonBlockingAppInstallation",
"descriptionResourceKey": "",
"entityKey": "allowNonBlockingAppInstallation",
"dataType": 0,
"booleanActions": 109,
"category": "TableHeaders.settings"
}
]
}
]
}
]
} }
] ]
} }
@@ -1,14 +1,31 @@
{ {
"customcompliance_compliancewindows10": { "customcompliance_compliancewindows10": {
"dataType": 25, "dataType": 0,
"category": 151, "category": 151,
"nameResourceKey": "AdminConfiguredComplianceSettingName",
"descriptionResourceKey": "CustomComplianceToolTip",
"childSettings": [ "childSettings": [
{
"dataType": 25,
"category": 151,
"childSettings": [
],
"options": [
],
"entityKey": "customCompliance",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
], ],
"options": [ "options": [
], ],
"booleanActions": 0, "entityKey": "customComplianceRequired",
"booleanActions": 1,
"defaultValue": false,
"policyType": 35, "policyType": 35,
"enabled": true "enabled": true
} }
@@ -317,7 +317,7 @@
"descriptionResourceKey": "kioskDropOutDescription", "descriptionResourceKey": "kioskDropOutDescription",
"childSettings": [ "childSettings": [
{ {
"dataType": 20, "dataType": 17,
"category": 46, "category": 46,
"nameResourceKey": "kioskModeExitCodeName", "nameResourceKey": "kioskModeExitCodeName",
"descriptionResourceKey": "kioskModeExitCodeDescription", "descriptionResourceKey": "kioskModeExitCodeDescription",
@@ -550,7 +550,6 @@
], ],
"entityKey": "kioskModeScreenSaverDisplayTimeInSeconds", "entityKey": "kioskModeScreenSaverDisplayTimeInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 0,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -568,7 +567,6 @@
], ],
"entityKey": "kioskModeScreenSaverStartDelayInSeconds", "entityKey": "kioskModeScreenSaverStartDelayInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 30,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -734,7 +732,6 @@
], ],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds", "entityKey": "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 300,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
}, },
@@ -752,7 +749,6 @@
], ],
"entityKey": "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds", "entityKey": "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": 60,
"policyType": 2, "policyType": 2,
"enabled": true "enabled": true
} }
@@ -1,5 +1,22 @@
{ {
"devicehealth_complianceandroiddeviceowner": [ "devicehealth_complianceandroiddeviceowner": [
{
"dataType": 0,
"category": 39,
"nameResourceKey": "complianceRootedAllowedName",
"descriptionResourceKey": "complianceRootedAllowedDescription",
"childSettings": [
],
"options": [
],
"entityKey": "securityBlockJailbrokenDevices",
"booleanActions": 3,
"defaultValue": false,
"policyType": 31,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 39, "category": 39,
@@ -12,7 +12,7 @@
"dataType": 16, "dataType": 16,
"category": 42, "category": 42,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "androidEnterpriseConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -4,7 +4,7 @@
"dataType": 16, "dataType": 16,
"category": 42, "category": 42,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "aospConfigurationRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -105,8 +105,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 44, "category": 44,
"nameResourceKey": "WifiTypeName", "nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "WiFiTypeDescription", "descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [ "childSettings": [
], ],
@@ -274,7 +274,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
}, },
@@ -1421,7 +1421,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 9, "policyType": 9,
"enabled": true "enabled": true
}, },
@@ -1,36 +1,64 @@
{ {
"importedpfx_macimportedpfx": { "importedpfx_macimportedpfx": [
"dataType": 16, {
"category": 69, "dataType": 16,
"nameResourceKey": "PFXImportPolicyIntendedPurpose", "category": 69,
"descriptionResourceKey": "empty", "nameResourceKey": "MacOSDeploymentChannelName",
"childSettings": [ "descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "options": [
{ {
"nameResourceKey": "notConfigured", "nameResourceKey": "MacOSDeploymentChannelUserChannel",
"enabled": true "value": "userChannel",
}, "enabled": true
{ },
"nameResourceKey": "PFXImportPolicyIntendedPurposeUnassigned", {
"value": "unassigned", "nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"enabled": true "value": "deviceChannel",
}, "enabled": true
{ }
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeEncryption", ],
"value": "smimeEncryption", "entityKey": "deploymentChannel",
"enabled": true "booleanActions": 0,
}, "defaultValue": "deviceChannel",
{ "policyType": 62,
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeSigning", "enabled": true
"value": "smimeSigning", },
"enabled": true {
} "dataType": 16,
], "category": 69,
"entityKey": "intendedPurpose", "nameResourceKey": "PFXImportPolicyIntendedPurpose",
"booleanActions": 0, "descriptionResourceKey": "empty",
"policyType": 62, "childSettings": [
"enabled": true
} ],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeUnassigned",
"value": "unassigned",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeEncryption",
"value": "smimeEncryption",
"enabled": true
},
{
"nameResourceKey": "PFXImportPolicyIntendedPurposeSmimeSigning",
"value": "smimeSigning",
"enabled": true
}
],
"entityKey": "intendedPurpose",
"booleanActions": 0,
"policyType": 62,
"enabled": true
}
]
} }
@@ -1,36 +1,5 @@
{ {
"password_androidgeneral": [ "password_androidgeneral": [
{
"dataType": 0,
"category": 90,
"nameResourceKey": "requireEncryptionName",
"descriptionResourceKey": "requireEncryptionDescription",
"childSettings": [
],
"options": [
],
"entityKey": "storageRequireDeviceEncryption",
"booleanActions": 1,
"defaultValue": false,
"policyType": 20,
"enabled": true
},
{
"dataType": 10,
"category": 90,
"nameResourceKey": "androidTenDeprecationInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 20,
"enabled": true
},
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": true, "showAsSectionHeader": true,
@@ -62,6 +31,23 @@
"policyType": 20, "policyType": 20,
"enabled": true "enabled": true
}, },
{
"dataType": 0,
"category": 90,
"nameResourceKey": "knoxRequireEncryptionName",
"descriptionResourceKey": "requireEncryptionDescription",
"childSettings": [
],
"options": [
],
"entityKey": "storageRequireDeviceEncryption",
"booleanActions": 1,
"defaultValue": false,
"policyType": 20,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 90, "category": 90,
@@ -203,14 +189,14 @@
"showAsSectionHeader": true, "showAsSectionHeader": true,
"dataType": 8, "dataType": 8,
"category": 90, "category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeader", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [ "childSettings": [
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 90, "category": 90,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [ "childSettings": [
], ],
@@ -438,7 +438,7 @@
"dataType": 4, "dataType": 4,
"category": 93, "category": 93,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -412,7 +412,7 @@
"dataType": 4, "dataType": 4,
"category": 93, "category": 93,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -279,7 +279,7 @@
"dataType": 4, "dataType": 4,
"category": 93, "category": 93,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -438,7 +438,7 @@
"dataType": 4, "dataType": 4,
"category": 93, "category": 93,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
+615 -319
View File
@@ -1,373 +1,669 @@
{ {
"pkcs_macospkcs": [ "pkcs_macospkcs": {
{ "dataType": 16,
"dataType": 14, "category": 93,
"category": 93, "nameResourceKey": "MacOSDeploymentChannelName",
"nameResourceKey": "sCEPPolicyRenewalThresholdName", "descriptionResourceKey": "empty",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription", "childSettings": [
"childSettings": [
], ],
"options": [ "options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"children": [
{
"dataType": 14,
"category": 93,
"nameResourceKey": "sCEPPolicyRenewalThresholdName",
"descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"childSettings": [
], ],
"entityKey": "renewalThresholdPercentage", "options": [
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
], ],
"options": [ "entityKey": "renewalThresholdPercentage",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
], ],
"entityKey": "certificateValidityPeriodValue", "options": [
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
], ],
"options": [ "entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
], ],
"entityKey": "certificationAuthority", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
], ],
"options": [ "entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
], ],
"entityKey": "certificationAuthorityName", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"entityKey": "certificateTemplateName", "options": [
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "entityKey": "certificateTemplateName",
{ "booleanActions": 0,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser", "defaultValue": "",
"value": "user", "policyType": 64,
"children": [ "enabled": true
{ },
"value": "custom", {
"dataType": 9, "dataType": 16,
"category": 93, "category": 93,
"childSettings": [ "nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"options": [ "options": [
{
], "nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"entityKey": "subjectNameFormat", "value": "user",
"booleanActions": 0, "children": [
"policyType": 64, {
"enabled": true "value": "custom",
}, "dataType": 9,
{
"dataType": 20,
"category": 93,
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93, "category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
], ],
"entityKey": "sanType", "entityKey": "subjectNameFormat",
"booleanActions": 0, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} },
}, {
{
"metadata": {
"dataType": 20, "dataType": 20,
"category": 93, "category": 93,
"nameResourceKey": "value", "nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "name", "entityKey": "subjectNameFormatString",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} },
} {
], "columns": [
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{ {
"nameResourceKey": "PolicyEmailAddress", "metadata": {
"value": "emailAddress", "dataType": 16,
"enabled": true "category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}, },
{ {
"nameResourceKey": "PolicyUserPrincipalName", "metadata": {
"value": "userPrincipalName", "dataType": 20,
"enabled": true "category": 93,
}, "nameResourceKey": "value",
{ "descriptionResourceKey": "empty",
"nameResourceKey": "PolicyDomainNameService", "childSettings": [
"value": "domainNameService",
"enabled": true ],
}, "options": [
{
"nameResourceKey": "PolicyUniversalResourceIdentifier", ],
"value": "universalResourceIdentifier", "entityKey": "name",
"enabled": true "booleanActions": 0,
}, "policyType": 64,
{ "enabled": true
"nameResourceKey": "SCEPPolicyCustomAADAttribute", }
"value": "customAzureADAttribute",
"enabled": true
} }
], ],
"entityKey": "sanType", "dataType": 21,
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93, "category": 93,
"nameResourceKey": "value", "nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "empty", "descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [ "childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "name", "entityKey": "customSubjectAlternativeNames",
"booleanActions": 0, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} }
} ],
], "enabled": true
"dataType": 21, }
"category": 93, ],
"nameResourceKey": "PolicySubjectAlternativeName", "entityKey": "certificateStore",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription", "booleanActions": 0,
"childSettings": [ "defaultValue": "user",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "customSubjectAlternativeNames", "entityKey": "allowAllAppsAccess",
"booleanActions": 0, "booleanActions": 2,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} }
], ],
"enabled": true "enabled": true
} },
], {
"entityKey": "certificateStore", "nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"booleanActions": 0, "value": "deviceChannel",
"defaultValue": "user", "children": [
"policyType": 64, {
"enabled": true "dataType": 14,
}, "category": 93,
{ "nameResourceKey": "sCEPPolicyRenewalThresholdName",
"dataType": 0, "descriptionResourceKey": "sCEPPolicyRenewalThresholdDescription",
"category": 93, "childSettings": [
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
], ],
"options": [ "options": [
], ],
"entityKey": "allowAllAppsAccess", "entityKey": "renewalThresholdPercentage",
"booleanActions": 2, "booleanActions": 0,
"policyType": 64, "policyType": 64,
"enabled": true "enabled": true
} },
] {
"scaleOptions": [
{
"nameResourceKey": "days",
"value": "days",
"enabled": true
},
{
"nameResourceKey": "months",
"value": "months",
"enabled": true
},
{
"nameResourceKey": "years",
"value": "years",
"enabled": true
}
],
"scaleEntityKey": "certificateValidityPeriodScale",
"defaultScale": "years",
"dataType": 22,
"category": 93,
"nameResourceKey": "sCEPPolicyCertificateValidityPeriodName",
"descriptionResourceKey": "sCEPPolicyCertificateValidityPeriodDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificateValidityPeriodValue",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthority",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificationAuthorityNameName",
"descriptionResourceKey": "pKCSPolicyCertificationAuthorityNameNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "certificationAuthorityName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "pKCSPolicyCertificateTemplateNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "certificateTemplateName",
"booleanActions": 0,
"defaultValue": "",
"policyType": 64,
"enabled": true
},
{
"dataType": 16,
"category": 93,
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreUser",
"value": "user",
"children": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 93,
"nameResourceKey": "MacOSDeploymentChannelWarningBanner",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "SCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicyCustomSubjectNameWithAadFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{UserName}},E={{EmailAddress}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyWindowsCertificateStoreMachine",
"value": "machine",
"children": [
{
"value": "custom",
"dataType": 9,
"category": 93,
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormat",
"booleanActions": 0,
"policyType": 64,
"enabled": true
},
{
"dataType": 20,
"category": 93,
"nameResourceKey": "sCEPPolicySubjectNameFormatName",
"descriptionResourceKey": "sCEPPolicySubjectNameFormatDescription",
"childSettings": [
],
"options": [
],
"entityKey": "subjectNameFormatString",
"booleanActions": 0,
"defaultValue": "CN={{AAD_Device_ID}}",
"policyType": 64,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 16,
"category": 93,
"nameResourceKey": "attribute",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "PolicyEmailAddress",
"value": "emailAddress",
"enabled": true
},
{
"nameResourceKey": "PolicyUserPrincipalName",
"value": "userPrincipalName",
"enabled": true
},
{
"nameResourceKey": "PolicyDomainNameService",
"value": "domainNameService",
"enabled": true
},
{
"nameResourceKey": "PolicyUniversalResourceIdentifier",
"value": "universalResourceIdentifier",
"enabled": true
},
{
"nameResourceKey": "SCEPPolicyCustomAADAttribute",
"value": "customAzureADAttribute",
"enabled": true
}
],
"entityKey": "sanType",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 93,
"nameResourceKey": "value",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
}
],
"dataType": 21,
"category": 93,
"nameResourceKey": "PolicySubjectAlternativeName",
"descriptionResourceKey": "PolicySubjectAlternativeNameDescription",
"childSettings": [
],
"options": [
],
"entityKey": "customSubjectAlternativeNames",
"booleanActions": 0,
"policyType": 64,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "certificateStore",
"booleanActions": 0,
"defaultValue": "machine",
"policyType": 64,
"enabled": true
},
{
"dataType": 0,
"category": 93,
"nameResourceKey": "MacOSAllowAllAppsAccess",
"descriptionResourceKey": "MacOSAllowAllAppsAccess",
"emptyValueResourceKey": "macOSAllowAllAppsAccessEmptyValueKey",
"childSettings": [
],
"options": [
],
"entityKey": "allowAllAppsAccess",
"booleanActions": 2,
"policyType": 64,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "deploymentChannel",
"booleanActions": 0,
"defaultValue": "deviceChannel",
"policyType": 64,
"enabled": true
}
} }
@@ -492,7 +492,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -462,7 +462,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -239,7 +239,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -462,7 +462,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -558,7 +558,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
File diff suppressed because it is too large Load Diff
@@ -501,7 +501,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -501,7 +501,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -278,7 +278,7 @@
"dataType": 4, "dataType": 4,
"category": 103, "category": 103,
"nameResourceKey": "sCEPPolicySelectRootCertificateName", "nameResourceKey": "sCEPPolicySelectRootCertificateName",
"descriptionResourceKey": "SCEPPolicySelectRootCertificateName", "descriptionResourceKey": "sCEPPolicySelectRootCertificateDescription",
"childSettings": [ "childSettings": [
], ],
@@ -187,51 +187,6 @@
"policyType": 29, "policyType": 29,
"enabled": true "enabled": true
}, },
{
"dataType": 10,
"category": 113,
"nameResourceKey": "androidTenDeprecationInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 29,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 113,
"nameResourceKey": "allAndroidVersionsPasswordHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 113,
"nameResourceKey": "allAndroidVersionsPasswordHeaderDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 29,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 29,
"enabled": true
},
{ {
"dataType": 16, "dataType": 16,
"category": 113, "category": 113,
@@ -370,14 +325,14 @@
"showAsSectionHeader": true, "showAsSectionHeader": true,
"dataType": 8, "dataType": 8,
"category": 113, "category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeader", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeader",
"childSettings": [ "childSettings": [
{ {
"isSettingDescription": false, "isSettingDescription": false,
"showAsSectionHeader": false, "showAsSectionHeader": false,
"dataType": 8, "dataType": 8,
"category": 113, "category": 113,
"nameResourceKey": "androidNineAndBelowPasswordHeaderDescription", "nameResourceKey": "knoxFifteenAndroidNineAndBelowPasswordHeaderDescription",
"childSettings": [ "childSettings": [
], ],
@@ -33,7 +33,7 @@
"dataType": 16, "dataType": 16,
"category": 113, "category": 113,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "androidEnterpriseComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -41,7 +41,7 @@
"dataType": 16, "dataType": 16,
"category": 113, "category": 113,
"nameResourceKey": "requiredPasswordTypeName", "nameResourceKey": "requiredPasswordTypeName",
"descriptionResourceKey": "androidEnterpriseRequiredPasswordTypeDescription", "descriptionResourceKey": "aospComplianceRequiredPasswordTypeDescription",
"emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey", "emptyValueResourceKey": "passwordExpirationInDaysEmptyValueKey",
"childSettings": [ "childSettings": [
@@ -1,20 +1,48 @@
{ {
"trustedcert_mactrustedcertificate": { "trustedcert_mactrustedcertificate": [
"dataEntityKey": "trustedRootCertificate", {
"filenameEntityKey": "certFileName", "dataType": 16,
"dataType": 1, "category": 115,
"category": 115, "nameResourceKey": "MacOSDeploymentChannelName",
"nameResourceKey": "trustedCertPolicySelectCertificateName", "descriptionResourceKey": "empty",
"descriptionResourceKey": "empty", "childSettings": [
"childSettings": [
], ],
"options": [ "options": [
{
"nameResourceKey": "MacOSDeploymentChannelUserChannel",
"value": "userChannel",
"enabled": true
},
{
"nameResourceKey": "MacOSDeploymentChannelDeviceChannel",
"value": "deviceChannel",
"enabled": true
}
],
"entityKey": "deploymentChannel",
"booleanActions": 0,
"defaultValue": "deviceChannel",
"policyType": 65,
"enabled": true
},
{
"dataEntityKey": "trustedRootCertificate",
"filenameEntityKey": "certFileName",
"dataType": 1,
"category": 115,
"nameResourceKey": "trustedCertPolicySelectCertificateName",
"descriptionResourceKey": "empty",
"childSettings": [
], ],
"entityKey": "trustedRootCertificate", "options": [
"booleanActions": 0,
"policyType": 65, ],
"enabled": true "entityKey": "trustedRootCertificate",
} "booleanActions": 0,
"policyType": 65,
"enabled": true
}
]
} }
File diff suppressed because it is too large Load Diff
@@ -4078,6 +4078,124 @@
"defaultValue": false, "defaultValue": false,
"policyType": 19, "policyType": 19,
"enabled": true "enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "openOption",
"value": "open",
"enabled": true
},
{
"nameResourceKey": "wEPPSKOption",
"value": "wep",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "wPAPSKOption",
"value": "wpaPersonal",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "wiFiSecurityType",
"booleanActions": 0,
"policyType": 19,
"enabled": true
},
{
"dataType": 16,
"category": 121,
"nameResourceKey": "wiFiPolicyProxySettingsName",
"descriptionResourceKey": "wiFiPolicyProxySettingsDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "noneOption",
"value": "none",
"enabled": true
},
{
"nameResourceKey": "automaticOption",
"value": "automatic",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "proxyServerURLName",
"descriptionResourceKey": "proxyServerURLDescription",
"emptyValueResourceKey": "proxyUrlExample",
"childSettings": [
],
"options": [
],
"entityKey": "proxyAutomaticConfigurationUrl",
"booleanActions": 0,
"policyType": 19,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "proxySettings",
"booleanActions": 0,
"defaultValue": "none",
"unconfiguredValue": "none",
"policyType": 19,
"enabled": true
} }
], ],
"enabled": true "enabled": true
@@ -4954,7 +5072,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 19, "policyType": 19,
"enabled": true "enabled": true
} }
@@ -105,8 +105,8 @@
{ {
"dataType": 16, "dataType": 16,
"category": 121, "category": 121,
"nameResourceKey": "WifiTypeName", "nameResourceKey": "wiFiPolicySecurityTypeName",
"descriptionResourceKey": "WiFiTypeDescription", "descriptionResourceKey": "wiFiPolicySecurityTypeDescription",
"childSettings": [ "childSettings": [
], ],
@@ -274,7 +274,7 @@
"entityKey": "proxySetting", "entityKey": "proxySetting",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 124, "policyType": 124,
"enabled": false "enabled": false
} }
@@ -1106,7 +1106,7 @@
"entityKey": "proxySetting", "entityKey": "proxySetting",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 124, "policyType": 124,
"enabled": false "enabled": false
} }
+51 -3
View File
@@ -144,6 +144,54 @@
], ],
"enabled": true "enabled": true
}, },
{
"nameResourceKey": "wPA2PersonalOption",
"value": "wpa2Personal",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 54,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "wPA3PersonalOption",
"value": "wpa3Personal",
"children": [
{
"dataType": 20,
"category": 121,
"nameResourceKey": "preSharedKeyName",
"descriptionResourceKey": "preSharedKeyDescription",
"emptyValueResourceKey": "wifiPasswordExample",
"childSettings": [
],
"options": [
],
"entityKey": "preSharedKey",
"booleanActions": 0,
"policyType": 54,
"enabled": true
}
],
"enabled": true
},
{ {
"nameResourceKey": "wEPOption", "nameResourceKey": "wEPOption",
"value": "wep", "value": "wep",
@@ -238,7 +286,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "enabled": true
}, },
@@ -1494,7 +1542,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "enabled": true
}, },
@@ -1940,7 +1988,7 @@
"entityKey": "proxySettings", "entityKey": "proxySettings",
"booleanActions": 0, "booleanActions": 0,
"defaultValue": "none", "defaultValue": "none",
"unconfiguredValue": "noneOption", "unconfiguredValue": "none",
"policyType": 54, "policyType": 54,
"enabled": true "enabled": true
}, },
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,909 @@
{
"windowsztdns_windows10ztdns": [
{
"dataType": 10,
"category": 154,
"nameResourceKey": "ztdnsMinimumBuildInfoboxName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 9,
"category": 154,
"childSettings": [
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsModeHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 16,
"category": 154,
"nameResourceKey": "ztdnsModeSelectionName",
"childSettings": [
],
"options": [
{
"nameResourceKey": "ZtdnsNotConfiguredName",
"enabled": true
},
{
"nameResourceKey": "ztdnsModeSelectionAuditName",
"value": "true",
"enabled": true
},
{
"nameResourceKey": "ztdnsModeSelectionEnforceName",
"value": "false",
"children": [
{
"dataType": 10,
"category": 154,
"nameResourceKey": "ztdnsModeWarningName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "auditModeEnabled",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsModeChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDisplayNameName",
"descriptionResourceKey": "ztdnsSecureDnsServerDisplayNameDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerDisplayNamePlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "displayName",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerIpAddressName",
"descriptionResourceKey": "ztdnsSecureDnsServerIpAddressDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerIpAddressPlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "ipAddress",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 16,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerTypeName",
"descriptionResourceKey": "ztdnsSecureDnsServerTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "ZtdnsNotConfiguredName",
"enabled": true
},
{
"nameResourceKey": "ztdnsSecureDnsServerDohOptionName",
"value": "doh",
"children": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohHeaderName",
"childSettings": [
{
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohUrlName",
"descriptionResourceKey": "ztdnsSecureDnsServerDohUrlDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerDohUrlPlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "dohQueryUrl",
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohPortName",
"descriptionResourceKey": "ztdnsSecureDnsServerDohPortDescription",
"childSettings": [
],
"options": [
],
"entityKey": "dohHttpsPort",
"booleanActions": 0,
"defaultValue": 443,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "ztdnsSecureDnsServerDotOptionName",
"value": "dot",
"children": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotHeaderName",
"childSettings": [
{
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotHostnameName",
"descriptionResourceKey": "ztdnsSecureDnsServerDotHostnameDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerDotHostnamePlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "dotCertificateSubjectName",
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotPortName",
"descriptionResourceKey": "ztdnsSecureDnsServerDotPortDescription",
"childSettings": [
],
"options": [
],
"entityKey": "dotTlsPort",
"booleanActions": 0,
"defaultValue": 853,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "ztdnsSecureDnsServerDohAndDotOptionName",
"value": "dohAndDot",
"children": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohHeaderName",
"childSettings": [
{
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohUrlName",
"descriptionResourceKey": "ztdnsSecureDnsServerDohUrlDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerDohUrlPlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "dohQueryUrl",
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohPortName",
"descriptionResourceKey": "ztdnsSecureDnsServerDohPortDescription",
"childSettings": [
],
"options": [
],
"entityKey": "dohHttpsPort",
"booleanActions": 0,
"defaultValue": 443,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotHeaderName",
"childSettings": [
{
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotHostnameName",
"descriptionResourceKey": "ztdnsSecureDnsServerDotHostnameDescription",
"emptyValueResourceKey": "ztdnsSecureDnsServerDotHostnamePlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "dotCertificateSubjectName",
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotPortName",
"descriptionResourceKey": "ztdnsSecureDnsServerDotPortDescription",
"childSettings": [
],
"options": [
],
"entityKey": "dotTlsPort",
"booleanActions": 0,
"defaultValue": 853,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "serverType",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotHostnameName",
"childSettings": [
],
"options": [
],
"entityKey": "dotCertificateSubjectName",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDotPortName",
"childSettings": [
],
"options": [
],
"entityKey": "dotTlsPort",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohUrlName",
"childSettings": [
],
"options": [
],
"entityKey": "dohQueryUrl",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerDohPortName",
"childSettings": [
],
"options": [
],
"entityKey": "dohHttpsPort",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
}
],
"dataType": 21,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerName",
"childSettings": [
],
"options": [
],
"entityKey": "secureDnsServers",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsSecureDnsServerChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsTrustedCAHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 154,
"nameResourceKey": "ztdnsServerRootCertificateHeader",
"descriptionResourceKey": "ztdnsRootCertificateDescription",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsServerRootCertificateHeader",
"descriptionResourceKey": "ztdnsRootCertificateDescription",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsTrustedCAChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsExemptionRulesHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsExemptionRuleDisplayNameName",
"emptyValueResourceKey": "ztdnsExemptionRuleDisplayNamePlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "displayName",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"columns": [
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsExemptionRuleIpAddressName",
"emptyValueResourceKey": "ztdnsExemptionRuleIpAddressPlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "ipAddress",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
}
],
"dataType": 21,
"category": 154,
"nameResourceKey": "ztdnsExemptionRuleIpAddressesName",
"descriptionResourceKey": "ztdnsExemptionRuleIpAddressesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "ipAddresses",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "ztdnsExemptionRuleDescriptionName",
"emptyValueResourceKey": "ztdnsExemptionRuleDescriptionPlaceholder",
"childSettings": [
],
"options": [
],
"entityKey": "description",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
}
],
"dataType": 21,
"category": 154,
"nameResourceKey": "ztdnsExemptionRulesName",
"descriptionResourceKey": "ztdnsExemptionRulesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "exemptionRules",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsExemptionRulesChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsClientCertificateHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 154,
"nameResourceKey": "ztdnsClientRootCertificateHeader",
"descriptionResourceKey": "ztdnsRootCertificateDescription",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificatesForClientValidation",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsClientRootCertificateHeader",
"descriptionResourceKey": "ztdnsRootCertificateDescription",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"isSettingDescription": true,
"showAsSectionHeader": false,
"dataType": 8,
"category": 154,
"nameResourceKey": "ztdnsClientCertificateEkuHeaderName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "eDPPolicyAppsListNameName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "name",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 154,
"nameResourceKey": "sCEPPolicyObjectIdentifierColumnName",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "objectIdentifier",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
}
],
"dataType": 21,
"category": 154,
"nameResourceKey": "sCEPPolicyExtendedKeyUsageName",
"childSettings": [
],
"options": [
],
"entityKey": "extendedKeyUsagesForClientAuthentication",
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsClientCertificateChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 0,
"category": 154,
"nameResourceKey": "ztdnsAdvancedSettingsLoopbackTrafficBlockedName",
"descriptionResourceKey": "ztdnsAdvancedSettingsLoopbackTrafficBlockedDescription",
"childSettings": [
{
"dataType": 0,
"category": 154,
"nameResourceKey": "ztdnsAdvancedSettingsLoopbackDnsForwarderEnabledName",
"descriptionResourceKey": "ztdnsAdvancedSettingsLoopbackDnsForwarderEnabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "loopbackDnsForwarderEnabled",
"booleanActions": 0,
"defaultValue": false,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"entityKey": "loopbackTrafficBlocked",
"booleanActions": 3,
"defaultValue": false,
"policyType": 130,
"enabled": true
},
{
"dataType": 0,
"category": 154,
"nameResourceKey": "ztdnsAdvancedSettingsHostsFileResolutionEnabledName",
"descriptionResourceKey": "ztdnsAdvancedSettingsHostsFileResolutionEnabledDescription",
"childSettings": [
],
"options": [
],
"entityKey": "hostsFileResolutionEnabled",
"booleanActions": 3,
"defaultValue": false,
"policyType": 130,
"enabled": true
},
{
"dataType": 14,
"category": 154,
"nameResourceKey": "ztdnsAdvancedSettingsMaximumConnectionTimeInSecondsName",
"descriptionResourceKey": "ztdnsAdvancedSettingsMaximumConnectionTimeInSecondsDescription",
"childSettings": [
],
"options": [
],
"entityKey": "maximumConnectionTimeInSeconds",
"booleanActions": 0,
"defaultValue": 86400,
"policyType": 130,
"enabled": true
}
],
"dataType": 5,
"category": 154,
"nameResourceKey": "ztdnsAdvancedSettingsChevronName",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 130,
"enabled": true
}
]
}
@@ -0,0 +1,735 @@
{
"wirednetwork_ioswirednetwork": [
{
"dataType": 16,
"category": 149,
"nameResourceKey": "networkInterface",
"descriptionResourceKey": "networkInterfaceDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "anyEthernet",
"value": "anyEthernet",
"enabled": true
}
],
"entityKey": "networkInterface",
"booleanActions": 0,
"defaultValue": "anyEthernet",
"policyType": 131,
"enabled": true
},
{
"dataType": 16,
"category": 149,
"nameResourceKey": "eAPTypeName",
"descriptionResourceKey": "eAPTypeDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "selectEAP",
"enabled": true
},
{
"nameResourceKey": "eAPFASTName",
"value": "eapFast",
"children": [
{
"dataType": 16,
"category": 149,
"nameResourceKey": "pACHeading",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
{
"nameResourceKey": "dontUsePACName",
"value": "noProtectedAccessCredential",
"enabled": true
},
{
"nameResourceKey": "usePACName",
"value": "useProtectedAccessCredential",
"enabled": true
},
{
"nameResourceKey": "provisionPACName",
"value": "useProtectedAccessCredentialAndProvision",
"enabled": true
},
{
"nameResourceKey": "provisionPACAnonName",
"value": "useProtectedAccessCredentialAndProvisionAnonymously",
"enabled": true
}
],
"entityKey": "eapFastConfiguration",
"booleanActions": 0,
"defaultValue": "noProtectedAccessCredential",
"policyType": 131,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "eAPTLSName",
"value": "eapTls",
"children": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "trust",
"descriptionResourceKey": "trustDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 149,
"nameResourceKey": "empty",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "trustedServerCertificateNameExample",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNamesName",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
}
],
"dataType": 21,
"category": 149,
"nameResourceKey": "trustedServerCertificateNamesName",
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNames",
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificates",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "authentication",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"value": "certificate",
"dataType": 9,
"category": 149,
"childSettings": [
],
"options": [
],
"entityKey": "authenticationMethod",
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfile",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "identityCertificateForClientAuthentication",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "certificatesOption",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 20,
"category": 149,
"nameResourceKey": "enableIdentityPrivacyName",
"descriptionResourceKey": "enableIdentityPrivacyDescription",
"emptyValueResourceKey": "identityPrivacyExample",
"childSettings": [
],
"options": [
],
"entityKey": "enableOuterIdentityPrivacy",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "eAPTTLSName",
"value": "eapTtls",
"children": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "trust",
"descriptionResourceKey": "trustDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 149,
"nameResourceKey": "empty",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "trustedServerCertificateNameExample",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNamesName",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
}
],
"dataType": 21,
"category": 149,
"nameResourceKey": "trustedServerCertificateNamesName",
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNames",
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificates",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "authentication",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 16,
"category": 149,
"nameResourceKey": "authenticationMethodName",
"descriptionResourceKey": "authenticationMethodTTLSDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "usernameAndPasswordOption",
"value": "usernameAndPassword",
"children": [
{
"dataType": 16,
"category": 149,
"nameResourceKey": "nonEapMethodName",
"descriptionResourceKey": "nonEapMethodDescription",
"childSettings": [
],
"options": [
{
"nameResourceKey": "selectNonEapMethod",
"enabled": true
},
{
"nameResourceKey": "pAPName",
"value": "unencryptedPassword",
"enabled": true
},
{
"nameResourceKey": "cHAPName",
"value": "challengeHandshakeAuthenticationProtocol",
"enabled": true
},
{
"nameResourceKey": "mSCHAPName",
"value": "microsoftChap",
"enabled": true
},
{
"nameResourceKey": "cHAPTWOName",
"value": "microsoftChapVersionTwo",
"enabled": true
}
],
"entityKey": "nonEapAuthenticationMethodForEapTtls",
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 20,
"category": 149,
"nameResourceKey": "enableIdentityPrivacyName",
"descriptionResourceKey": "enableIdentityPrivacyDescription",
"emptyValueResourceKey": "identityPrivacyExample",
"childSettings": [
],
"options": [
],
"entityKey": "enableOuterIdentityPrivacy",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "certificatesOption",
"value": "certificate",
"children": [
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfile",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "identityCertificateForClientAuthentication",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "certificatesOption",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 20,
"category": 149,
"nameResourceKey": "enableIdentityPrivacyName",
"descriptionResourceKey": "enableIdentityPrivacyDescription",
"emptyValueResourceKey": "identityPrivacyExample",
"childSettings": [
],
"options": [
],
"entityKey": "enableOuterIdentityPrivacy",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "authenticationMethod",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "eAPAKAName",
"value": "eapAka",
"enabled": true
},
{
"nameResourceKey": "pEAPName",
"value": "peap",
"children": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "trust",
"descriptionResourceKey": "trustDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 149,
"nameResourceKey": "empty",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "trustedServerCertificateNameExample",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNamesName",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
}
],
"dataType": 21,
"category": 149,
"nameResourceKey": "trustedServerCertificateNamesName",
"descriptionResourceKey": "trustedServerCertificateNamesDescription",
"childSettings": [
],
"options": [
],
"entityKey": "trustedServerCertificateNames",
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfiles",
"descriptionResourceKey": "selectRootCertificatesForServerValidationName",
"childSettings": [
],
"options": [
],
"entityKey": "rootCertificatesForServerValidation",
"booleanActions": 0,
"unconfiguredValue": "notConfigured",
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "selectRootCertificatesForServerValidationName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificates",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 149,
"nameResourceKey": "authentication",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 16,
"category": 149,
"nameResourceKey": "authenticationMethodName",
"descriptionResourceKey": "authenticationMethodName",
"childSettings": [
],
"options": [
{
"nameResourceKey": "notConfigured",
"enabled": true
},
{
"nameResourceKey": "usernameAndPasswordOption",
"value": "usernameAndPassword",
"children": [
{
"dataType": 20,
"category": 149,
"nameResourceKey": "enableIdentityPrivacyName",
"descriptionResourceKey": "enableIdentityPrivacyDescription",
"emptyValueResourceKey": "identityPrivacyExample",
"childSettings": [
],
"options": [
],
"entityKey": "outerIdentityPrivacyMaskValue",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
},
{
"nameResourceKey": "certificatesOption",
"value": "certificate",
"children": [
{
"complexOptions": [
{
"dataType": 4,
"category": 149,
"nameResourceKey": "selectCertificateProfile",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "identityCertificateForClientAuthentication",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"dataType": 5,
"category": 149,
"nameResourceKey": "certificatesOption",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "selectCertificate",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 131,
"enabled": true
},
{
"dataType": 20,
"category": 149,
"nameResourceKey": "enableIdentityPrivacyName",
"descriptionResourceKey": "enableIdentityPrivacyDescription",
"emptyValueResourceKey": "identityPrivacyExample",
"childSettings": [
],
"options": [
],
"entityKey": "enableOuterIdentityPrivacy",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "authenticationMethod",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
],
"enabled": true
}
],
"entityKey": "eapType",
"booleanActions": 0,
"policyType": 131,
"enabled": true
}
]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,50 @@
{
"workprofile_androidforworkmigrationpolicy": [
{
"dataType": 10,
"category": 127,
"nameResourceKey": "migrationPolicyCannotBeUnassigned",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidForWorkMigrationPolicyDescriptionParagraph1",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 127,
"nameResourceKey": "androidForWorkMigrationPolicyLearnMoreText",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 129,
"enabled": true
}
]
}
@@ -0,0 +1,140 @@
{
"wslcompliance_compliancewindows10": [
{
"dataType": 10,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceInfoBox",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceDescription",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"isSettingDescription": false,
"showAsSectionHeader": true,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceHeader",
"childSettings": [
{
"isSettingDescription": false,
"showAsSectionHeader": false,
"dataType": 8,
"category": 153,
"nameResourceKey": "windowsSubsystemLinuxComplianceLearnMore",
"childSettings": [
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
],
"options": [
],
"booleanActions": 0,
"policyType": 35,
"enabled": true
},
{
"columns": [
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyDistributionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "distribution",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyMinOSVersionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "optionalValue",
"childSettings": [
],
"options": [
],
"entityKey": "minimumOSVersion",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
},
{
"metadata": {
"dataType": 20,
"category": 153,
"nameResourceKey": "wSLPolicyMaxOSVersionName",
"descriptionResourceKey": "empty",
"emptyValueResourceKey": "optionalValue",
"childSettings": [
],
"options": [
],
"entityKey": "maximumOSVersion",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
}
],
"dataType": 21,
"category": 153,
"nameResourceKey": "empty",
"descriptionResourceKey": "empty",
"childSettings": [
],
"options": [
],
"entityKey": "wslDistributions",
"booleanActions": 0,
"policyType": 35,
"enabled": true
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+141 -25
View File
@@ -188,6 +188,12 @@ function Show-CompareBulkForm
$global:chkSkipCompareAssignments.IsChecked = (Get-Setting "Compare" "SkipCompareAssignments") -eq "true" $global:chkSkipCompareAssignments.IsChecked = (Get-Setting "Compare" "SkipCompareAssignments") -eq "true"
$global:chkSkipMissingSourcePolicies.IsChecked = (Get-Setting "Compare" "SkipMissingSourcePolicies") -eq "true" $global:chkSkipMissingSourcePolicies.IsChecked = (Get-Setting "Compare" "SkipMissingSourcePolicies") -eq "true"
$global:chkSkipMissingDestinationPolicies.IsChecked = (Get-Setting "Compare" "SkipMissingDestinationPolicies") -eq "true" $global:chkSkipMissingDestinationPolicies.IsChecked = (Get-Setting "Compare" "SkipMissingDestinationPolicies") -eq "true"
$global:chkBulkCompareSaveJson.IsChecked = (Get-Setting "Compare" "SaveJson") -eq "true"
$global:chkBulkCompareRemoveOData.IsChecked = (Get-Setting "Compare" "RemoveOData") -eq "true"
$objectSeparator = "[ { Name: `"New line`",Value: `"$([System.Environment]::NewLine)`" }, {Name: `";`",Value: `";`" }, {Name: `"|`",Value: `"|`" }]" | ConvertFrom-Json
$global:cbCompareMultiValueDelimiter.ItemsSource = $objectSeparator
$global:cbCompareMultiValueDelimiter.SelectedValue = (Get-Setting "Compare" "ObjectSeparator" ([System.Environment]::NewLine))
$script:compareObjects = @() $script:compareObjects = @()
foreach($objType in $global:lstMenuItems.ItemsSource) foreach($objType in $global:lstMenuItems.ItemsSource)
@@ -239,6 +245,9 @@ function Show-CompareBulkForm
Save-Setting "Compare" "SkipCompareAssignments" $global:chkSkipCompareAssignments.IsChecked Save-Setting "Compare" "SkipCompareAssignments" $global:chkSkipCompareAssignments.IsChecked
Save-Setting "Compare" "SkipMissingSourcePolicies" $global:chkSkipMissingSourcePolicies.IsChecked Save-Setting "Compare" "SkipMissingSourcePolicies" $global:chkSkipMissingSourcePolicies.IsChecked
Save-Setting "Compare" "SkipMissingDestinationPolicies" $global:chkSkipMissingDestinationPolicies.IsChecked Save-Setting "Compare" "SkipMissingDestinationPolicies" $global:chkSkipMissingDestinationPolicies.IsChecked
Save-Setting "Compare" "SaveJson" $global:chkBulkCompareSaveJson.IsChecked
Save-Setting "Compare" "RemoveOData" $global:chkBulkCompareRemoveOData.IsChecked
Save-Setting "Compare" "ObjectSeparator" $global:cbCompareMultiValueDelimiter.SelectedValue
if($global:cbCompareProvider.SelectedItem.BulkCompare) if($global:cbCompareProvider.SelectedItem.BulkCompare)
{ {
@@ -534,18 +543,26 @@ function Invoke-BulkCompareNamedObjects
{ {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.csv") $fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.json")
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder $fileName)
}
} }
} }
#$fileName = Expand-FileName $fileName #$fileName = Expand-FileName $fileName
if($compareObjectsResult.Count -eq 0) if($compareObjectsResult.Count -eq 0)
{ {
[System.Windows.MessageBox]::Show("No objects were comparced. Verify name patterns", "Error", "OK", "Error") [System.Windows.MessageBox]::Show("No objects were compared. Verify name patterns", "Error", "OK", "Error")
} }
elseif($outputType -eq "all") elseif($outputType -eq "all")
{ {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$sourcePattern-$comparePattern-%DateTime%.csv") $fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$sourcePattern-$comparePattern-%DateTime%.csv")
Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps Save-BulkCompareResults $compResultValues (Join-Path $outputFolder $fileName) $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
$fileName = Remove-InvalidFileNameChars (Expand-FileName "Compare-$($graphObj.ObjectType.Id)-$sourcePattern-$comparePattern-%DateTime%.json")
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder $fileName)
}
} }
} }
@@ -689,7 +706,7 @@ function Start-BulkCompareExportObjects
$objName = Get-GraphObjectName (?? $compObj.Object1 $compObj.Object2) $item.ObjectType $objName = Get-GraphObjectName (?? $compObj.Object1 $compObj.Object2) $item.ObjectType
foreach($compValue in $compObj.Result) foreach($compValue in $compObj.Result)
{ {
$compResultValues += [PSCustomObject]@{ $compResultValue = [PSCustomObject]@{
ObjectName = $objName ObjectName = $objName
Id = $compObj.Id Id = $compObj.Id
Type = $compObj.ObjectType.Title Type = $compObj.ObjectType.Title
@@ -701,12 +718,34 @@ function Start-BulkCompareExportObjects
SubCategory = $compValue.SubCategory SubCategory = $compValue.SubCategory
Match = $compValue.Match Match = $compValue.Match
} }
if($global:chkBulkCompareRemoveOData.IsChecked -and ($compResultValue.Value1 -like "@odata*" -or $compResultValue.Value2 -like "@odata*")) {
foreach($prop in $('Value1','Value2'))
{
$tmpValue1 = ""
$tmpValue2 = ""
$vauleString = $compResultValue.$prop
if($vauleString -is [String]) {
$vauleString = $vauleString -replace $compResultValue.Id, ""
$tmpObj = $compResultValue.$prop | ConvertFrom-Json
if($compResultValue.$prop -and $compResultValue.$prop -like "@odata*") {
Remove-GraphODataProperties $tmpObj.$prop | ConvertTo-Json -Depth 50 | Set-Variable -Name "tmp$prop"
}
}
}
$compResultValue.Match = $tmpValue1 -eq $tmpValue2
}
$compResultValues += $compResultValue
} }
} }
if($outputType -eq "objectType") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
} }
else else
@@ -717,7 +756,10 @@ function Start-BulkCompareExportObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0) if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{ {
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
Write-Log "****************************************************************" Write-Log "****************************************************************"
@@ -726,7 +768,7 @@ function Start-BulkCompareExportObjects
Write-Status "" Write-Status ""
if($compareObjectsResult.Count -eq 0) if($compareObjectsResult.Count -eq 0)
{ {
[System.Windows.MessageBox]::Show("No objects were comparced. Verify folder and exported files", "Error", "OK", "Error") [System.Windows.MessageBox]::Show("No objects were compared. Verify folder and exported files", "Error", "OK", "Error")
} }
} }
@@ -796,6 +838,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter)) if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{ {
Write-LogDebug "Excluded based on filter. Intune object name: '$($objName)'"
continue continue
} }
@@ -803,7 +846,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if(-not $fileObj) if(-not $fileObj)
{ {
# Add objects that are exported but deleted # Add objects that are in Intune but no exported file found
if($global:chkSkipMissingDestinationPolicies.IsChecked -ne $true) { if($global:chkSkipMissingDestinationPolicies.IsChecked -ne $true) {
Write-Log "Object '$($objName)' with id $($fileObj.Object.Id) not found in exported folder. New Object?" 2 Write-Log "Object '$($objName)' with id $($fileObj.Object.Id) not found in exported folder. New Object?" 2
$compareProperties = @([PSCustomObject]@{ $compareProperties = @([PSCustomObject]@{
@@ -815,7 +858,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
} }
elseif(($fileObj | measure).Count -gt 1) elseif(($fileObj | measure).Count -gt 1)
{ {
# Add objects that are exported but deleted # Add objects where multiple files match based on name
Write-Log "Multiple exported objects found with name '$($objName)" 2 Write-Log "Multiple exported objects found with name '$($objName)" 2
$compareProperties = @([PSCustomObject]@{ $compareProperties = @([PSCustomObject]@{
Object1Value = $objName Object1Value = $objName
@@ -843,12 +886,16 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($global:chkSkipMissingSourcePolicies.IsChecked -ne $true) { if($global:chkSkipMissingSourcePolicies.IsChecked -ne $true) {
foreach ($fileObj in @($fileObjects)) foreach ($fileObj in @($fileObjects))
{ {
# Add objects that are exported but not in Intune # Skip objects if they are already processed
if(($compareObjectsResult | Where { $_.FileInfo.FullName -eq $fileObj.FileInfo.FullName})) { continue } if(($compareObjectsResult | Where { $_.Object2 -eq $fileObj.Object})) {
Write-LogDebug "Skip already processed file '$($fileObj.FileInfo.FullName)'"
continue
}
$objName = Get-GraphObjectName $fileObj.Object $item.ObjectType $objName = Get-GraphObjectName $fileObj.Object $item.ObjectType
if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter)) if($txtNameFilter -and $objName -notmatch [RegEx]::Escape($txtNameFilter))
{ {
Write-LogDebug "Excluded based on filter. File: '$($fileObj.FileInfo.FullName)'"
continue continue
} }
@@ -894,6 +941,9 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "objectType") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $folder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
} }
else else
@@ -904,7 +954,10 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
if($outputType -eq "all" -and $compResultValues.Count -gt 0) if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{ {
Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
Write-Log "****************************************************************" Write-Log "****************************************************************"
@@ -913,7 +966,7 @@ function Start-BulkCompareExportIntuneToNamedExportedObjects
Write-Status "" Write-Status ""
if($compareObjectsResult.Count -eq 0) if($compareObjectsResult.Count -eq 0)
{ {
[System.Windows.MessageBox]::Show("No objects were comparced. Verify folder and exported files", "Error", "OK", "Error") [System.Windows.MessageBox]::Show("No objects were compared. Verify folder and exported files", "Error", "OK", "Error")
} }
} }
@@ -1080,6 +1133,9 @@ function Start-BulkCompareExportFolders
if($outputType -eq "objectType") if($outputType -eq "objectType")
{ {
Save-BulkCompareResults $compResultValues (Join-Path $folderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $folderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
} }
else else
@@ -1090,7 +1146,10 @@ function Start-BulkCompareExportFolders
if($outputType -eq "all" -and $compResultValues.Count -gt 0) if($outputType -eq "all" -and $compResultValues.Count -gt 0)
{ {
Save-BulkCompareResults $compResultValues (Join-Path $rootFolderSource "Compare_$(((Get-Date).ToString("yyyyMMDD-HHmm"))).csv") $compareProps Save-BulkCompareResults $compResultValues (Join-Path $rootFolderSource "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).csv") $compareProps
if($global:chkBulkCompareSaveJson.IsChecked) {
Save-BulkCompareJsonResults $compResultValues (Join-Path $rootFolder "Compare_$(((Get-Date).ToString("yyyyMMdd-HHmm"))).json")
}
} }
Write-Log "****************************************************************" Write-Log "****************************************************************"
@@ -1103,6 +1162,13 @@ function Start-BulkCompareExportFolders
} }
} }
function Save-BulkCompareJsonResults
{
param($CompareResults, $FileName)
$CompareResults | ConvertTo-Json -Depth 50 | Out-File $FileName -Force -Encoding UTF8
}
function Save-BulkCompareResults function Save-BulkCompareResults
{ {
param($compResultValues, $file, $props) param($compResultValues, $file, $props)
@@ -1359,7 +1425,7 @@ function Add-CompareProperty
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") } $value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") } $value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
$compare += [PSCustomObject]@{ $compare = [PSCustomObject]@{
PropertyName = $name PropertyName = $name
Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" } Object1Value = $value1 #if($value1 -ne $null) { $value1.ToString().Trim("`"") } else { "" }
Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" } Object2Value = $value2 #if($value2 -ne $null) { $value2.ToString().Trim("`"") } else { "" }
@@ -1367,10 +1433,12 @@ function Add-CompareProperty
SubCategory = $subCategory SubCategory = $subCategory
Match = ?? $match ($value1 -eq $value2) Match = ?? $match ($value1 -eq $value2)
} }
if($skip -eq $true) { if($skip -eq $true) {
$compare.Match = $null $compare.Match = $null
} }
Write-LogDebug "Add property $($compare.PropertyName)"
$script:compareProperties += $compare $script:compareProperties += $compare
} }
@@ -1474,17 +1542,19 @@ function Compare-ObjectsBasedonDocumentation
# ToDo: set this based on configuration value # ToDo: set this based on configuration value
$script:assignmentOutput = "simpleFullCompare" $script:assignmentOutput = "simpleFullCompare"
$docObj1 = Invoke-ObjectDocumentation ([PSCustomObject]@{ $tmpObj1 = ([PSCustomObject]@{
Object = $obj1 Object = $obj1
ObjectType = $objectType ObjectType = $objectType})
})
$docObj1 = Invoke-ObjectDocumentation $tmpObj1 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$docObj2 = Invoke-ObjectDocumentation ([PSCustomObject]@{ $tmpObj2 = ([PSCustomObject]@{
Object = $obj2 Object = $obj2
ObjectType = $objectType ObjectType = $objectType
}) })
$docObj2 = Invoke-ObjectDocumentation $tmpObj2 -ObjectSeparator ($global:cbCompareMultiValueDelimiter.SelectedValue)
$settingsValue = ?? $objectType.CompareValue "Value" $settingsValue = ?? $objectType.CompareValue "Value"
$skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked" $skipBasicProperties = Get-XamlProperty $script:cmpForm "chkSkipCompareBasicProperties" "IsChecked"
@@ -1505,8 +1575,10 @@ function Compare-ObjectsBasedonDocumentation
$addedProperties = @() $addedProperties = @()
if($docObj1.InputType -eq "Settings") if($docObj1.InputType -eq "Intent")
{ {
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where ParentSettingId -ne $null))
foreach ($prop in $docObj1.Settings) foreach ($prop in $docObj1.Settings)
{ {
if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue } if(($prop.SettingId + $prop.ParentSettingId + $prop.RowIndex) -in $addedProperties) { continue }
@@ -1580,8 +1652,48 @@ function Compare-ObjectsBasedonDocumentation
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category Add-CompareProperty $prop.Name $val1 $val2 $prop.Category
} }
} }
elseif($docObj1.InputType -eq "Settings")
{
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where SubCategory -ne $null))
foreach ($prop in $docObj1.Settings)
{
if(($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id)
$val1 = $prop.$settingsValue
$prop2 = $docObj2.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.CategoryId -eq $prop.CategoryId -and $_.SubCategoryDefinition.Id -eq $prop.SubCategoryDefinition.Id }
$val2 = $prop2.$settingsValue
if($val1 -isnot [array] -and $val2 -is [array] -and $val2.Count -gt 1)
{
Write-Log "Multiple compare results returend for $($prop.Name). Using first result" 2
$val2 = $val2[0]
}
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}
# These objects are defined only on Object 2. They will be last in the table
foreach ($prop in $docObj2.Settings)
{
if(($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id) -in $addedProperties) { continue }
$addedProperties += ($prop.SettingId + $prop.CategoryId + $prop.SubCategoryDefinition.Id)
$val2 = $prop.$settingsValue
$prop2 = $docObj1.Settings | Where { $_.SettingId -eq $prop.SettingId -and $_.CategoryId -eq $prop.CategoryId -and $_.SubCategoryDefinition.Id -eq $prop.SubCategoryDefinition.Id }
$val1 = $prop2.$settingsValue
if($val2 -isnot [array] -and $val1 -is [array] -and $val1.Count -gt 1)
{
Write-Log "Multiple compare results returend for $($prop.Name). Using first result" 2
$val1 = $val1[0]
}
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}
}
else else
{ {
Set-ColumnVisibility $true ($null -ne ($docObj1.Settings | Where SubCategory -ne $null))
foreach ($prop in $docObj1.Settings) foreach ($prop in $docObj1.Settings)
{ {
if(($prop.EntityKey + $prop.Category + $prop.SubCategory) -in $addedProperties) { continue } if(($prop.EntityKey + $prop.Category + $prop.SubCategory) -in $addedProperties) { continue }
@@ -1623,8 +1735,8 @@ function Compare-ObjectsBasedonDocumentation
{ {
$applicabilityRule2 = $docObj2.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id } $applicabilityRule2 = $docObj2.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$applicabilityRulesAdded += $applicabilityRule.Id $applicabilityRulesAdded += $applicabilityRule.Id
$val1 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value) $val1 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val2 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value) $val2 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
} }
@@ -1634,8 +1746,8 @@ function Compare-ObjectsBasedonDocumentation
if(($applicabilityRule.Id) -in $applicabilityRulesAdded) { continue } if(($applicabilityRule.Id) -in $applicabilityRulesAdded) { continue }
$applicabilityRule2 = $docObj1.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id } $applicabilityRule2 = $docObj1.ApplicabilityRules | Where { $_.Id -eq $applicabilityRule.Id }
$script:applicabilityRulesAdded += $applicabilityRule.Id $script:applicabilityRulesAdded += $applicabilityRule.Id
$val2 = ($applicabilityRule.Rule + [environment]::NewLine + $applicabilityRule.Value) $val2 = ($applicabilityRule.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule.Value)
$val1 = ($applicabilityRule2.Rule + [environment]::NewLine + $applicabilityRule2.Value) $val1 = ($applicabilityRule2.Rule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $applicabilityRule2.Value)
Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category Add-CompareProperty $applicabilityRule.Property $val1 $val2 $applicabilityRule.Category
} }
@@ -1645,8 +1757,8 @@ function Compare-ObjectsBasedonDocumentation
{ {
$complianceAction2 = $docObj2.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr } $complianceAction2 = $docObj2.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr $complianceActionsAdded += $complianceAction.IdStr
$val1 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds) $val1 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val2 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.EmailCCIds) $val2 = ($complianceAction2.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.EmailCCIds)
Add-CompareProperty $complianceAction.Category $val1 $val2 Add-CompareProperty $complianceAction.Category $val1 $val2
} }
@@ -1656,8 +1768,8 @@ function Compare-ObjectsBasedonDocumentation
if(($complianceAction.IdStr) -in $complianceActionsAdded) { continue } if(($complianceAction.IdStr) -in $complianceActionsAdded) { continue }
$complianceAction2 = $docObj1.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr } $complianceAction2 = $docObj1.ComplianceActions | Where { $_.IdStr -eq $complianceAction.IdStr }
$complianceActionsAdded += $complianceAction.IdStr $complianceActionsAdded += $complianceAction.IdStr
$val2 = ($complianceAction.Action + [environment]::NewLine + $complianceAction.Schedule + [environment]::NewLine + $complianceAction.MessageTemplateId + [environment]::NewLine + $complianceAction.EmailCCIds) $val2 = ($complianceAction.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction.EmailCCIds)
$val1 = ($complianceAction2.Action + [environment]::NewLine + $complianceAction2.Schedule + [environment]::NewLine + $complianceAction2.MessageTemplateId + [environment]::NewLine + $complianceAction2.EmailCCIds) $val1 = ($complianceAction2.Action + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.Schedule + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.MessageTemplateId + ($global:cbCompareMultiValueDelimiter.SelectedValue) + $complianceAction2.EmailCCIds)
Add-CompareProperty $complianceAction.Category $val1 $val2 Add-CompareProperty $complianceAction.Category $val1 $val2
} }
@@ -1783,6 +1895,10 @@ function Invoke-SilentBatchJob
$global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|") $global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|")
$global:cbCompareCSVDelimiter.SelectedValue = ($settingsObj.BulkCompare | Where Name -eq "cbCompareCSVDelimiter").Value $global:cbCompareCSVDelimiter.SelectedValue = ($settingsObj.BulkCompare | Where Name -eq "cbCompareCSVDelimiter").Value
$objectSeparator = "[ { Name: `"New line`",Value: `"$([System.Environment]::NewLine)`" }, {Name: `";`",Value: `";`" }, {Name: `"|`",Value: `"|`" }]" | ConvertFrom-Json
$global:cbCompareMultiValueDelimiter.ItemsSource = $objectSeparator
$global:cbCompareMultiValueDelimiter.SelectedValue = (Get-Setting "Compare" "ObjectSeparator" ([System.Environment]::NewLine))
Set-CompareProviderOptions $global:cbCompareProvider Set-CompareProviderOptions $global:cbCompareProvider
Set-BatchProperties $settingsObj.BulkCompare $script:cmpForm -SkipMissingControlWarning Set-BatchProperties $settingsObj.BulkCompare $script:cmpForm -SkipMissingControlWarning
+173 -19
View File
@@ -40,6 +40,7 @@ function Invoke-InitializeModule
useDeviceContext="SettingDetails.installContextLabel" useDeviceContext="SettingDetails.installContextLabel"
uninstallOnDeviceRemoval="SettingDetails.UninstallOnRemoval" uninstallOnDeviceRemoval="SettingDetails.UninstallOnRemoval"
isRemovable="SettingDetails.installAsRemovable" isRemovable="SettingDetails.installAsRemovable"
preventManagedAppBackup="AppResources.AppSettingsUx.preventManagedAppBackup"
vpnConfigurationId="PolicyType.vpn" vpnConfigurationId="PolicyType.vpn"
Action="SettingDetails.actionColumnName" Action="SettingDetails.actionColumnName"
Schedule="ScheduledAction.List.schedule" Schedule="ScheduledAction.List.schedule"
@@ -289,12 +290,20 @@ function Get-ObjectDocumentation
$properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description") $properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description")
} }
#endregion #endregion
#region Compliance Policies V2
elseif($type -eq "#microsoft.graph.deviceManagementCompliancePolicy")
{
Invoke-TranslateComplianceV2Object $obj $objectType | Out-Null
$properties = @("Name","Value","RootCategory","Category","RawValue","RawJsonValue","DefaultValue","Description")
}
#endregion
#region Endpoint Security #region Endpoint Security
elseif($type -eq "#microsoft.graph.deviceManagementIntent") elseif($type -eq "#microsoft.graph.deviceManagementIntent")
{ {
Invoke-TranslateIntentObject $obj $objectType | Out-Null Invoke-TranslateIntentObject $obj $objectType | Out-Null
$properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description") $properties = @("Name","Value","Category","FullValueTable","RawValue","RecommendedValue","SettingId","Description")
$defaultDocumentationProperties = @("Name","Value","RecommendedValue") $defaultDocumentationProperties = @("Name","Value","RecommendedValue")
$inputType = "Intent"
} }
#endregion #endregion
#region Administrative Templates #region Administrative Templates
@@ -381,7 +390,11 @@ function Get-DocumentedSettings
function Invoke-ObjectDocumentation function Invoke-ObjectDocumentation
{ {
param($documentationObj) param($documentationObj,
$ObjectSeparator,
$PropertySeparator,
$DocumentationLanguage
)
$global:intentCategories = $null $global:intentCategories = $null
$global:catRecommendedSettings = $null $global:catRecommendedSettings = $null
@@ -389,10 +402,11 @@ function Invoke-ObjectDocumentation
$global:cfgCategories = $null $global:cfgCategories = $null
$script:admxCategories = $null $script:admxCategories = $null
$script:migTable = $null $script:migTable = $null
$script:offlineObjects = @{}
$script:DocumentationLanguage = "en" $script:DocumentationLanguage = ?? $DocumentationLanguage "en"
$script:objectSeparator = [System.Environment]::NewLine $script:objectSeparator = ?? $ObjectSeparator ([System.Environment]::NewLine)
$script:propertySeparator = "," $script:propertySeparator = ?? $PropertySeparator ","
$loadExportedInfo = $false $loadExportedInfo = $false
@@ -592,7 +606,7 @@ function Get-ObjectTypeString
function Add-BasicDefaultValues function Add-BasicDefaultValues
{ {
param($obj, $objectType) param($obj, $objectType, $profileTypeName = $null)
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") (Get-GraphObjectName $obj $objectType) Add-BasicPropertyValue (Get-LanguageString "SettingDetails.nameName") (Get-GraphObjectName $obj $objectType)
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.descriptionName") $obj.description Add-BasicPropertyValue (Get-LanguageString "SettingDetails.descriptionName") $obj.description
@@ -603,7 +617,7 @@ function Add-BasicDefaultValues
if($objInfo) if($objInfo)
{ {
$platformType = Get-LanguageString "Platform.$($objInfo.PlatformLanguageId)" $platformType = Get-LanguageString "Platform.$($objInfo.PlatformLanguageId)"
$profileType = Get-LanguageString "ConfigurationTypes.$($objInfo.PolicyType)" $profileType = (?? $profileTypeName (Get-LanguageString "ConfigurationTypes.$($objInfo.PolicyType)"))
if($platformType) { Add-BasicPropertyValue (Get-LanguageString "SettingDetails.platformSupported") $platformType } if($platformType) { Add-BasicPropertyValue (Get-LanguageString "SettingDetails.platformSupported") $platformType }
if($profileType) { Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") $profileType } if($profileType) { Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") $profileType }
@@ -691,6 +705,10 @@ function Add-BasicAdditionalValues
if($obj.createdDateTime -is [DateTime]) if($obj.createdDateTime -is [DateTime])
{ {
$tmpDate = $obj.createdDateTime $tmpDate = $obj.createdDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -714,6 +732,10 @@ function Add-BasicAdditionalValues
if($obj.lastModifiedDateTime -is [DateTime]) if($obj.lastModifiedDateTime -is [DateTime])
{ {
$tmpDate = $obj.lastModifiedDateTime $tmpDate = $obj.lastModifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -735,6 +757,10 @@ function Add-BasicAdditionalValues
if($obj.modifiedDateTime -is [DateTime]) if($obj.modifiedDateTime -is [DateTime])
{ {
$tmpDate = $obj.modifiedDateTime $tmpDate = $obj.modifiedDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -1037,15 +1063,26 @@ function Invoke-TranslateADMXObject
$rawValues += $rawValue $rawValues += $rawValue
} }
$status = (?: ($definitionValue.enabled -eq $true) $enabledStr $disabledStr) $status = (?: ($definitionValue.enabled -eq $true) $enabledStr $disabledStr)
$combinedValue = $status
if($values) {
$combinedValue += $script:objectSeparator + ($values -join $script:objectSeparator)
}
$combinedValueWithLabel = $status
if($valuesWithLabel) {
$combinedValueWithLabel += $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator)
}
$script:objectSettingsData += New-Object PSObject -Property @{ $script:objectSettingsData += New-Object PSObject -Property @{
Name = $definitionValue.definition.displayName Name = $definitionValue.definition.displayName
Description = $definitionValue.definition.explainText Description = $definitionValue.definition.explainText
Status = $status Status = $status
Value = $values -join $script:objectSeparator Value = $values -join $script:objectSeparator
CombinedValue = ($status + $script:objectSeparator + ($values -join $script:objectSeparator)) CombinedValue = $combinedValue #($status + $script:objectSeparator + ($values -join $script:objectSeparator))
ValueWithLabel = $valuesWithLabel -join $script:objectSeparator ValueWithLabel = $valuesWithLabel -join $script:objectSeparator
FullValueTable = $tableValue FullValueTable = $tableValue
CombinedValueWithLabel = ($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator)) CombinedValueWithLabel = $combinedValueWithLabel #($status + $script:objectSeparator + ($valuesWithLabel -join $script:objectSeparator))
RawValue = $rawValues -join $script:propertySeparator RawValue = $rawValues -join $script:propertySeparator
Class = $definitionValue.definition.classType Class = $definitionValue.definition.classType
DefinitionId = $definitionValue.definition.id DefinitionId = $definitionValue.definition.id
@@ -1109,9 +1146,9 @@ function Invoke-TranslateSettingsObject
$cfgSettings = $obj.Settings $cfgSettings = $obj.Settings
} }
if(-not $global:cfgCategories) if(-not $global:cfgCategories -or -not ($global:cfgCategories | where { $_.settingUsage -eq "configuration" }))
{ {
$global:cfgCategories = (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value $global:cfgCategories += (Invoke-GraphRequest "/deviceManagement/configurationCategories?`$filter=platforms has 'windows10' and technologies has 'mdm'" -ODataMetadata "minimal" @params).Value
} }
if(-not $global:cachedCfgSettings) if(-not $global:cachedCfgSettings)
@@ -1210,13 +1247,23 @@ function Add-SettingsSetting
$objCategory = $categoryDef $objCategory = $categoryDef
} }
$settingName = ""
$settingDescription = ""
if($settingsDef.displayName) {
$settingName = $settingsDef.displayName.Trim([Environment]::NewLine).Trim("`n")
}
if($settingsDef.description) {
$settingDescription = $settingsDef.description.Trim([Environment]::NewLine).Trim("`n")
}
$settingInfo = [PSCustomObject]@{ $settingInfo = [PSCustomObject]@{
SettingId = $settingsDef.Id SettingId = $settingsDef.Id
SettingKey = "" SettingKey = ""
SettingName = $settingsDef.Name SettingName = $settingsDef.Name
Name = $settingsDef.displayName Name = $settingName
Description=$settingsDef.description Description = $settingDescription
CategortyId = $objCategory.id CategoryId = $objCategory.id
Category=$objCategory.displayName Category=$objCategory.displayName
CategoryDefinition=$objCategory CategoryDefinition=$objCategory
SubCategory=$subCategory.displayName SubCategory=$subCategory.displayName
@@ -1392,6 +1439,85 @@ function Add-SettingsSetting
#endregion #endregion
#region Compliance V2 Policies - Based on Settings Catalog
function Invoke-TranslateComplianceV2Object
{
param($obj, $objectType)
$platformType = Get-LanguageString "Platform.$($obj.platforms)"
Add-BasicDefaultValues $obj $objectType
Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "ConfigurationTypes.settingsCatalog")
Add-BasicPropertyValue (Get-LanguageString "SettingDetails.platformSupported") $platformType
Add-BasicAdditionalValues $obj $objectType
$params = @{}
## Set language
if($script:DocumentationLanguage)
{
$params.Add("AdditionalHeaders", @{"Accept-Language"=$script:DocumentationLanguage})
}
$cfgSettings = (Invoke-GraphRequest "/deviceManagement/compliancePolicies('$($obj.Id)')/settings?`$expand=settingDefinitions&top=1000" -ODataMetadata "minimal" @params).Value
if($obj.'@ObjectFromFile')
{
$cfgSettings = $obj.Settings
}
if(-not $global:cfgCategories -or -not ($global:cfgCategories | where { $_.settingUsage -eq "compliance" }))
{
$global:cfgCategories += (Invoke-GraphRequest "/deviceManagement/complianceCategories?`$templateCategory=True&`$filter=platforms has 'linux' and technologies has 'linuxMdm'" -ODataMetadata "minimal" @params).Value
}
if(-not $global:cachedCfgSettings)
{
$global:cachedCfgSettings = @{}
}
$script:settingCatalogasCategories = @{}
foreach($cfgSetting in $cfgSettings)
{
if($obj.'@ObjectFromFile' -and -not $cfgSetting.settingDefinitions)
{
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$defObj = Invoke-GraphRequest "/deviceManagement/configurationSettings/$($cfgSetting.settingInstance.settingDefinitionId)"
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
else
{
$defObj = $cfgSetting.settingDefinitions | Where id -eq $cfgSetting.settingInstance.settingDefinitionId
if($global:cachedCfgSettings.ContainsKey($cfgSetting.settingInstance.settingDefinitionId) -eq $false)
{
$global:cachedCfgSettings.Add($defObj.Id, $defObj)
}
}
if(-not $defObj -or $script:settingCatalogasCategories.ContainsKey($defObj.categoryId)) { continue }
$catObj = $global:cfgCategories | Where Id -eq $defObj.categoryId
$rootCatObj = $global:cfgCategories | Where Id -eq $catObj.rootCategoryId
$script:settingCatalogasCategories.Add($defObj.categoryId, (New-Object PSObject -Property @{
Category=$catObj
RootCategory=$rootCatObj
}))
}
$script:curSettingsCatologPolicy = @()
$cfgSettings | % { Add-SettingsSetting $_.settingInstance $_.settingDefinitions } | Out-Null
foreach($item in ($script:curSettingsCatologPolicy | Select @{l="CategoryID";e={$_.CategoryDefinition.Id}}, @{l="SubCategoryID";e={$_.SubCategoryDefinition.Id}} -Unique))
{
$script:objectSettingsData += ($script:curSettingsCatologPolicy | Where { $_.CategoryDefinition.Id -eq $item.CategoryID -and $_.SubCategoryDefinition.Id -eq $item.SubCategoryID })
}
}
#endregion
#region Intent Objects (Endpoint Security) #region Intent Objects (Endpoint Security)
function Get-IntentCategory function Get-IntentCategory
@@ -1574,7 +1700,7 @@ function Add-IntentSettingObjectToList
{ {
$passConstraint = ($dependencyItemObj.RawValue -ne $null -and $dependencyItemObj.RawValue.ToString() -ne "NotConfigured" -and $dependencyItemObj.RawValue.ToString() -ne "False") $passConstraint = ($dependencyItemObj.RawValue -ne $null -and $dependencyItemObj.RawValue.ToString() -ne "NotConfigured" -and $dependencyItemObj.RawValue.ToString() -ne "False")
} }
if(-not $passConstraint) { break ]} if(-not $passConstraint) { break }
} }
if(-not $passConstraint) if(-not $passConstraint)
@@ -2166,6 +2292,7 @@ function Invoke-TranslateSection
$value = $null $value = $null
$valueSet = $false $valueSet = $false
$useParentProp = $false $useParentProp = $false
$payloadFile = $false
#if($prop.enabled -eq $false -and $objInfo.ShowDisabled -ne $true) { continue } #if($prop.enabled -eq $false -and $objInfo.ShowDisabled -ne $true) { continue }
@@ -2397,6 +2524,7 @@ function Invoke-TranslateSection
if($prop.filenameEntityKey -and $obj."$($prop.filenameEntityKey)") if($prop.filenameEntityKey -and $obj."$($prop.filenameEntityKey)")
{ {
$value = $obj."$($prop.filenameEntityKey)" $value = $obj."$($prop.filenameEntityKey)"
$payloadFile = $true
} }
else else
{ {
@@ -2550,6 +2678,23 @@ function Invoke-TranslateSection
if($addPropertyInfo) if($addPropertyInfo)
{ {
Add-PropertyInfo (?: ($useParentProp -and $parent) $parent $prop) $value $rawValue Add-PropertyInfo (?: ($useParentProp -and $parent) $parent $prop) $value $rawValue
if($payloadFile -eq $true -and $obj.payload)
{
# Add payload file conetent as a property
$tmpProp = [PSCustomObject]@{
nameResourceKey = "uploadResult"
descriptionResourceKey = ""
entityKey = "payloadData"
dataType = 20
booleanActions = 0
category = $prop.Category
}
$propValue = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($obj.payload))
Add-PropertyInfo $tmpProp $propValue -originalValue $obj.payload
}
} }
} }
else else
@@ -3636,6 +3781,7 @@ function Invoke-TranslateAssignments
"uninstallOnDeviceRemoval", "uninstallOnDeviceRemoval",
"isRemovable", "isRemovable",
"useDeviceLicensing", "useDeviceLicensing",
"preventManagedAppBackup",
"androidManagedStoreAppTrackIds", "androidManagedStoreAppTrackIds",
"deliveryOptimizationPriority", "deliveryOptimizationPriority",
"installTimeSettings", "installTimeSettings",
@@ -3736,7 +3882,7 @@ function Invoke-TranslateAssignments
} }
$value = $tmpStr -f $tmpType $value = $tmpStr -f $tmpType
} }
elseif($assignment.settings.$settingProp -eq "notConfigured") elseif("$($assignment.settings.$settingProp)" -eq "notConfigured")
{ {
$value = Get-LanguageString "BooleanActions.notConfigured" $value = Get-LanguageString "BooleanActions.notConfigured"
} }
@@ -4278,7 +4424,7 @@ function local:Invoke-StartDocumentatiom
$script:migTable = $null $script:migTable = $null
$script:scopeTags = $null $script:scopeTags = $null
$diSource = $nul $diSource = $null
$global:intentCategories = $null $global:intentCategories = $null
$global:catRecommendedSettings = $null $global:catRecommendedSettings = $null
$global:intentCategoryDefs = $null $global:intentCategoryDefs = $null
@@ -4340,7 +4486,7 @@ function local:Invoke-StartDocumentatiom
$tmpObj | Add-Member Noteproperty -Name "GroupName" -Value (Get-ObjectTypeGroupName $tmpObj.ObjectType) -Force $tmpObj | Add-Member Noteproperty -Name "GroupName" -Value (Get-ObjectTypeGroupName $tmpObj.ObjectType) -Force
} }
if($groupSourceList.Count -eq 0) { contnue } if($groupSourceList.Count -eq 0) { continue }
if($curObjectType.GroupId -eq "EndpointSecurity") if($curObjectType.GroupId -eq "EndpointSecurity")
{ {
@@ -4594,13 +4740,21 @@ function local:Invoke-StartDocumentatiom
{ {
Write-Status "Process $((Get-GraphObjectName $tmpObj.Object $tmpObj.ObjectType)) ($($obj.ObjectType.Title)) - $($global:cbDocumentationType.SelectedItem.Name)" Write-Status "Process $((Get-GraphObjectName $tmpObj.Object $tmpObj.ObjectType)) ($($obj.ObjectType.Title)) - $($global:cbDocumentationType.SelectedItem.Name)"
$hasRawValue = $false
$documentedObj.Settings | % { if(($_.PSObject.Properties | Where Name -eq "RawValue")) { $hasRawValue=$true } }
$hasRawValue
$filteredSettings = @() $filteredSettings = @()
foreach($item in $documentedObj.Settings) foreach($item in $documentedObj.Settings)
{ {
if(-not ($item.PSObject.Properties | Where Name -eq "RawValue") -or $documentedObj.UpdateFilteredObject -eq $false) if(-not ($item.PSObject.Properties | Where Name -eq "RawValue") -or $documentedObj.UpdateFilteredObject -eq $false)
{ {
$filteredSettings = $documentedObj.Settings if($hasRawValue -eq $false) {
break $filteredSettings = $documentedObj.Settings
break
}
$filteredSettings += $item
continue
} }
if($item.AlwaysAddValue -eq $true) if($item.AlwaysAddValue -eq $true)
+132 -5
View File
@@ -422,7 +422,7 @@ function Add-CDDocumentCustomProfileValue
$value = $obj.startMenuAppListVisibility $value = $obj.startMenuAppListVisibility
if($value.IndexOf(", ") -eq -1) if($value.IndexOf(", ") -eq -1)
{ {
$value = $value -replace ",",", " # Option values in json file has space afte , but value in object don't $value = $value -replace ",",", " # Option values in json file has space after , but value in object don't
} }
Invoke-TranslateOption $obj $prop -PropValue $value Invoke-TranslateOption $obj $prop -PropValue $value
return $false return $false
@@ -908,6 +908,27 @@ function Add-CDDocumentCustomProfileProperty
} }
elseif($obj.'@OData.Type' -like "#microsoft.graph.iosDeviceFeaturesConfiguration") elseif($obj.'@OData.Type' -like "#microsoft.graph.iosDeviceFeaturesConfiguration")
{ {
foreach($configuration in $obj.iosSingleSignOnExtension.configurations)
{
$configurationType = "notConfigured"
if($configuration."@OData.Type" -eq "#microsoft.graph.keyStringValuePair")
{
$configurationType = Get-LanguageString "SettingDetails.singleSignOnExtensionConfigurationsTypeColumnOptionString"
}
elseif($configuration."@OData.Type" -eq "#microsoft.graph.keyBooleanValuePair")
{
$configurationType = Get-LanguageString "SettingDetails.singleSignOnExtensionConfigurationsTypeColumnOptionBoolean"
}
elseif($configuration."@OData.Type" -eq "#microsoft.graph.keyIntegerValuePair")
{
$configurationType = Get-LanguageString "SettingDetails.singleSignOnExtensionConfigurationsTypeColumnOptionInteger"
}
$configuration | Add-Member Noteproperty -Name "configurationKey" -Value $configuration.key -Force
$configuration | Add-Member Noteproperty -Name "configurationValue" -Value $configuration.value -Force
$configuration | Add-Member Noteproperty -Name "configurationType" -Value $configurationType -Force
}
#singleSignOnSettings #singleSignOnSettings
$obj | Add-Member Noteproperty -Name "kerberosPrincipalName" -Value (?? $obj.singleSignOnSettings.kerberosPrincipalName "notConfigured") -Force $obj | Add-Member Noteproperty -Name "kerberosPrincipalName" -Value (?? $obj.singleSignOnSettings.kerberosPrincipalName "notConfigured") -Force
@@ -1180,6 +1201,12 @@ function Add-CDDocumentCustomProfileProperty
} }
elseif($obj.'@OData.Type' -eq "#microsoft.graph.windows10EnrollmentCompletionPageConfiguration") elseif($obj.'@OData.Type' -eq "#microsoft.graph.windows10EnrollmentCompletionPageConfiguration")
{ {
$installProgressTimeout = $obj.installProgressTimeoutInMinutes
if($installProgressTimeout -eq 0) {
$installProgressTimeout = 60
}
$obj | Add-Member Noteproperty -Name "InstallProgressTimeout" -Value $installProgressTimeout
if($obj.selectedMobileAppIds.Count -eq 0) if($obj.selectedMobileAppIds.Count -eq 0)
{ {
$apps = Get-LanguageString "EnrollmentStatusScreen.Apps.useSelectedAppsAll" $apps = Get-LanguageString "EnrollmentStatusScreen.Apps.useSelectedAppsAll"
@@ -1212,6 +1239,10 @@ function Add-CDDocumentCustomProfileProperty
$returnCodes = @() $returnCodes = @()
$detectionRules = @() $detectionRules = @()
$requirementRules = @() $requirementRules = @()
$activeScripts = @()
$activeInstallScript = $null
$activeUninstallScript = $null
foreach($rc in $obj.returnCodes) foreach($rc in $obj.returnCodes)
{ {
$returnCodes += [PSCustomObject]@{ $returnCodes += [PSCustomObject]@{
@@ -1240,6 +1271,46 @@ function Add-CDDocumentCustomProfileProperty
} }
} }
if($obj.activeInstallScript.'#ScriptInfo')
{
$scriptType = "install"
$obj.installCommandLine = $null
$installType = "Win32Program.installScript"
$activeInstallScript = [PSCustomObject]@{
scriptType = $scriptType
scriptName = $obj.activeInstallScript.'#ScriptInfo'.displayName
scriptContent = $obj.activeInstallScript.'#ScriptInfo'.ScriptContent
enforceSignatureCheck = $obj.activeInstallScript.'#ScriptInfo'.enforceSignatureCheck
runAs32Bit = $obj.activeInstallScript.'#ScriptInfo'.runAs32Bit
}
Add-ObjectScript $header ("{0} - {1}" -f @($obj.displayName,$obj.activeInstallScript.'#ScriptInfo'.displayName)) $obj.activeInstallScript.'#ScriptInfo'.content
}
else
{
$installType = "Win32Program.installCommand"
}
if($obj.activeUninstallScript.'#ScriptInfo')
{
$scriptType = "uninstall"
$obj.uninstallCommandLine = $null
$uninstallType = "Win32Program.uninstallScript"
$activeUninstallScript = [PSCustomObject]@{
scriptType = $scriptType
scriptName = $obj.activeUninstallScript.'#ScriptInfo'.displayName
scriptContent = $obj.activeUninstallScript.'#ScriptInfo'.ScriptContent
enforceSignatureCheck = $obj.activeUninstallScript.'#ScriptInfo'.enforceSignatureCheck
runAs32Bit = $obj.activeUninstallScript.'#ScriptInfo'.runAs32Bit
}
Add-ObjectScript $header ("{0} - {1}" -f @($obj.displayName,$obj.activeUninstallScript.'#ScriptInfo'.displayName)) $obj.activeUninstallScript.'#ScriptInfo'.content
}
else
{
$uninstallType = "Win32Program.uninstallCommand"
}
foreach($rule in $obj.requirementRules) foreach($rule in $obj.requirementRules)
{ {
if($rule.'@OData.Type' -eq "#microsoft.graph.win32LobAppFileSystemRequirement") if($rule.'@OData.Type' -eq "#microsoft.graph.win32LobAppFileSystemRequirement")
@@ -1308,7 +1379,11 @@ function Add-CDDocumentCustomProfileProperty
$obj | Add-Member Noteproperty -Name "requirementRulesTranslated" -Value $requirementRules -Force $obj | Add-Member Noteproperty -Name "requirementRulesTranslated" -Value $requirementRules -Force
$obj | Add-Member Noteproperty -Name "detectionRulesTranslated" -Value $detectionRules -Force $obj | Add-Member Noteproperty -Name "detectionRulesTranslated" -Value $detectionRules -Force
$obj | Add-Member Noteproperty -Name "returnCodes" -Value $returnCodes -Force $obj | Add-Member Noteproperty -Name "returnCodes" -Value $returnCodes -Force
$obj | Add-Member Noteproperty -Name "activeInstallScript" -Value $activeInstallScript -Force
$obj | Add-Member Noteproperty -Name "activeUninstallScript" -Value $activeUninstallScript -Force
$obj | Add-Member Noteproperty -Name "win10Release" -Value (Get-LanguageString "MinimumOperatingSystem.Windows.V10Release.release$($obj.minimumSupportedWindowsRelease)") -Force $obj | Add-Member Noteproperty -Name "win10Release" -Value (Get-LanguageString "MinimumOperatingSystem.Windows.V10Release.release$($obj.minimumSupportedWindowsRelease)") -Force
$obj | Add-Member Noteproperty -Name "installerType" -Value (Get-LanguageString $installType) -Force
$obj | Add-Member Noteproperty -Name "uninstallerType" -Value (Get-LanguageString $uninstallType) -Force
} }
elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceHealthScript") elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceHealthScript")
{ {
@@ -1329,6 +1404,17 @@ function Add-CDDocumentCustomProfileProperty
Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.remediationScriptContent Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.remediationScriptContent
} }
} }
elseif($obj.'@OData.Type' -eq "#microsoft.graph.hardwareConfiguration")
{
$vendor = ?? (Get-LanguageString "HardwareConfig.Settings.Tab.HardwareDropDown.$($obj.hardwareConfigurationFormat)" -IgnoreMissing) $obj.hardwareConfigurationFormat
$obj | Add-Member Noteproperty -Name "vendor" -Value $vendor
if($obj.configurationFileContent)
{
$obj | Add-Member Noteproperty -Name "configurationFileContentString" -Value ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(($obj.configurationFileContent))))
$header = Get-LanguageString "HardwareConfig.Settings.Tab.Configurations.perDevicePassword"
Add-ObjectScript $header ("{1} - {0}" -f $obj.displayName,$header) $obj.configurationFileContent
}
}
elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceManagementScript") elseif($obj.'@OData.Type' -eq "#microsoft.graph.deviceManagementScript")
{ {
if($obj.ScriptContent) if($obj.ScriptContent)
@@ -1852,8 +1938,21 @@ function Invoke-CDDocumentAndroidManagedStoreAppConfiguration
################################################### ###################################################
# Basic info # Basic info
################################################### ###################################################
$profileString = $null
if($obj.profileApplicability -eq "default")
{
$profileString = Get-LanguageString "ProfileType.workProfileAndDeviceOwner"
}
elseif($obj.profileApplicability -eq "androidWorkProfile")
{
$profileString = Get-LanguageString "ProfileType.workProfileOnly"
}
elseif($obj.profileApplicability -eq "androidDeviceOwner")
{
$profileString = Get-LanguageString "ProfileType.deviceOwnerOnly"
}
Add-BasicDefaultValues $obj $objectType Add-BasicDefaultValues $obj $objectType $profileString
Add-BasicAdditionalValues $obj $objectType Add-BasicAdditionalValues $obj $objectType
#Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "SettingDetails.appConfiguration") #Add-BasicPropertyValue (Get-LanguageString "TableHeaders.configurationType") (Get-LanguageString "SettingDetails.appConfiguration")
#Add-BasicPropertyValue (Get-LanguageString "Inputs.enrollmentTypeLabel") (Get-LanguageString "EnrollmentType.devicesWithEnrollment") #Add-BasicPropertyValue (Get-LanguageString "Inputs.enrollmentTypeLabel") (Get-LanguageString "EnrollmentType.devicesWithEnrollment")
@@ -2016,11 +2115,22 @@ function Invoke-CDDocumentMobileAppConfiguration
{ {
$name = $xml.dict.ChildNodes[$i].'#text' $name = $xml.dict.ChildNodes[$i].'#text'
$i++ $i++
$value = $xml.dict.ChildNodes[$i].'#text'
if($xml.dict.ChildNodes[$i].Name -eq "true" -or $xml.dict.ChildNodes[$i].Name -eq "false")
{
$value = $xml.dict.ChildNodes[$i].Name
$type = "boolean"
}
else
{
$value = $xml.dict.ChildNodes[$i].'#text'
$type = $xml.dict.ChildNodes[$i].Name
}
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = $name Name = $name
Value = $value Value = $value
ValueType = $type
EntityKey = $name EntityKey = $name
Category = $category Category = $category
}) })
@@ -2200,7 +2310,7 @@ function Invoke-CDDocumentCountryNamedLocation
$countryList = @() $countryList = @()
foreach($country in $obj.countriesAndRegions) foreach($country in $obj.countriesAndRegions)
{ {
$countryList += Get-LanguageString "CountryNames.countryName$($country.ToLower())" $countryList += Get-LanguageString "AzureIAMCommon.CountryNames.countryName$($country.ToUpper())"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
@@ -2299,6 +2409,10 @@ function Invoke-CDDocumentTermsOfUse
if($obj.termsExpiration.startDateTime -is [DateTime]) if($obj.termsExpiration.startDateTime -is [DateTime])
{ {
$tmpDate = $obj.termsExpiration.startDateTime $tmpDate = $obj.termsExpiration.startDateTime
if($tmpDate.Kind -eq "UTC")
{
$tmpDate = $tmpDate.ToLocalTime()
}
} }
else else
{ {
@@ -4154,7 +4268,17 @@ function Invoke-CDDocumentWindowsKioskConfiguration
{ {
try try
{ {
$startDateObj = Get-Date $obj.windowsKioskForceUpdateSchedule.startDateTime -ErrorAction Stop if($obj.windowsKioskForceUpdateSchedule.startDateTime -is [DateTime]) {
$startDateObj = $obj.windowsKioskForceUpdateSchedule.startDateTime
if($startDateObj.Kind -eq "UTC")
{
$startDateObj = $startDateObj.ToLocalTime()
}
}
else
{
$startDateObj = Get-Date $obj.windowsKioskForceUpdateSchedule.startDateTime -ErrorAction Stop
}
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.kioskStartDateTime" Name = Get-LanguageString "SettingDetails.kioskStartDateTime"
@@ -4608,15 +4732,18 @@ function Invoke-CDDocumentTranslateSectionFile
if($null -eq $obj.deviceCompliancePolicyScript) if($null -eq $obj.deviceCompliancePolicyScript)
{ {
$propValue = Get-LanguageString "BooleanActions.notConfigured" $propValue = Get-LanguageString "BooleanActions.notConfigured"
$rawValue = "notConfigured"
} }
else else
{ {
$propValue = Get-LanguageString "BooleanActions.require" $propValue = Get-LanguageString "BooleanActions.require"
$rawValue = "require"
} }
Add-CustomSettingObject ([PSCustomObject]@{ Add-CustomSettingObject ([PSCustomObject]@{
Name = Get-LanguageString "SettingDetails.adminConfiguredComplianceSettingName" Name = Get-LanguageString "SettingDetails.adminConfiguredComplianceSettingName"
Value = $propValue Value = $propValue
EntityKey = "deviceCompliancePolicyScript" EntityKey = "deviceCompliancePolicyScript"
RawValue = $rawValue
Category = $category Category = $category
SubCategory = $null SubCategory = $null
}) })
+1 -1
View File
@@ -74,7 +74,7 @@ function Invoke-HTMLPreProcessItems
Write-Log "CSS file not specified. Using default" 2 Write-Log "CSS file not specified. Using default" 2
$HTMLCssFile = $defaultCSSFile $HTMLCssFile = $defaultCSSFile
} }
elseif([IO.File]::Exists($HTMLCssFile) -eq -$false) elseif([IO.File]::Exists($HTMLCssFile) -eq $false)
{ {
Write-Log "CSS file $($HTMLCssFile) not found. Using default" 2 Write-Log "CSS file $($HTMLCssFile) not found. Using default" 2
$HTMLCssFile = $defaultCSSFile $HTMLCssFile = $defaultCSSFile
+265
View File
@@ -0,0 +1,265 @@
function Get-ModuleVersion
{
'1.0.0'
}
function Invoke-InitializeModule
{
Add-OutputType ([PSCustomObject]@{
Name = "Json"
Value = "json"
OutputOptions = (Add-JsonOptionsControl)
PreProcess = { Invoke-JsonPreProcessItems @args }
NewObjectGroup = { Invoke-JsonNewObjectGroup @args }
NewObjectType = { Invoke-JsonNewObjectType @args }
Process = { Invoke-JsonProcessItem @args }
PostProcess = { Invoke-JsonPostProcessItems @args }
})
}
function Add-JsonOptionsControl
{
$script:jsonForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\DocumentationJsonOptions.xaml") -AddVariables
Set-XamlProperty $script:jsonForm "txtJsonFileName" "Text" (Get-Setting "Documentation" "JsonDocumentName" "")
Set-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked" (Get-Setting "Documentation" "JsonOpenFile" $true)
$outputFileTypes = '[ { "Name": "Single file", "Value": "Full" }, { "Name": "One file per object type", "Value": "ObjectType" } ]' | ConvertFrom-Json
Set-XamlProperty $script:jsonForm "cbJsonOutputFile" "ItemsSource" $outputFileTypes
Set-XamlProperty $script:jsonForm "cbJsonOutputFile" "SelectedValue" (Get-Setting "Documentation" "JsonOutputFileType" "Full")
Add-XamlEvent $script:jsonForm "browseJsonFileName" "add_click" {
$sf = [System.Windows.Forms.SaveFileDialog]::new()
$sf.DefaultExt = "json"
$sf.Filter = "Json (*.json)|*.json|All files (*.*)|*.*"
if ($sf.ShowDialog() -eq "OK")
{
Set-XamlProperty $script:jsonForm "txtJsonFileName" "Text" $sf.FileName
Save-Setting "Documentation" "JsonDocumentName" $sf.FileName
}
}
$script:jsonForm
}
function Invoke-JsonPreProcessItems
{
$script:jsonAllObjects = [System.Collections.Generic.List[object]]::new()
$script:jsonCurrentTypeObjects = [System.Collections.Generic.List[object]]::new()
$script:jsonCurrentTypeName = $null
$script:jsonOutputType = Get-XamlProperty $script:jsonForm "cbJsonOutputFile" "SelectedValue" "Full"
$jsonFileName = Get-XamlProperty $script:jsonForm "txtJsonFileName" "Text" ""
Save-Setting "Documentation" "JsonDocumentName" $jsonFileName
Save-Setting "Documentation" "JsonOpenFile" (Get-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked")
Save-Setting "Documentation" "JsonOutputFileType" $script:jsonOutputType
$script:jsonOutFile = Expand-FileName (?? $jsonFileName "%MyDocuments%\%Organization%-%Date%.json")
$script:jsonDocumentPath = [IO.Path]::GetDirectoryName($script:jsonOutFile)
}
function Invoke-JsonNewObjectGroup
{
param($groupId)
# Groups are not used in flat Json output
}
function Invoke-JsonNewObjectType
{
param($objectTypeName)
if ($script:jsonOutputType -eq "ObjectType" -and
$script:jsonCurrentTypeName -and
$script:jsonCurrentTypeObjects.Count -gt 0)
{
Save-JsonTypeFile $script:jsonCurrentTypeName $script:jsonCurrentTypeObjects
}
$script:jsonCurrentTypeName = $objectTypeName
$script:jsonCurrentTypeObjects = [System.Collections.Generic.List[object]]::new()
}
function Invoke-JsonProcessItem
{
param($obj, $objectType, $documentedObj)
if (-not $documentedObj -or -not $obj -or -not $objectType) { return }
$objName = Get-GraphObjectName $obj $objectType
try
{
$jsonObj = [ordered]@{
objectType = $objectType.Title
name = $objName
}
# BasicInfo as a flat key/value object
if ($documentedObj.BasicInfo.Count -gt 0)
{
$basicInfo = [ordered]@{}
foreach ($item in $documentedObj.BasicInfo)
{
if ($item.Name) { $basicInfo[$item.Name] = $item.Value }
}
$jsonObj.basicInfo = $basicInfo
}
# Detailed settings as an array
if ($documentedObj.FilteredSettings.Count -gt 0)
{
$settings = [System.Collections.Generic.List[object]]::new()
foreach ($item in $documentedObj.FilteredSettings)
{
$setting = [ordered]@{ name = $item.Name; value = $item.Value }
if ($item.Category) { $setting.category = $item.Category }
if ($item.SubCategory) { $setting.subCategory = $item.SubCategory }
$settings.Add($setting)
}
$jsonObj.settings = $settings
}
# Compliance actions
if (($documentedObj.ComplianceActions | Measure-Object).Count -gt 0)
{
$actions = [System.Collections.Generic.List[object]]::new()
foreach ($item in $documentedObj.ComplianceActions)
{
$actions.Add([ordered]@{
action = $item.Action
schedule = $item.Schedule
messageTemplate = $item.MessageTemplate
emailCC = $item.EmailCC
})
}
$jsonObj.complianceActions = $actions
}
# Applicability rules
if (($documentedObj.ApplicabilityRules | Measure-Object).Count -gt 0)
{
$rules = [System.Collections.Generic.List[object]]::new()
foreach ($item in $documentedObj.ApplicabilityRules)
{
$rules.Add([ordered]@{
rule = $item.Rule
property = $item.Property
value = $item.Value
})
}
$jsonObj.applicabilityRules = $rules
}
# Custom tables — each becomes a top-level array keyed by the last segment of the language ID
foreach ($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
{
if (-not $customTable.Values -or ($customTable.Values | Measure-Object).Count -eq 0) { continue }
$tableKey = if ($customTable.LanguageId) { $customTable.LanguageId.Split('.')[-1] } else { "customTable" }
$tableArr = [System.Collections.Generic.List[object]]::new()
foreach ($item in $customTable.Values)
{
$tableObj = [ordered]@{}
foreach ($col in $customTable.Columns)
{
$colName = $col.Split('.')[-1]
$tableObj[$colName] = "$($item.$colName)"
}
$tableArr.Add($tableObj)
}
$jsonObj[$tableKey] = $tableArr
}
# Assignments
if (($documentedObj.Assignments | Measure-Object).Count -gt 0)
{
$assignments = [System.Collections.Generic.List[object]]::new()
$hasRawIntent = $null -ne $documentedObj.Assignments[0].RawIntent
foreach ($item in $documentedObj.Assignments)
{
if ($hasRawIntent)
{
$assignObj = [ordered]@{
groupMode = $item.GroupMode
group = $item.Group
}
if ($null -ne $item.Filter) { $assignObj.filter = $item.Filter }
if ($null -ne $item.FilterMode) { $assignObj.filterMode = $item.FilterMode }
if ($item.Settings)
{
$settingsObj = [ordered]@{}
foreach ($key in $item.Settings.Keys)
{
if ($key -in @("Category","RawIntent")) { continue }
$settingsObj[$key] = $item.Settings[$key]
}
$assignObj.settings = $settingsObj
}
}
else
{
$assignObj = [ordered]@{ group = $item.Group }
if ($item.PSObject.Properties.Name -contains "Filter") { $assignObj.filter = $item.Filter }
if ($item.PSObject.Properties.Name -contains "FilterMode") { $assignObj.filterMode = $item.FilterMode }
}
$assignments.Add($assignObj)
}
$jsonObj.assignments = $assignments
}
# Scripts — included when "Document scripts" is checked in the documentation form
if ($global:chkIncludeScripts.IsChecked -and ($documentedObj.Scripts | Measure-Object).Count -gt 0)
{
$scripts = [System.Collections.Generic.List[object]]::new()
foreach ($scriptItem in $documentedObj.Scripts)
{
if (-not $scriptItem.ScriptContent) { continue }
$scripts.Add([ordered]@{
caption = $scriptItem.Caption
content = $scriptItem.ScriptContent
})
}
if ($scripts.Count -gt 0) { $jsonObj.scripts = $scripts }
}
$script:jsonCurrentTypeObjects.Add($jsonObj)
if ($script:jsonOutputType -ne "ObjectType") { $script:jsonAllObjects.Add($jsonObj) }
}
catch
{
Write-LogError "Failed to process object $objName" $_.Exception
}
}
function Invoke-JsonPostProcessItems
{
$openFile = (Get-XamlProperty $script:jsonForm "chkJsonOpenDocument" "IsChecked") -eq $true
if ($script:jsonOutputType -eq "ObjectType")
{
if ($script:jsonCurrentTypeName -and $script:jsonCurrentTypeObjects.Count -gt 0)
{
Save-JsonTypeFile $script:jsonCurrentTypeName $script:jsonCurrentTypeObjects
}
Write-Log "Json documentation saved to folder: $($script:jsonDocumentPath)"
}
else
{
$jsonContent = ConvertTo-Json -InputObject @($script:jsonAllObjects) -Depth 20
Save-DocumentationFile $jsonContent $script:jsonOutFile -OpenFile:$openFile
}
}
function Save-JsonTypeFile
{
param($typeName, $objects)
$safeTypeName = Remove-InvalidFileNameChars ($typeName.Replace(" ", "_"))
$typeFileName = [IO.Path]::Combine($script:jsonDocumentPath, "$safeTypeName.json")
$jsonContent = ConvertTo-Json -InputObject @($objects) -Depth 20
Save-DocumentationFile $jsonContent $typeFileName
Write-Log "Saved $($objects.Count) objects to $typeFileName"
}
+8 -4
View File
@@ -29,6 +29,7 @@ function Add-MDOptionsControl
Set-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked" (Get-Setting "Documentation" "MDOpenFile" $true) Set-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked" (Get-Setting "Documentation" "MDOpenFile" $true)
Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "ItemsSource" ("[ { Name: `"Single file`",Value: `"Full`" }, { Name: `"One file per object`",Value: `"Object`" }]" | ConvertFrom-Json) Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "ItemsSource" ("[ { Name: `"Single file`",Value: `"Full`" }, { Name: `"One file per object`",Value: `"Object`" }]" | ConvertFrom-Json)
Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" (Get-Setting "Documentation" "MDDocumentFileType" "Full") Set-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" (Get-Setting "Documentation" "MDDocumentFileType" "Full")
Set-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked" ((Get-Setting "Documentation" "MDDocumentSkipDate" "False") -eq "True")
Add-XamlEvent $script:mdForm "browseMDDocumentName" "add_click" { Add-XamlEvent $script:mdForm "browseMDDocumentName" "add_click" {
$sf = [System.Windows.Forms.SaveFileDialog]::new() $sf = [System.Windows.Forms.SaveFileDialog]::new()
@@ -72,6 +73,7 @@ function Invoke-MDPreProcessItems
Save-Setting "Documentation" "MDCSSFile" (Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" "") Save-Setting "Documentation" "MDCSSFile" (Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" "")
Save-Setting "Documentation" "MDOpenFile" (Get-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked") Save-Setting "Documentation" "MDOpenFile" (Get-XamlProperty $script:mdForm "chkMDOpenDocument" "IsChecked")
Save-Setting "Documentation" "MDDocumentFileType" (Get-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" '') Save-Setting "Documentation" "MDDocumentFileType" (Get-XamlProperty $script:mdForm "cbMDDocumentOutputFile" "SelectedValue" '')
Save-Setting "Documentation" "MDDocumentSkipDate" (Get-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked")
$defaultCSSFile = $global:AppRootFolder + "\Documentation\DefaultMDStyle.css" $defaultCSSFile = $global:AppRootFolder + "\Documentation\DefaultMDStyle.css"
$MDCssFile = Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" $defaultCSSFile $MDCssFile = Get-XamlProperty $script:mdForm "txtMDCSSFile" "Text" $defaultCSSFile
@@ -81,7 +83,7 @@ function Invoke-MDPreProcessItems
Write-Log "CSS file not specified. Using default" 2 Write-Log "CSS file not specified. Using default" 2
$MDCssFile = $defaultCSSFile $MDCssFile = $defaultCSSFile
} }
elseif([IO.File]::Exists($MDCssFile) -eq -$false) elseif([IO.File]::Exists($MDCssFile) -eq $false)
{ {
Write-Log "CSS file $($MDCssFile) not found. Using default" 2 Write-Log "CSS file $($MDCssFile) not found. Using default" 2
$MDCssFile = $defaultCSSFile $MDCssFile = $defaultCSSFile
@@ -142,7 +144,9 @@ function Invoke-MDPostProcessItems
$script:mdContent.AppendLine("*Organization:* $($global:Organization.displayName)`n") $script:mdContent.AppendLine("*Organization:* $($global:Organization.displayName)`n")
$script:mdContent.AppendLine("*Generated by:* $userName$mail`n") $script:mdContent.AppendLine("*Generated by:* $userName$mail`n")
$script:mdContent.AppendLine("*Generated:* $((Get-Date).ToShortDateString()) $((Get-Date).ToLongTimeString())`n") if((Get-XamlProperty $script:mdForm "cbMDDocumentSkipDate" "IsChecked") -ne $true) {
$script:mdContent.AppendLine("*Generated:* $((Get-Date).ToShortDateString()) $((Get-Date).ToLongTimeString())`n")
}
if($script:sectionAnchors.Count -gt 0) if($script:sectionAnchors.Count -gt 0)
{ {
@@ -265,7 +269,7 @@ function Invoke-MDProcessItem
foreach($prop in $global:txtMDCustomProperties.Text.Split(",")) foreach($prop in $global:txtMDCustomProperties.Text.Split(","))
{ {
# This will add language support for custom columens (or replacing existing header) # This will add language support for custom columns (or replacing existing header)
$propInfo = $prop.Split('=') $propInfo = $prop.Split('=')
if(($propInfo | measure).Count -gt 1) if(($propInfo | measure).Count -gt 1)
{ {
@@ -312,7 +316,7 @@ function Invoke-MDProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order)) foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
{ {
Add-MDTableItems $obj $objectType $documentedObj $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories Add-MDTableItems $obj $objectType $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
} }
if(($documentedObj.Assignments | measure).Count -gt 0) if(($documentedObj.Assignments | measure).Count -gt 0)
+108 -16
View File
@@ -10,15 +10,32 @@ function Invoke-InitializeModule
{ {
if(!("Microsoft.Office.Interop.Word.Application" -as [Type])) if(!("Microsoft.Office.Interop.Word.Application" -as [Type]))
{ {
$loaded = $false
try try
{ {
Add-Type -AssemblyName Microsoft.Office.Interop.Word Add-Type -AssemblyName Microsoft.Office.Interop.Word
$loaded = $true
}
catch { }
try
{
$wordFile = Get-ChildItem -path "$($env:windir)\assembly\GAC_MSIL" -Filter "Microsoft.Office.Interop.Word.dll" -Recurse
if($wordFile -and $wordFile.Exists)
{
Add-Type -Path $wordFile.FullName
$loaded = $true
}
} }
catch catch
{ {
Write-LogError "Failed to add Word Interop type. Cannot create word documents. Verify that Word is installed properly." $_.Exception Write-LogError "Failed to add Word Interop type. Cannot create word documents. Verify that Word is installed properly." $_.Exception
return return
} }
if(-not $loaded) {
Write-LogError "Word Interop type not found. Cannot create word documents. Verify that Word is installed properly." $_.Exception
return
}
} }
Add-OutputType ([PSCustomObject]@{ Add-OutputType ([PSCustomObject]@{
@@ -46,6 +63,18 @@ function Add-WordOptionsControl
$global:spWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible") $global:spWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:txtWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible") $global:txtWordCustomProperties.Visibility = (?: ($global:cbWordDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:cbWordDocumentationFormat.ItemsSource = ("[ { Name: `"Word default document (docx)`",Value: `"wdFormatDocumentDefault`" }, { Name: `"Strict Open XML document`",Value: `"wdFormatStrictOpenXMLDocument`" }, { Name: `"PDF`",Value: `"wdFormatPDF`" }]" | ConvertFrom-Json)
$currentFormat = (Get-Setting "Documentation" "WordDocumentFormat" "wdFormatDocumentDefault")
if($currentFormat -eq "pdf")
{
$currentFormat = "wdFormatPDF"
}
elseif($currentFormat -eq "docx")
{
$currentFormat = "wdFormatDocumentDefault"
}
$global:cbWordDocumentationFormat.SelectedValue = $currentFormat
$global:cbWordDocumentationLevel.ItemsSource = ("[ { Name: `"Full`",Value: `"full`" }, { Name: `"Limited`",Value: `"limited`" }, { Name: `"Basic`",Value: `"basic`" }]" | ConvertFrom-Json) $global:cbWordDocumentationLevel.ItemsSource = ("[ { Name: `"Full`",Value: `"full`" }, { Name: `"Limited`",Value: `"limited`" }, { Name: `"Basic`",Value: `"basic`" }]" | ConvertFrom-Json)
$global:cbWordDocumentationLevel.SelectedValue = (Get-Setting "Documentation" "WordDocumentationLevel" "full") $global:cbWordDocumentationLevel.SelectedValue = (Get-Setting "Documentation" "WordDocumentationLevel" "full")
@@ -114,6 +143,7 @@ function Invoke-WordPreProcessItems
{ {
Save-Setting "Documentation" "WordExportProperties" $global:cbWordDocumentationProperties.SelectedValue Save-Setting "Documentation" "WordExportProperties" $global:cbWordDocumentationProperties.SelectedValue
Save-Setting "Documentation" "WordCustomDisplayProperties" $global:txtWordCustomProperties.Text Save-Setting "Documentation" "WordCustomDisplayProperties" $global:txtWordCustomProperties.Text
Save-Setting "Documentation" "WordDocumentFormat" $global:cbWordDocumentationFormat.SelectedValue
Save-Setting "Documentation" "WordDocumentTemplate" $global:txtWordDocumentTemplate.Text Save-Setting "Documentation" "WordDocumentTemplate" $global:txtWordDocumentTemplate.Text
Save-Setting "Documentation" "WordDocumentName" $global:txtWordDocumentName.Text Save-Setting "Documentation" "WordDocumentName" $global:txtWordDocumentName.Text
@@ -262,7 +292,7 @@ function Invoke-WordPreProcessItems
$script:wordStyles = @() $script:wordStyles = @()
$script:doc.Styles | foreach { $script:doc.Styles | foreach {
$script:wordStyles += [PSCUstomObject]@{ $script:wordStyles += [PSCustomObject]@{
Name=$_.NameLocal Name=$_.NameLocal
Type=$_.Type Type=$_.Type
Style=$_ Style=$_
@@ -379,10 +409,51 @@ function Invoke-WordPostProcessItems
catch {} catch {}
#update fields, ToC etc. #update fields, ToC etc.
$script:doc.Fields | ForEach-Object -Process { $_.Update() | Out-Null } try {
$script:doc.TablesOfContents | ForEach-Object -Process { $_.Update() | Out-Null } $script:doc.Fields | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null } }
$script:doc.TablesOfAuthorities | ForEach-Object -Process { $_.Update() | Out-Null } catch {
Write-LogError "Failed to update document fields" $_.Exception
}
try {
$script:doc.TablesOfContents | ForEach-Object -Process { $_.Update() | Out-Null }
}
catch {
Write-LogError "Failed to update Table of Contents" $_.Exception
}
try {
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
}
catch {
Write-LogError "Failed to update Table of Figures" $_.Exception
}
try {
$script:doc.TablesOfAuthorities | ForEach-Object -Process { $_.Update() | Out-Null }
}
catch {
Write-LogError "Failed to update Table of Authorities" $_.Exception
}
Write-Log "Using document format: $($global:cbWordDocumentationFormat.SelectedValue)"
try {
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]$global:cbWordDocumentationFormat.SelectedValue
}
catch
{
Write-LogError "Document validation failed" $_.Exception
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatDocumentDefault
}
<#
if($global:cbWordDocumentationFormat.SelectedValue -eq "pdf")
{
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatPDF
}
else {
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatDocumentDefault
}
#>
$fileName = $global:txtWordDocumentName.Text $fileName = $global:txtWordDocumentName.Text
if(-not $fileName) if(-not $fileName)
@@ -392,7 +463,10 @@ function Invoke-WordPostProcessItems
$fileName = Expand-FileName $fileName $fileName = Expand-FileName $fileName
$format = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatDocumentDefault if($format -eq [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatPDF -and $fileName -notlike "*.pdf")
{
$fileName = [IO.Path]::ChangeExtension($fileName, ".pdf")
}
try try
{ {
@@ -404,17 +478,28 @@ function Invoke-WordPostProcessItems
Write-LogError "Failed to save file $fileName" $_.Excption Write-LogError "Failed to save file $fileName" $_.Excption
} }
if($global:chkWordOpenDocument.IsChecked -eq $true -and $global:hideUI -ne $true) try {
{ if($global:chkWordOpenDocument.IsChecked -eq $true -and $global:hideUI -ne $true)
$script:wordApp.Visible = $true {
$script:wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize $script:wordApp.Visible = $true
$script:wordApp.Activate() $script:wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize
[Console.Window]::SetForegroundWindow($script:wordApp.ActiveWindow.Hwnd) | Out-Null $script:wordApp.Activate()
[Console.Window]::SetForegroundWindow($script:wordApp.ActiveWindow.Hwnd) | Out-Null
}
else
{
$script:doc.Close([Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges)
$script:wordApp.Quit()
}
} }
else catch
{ {
$script:doc.Close([Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges) Write-LogError "Failed to close the Word application" $_.Exception
$script:wordApp.Quit() }
finally {
[void][Runtime.InteropServices.Marshal]::ReleaseComObject($script:doc)
[void][Runtime.InteropServices.Marshal]::ReleaseComObject($script:wordApp)
[GC]::Collect(); [GC]::WaitForPendingFinalizers()
} }
} }
@@ -575,7 +660,7 @@ function Invoke-WordProcessItem
foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order)) foreach($customTable in ($documentedObj.CustomTables | Sort-Object -Property Order))
{ {
Add-DocTableItems $obj $objectType $documentedObj $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories Add-DocTableItems $obj $objectType $customTable.Values $customTable.Columns $customTable.LanguageId -AddCategories -AddSubcategories
} }
} }
@@ -678,6 +763,10 @@ function Set-DocTableSettingsItems
$cellRow = $row $cellRow = $row
foreach($settingProp in $properties) foreach($settingProp in $properties)
{ {
if([String]::IsNullOrEmpty($settingProp)) {
continue
}
$script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-DocTranslateColumnHeader ($settingProp.Split('.')[-1])) $script:docTable.Cell($cellRow, $firstColumn).Range.Text = (Invoke-DocTranslateColumnHeader ($settingProp.Split('.')[-1]))
$propArr = $settingProp.Split('.') $propArr = $settingProp.Split('.')
@@ -779,6 +868,9 @@ function Add-DocTableItems
$i = 1 $i = 1
foreach($prop in $properties) foreach($prop in $properties)
{ {
if([String]::IsNullOrEmpty($prop)) {
continue
}
$script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1])) $script:docTable.Cell(1, $i).Range.Text = (Invoke-DocTranslateColumnHeader ($prop.Split(".")[-1]))
$i++ $i++
} }
+525 -23
View File
@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.9.8' '3.10.0.6'
} }
function Invoke-InitializeModule function Invoke-InitializeModule
@@ -157,6 +157,7 @@ function Invoke-InitializeModule
PreImportCommand = { Start-PreImportConditionalAccess @args } PreImportCommand = { Start-PreImportConditionalAccess @args }
PostExportCommand = { Start-PostExportConditionalAccess @args } PostExportCommand = { Start-PostExportConditionalAccess @args }
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -171,6 +172,7 @@ function Invoke-InitializeModule
PreImportCommand = { Start-PreImportTermsOfUse @args } PreImportCommand = { Start-PreImportTermsOfUse @args }
PostExportCommand = { Start-PostExportTermsOfUse @args } PostExportCommand = { Start-PostExportTermsOfUse @args }
GroupId = "ConditionalAccess" GroupId = "ConditionalAccess"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -182,6 +184,7 @@ function Invoke-InitializeModule
ImportOrder = 50 ImportOrder = 50
GroupId = "ConditionalAccess" GroupId = "ConditionalAccess"
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -201,6 +204,7 @@ function Invoke-InitializeModule
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Dependencies = @("ReusableSettings") Dependencies = @("ReusableSettings")
GroupId = "EndpointSecurity" GroupId = "EndpointSecurity"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -214,6 +218,7 @@ function Invoke-InitializeModule
PostExportCommand = { Start-PostExportCompliancePolicies @args } PostExportCommand = { Start-PostExportCompliancePolicies @args }
PreUpdateCommand = { Start-PreUpdateCompliancePolicies @args } PreUpdateCommand = { Start-PreUpdateCompliancePolicies @args }
GroupId = "CompliancePolicies" GroupId = "CompliancePolicies"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -221,7 +226,7 @@ function Invoke-InitializeModule
Id = "CompliancePoliciesV2" Id = "CompliancePoliciesV2"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/deviceManagement/compliancePolicies" API = "/deviceManagement/compliancePolicies"
NameProperty = "Name" NameProperty = "name"
PropertiesToRemove = @('settingCount') PropertiesToRemove = @('settingCount')
ViewProperties = @("name","description","Id") ViewProperties = @("name","description","Id")
Expand="settings" Expand="settings"
@@ -236,9 +241,11 @@ function Invoke-InitializeModule
Id = "ComplianceScripts" Id = "ComplianceScripts"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/deviceManagement/deviceComplianceScripts" API = "/deviceManagement/deviceComplianceScripts"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") PostImportCommand = { Start-PostImportComplianceScripts @args }
Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "CompliancePolicies" GroupId = "CompliancePolicies"
Icon = "Scripts" Icon = "Scripts"
ImportOrder = 80
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -259,6 +266,7 @@ function Invoke-InitializeModule
SkipRemoveProperties = @('Id') # Id is removed by PreImport. Required for default profile SkipRemoveProperties = @('Id') # Id is removed by PreImport. Required for default profile
PropertiesToRemoveForUpdate = @('isDefaultProfile','disableClientTelemetry') PropertiesToRemoveForUpdate = @('isDefaultProfile','disableClientTelemetry')
GroupId = "TenantAdmin" GroupId = "TenantAdmin"
SupportsPageSize = $false
}) })
<# <#
@@ -286,6 +294,7 @@ function Invoke-InitializeModule
GroupId = "Azure" GroupId = "Azure"
SkipAddIDOnExport = $true SkipAddIDOnExport = $true
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -309,6 +318,7 @@ function Invoke-InitializeModule
AssignmentsType = "enrollmentConfigurationAssignments" AssignmentsType = "enrollmentConfigurationAssignments"
PropertiesToRemoveForUpdate = @('priority') PropertiesToRemoveForUpdate = @('priority')
GroupId = "WinEnrollment" GroupId = "WinEnrollment"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -332,6 +342,7 @@ function Invoke-InitializeModule
AssignmentsType = "enrollmentConfigurationAssignments" AssignmentsType = "enrollmentConfigurationAssignments"
GroupId = "EnrollmentRestrictions" GroupId = "EnrollmentRestrictions"
ViewProperties = @("displayName","platformType","description","Id") ViewProperties = @("displayName","platformType","description","Id")
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -347,6 +358,7 @@ function Invoke-InitializeModule
SkipRemoveProperties = @('Id') SkipRemoveProperties = @('Id')
GroupId = "WinEnrollment" GroupId = "WinEnrollment"
Icon = "EnrollmentStatusPage" Icon = "EnrollmentStatusPage"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -376,7 +388,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args } DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args } PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts" Icon="Scripts"
GroupId = "Scripts" GroupId = "Scripts"
@@ -390,7 +402,7 @@ function Invoke-InitializeModule
DetailExtension = { Add-ScriptExtensions @args } DetailExtension = { Add-ScriptExtensions @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
PostExportCommand = { Start-PostExportScripts @args } PostExportCommand = { Start-PostExportScripts @args }
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="Scripts" Icon="Scripts"
GroupId = "Scripts" GroupId = "Scripts"
@@ -401,7 +413,7 @@ function Invoke-InitializeModule
Id = "MacCustomAttributes" Id = "MacCustomAttributes"
API = "/deviceManagement/deviceCustomAttributeShellScripts" API = "/deviceManagement/deviceCustomAttributeShellScripts"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
Permissons=@("DeviceManagementManagedDevices.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
AssignmentsType = "deviceManagementScriptAssignments" AssignmentsType = "deviceManagementScriptAssignments"
Icon="CustomAttributes" Icon="CustomAttributes"
GroupId = "CustomAttributes" # MacOS Settings GroupId = "CustomAttributes" # MacOS Settings
@@ -423,6 +435,7 @@ function Invoke-InitializeModule
PreImportAssignmentsCommand = { Start-PreImportAssignmentsTermsAndConditions @args } PreImportAssignmentsCommand = { Start-PreImportAssignmentsTermsAndConditions @args }
GroupId = "TenantAdmin" GroupId = "TenantAdmin"
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -443,6 +456,7 @@ function Invoke-InitializeModule
Dependencies = @("Applications") Dependencies = @("Applications")
GroupId = "AppProtection" GroupId = "AppProtection"
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
# These are also included in the managedAppPolicies API # These are also included in the managedAppPolicies API
@@ -462,6 +476,7 @@ function Invoke-InitializeModule
Icon = "AppConfiguration" Icon = "AppConfiguration"
GroupId = "AppConfiguration" GroupId = "AppConfiguration"
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -494,8 +509,8 @@ function Invoke-InitializeModule
ImportOrder = 60 ImportOrder = 60
Expand="categories,assignments" # ODataMetadata is set to minimal so assignments can't be autodetected Expand="categories,assignments" # ODataMetadata is set to minimal so assignments can't be autodetected
ODataMetadata="minimal" # categories property not supported with ODataMetadata full ODataMetadata="minimal" # categories property not supported with ODataMetadata full
PostFileImportCommand = { Start-PostFileImportApplications @args } PostFileImportCommand = { Start-PostFileImportApplication @args }
PostCopyCommand = { Start-PostCopyApplications @args } PostCopyCommand = { Start-PostCopyApplication @args }
PreUpdateCommand = { Start-PreUpdateApplication @args } PreUpdateCommand = { Start-PreUpdateApplication @args }
PreImportCommand = { Start-PreImportCommandApplication @args } PreImportCommand = { Start-PreImportCommandApplication @args }
DetailExtension = { Add-DetailExtensionApplications @args } DetailExtension = { Add-DetailExtensionApplications @args }
@@ -565,7 +580,7 @@ function Invoke-InitializeModule
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
Title = "Quality Updates" Title = "Quality Updates (Profiles)"
Id = "QualityUpdates" Id = "QualityUpdates"
ViewID = "IntuneGraphAPI" ViewID = "IntuneGraphAPI"
API = "/deviceManagement/windowsQualityUpdateProfiles" API = "/deviceManagement/windowsQualityUpdateProfiles"
@@ -573,6 +588,18 @@ function Invoke-InitializeModule
Icon = "UpdatePolicies" Icon = "UpdatePolicies"
GroupId = "WinQualityUpdates" GroupId = "WinQualityUpdates"
PropertiesToRemoveForUpdate = @('releaseDateDisplayName','deployableContentDisplayName') PropertiesToRemoveForUpdate = @('releaseDateDisplayName','deployableContentDisplayName')
SupportsPageSize = $false
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Quality Updates (Policies)"
Id = "QualityUpdatePolicies"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/windowsQualityUpdatePolicies"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon = "UpdatePolicies"
GroupId = "WinQualityUpdates"
SupportsPageSize = $false
}) })
# Locations are not FULLY supported # Locations are not FULLY supported
@@ -604,10 +631,11 @@ function Invoke-InitializeModule
API = "/deviceManagement/configurationPolicies" API = "/deviceManagement/configurationPolicies"
PropertiesToRemove = @('settingCount') PropertiesToRemove = @('settingCount')
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
NameProperty = "Name" NameProperty = "name"
ViewProperties = @("name","description","Id") ViewProperties = @("name","description","Id")
Expand="Settings" Expand="Settings"
Icon="DeviceConfiguration" Icon="DeviceConfiguration"
PreImportCommand = { Start-PreImportSettingsCatalog @args }
PostExportCommand = { Start-PostExportSettingsCatalog @args } PostExportCommand = { Start-PostExportSettingsCatalog @args }
PreUpdateCommand = { Start-PreUpdateSettingsCatalog @args } PreUpdateCommand = { Start-PreUpdateSettingsCatalog @args }
PostGetCommand = { Start-PostGetSettingsCatalog @args } PostGetCommand = { Start-PostGetSettingsCatalog @args }
@@ -615,6 +643,36 @@ function Invoke-InitializeModule
GroupId = "DeviceConfiguration" GroupId = "DeviceConfiguration"
}) })
Add-ViewItem (New-Object PSObject -Property @{
Title = "Inventory Policies"
Id = "InventoryPolicies"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/inventoryPolicies"
PropertiesToRemove = @('settingCount')
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
NameProperty = "name"
ViewProperties = @("name","description","Id")
Expand="Settings"
Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "BIOS Configurations"
Id = "HardwareConfigurations"
ViewID = "IntuneGraphAPI"
DetailExtension = { Add-PolicyFileExtensions @args }
ExportExtension = { Add-PolicyFileExportExtensions @args }
PostExportCommand = { Start-PostExportPolicyFile @args }
PropertiesToRemoveForUpdate = @('version')
PolicyFileAttribute = "configurationFileContent"
API = "/deviceManagement/hardwareConfigurations"
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="DeviceConfiguration"
GroupId = "DeviceConfiguration"
SupportsPageSize = $false
})
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
Title = "Role Definitions" Title = "Role Definitions"
Id = "RoleDefinitions" Id = "RoleDefinitions"
@@ -718,7 +776,7 @@ function Invoke-InitializeModule
PreUpdateCommand = { Start-PreUpdateDeviceHealthScripts @args } PreUpdateCommand = { Start-PreUpdateDeviceHealthScripts @args }
PostExportCommand = { Start-PostExportDeviceHealthScripts @args } PostExportCommand = { Start-PostExportDeviceHealthScripts @args }
ExportExtension = { Add-ScriptExportExtensions @args } ExportExtension = { Add-ScriptExportExtensions @args }
Permissons=@("DeviceManagementConfiguration.ReadWrite.All") Permissons=@("DeviceManagementScripts.ReadWrite.All")
GroupId = "EndpointAnalytics" GroupId = "EndpointAnalytics"
Icon = "Report" Icon = "Report"
AssignmentsType = "deviceHealthScriptAssignments" AssignmentsType = "deviceHealthScriptAssignments"
@@ -743,6 +801,7 @@ function Invoke-InitializeModule
PreDeleteCommand = { Start-PreDeleteADMXFiles @args } PreDeleteCommand = { Start-PreDeleteADMXFiles @args }
ViewProperties = @("fileName","status","Id") ViewProperties = @("fileName","status","Id")
PropertiesToRemove = @("languageCodes","targetPrefix","targetNamespace","policyType","revision","status","uploadDateTime") PropertiesToRemove = @("languageCodes","targetPrefix","targetNamespace","policyType","revision","status","uploadDateTime")
SupportsPageSize = $false
}) })
<# <#
@@ -786,6 +845,7 @@ function Invoke-InitializeModule
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
Icon = "ConditionalAccess" Icon = "ConditionalAccess"
GroupId = "EndpointSecurity" GroupId = "EndpointSecurity"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -801,6 +861,7 @@ function Invoke-InitializeModule
ExpandAssignmentsList = $false ExpandAssignmentsList = $false
Icon = "ConditionalAccess" Icon = "ConditionalAccess"
GroupId = "EndpointSecurity" GroupId = "EndpointSecurity"
SupportsPageSize = $false
}) })
Add-ViewItem (New-Object PSObject -Property @{ Add-ViewItem (New-Object PSObject -Property @{
@@ -832,6 +893,18 @@ function Invoke-InitializeModule
Icon = "UpdatePolicies" Icon = "UpdatePolicies"
GroupId = "WinDriverUpdatePolicies" GroupId = "WinDriverUpdatePolicies"
}) })
Add-ViewItem (New-Object PSObject -Property @{
Title = "Device Categories"
Id = "DeviceCategories"
ViewID = "IntuneGraphAPI"
API = "/deviceManagement/deviceCategories"
QUERYLIST = "`$top=500"
Permissons = @("DeviceManagementConfiguration.ReadWrite.All")
GroupId = "DeviceConfiguration"
ExpandAssignmentsList = $false
})
} }
function Invoke-EMAuthenticateToMSAL function Invoke-EMAuthenticateToMSAL
@@ -1010,7 +1083,14 @@ function Set-EMViewPanel
$global:btnLoadAllPages.add_click({ $global:btnLoadAllPages.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects" Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -AllPages [array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -AllPages
$graphObjects | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null } if(-not $global:dgObjects.Columns)
{
Show-GraphObjects -FromGraphObjects $graphObjects
}
else
{
$graphObjects | Where-Object { $_ -ne $null } | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
}
$global:dgObjects.ItemsSource.CommitNew() $global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate Invoke-FilterBoxChanged $global:txtFilter -ForceUpdate
@@ -1020,7 +1100,14 @@ function Set-EMViewPanel
$global:btnLoadNextPage.add_click({ $global:btnLoadNextPage.add_click({
Write-Status "Loading $($global:curObjectType.Title) objects" Write-Status "Loading $($global:curObjectType.Title) objects"
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage [array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage
$graphObjects | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null } if(-not $global:dgObjects.Columns)
{
Show-GraphObjects -FromGraphObjects $graphObjects
}
else
{
$graphObjects | Where-Object { $_ -ne $null } | ForEach-Object { $global:dgObjects.ItemsSource.AddNewItem($_) | Out-Null }
}
$global:dgObjects.ItemsSource.CommitNew() $global:dgObjects.ItemsSource.CommitNew()
Set-GraphPagesButtonStatus Set-GraphPagesButtonStatus
Invoke-FilterBoxChanged $global:txtFilter Invoke-FilterBoxChanged $global:txtFilter
@@ -1391,6 +1478,30 @@ function Start-PreUpdateCompliancePolicies
#endregion #endregion
function Start-PostImportComplianceScripts
{
param($obj, $objectType, $file)
$endTime = (Get-Date).AddMinutes(2)
$found = $false
while($endTime -gt (Get-Date))
{
$tmpObj = Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -ErrorAction SilentlyContinue
if($tmpObj) {
$found = $true
break
}
Start-Sleep -Seconds 10
}
if(-not $found)
{
Write-LogError "Compliance script $($obj.Id) not found after import. Please check the import file."
return
}
}
#region Intune Branding functions #region Intune Branding functions
function Start-PreImportIntuneBranding function Start-PreImportIntuneBranding
{ {
@@ -1440,7 +1551,7 @@ function Start-PreImportIntuneBranding
function Start-PostImportIntuneBranding function Start-PostImportIntuneBranding
{ {
param($obj, $objectType) param($obj, $objectType, $file)
if($obj.isDefaultProfile -or -not $global:brandingClone) { return } if($obj.isDefaultProfile -or -not $global:brandingClone) { return }
@@ -1744,6 +1855,194 @@ function Invoke-EditScript
#endregion #endregion
#region Policy File functions
function Add-PolicyFileExtensions
{
param($form, $buttonPanel, $index = 0)
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Download'
$btnDownload.Name = 'btnDownload'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Invoke-DownloadPolicyFile
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Edit'
$btnDownload.Name = 'btnEdit'
$btnDownload.Margin = "0,0,5,0"
$btnDownload.Width = "100"
$btnDownload.Add_Click({
Invoke-EditPolicyFile
})
$tmp = $form.FindName($buttonPanel)
if($tmp)
{
$tmp.Children.Insert($index, $btnDownload)
}
}
function Add-PolicyFileExportExtensions
{
param($form, $buttonPanel, $index = 0)
$ctrl = $form.FindName("chkExportPolicyFile")
if(-not $ctrl)
{
$xaml = @"
<StackPanel $($global:wpfNS) Orientation="Horizontal" Margin="0,0,5,0">
<Label Content="Export Policy File" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Export the file associated with policies eg BIOS Configuration" />
</StackPanel>
"@
$label = [Windows.Markup.XamlReader]::Parse($xaml)
$global:chkExportPolicyFile = [System.Windows.Controls.CheckBox]::new()
$global:chkExportPolicyFile.IsChecked = $true
$global:chkExportPolicyFile.VerticalAlignment = "Center"
$global:chkExportPolicyFile.Name = "chkExportPolicyFile"
@($label, $global:chkExportPolicyFile)
}
}
function Start-PostExportPolicyFile
{
param($obj, $objectType, $exportPath)
if($objectType.PolicyFileAttribute -and $obj.$($objectType.PolicyFileAttribute) -and $global:chkExportPolicyFile.IsChecked)
{
Write-Log "Export policy file from attribute $($obj.PolicyFileAttribute)"
$fileNameOut = ?? $obj.FileName "$($obj.PolicyFileAttribute).json"
$fileName = [IO.Path]::Combine($exportPath, $fileNameOut)
[IO.File]::WriteAllBytes($fileName, ([System.Convert]::FromBase64String($obj.$($objectType.PolicyFileAttribute))))
}
}
function Invoke-DownloadPolicyFile
{
if(-not $global:dgObjects.SelectedItem.Object.id) { return }
$obj = (Get-GraphObject $global:dgObjects.SelectedItem $global:curObjectType).Object
Write-Status ""
if($global:curObjectType.PolicyFileAttribute -and $obj.$($global:curObjectType.PolicyFileAttribute))
{
$fileNameOut = ?? $obj.FileName "$($obj.PolicyFileAttribute).json"
Write-Log "Download policy file '$($fileNameOut)' from $($obj.displayName)"
$dlgSave = New-Object -Typename System.Windows.Forms.SaveFileDialog
$dlgSave.InitialDirectory = Get-SettingValue "IntuneRootFolder" $env:Temp
$dlgSave.FileName = $fileNameOut
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
# Changed to WriteAllBytes to get rid of BOM characters from Custom Attribute file
[IO.File]::WriteAllBytes($dlgSave.FileName, ([System.Convert]::FromBase64String($obj.$($global:curObjectType.PolicyFileAttribute))))
}
}
}
function Invoke-EditPolicyFile
{
if(-not $global:dgObjects.SelectedItem.Object.id) { return }
$obj = (Get-GraphObject $global:dgObjects.SelectedItem $global:curObjectType)
Write-Status ""
if(-not $global:curObjectType.PolicyFileAttribute -or -not $obj.Object.$($global:curObjectType.PolicyFileAttribute)) { return }
$script:currentScriptObject = $obj
$script:editForm = Get-XamlObject ($global:AppRootFolder + "\Xaml\EditScriptDialog.xaml")
if(-not $script:editForm) { return }
Set-XamlProperty $script:editForm "txtEditScriptTitle" "Text" "Edit: $($obj.Object.displayName)"
$scriptText = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($obj.Object.$($global:curObjectType.PolicyFileAttribute)))
Set-XamlProperty $script:editForm "txtScriptText" "Text" $scriptText
$script:currentModal = $null
if($global:grdModal.Children.Count -gt 0)
{
$script:currentModal = $global:grdModal.Children[0]
}
Add-XamlEvent $script:editForm "btnSaveScriptEdit" "add_click" ({
$scriptText = Get-XamlProperty $script:editForm "txtScriptText" "Text"
$pre = [System.Text.Encoding]::UTF8.GetPreamble()
$utfBOM = [System.Text.Encoding]::UTF8.GetString($pre)
if($scriptText.startsWith($utfBOM))
{
# Remove UTF8 BOM bytes
$scriptText = $scriptText.Remove(0, $utfBOM.Length)
}
$bytes = [System.Text.Encoding]::UTF8.GetBytes($scriptText)
$encodedText = [Convert]::ToBase64String($bytes)
if($script:currentScriptObject.Object.scriptContent -ne $encodedText)
{
# Save script
if(([System.Windows.MessageBox]::Show("Are you sure you want to update the $($global:curObjectType.PolicyFileAttribute) attribute?`n`nObject:`n$($script:currentScriptObject.displayName)", "Update script?", "YesNo", "Warning")) -eq "Yes")
{
Write-Status "Update $($script:currentScriptObject.displayName)"
$obj = $script:currentScriptObject.Object | ConvertTo-Json -Depth 20 | ConvertFrom-Json
$obj.$($global:curObjectType.PolicyFileAttribute) = $encodedText
Start-GraphPreImport $obj $script:currentScriptObject.ObjectType
foreach($prop in $script:currentScriptObject.ObjectType.PropertiesToRemoveForUpdate)
{
Remove-Property $obj $prop
}
Remove-Property $obj "Assignments"
Remove-Property $obj "isAssigned"
$json = ConvertTo-Json $obj -Depth 15
$objectUpdated = (Invoke-GraphRequest -Url "$($script:currentScriptObject.ObjectType.API)/$($script:currentScriptObject.Object.Id)" -Content $json -HttpMethod "PATCH")
if(-not $objectUpdated)
{
Write-Log "Failed to update script" 3
[System.Windows.MessageBox]::Show("Failed to save the policy. See log for more information","Update failed!", "OK", "Error")
}
Write-Status ""
}
}
$global:grdModal.Children.Clear()
if($script:currentModal)
{
$global:grdModal.Children.Add($script:currentModal)
}
[System.Windows.Forms.Application]::DoEvents()
})
Add-XamlEvent $script:editForm "btnCancelScriptEdit" "add_click" ({
$global:grdModal.Children.Clear()
if($script:currentModal)
{
$global:grdModal.Children.Add($script:currentModal)
}
[System.Windows.Forms.Application]::DoEvents()
})
$global:grdModal.Children.Clear()
$script:editForm.SetValue([System.Windows.Controls.Grid]::RowProperty,1)
$script:editForm.SetValue([System.Windows.Controls.Grid]::ColumnProperty,1)
$global:grdModal.Children.Add($script:editForm) | Out-Null
[System.Windows.Forms.Application]::DoEvents()
}
#endregion
#region Terms and Conditions #region Terms and Conditions
function Start-PostExportTermsAndConditions function Start-PostExportTermsAndConditions
{ {
@@ -2054,7 +2353,7 @@ function local:Add-AppConfigurationTargets
$appName, $appId, $appType = $targetedApp -split "[|][!][|]" $appName, $appId, $appType = $targetedApp -split "[|][!][|]"
if(-not $appName -or -not $appId) if(-not $appName -or -not $appId)
{ {
Write-Log "App Name and Id is missing in string: $appApp" 2 Write-Log "App Name and Id is missing in string: $targetedApp" 2
continue continue
} }
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value $tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
@@ -2104,15 +2403,16 @@ function Start-PreImportAssignmentsAppConfiguration
#region Applications #region Applications
function Start-PostCopyApplications function Start-PostCopyApplication
{ {
param($objCopyFrom, $objNew, $objectType) param($objCopyFrom, $objNew, $objectType)
Start-ImportApp $objNew Start-ImportApp $objNew
Start-AddInstallScripts $objNew $objCopyFrom
Write-Status "" Write-Status ""
} }
function Start-PostFileImportApplications function Start-PostFileImportApplication
{ {
param($obj, $objectType, $file) param($obj, $objectType, $file)
@@ -2133,6 +2433,7 @@ function Start-PostFileImportApplications
} }
Start-ImportApp $obj $tmpFilName Start-ImportApp $obj $tmpFilName
Start-AddInstallScripts $obj $tmpObj
} }
function local:Start-ImportApp function local:Start-ImportApp
@@ -2208,6 +2509,84 @@ function local:Start-ImportApp
} }
} }
function local:Start-AddInstallScripts
{
param($obj, $fromAppObj)
if($fromAppObj -and ($fromAppObj.activeInstallScript."#ScriptInfo" -or $fromAppObj.activeUninstallScript."#ScriptInfo"))
{
Write-Log "Importing scripts for $($obj.displayName)"
$scriptsAdded = $false
$jsonData = @{}
$jsonData."@odata.type" = "#microsoft.graph.win32LobApp"
$jsonData."committedContentVersion" = "1"
foreach ($scriptType in @('activeInstallScript','activeUninstallScript')) {
$scriptInfo = $fromAppObj.$scriptType.'#ScriptInfo'
if (-not $scriptInfo) { continue }
Write-Log "Add $($scriptType -replace '^active','') script: $($scriptInfo.displayName)"
$json = [ordered]@{
'@odata.type' = $scriptInfo.'@odata.type'
displayName = $scriptInfo.displayName
enforceSignatureCheck = $scriptInfo.enforceSignatureCheck
runAs32Bit = $scriptInfo.runAs32Bit
content = $scriptInfo.content
} | ConvertTo-Json -Depth 10 -Compress
$scriptObject = Invoke-GraphRequest -Url "deviceAppManagement/mobileApps/$($obj.id)/microsoft.graph.win32LobApp/contentVersions/1/scripts" -Method POST -Content $json
if ($scriptObject) {
$jsonData.$scriptType = @{ targetId = $scriptObject.Id }
$scriptsAdded = $true
}
}
$i = 0
while($true)
{
$scripts = Invoke-GraphRequest -Url "deviceAppManagement/mobileApps/$($obj.id)/microsoft.graph.win32LobApp/contentVersions/1/scripts"
if(-not $scripts)
{
Write-Log "Failed to retrieve scripts for app after adding. Skipping Install/Uninstall script config." 2
return
}
if(($scripts.value.state | Select -Unique) -eq "commitSuccess")
{
Write-Log "Scripts added successfully"
break
}
if($i -ge 12)
{
Write-Log "Install/Uninstall scripts are still not in pending state after waiting for 1 minute." 3
return
}
Write-Log "Waiting for scripts to be added..."
Start-Sleep -Seconds 5
$i++
}
if($scriptsAdded)
{
Write-Log "Add script info to app"
$json = ConvertTo-Json $jsonData -Depth 10
$status = Invoke-GraphRequest -Url "deviceAppManagement/mobileApps/$($obj.id)" -Method PATCH -Body $json
if($status -eq $true)
{
Write-Log "Install/Uninstall script info updated successfully"
}
else
{
Write-Log "Failed to update Install/Uninstall script info" 2
}
}
}
}
function Start-PreUpdateApplication function Start-PreUpdateApplication
{ {
param($obj, $objectType, $curObject, $fromObj) param($obj, $objectType, $curObject, $fromObj)
@@ -2245,6 +2624,9 @@ function Start-PreImportCommandApplication
$obj.officeSuiteAppDefaultFileFormat = "officeOpenXMLFormat" $obj.officeSuiteAppDefaultFileFormat = "officeOpenXMLFormat"
} }
} }
if($obj.activeInstallScript) { $obj.activeInstallScript = $null }
if($obj.activeUninstallScript) { $obj.activeUninstallScript = $null }
} }
function Add-DetailExtensionApplications function Add-DetailExtensionApplications
@@ -2432,6 +2814,8 @@ function Start-PreImportAssignmentsApplications
function Start-PreDeleteApplications function Start-PreDeleteApplications
{ {
param($obj, $objectType)
if($obj.'@odata.type' -eq "#microsoft.graph.microsoftStoreForBusinessApp") if($obj.'@odata.type' -eq "#microsoft.graph.microsoftStoreForBusinessApp")
{ {
# Don't delete Microsoft Store for Business Apps # Don't delete Microsoft Store for Business Apps
@@ -2469,6 +2853,16 @@ function Start-PostExportApplications
} }
} }
} }
if($obj.activeInstallScript.'#ScriptInfo'.displayName)
{
[IO.File]::WriteAllBytes(("$path\$($fi.BaseName)_$($obj.activeInstallScript.'#ScriptInfo'.displayName)"), ([System.Convert]::FromBase64String($obj.activeInstallScript.'#ScriptInfo'.content)))
}
if($obj.activeUninstallScript.'#ScriptInfo'.displayName)
{
[IO.File]::WriteAllBytes(("$path\$($fi.BaseName)_$($obj.activeUninstallScript.'#ScriptInfo'.displayName)"), ([System.Convert]::FromBase64String($obj.activeUninstallScript.'#ScriptInfo'.content)))
}
} }
catch catch
{ {
@@ -2512,7 +2906,7 @@ function Start-PostExportApplications
} }
else else
{ {
Write-Log "Cound not file encryption file" Write-Log "Could not find encryption file"
} }
} }
} }
@@ -2572,7 +2966,7 @@ function Add-ScriptExportApplications
function Start-PostGetApplications { function Start-PostGetApplications {
param($obj, $objectType) param($obj, $objectType)
if($obj.Object.dependentAppCount -is [Int] -and ($obj.Object.dependentAppCount -gt 0 -or $obj.Object.supersededAppCount -gt 0)) { if(($obj.Object.dependentAppCount -as [int]) -gt 0 -or ($obj.Object.supersededAppCount -as [int]) -gt 0) {
$relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value $relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value
$dependencyApps = @() $dependencyApps = @()
$supersededApps = @() $supersededApps = @()
@@ -2592,6 +2986,37 @@ function Start-PostGetApplications {
$obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefSupersedence" -Value ($supersededApps -join "|*|") $obj.Object | Add-Member -MemberType NoteProperty -Name "#CustomRefSupersedence" -Value ($supersededApps -join "|*|")
} }
} }
if($obj.Object.'@odata.type' -eq "#microsoft.graph.win32LobApp")
{
if($obj.Object.activeInstallScript.targetId -or $obj.Object.activeUninstallScript.targetId)
{
$scriptInfo = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/microsoft.graph.win32LobApp/contentVersions/$($obj.Object.committedContentVersion)/scripts/").value
foreach($script in $scriptInfo) {
$scriptFullInfo = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/microsoft.graph.win32LobApp/contentVersions/$($obj.Object.committedContentVersion)/scripts/$($script.id)?`$select=Id,Content")
if($scriptFullInfo.Content)
{
$script.content = $scriptFullInfo.Content
}
if($obj.Object.activeInstallScript.targetId -eq $script.id)
{
$tpObject = $obj.Object.activeInstallScript
}
elseif($obj.Object.activeUninstallScript.targetId -eq $script.id)
{
$tpObject = $obj.Object.activeUninstallScript
}
else
{
Write-Log "Script with id $($script.id) is not referenced by active install or uninstall script. Skipping." 2
continue
}
$tpObject | Add-Member -MemberType NoteProperty -Name "#ScriptInfo" -Value $script -Force
}
}
}
} }
function Start-PostImportApplications function Start-PostImportApplications
@@ -2654,9 +3079,9 @@ function local:Add-ApplicationReferences
Write-Log "No $appName application found with version $appVer" 2 Write-Log "No $appName application found with version $appVer" 2
continue continue
} }
elseif(-not ($tmpApp | measure).Count -gt 1) elseif(($tmpApp | measure).Count -gt 1)
{ {
Write-Log "Multiple $appName application found with version $appVer" 2 Write-Log "Multiple $appName applications found with version $appVer" 2
continue continue
} }
Write-Log "Add $appName ($appVer) to Dependency list" Write-Log "Add $appName ($appVer) to Dependency list"
@@ -2675,7 +3100,7 @@ function local:Add-ApplicationReferences
$appName, $appVer, $appId, $appType = $suppApp -split "[|][!][|]" $appName, $appVer, $appId, $appType = $suppApp -split "[|][!][|]"
if(-not $appName -or -not $appVer) if(-not $appName -or -not $appVer)
{ {
Write-Log "Could not get Name and Version from string: $appApp" 2 Write-Log "Could not get Name and Version from string: $suppApp" 2
continue continue
} }
$tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value $tmpApps = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps?`$filter=displayName eq '$appName'").value
@@ -3265,6 +3690,75 @@ function Start-PostFileImportRoleDefinitions
#endregion #endregion
#region SettingsCatalog #region SettingsCatalog
function Start-PreImportSettingsCatalog
{
param($obj, $objectType)
$returnHT = @{}
$updated = $false
if($obj.templateReference.templateId) {
# I do not like this at all and it is a lazy but simple implementation...
# It turns out that settingInstanceTemplateId and settingValueTemplateId are case sensitive
# and there is ONE setting with a different casing in the Windows Baseline template.
# The export saves it with lowercase which causes the import to fail.
Write-Log "Get template $($obj.templateReference.templateId)"
$templateObj = Invoke-GraphRequest -Url "/deviceManagement/configurationPolicyTemplates('$($obj.templateReference.templateId)')"
if($templateObj.lifecycleState -and $templateObj.lifecycleState -ne "active") {
Write-Log "Template '$($templateObj.displayName)' '$($templateObj.displayVersion)' is in '$($templateObj.lifecycleState)' state. Current state: $($templateObj.lifecycleState). Import might fail." 2
}
#Todo: Should probably check for the latest active version and use that instead of the one in the templateReference
if(-not $script:baseLineTemplate) {
$script:baseLineTemplate = @{}
}
if($script:baseLineTemplate.ContainsKey($obj.templateReference.templateId)) {
$templateReference = $script:baseLineTemplate[$obj.templateReference.templateId]
}
else {
Write-Log "Get template settings for '$($templateObj.displayName)' '$($templateObj.displayVersion)' ($($obj.templateReference.templateId))"
$templateReference = Invoke-GraphRequest -Url "/deviceManagement/configurationPolicyTemplates('$($obj.templateReference.templateId)')/settingTemplates?`$expand=settingDefinitions&top=1000"
$script:baseLineTemplate.Add($obj.templateReference.templateId, $templateReference)
}
if($templateReference) {
$newObjJson = $obj | ConvertTo-Json -Depth 50
$templateIDs = Get-GUIDs ($templateReference | ConvertTo-Json -Depth 50)
$objectIDs = Get-GUIDs ($obj.Settings | ConvertTo-Json -Depth 50)
$diff = Compare-Object $templateIDs $objectIDs -CaseSensitive
foreach($diffItem in ($diff | where SideIndicator -eq "=>")) {
$templateID = $templateIDs | Where { $_ -eq $diffItem.InputObject }
if($templateID) {
# Found but with different casing
$newObjJson = $newObjJson -replace $diffItem.InputObject, $templateID
$updated = $true
}
}
if($updated) {
$returnHT.Add("JSON", $newObjJson)
}
}
}
return $returnHT
}
function Invoke-CheckSettingsCatalogIds
{
param($obj, $templateReference)
foreach($settingTemplate in $obj.value) {
if($settingTemplate.settingDefinitions) {
foreach($settingDefinition in $settingTemplate.settingDefinitions) {
if($settingDefinition.id -and $settingDefinition.id -ne $obj.Id) {
Write-Log "Setting definition ID $($settingDefinition.id) does not match the settings catalog ID $($obj.Id)" 2
}
}
}
}
}
function Start-PostExportSettingsCatalog function Start-PostExportSettingsCatalog
{ {
param($obj, $objectType, $path) param($obj, $objectType, $path)
@@ -3813,11 +4307,13 @@ function Add-ConditionalAccessImportExtensions
Value = "disabled" Value = "disabled"
} }
$defaultCAState = Get-SettingValue "ConditionalAccessState"
$global:cbImportCAState = [System.Windows.Controls.ComboBox]::new() $global:cbImportCAState = [System.Windows.Controls.ComboBox]::new()
$global:cbImportCAState.DisplayMemberPath = "Name" $global:cbImportCAState.DisplayMemberPath = "Name"
$global:cbImportCAState.SelectedValuePath = "Value" $global:cbImportCAState.SelectedValuePath = "Value"
$global:cbImportCAState.ItemsSource = $CAStates $global:cbImportCAState.ItemsSource = $CAStates
$global:cbImportCAState.SelectedValue = "disabled" $global:cbImportCAState.SelectedValue = $defaultCAState
$global:cbImportCAState.Margin="0,5,0,0" $global:cbImportCAState.Margin="0,5,0,0"
$global:cbImportCAState.HorizontalAlignment="Left" $global:cbImportCAState.HorizontalAlignment="Left"
$global:cbImportCAState.Width=250 $global:cbImportCAState.Width=250
@@ -3855,6 +4351,12 @@ function Start-PreImportConditionalAccess
{ {
$obj.sessionControls.disableResilienceDefaults = $null $obj.sessionControls.disableResilienceDefaults = $null
} }
# DeviceStates property is depricated
if(($obj.conditions.PSObject.Properties | Where Name -eq "DeviceStates"))
{
$obj.conditions.PSObject.Properties.Remove('DeviceStates')
}
} }
function Start-PostExportConditionalAccess function Start-PostExportConditionalAccess
+8 -1
View File
@@ -521,6 +521,13 @@ function Write-AzureStorageChunk
"Content-Type" = "application/octet-stream" "Content-Type" = "application/octet-stream"
} }
# In PowerShell (Core) 7 v7.4+, the web cmdlets (Invoke-WebRequest, Invoke-RestMethod)
# consistently encode text-based request bodies as UTF-8, unless explicitly specified otherwise.
if ($PSVersionTable.PSVersion -ge [Version]"7.4")
{
$headers["Content-Type"] += "; charset=iso-8859-1"
}
$curProgressPreference = $ProgressPreference $curProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue'
@@ -783,7 +790,7 @@ function Start-DownloadAppContent
{ {
foreach($file in $contentFiles.value) foreach($file in $contentFiles.value)
{ {
if($contentFiles.value[-1].Id -eq $file.id) { continune } if($contentFiles.value[-1].Id -eq $file.id) { continue }
# NOT happy about this. file objects are not always returned in the order of upload. # NOT happy about this. file objects are not always returned in the order of upload.
$contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($file.Id)" -NoError $contentFile = Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$appId/$appType/contentVersions/$contentVerId/files/$($file.Id)" -NoError
+1 -1
View File
@@ -348,7 +348,7 @@ function Get-EMIntuneFilterUsage
foreach($groupID in $loadedGroups.Keys) foreach($groupID in $loadedGroups.Keys)
{ {
$filterObjs = $script:objFilterUsage | WHere GroupID -eq $groupID $filterObjs = $script:objFilterUsage | Where GroupID -eq $groupID
if($filterObjs -and $loadedGroups[$groupID]) if($filterObjs -and $loadedGroups[$groupID])
{ {
foreach($filterObj in $filterObjs) { foreach($filterObj in $filterObjs) {
+59 -13
View File
@@ -55,10 +55,25 @@ function Invoke-InitializeModule
<elements> <elements>
</elements> </elements>
</policy> </policy>
</policies> </policies>
</policyDefinitions> </policyDefinitions>
"@ "@
# Add settings
$global:appSettingSections += (New-Object PSObject -Property @{
Title = "Intune Tools"
Id = "IntuneTools"
Values = @()
})
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Format OM-URI Settings"
Key = "FormatOMAURI"
Type = "Boolean"
DefaultValue = $false
Description = "Formats the XML for OMA-URI settings e.g. removes unnecessary spaces and empty lines."
}) "IntuneTools"
} }
function Add-EMToolsViewItem function Add-EMToolsViewItem
@@ -704,7 +719,10 @@ function Invoke-LoadADMXSettings
$tvItem | Add-Member -MemberType NoteProperty -Name "AllPolicies" -Value $true $tvItem | Add-Member -MemberType NoteProperty -Name "AllPolicies" -Value $true
} }
$global:tvADMXCategories.Items[1].Items.Add($tvItem) | Out-Null try {
$global:tvADMXCategories.Items[1].Items.Add($tvItem) | Out-Null
}
catch{}
} }
function Set-ADMXSettingStatusText function Set-ADMXSettingStatusText
@@ -854,6 +872,7 @@ function Get-ADMXCategoryNamePath
} }
$catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($categoryId)']",$script:xmlNS) $catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($categoryId)']",$script:xmlNS)
#$catObj = $script:admxXML.policyDefinitions.categories.category | Where Name -eq "$categoryId"
$categories = @() $categories = @()
while($catObj) while($catObj)
@@ -862,6 +881,7 @@ function Get-ADMXCategoryNamePath
if($catObj.parentCategory.ref) if($catObj.parentCategory.ref)
{ {
$catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($catObj.parentCategory.ref)']", $script:xmlNS) $catObj = $script:admxXML.policyDefinitions.categories.selectSingleNode("$($script:xmlNSPrefix)category[@name='$($catObj.parentCategory.ref)']", $script:xmlNS)
#$catObj = $script:admxXML.policyDefinitions.categories.category | where name -eq $catObj.parentCategory.ref
} }
else else
{ {
@@ -1037,17 +1057,18 @@ function Set-ADMXElementsPanel
} }
elseif($valItem.value.longDecimal) elseif($valItem.value.longDecimal)
{ {
$value = $valItem.value.longDecimal.'#text' $value = ?? $valItem.value.longDecimal.'#text' $valItem.value.longDecimal
} }
elseif($valItem.value.string) elseif($valItem.value.string)
{ {
$value = $valItem.value.string.'#text' $value = ?? $valItem.value.string.'#text' $valItem.value.string
} }
else else
{ {
Write-Log "Unsupported value type for $($elementNode.Id): $($valItem.value.InnerXml)" 2 Write-Log "Unsupported value type for $($elementNode.Id): $($valItem.value.InnerXml)" 2
$value = "<SET MANUALLY!!!>" $value = "<SET MANUALLY!!!>"
} }
$valItems += [PSCustomObject]@{ $valItems += [PSCustomObject]@{
Name = $displayName Name = $displayName
Value = $value Value = $value
@@ -1151,7 +1172,7 @@ function Set-ADMXElementsPanel
} }
elseif($valItem.value.string) elseif($valItem.value.string)
{ {
$value = $valItem.value.string.'#text' $value = ?? $valItem.value.string.'#text' $valItem.value.string
} }
else else
{ {
@@ -1403,20 +1424,25 @@ function Import-ADMXPolicy
{ {
if($admxPolicy.SettingStatus -eq 0) if($admxPolicy.SettingStatus -eq 0)
{ {
$policyValue = "<disabled />" $policyValue = "<disabled/>"
} }
else else
{ {
$policyValue = "<enabled />" $policyValue = "<enabled/>"
$strValue = $admxPolicy.PolicySettings $strValue = $admxPolicy.PolicySettings
if($strValue) if($strValue)
{ {
$policyValue += "`n`n$strValue" $policyValue += "`n$strValue"
} }
} }
if((Get-SettingValue "FormatOMAURI") -eq $true)
{
$policyValue = Update-XmlFormatting $policyValue
}
$catPath = Get-ADMXCategoryOMAURIPath $admxPolicy.Definition.parentCategory.ref $catPath = Get-ADMXCategoryOMAURIPath $admxPolicy.Definition.parentCategory.ref
$omaUriPath = "./$($admxPolicy.SettingClass)/Vendor/MSFT/Policy/Config/$($global:txtADMXPolicyAppName.Text)~Policy~$catPath/$($admxPolicy.Definition.name)" $omaUriPath = "./$($admxPolicy.SettingClass)/Vendor/MSFT/Policy/Config/$($global:txtADMXPolicyAppName.Text)~Policy~$catPath/$($admxPolicy.Definition.name)"
@@ -1458,12 +1484,18 @@ function Import-ADMXPolicy
if($global:chkADMXPolicyIngest.IsChecked) if($global:chkADMXPolicyIngest.IsChecked)
{ {
$xmlString = Format-XML $script:admxXML
if((Get-SettingValue "FormatOMAURI") -eq $true)
{
$xmlString = Update-XmlFormatting $xmlString
}
$intuneObj.omaSettings += [PSCustomObject]@{ $intuneObj.omaSettings += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.omaSettingString" "@odata.type" = "#microsoft.graph.omaSettingString"
"displayName" = (?? $global:txtADMXPolicyIngestName.Text ("$($script:currentADMXFile.Name) Ingestion")) "displayName" = (?? $global:txtADMXPolicyIngestName.Text ("$($script:currentADMXFile.Name) Ingestion"))
"description" = $null "description" = $null
"omaUri" = "./Device/Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/$($global:txtADMXPolicyAppName.Text)/Policy/$($global:txtADMXPolicyFileName.Text)" "omaUri" = "./Device/Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/$($global:txtADMXPolicyAppName.Text)/Policy/$($global:txtADMXPolicyFileName.Text)"
"value" = (Format-XML $script:admxXML) "value" = $xmlString
} }
} }
@@ -1780,7 +1812,7 @@ function Get-ADMXRegIsKeySupported
if($blockedSource) if($blockedSource)
{ {
[System.Windows.MessageBox]::Show("The registry key '$($global:txtADMXRegKey.Text)' is not supported" + [Environment]::NewLine + [Environment]::NewLine + "Blocked by root key: $blockedSource", "Unsupported reg ket", "OK", "Error") [System.Windows.MessageBox]::Show("The registry key '$($global:txtADMXRegKey.Text)' is not supported" + [Environment]::NewLine + [Environment]::NewLine + "Blocked by root key: $blockedSource", "Unsupported reg key", "OK", "Error")
return $false return $false
} }
return $true return $true
@@ -1927,6 +1959,11 @@ function Import-ADMXRegProfile
$OMAURIString = ($OMAURIString + [Environment]::NewLine + [Environment]::NewLine + ($omaUriItems -join [Environment]::NewLine)) $OMAURIString = ($OMAURIString + [Environment]::NewLine + [Environment]::NewLine + ($omaUriItems -join [Environment]::NewLine))
} }
if((Get-SettingValue "FormatOMAURI") -eq $true)
{
$OMAURIString = Update-XmlFormatting $OMAURIString
}
$xml.policyDefinitions.SelectSingleNode("policies").AppendChild($newNode) | Out-Null $xml.policyDefinitions.SelectSingleNode("policies").AppendChild($newNode) | Out-Null
$admxRegSettings += [PSCustomObject]@{ $admxRegSettings += [PSCustomObject]@{
@@ -1939,12 +1976,18 @@ function Import-ADMXRegProfile
$xml.policyDefinitions.SelectSingleNode("policies").RemoveChild($xml.policyDefinitions.policies.SelectSingleNode("policy")) | Out-Null $xml.policyDefinitions.SelectSingleNode("policies").RemoveChild($xml.policyDefinitions.policies.SelectSingleNode("policy")) | Out-Null
$xmlString = Format-XML $xml
if((Get-SettingValue "FormatOMAURI") -eq $true)
{
$xmlString = Update-XmlFormatting $xmlString
}
$intuneObj.omaSettings += [PSCustomObject]@{ $intuneObj.omaSettings += [PSCustomObject]@{
"@odata.type" = "#microsoft.graph.omaSettingString" "@odata.type" = "#microsoft.graph.omaSettingString"
"displayName" = "Reg ADMX Ingestion" "displayName" = "Reg ADMX Ingestion"
"description" = "This XML is generated by Intune Managemet tool" "description" = "This XML is generated by Intune Managemet tool"
"omaUri" = "./Device/Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/IntuneManagementReg/$(($script:frmADMXRegProfile.DataContext.PolicyType))/$($rgPolicyFileName)" "omaUri" = "./Device/Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/IntuneManagementReg/$(($script:frmADMXRegProfile.DataContext.PolicyType))/$($rgPolicyFileName)"
"value" = (Format-XML $xml) "value" = $xmlString
} }
$intuneObj.omaSettings += $admxRegSettings $intuneObj.omaSettings += $admxRegSettings
@@ -1981,9 +2024,11 @@ function Add-ADMXRegClasses
} }
$classDef = @" $classDef = @"
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Collections.ObjectModel;
public class ADMXRegPolicyElement : INotifyPropertyChanged public class ADMXRegPolicyElement : System.ComponentModel.INotifyPropertyChanged
{ {
public string DataType { get { return _dataType; } set { _dataType = value; NotifyPropertyChanged("DataType"); NotifyPropertyChanged("DataTypeDisplayString"); } } public string DataType { get { return _dataType; } set { _dataType = value; NotifyPropertyChanged("DataType"); NotifyPropertyChanged("DataTypeDisplayString"); } }
private string _dataType = null; private string _dataType = null;
@@ -2069,8 +2114,9 @@ function Add-ADMXRegClasses
} }
} }
"@ "@
[Reflection.Assembly]::LoadWithPartialName("mscorlib") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null [Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel') Add-Type -TypeDefinition $classDef
} }
#endregion #endregion
+261 -34
View File
@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
#> #>
function Get-ModuleVersion function Get-ModuleVersion
{ {
'3.9.8a' '3.9.9'
} }
$global:msalAuthenticator = $null $global:msalAuthenticator = $null
@@ -129,6 +129,36 @@ function Invoke-InitializeModule
Description = "Sort the list of available tenants based on Tenant name. Updated at restart or account change" Description = "Sort the list of available tenants based on Tenant name. Updated at restart or account change"
}) "MSAL" }) "MSAL"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Use WAM for enhanced login methods"
Key = "UseWAM"
Type = "Boolean"
DefaultValue = $false
Description = "Use WAM for enhanced login methods"
}) "MSAL"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Use System Browser for login"
Key = "UseSystemBrowser"
Type = "Boolean"
DefaultValue = $false
Description = "Use the default system browser (Edge/Chrome/Firefox) for interactive login instead of the embedded WebView. Required for passkey / FIDO2 sign-in. Redirect URI is forced to http://localhost when enabled. Takes precedence over WAM. Note: Requires restart"
}) "MSAL"
$script:MSALUseWAM = Get-SettingValue "UseWAM"
if($script:MSALUseWAM -and $PSVersionTable.PSVersion.Major -lt 7) {
Write-Log "WAM is only supported in PowerShell 7 and later. Disabling WAM" 2
$script:MSALUseWAM = $false
}
# System Browser takes precedence over WAM: passkey/FIDO2 login works in the real browser
# but not in the WAM pane or the embedded WebView. If both are enabled, disable WAM.
$script:MSALUseSystemBrowser = Get-SettingValue "UseSystemBrowser"
if($script:MSALUseSystemBrowser -and $script:MSALUseWAM) {
Write-Log "Both UseWAM and UseSystemBrowser are enabled - the system browser takes precedence for interactive login" 2
$script:MSALUseWAM = $false
}
Add-MSALPrereq Add-MSALPrereq
} }
@@ -200,6 +230,9 @@ function Set-MSALGraphEnvironment
{ {
$curAADEnv = $script:lstAADEnvironments | Where URL -eq $user.Environment $curAADEnv = $script:lstAADEnvironments | Where URL -eq $user.Environment
} }
elseif($global:UseGraphEnvironment) {
$curAADEnv = $script:lstAADEnvironments | Where value -eq $global:UseGraphEnvironment
}
else else
{ {
$curAADEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public") $curAADEnv = $script:lstAADEnvironments | Where value -eq (Get-Setting "" "MSALCloudType" "public")
@@ -207,7 +240,14 @@ function Set-MSALGraphEnvironment
if($curAADEnv.Value -eq "usGov") if($curAADEnv.Value -eq "usGov")
{ {
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc") if($global:UseGCCType)
{
$gccEnv = $global:UseGCCType
}
else {
$gccEnv = (Get-Setting "" "MSALGCCType" "gcc")
}
if($gccEnv) if($gccEnv)
{ {
$GCCEnvObj = $script:lstGCCEnvironments | Where Value -eq $gccEnv $GCCEnvObj = $script:lstGCCEnvironments | Where Value -eq $gccEnv
@@ -259,6 +299,7 @@ function Get-MSALUserInfo
if($global:Organization) if($global:Organization)
{ {
if($global:Organization -is [array]) { $global:Organization = $global:Organization[0]} if($global:Organization -is [array]) { $global:Organization = $global:Organization[0]}
$global:Organization.displayName = ($global:Organization.displayName).Trim()
Save-Setting $global:Organization.Id "_Name" $global:Organization.displayName Save-Setting $global:Organization.Id "_Name" $global:Organization.displayName
} }
Set-EnvironmentInfo $global:Organization.displayName Set-EnvironmentInfo $global:Organization.displayName
@@ -487,6 +528,129 @@ function Install-MSALDependencyModule
} }
function Add-MSALPrereq function Add-MSALPrereq
{
$ScriptRoot = $global:AppRootFolder
$DLLFiles = @()
if($PSVersionTable.PSVersion.Major -ge 7) {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\Microsoft.IdentityModel.Abstractions.dll")
}
else {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\6.35.0\Microsoft.IdentityModel.Abstractions.dll")
}
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\Bin\Microsoft.Identity.Client.dll")
if($script:MSALUseWAM) {
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Extensions.Msal.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Broker.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.Desktop.dll")
$DLLFiles += [IO.FileInfo]($ScriptRoot + "\BIN\$MSALDLLPath\Microsoft.Identity.Client.NativeInterop.dll")
}
$DLLFiles | ForEach-Object {
$dllFile = $_
# ToDo: Unblock files
if($_.Exists) {
try {
[void][System.Reflection.Assembly]::LoadFrom($_.FullName)
Write-Log "Loaded $($_.Name) version $($_.VersionInfo.FileVersion)"
}
catch {
$loadedFile = [Appdomain]::CurrentDomain.GetAssemblies() | Where Location -like "*\$($dllFile.Name)"
if($loadedFile) {
$loadedFI = [IO.FileInfo]($loadedFile.Location)
Write-Log "Failed to load $($dllFile.Name) version $($dllFile.VersionInfo.FileVersion). File already loaded: $($loadedFI.FullName) version $($loadedFI.VersionInfo.FileVersion)" 2
}
else {
Write-LogError "Failed to load $($dllFile.Name) version $($dllFile.VersionInfo.FileVersion)" $_.Exception
}
}
}
else {
Write-LogError "Microsoft.Identity file not found: $($_.FullName)"
}
}
if (-not ("TokenCacheHelperEx" -as [type]))
{
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
foreach($file in $DLLFiles) {
$RequiredAssemblies.Add($file.FullName)
}
$RequiredAssemblies.Add('System.Security.dll')
$RequiredAssemblies.Add('mscorlib.dll')
if($PSVersionTable.PSVersion.Major -ge 7) {
$RequiredAssemblies.Add('System.Security.Cryptography.ProtectedData.dll')
}
$RequiredAssemblies.Add('System.Threading.dll')
try
{
Add-Type -Path ($ScriptRoot + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies -IgnoreWarnings
}
catch
{
Write-LogError "Failed to compile TokenCacheHelperEx. The access token will not be cached. Check write access to the CS folder and ASR policies" $_.Exception
}
}
if($script:MSALUseWAM) {
[System.Collections.Generic.List[string]] $RequiredAssemblies = New-Object System.Collections.Generic.List[string]
foreach($file in $DLLFiles) {
$RequiredAssemblies.Add($file.FullName)
}
$RequiredAssemblies.Add('mscorlib.dll')
$RequiredAssemblies.Add('System.dll')
$RequiredAssemblies.Add('System.Windows.Forms')
# Import necessary methods from user32.dll and kernel32.dll
Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Identity.Client;
//using Microsoft.Identity.Client.Desktop;
using Microsoft.Identity.Client.Broker;
using System.Windows.Forms;
public class MSALMethods
{
enum GetAncestorFlags {
GetParent = 1,
GetRoot = 2,
GetRootOwner = 3
}
[DllImport("user32.dll", ExactSpelling = true)]
public static extern IntPtr GetAncestor(IntPtr hwnd, int flags);
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
// This is your window handle!
public static IntPtr GetConsoleOrTerminalWindow()
{
IntPtr consoleHandle = GetConsoleWindow();
IntPtr handle = GetAncestor(consoleHandle, (int)GetAncestorFlags.GetRootOwner );
return handle;
}
public static void AddParentActivirtyOrWindow(PublicClientApplicationBuilder appBuilder)
{
appBuilder.WithParentActivityOrWindow(GetConsoleOrTerminalWindow);
}
public static void AddWithBroker(PublicClientApplicationBuilder appBuilder, BrokerOptions options)
{
appBuilder.WithBroker(options);
}
}
"@ -ReferencedAssemblies $RequiredAssemblies -IgnoreWarnings
}
}
function Add-MSALPrereq_old
{ {
$msalPath = "" $msalPath = ""
@@ -565,7 +729,15 @@ function Add-MSALPrereq
$RequiredAssemblies.Add($msalPath) $RequiredAssemblies.Add($msalPath)
$script:msalFile = $msalPath $script:msalFile = $msalPath
} }
$RequiredAssemblies.Add('System.Security.dll') $RequiredAssemblies.Add('System.Security.dll')
$RequiredAssemblies.Add('mscorlib.dll')
if($PSVersionTable.PSVersion.Major -ge 7)
{
$RequiredAssemblies.Add('System.Security.Cryptography.ProtectedData.dll')
}
$RequiredAssemblies.Add('System.Threading.dll')
try try
{ {
@@ -586,6 +758,10 @@ function Connect-MSALClientApp
if(-not $script:MSALApp) if(-not $script:MSALApp)
{ {
if($global:UseGraphEnvironment) {
Set-MSALGraphEnvironment $null $null
}
$authority = "https://login.microsoftonline.com/$tenantId" $authority = "https://login.microsoftonline.com/$tenantId"
#$redirectUri = "http://localhost" #$redirectUri = "http://localhost"
@@ -747,7 +923,7 @@ function Get-MSALApp
{ {
param($appInfo, $loginHint) param($appInfo, $loginHint)
$msalApp = $script:MSALAllApps | Where { $_.ClientId -eq $appInfo.ClientID -and (-not $appInfo.RedirectUri -or $_.AppConfig.RedirectUri -eq $appInfo.RedirectUri)} $msalApp = $script:MSALAllApps | Where { $_.AppConfig.ClientId -eq $appInfo.ClientID -and (-not $appInfo.RedirectUri -or $_.AppConfig.RedirectUri -eq $appInfo.RedirectUri)}
$tenant = ?? $appInfo.TenantId "organizations" $tenant = ?? $appInfo.TenantId "organizations"
@@ -770,14 +946,33 @@ function Get-MSALApp
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($appInfo.ClientID) $appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($appInfo.ClientID)
[void]$appBuilder.WithAuthority($authority) [void]$appBuilder.WithAuthority($authority)
#if($appInfo.TenantId) { [void]$appBuilder.WithAuthority("https://$((?? $loginHint.Environment (Get-MSALLoginEnvironment)))/$($appInfo.TenantId)/") }
#elseif ($appInfo.Authority) { [void]$appBuilder.WithAuthority($appInfo.Authority) }
if($appInfo.RedirectUri) { [void]$appBuilder.WithRedirectUri($appInfo.RedirectUri) } # System Browser mode: MSAL's system-browser flow only accepts loopback redirects,
# so any custom redirect URI (nativeclient, ms-appx-web://, etc.) is replaced with
# http://localhost. The app registration in Entra must have this loopback URI added
# under the "Mobile and desktop applications" platform for the login to succeed.
$redirectUri = $appInfo.RedirectUri
if($script:MSALUseSystemBrowser -and $redirectUri -and ($redirectUri -notmatch '^http://localhost')) {
Write-LogDebug "UseSystemBrowser: overriding redirect URI '$redirectUri' with http://localhost"
$redirectUri = "http://localhost"
}
elseif($script:MSALUseSystemBrowser -and -not $redirectUri) {
$redirectUri = "http://localhost"
}
if($redirectUri) { [void]$appBuilder.WithRedirectUri($redirectUri) }
[void] $appBuilder.WithClientName("CloudAPIPowerShellManagement") [void] $appBuilder.WithClientName("CloudAPIPowerShellManagement")
[void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion) [void] $appBuilder.WithClientVersion($PSVersionTable.PSVersion)
if($script:MSALUseWAM) {
[MSALMethods]::AddParentActivirtyOrWindow($appBuilder)
$options = [Microsoft.Identity.Client.BrokerOptions]::new([Microsoft.Identity.Client.BrokerOptions+OperatingSystems]::Windows)
$options.Title = "Intune Manager"
[MSALMethods]::AddWithBroker($appBuilder, $options)
}
Add-MSALProxy $appBuilder Add-MSALProxy $appBuilder
# Ceck if correct version... # Ceck if correct version...
@@ -858,6 +1053,11 @@ function Connect-MSALUser
if($global:MainAppStarted -eq $false) if($global:MainAppStarted -eq $false)
{ {
$script:AppLogin = (Get-SettingValue "GraphAzureAppLogin") -or ($global:TenantId -and $global:AzureAppId -and ($global:ClientSecret -or $global:ClientCert)) $script:AppLogin = (Get-SettingValue "GraphAzureAppLogin") -or ($global:TenantId -and $global:AzureAppId -and ($global:ClientSecret -or $global:ClientCert))
if((Get-SettingValue "GraphAzureAppLogin") -and -not $global:TenantId)
{
$global:TenantId = Get-SettingValue "GraphAzureTenantId"
}
} }
if($script:AppLogin) if($script:AppLogin)
@@ -908,8 +1108,6 @@ function Connect-MSALUser
Add-MSALPrereq Add-MSALPrereq
} }
$curTicks = $global:MSALToken.ExpiresOn.LocalDateTime.Ticks
$currentLoggedInUserApp = ($global:MSALToken.Account.HomeAccountId.Identifier + $global:MSALToken.TenantId + $global:MSALApp.ClientId) $currentLoggedInUserApp = ($global:MSALToken.Account.HomeAccountId.Identifier + $global:MSALToken.TenantId + $global:MSALApp.ClientId)
$currentLoggedInUserId = $global:MSALToken.Account.HomeAccountId.Identifier $currentLoggedInUserId = $global:MSALToken.Account.HomeAccountId.Identifier
if($Interactive -eq $true) if($Interactive -eq $true)
@@ -946,7 +1144,6 @@ function Connect-MSALUser
} }
else else
{ {
$lastUser =
$lastUserId = Get-Setting "" "LastLoggedOnUserId" $lastUserId = Get-Setting "" "LastLoggedOnUserId"
if($lastUserId) if($lastUserId)
{ {
@@ -1015,15 +1212,6 @@ function Connect-MSALUser
return return
} }
if($authResult -and $authResult.ExpiresOn.LocalDateTime.Ticks -ne $curTicks)
{
Write-Log "$($authResult.Account.UserName) authenticated successfully (Silent). CorrelationId: $($global:MSALToken.CorrelationId)"
}
else
{
Write-LogDebug "$($authResult.Account.UserName) authenticated successfully (Silent). CorrelationId: $($global:MSALToken.CorrelationId)"
}
#AADSTS65001 #AADSTS65001
if($script:authenticationFailure.Classification -eq "ConsentRequired") if($script:authenticationFailure.Classification -eq "ConsentRequired")
{ {
@@ -1113,6 +1301,10 @@ function Connect-MSALUser
{ {
Write-Log "Login hint: $loginHintName" Write-Log "Login hint: $loginHintName"
[void]$AquireTokenObj.WithLoginHint($loginHintName) [void]$AquireTokenObj.WithLoginHint($loginHintName)
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::NoPrompt)
}
else {
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::SelectAccount)
} }
if($script:authenticationFailure.Claims) if($script:authenticationFailure.Claims)
@@ -1127,17 +1319,21 @@ function Connect-MSALUser
[void]$aquireTokenObj.WithParentActivityOrWindow($ParentWindow) [void]$aquireTokenObj.WithParentActivityOrWindow($ParentWindow)
} }
# UseSystemBrowser: force MSAL to launch the default system browser instead of
# any embedded WebView. Required for passkey / FIDO2 sign-in which the embedded
# WebView cannot service.
if($script:MSALUseSystemBrowser)
{
try { [void]$aquireTokenObj.WithUseEmbeddedWebView($false) }
catch { Write-LogDebug "WithUseEmbeddedWebView unavailable: $($_.Exception.Message)" }
}
# If we need a consent (e.g. App is not approved in the environment) # If we need a consent (e.g. App is not approved in the environment)
if ($script:authenticationFailure.Classification -eq "ConsentRequired") if ($script:authenticationFailure.Classification -eq "ConsentRequired")
{ {
Write-Log "Interactive login with Consent prompt" Write-Log "Interactive login with Consent prompt"
[void]$aquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::Consent) [void]$aquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::Consent)
} }
elseif(-not $loginHintName)
{
Write-Log "Interactive login with Select account prompt"
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::SelectAccount)
}
$authResult = Get-MsalAuthenticationToken $aquireTokenObj $authResult = Get-MsalAuthenticationToken $aquireTokenObj
if($authResult) if($authResult)
@@ -1146,6 +1342,31 @@ function Connect-MSALUser
} }
} }
if($authResult) {
$telemetry = $null
$wamTelemetry = $null
if($authResult.AuthenticationResultMetadata.Telemetry) {
try {
$telemetry = $authResult.AuthenticationResultMetadata.Telemetry | ConvertFrom-Json
if($telemetry.wam_telemetry) {
$wamTelemetry = $telemetry.wam_telemetry | ConvertFrom-Json
}
}
catch {}
}
if($authResult.AuthenticationResultMetadata.TokenSource -eq "Broker" -and $telemetry.broker_app_used -eq "true") {
Write-Log "Token received from Broker. Time (ms): $($authResult.AuthenticationResultMetadata.DurationTotalInMs). CorrelationId: $($authResult.CorrelationId)"
}
elseif($authResult.AuthenticationResultMetadata.TokenSource -eq "IdentityProvider") {
Write-Log "Token received from IdentityProvider. Time (ms) $($authResult.AuthenticationResultMetadata.DurationTotalInMs)"
}
else {
# ToDo: Change to debug
Write-Log "Token received from Cache. Time (ms) $($authResult.AuthenticationResultMetadata.DurationTotalInMs)"
}
}
if($currentLoggedInUserId -ne $authResult.Account.HomeAccountId.Identifier) if($currentLoggedInUserId -ne $authResult.Account.HomeAccountId.Identifier)
{ {
$script:AccessableTenants = $null $script:AccessableTenants = $null
@@ -1162,7 +1383,17 @@ function Connect-MSALUser
$appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($global:appObj.ClientID) $appBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($global:appObj.ClientID)
if($tenantId) { [void]$appBuilder.WithAuthority("https://$((Get-MSALAppAuthority))/$($tenantId)") } if($tenantId) { [void]$appBuilder.WithAuthority("https://$((Get-MSALAppAuthority))/$($tenantId)") }
else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) } else { [void]$appBuilder.WithAuthority($global:MSALApp.Authority) }
if($global:appObj.RedirectUri) { [void]$appBuilder.WithRedirectUri($global:appObj.RedirectUri) }
# Match the redirect URI substitution done in Get-MSALApp - keeps this
# secondary MSAL app consistent with System Browser mode.
$tenantRedirectUri = $global:appObj.RedirectUri
if($script:MSALUseSystemBrowser -and $tenantRedirectUri -and ($tenantRedirectUri -notmatch '^http://localhost')) {
$tenantRedirectUri = "http://localhost"
}
elseif($script:MSALUseSystemBrowser -and -not $tenantRedirectUri) {
$tenantRedirectUri = "http://localhost"
}
if($tenantRedirectUri) { [void]$appBuilder.WithRedirectUri($tenantRedirectUri) }
Add-MSALProxy $appBuilder Add-MSALProxy $appBuilder
@@ -1183,6 +1414,11 @@ function Connect-MSALUser
#[void]$AquireTokenObj.WithAccount($authResult.Account) #[void]$AquireTokenObj.WithAccount($authResult.Account)
[void]$AquireTokenObj.WithLoginHint($authResult.Account.Username) [void]$AquireTokenObj.WithLoginHint($authResult.Account.Username)
[void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::NoPrompt) [void]$AquireTokenObj.WithPrompt([Microsoft.Identity.Client.Prompt]::NoPrompt)
if($script:MSALUseSystemBrowser)
{
try { [void]$AquireTokenObj.WithUseEmbeddedWebView($false) }
catch { Write-LogDebug "WithUseEmbeddedWebView unavailable: $($_.Exception.Message)" }
}
$tmpResults = Get-MsalAuthenticationToken $AquireTokenObj $tmpResults = Get-MsalAuthenticationToken $AquireTokenObj
} }
@@ -1225,15 +1461,6 @@ function Connect-MSALUser
Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId Save-Setting "" "LastLoggedOnUserId" $authResult.Account.HomeAccountId.ObjectId
} }
Invoke-MSALAuthenticationUpdated $authResult Invoke-MSALAuthenticationUpdated $authResult
<#
Write-LogDebug "User, tenant or app has changed"
Get-MSALUserInfo
if($authResult)
{
Invoke-MSALCheckObjectViewAccess $authResult
}
Invoke-ModuleFunction "Invoke-GraphAuthenticationUpdated"
#>
} }
} }
@@ -2161,7 +2388,7 @@ function Show-MSALDecodedToken {
{ {
if($prop.Name -in @("exp","iat","nbf","xms_tcdt")) if($prop.Name -in @("exp","iat","nbf","xms_tcdt"))
{ {
$value =[datetime]::new(1970, 1, 1, 0, 0, 0, 0, "UTC").AddSeconds(($tokenData.Payload."$($prop.Name)")).ToLocalTime() $value = [datetime]::new(1970, 1, 1, 0, 0, 0, 0, [System.DateTimeKind]::Utc).AddSeconds(($tokenData.Payload."$($prop.Name)")).ToLocalTime()
} }
elseif($prop.Name -in @("acrs","amr")) elseif($prop.Name -in @("acrs","amr"))
{ {
+440 -31
View File
@@ -43,12 +43,85 @@ function Invoke-InitializeModule
Name = "Replace (Preview)" Name = "Replace (Preview)"
Value = "replace" Value = "replace"
}, },
[PSCustomObject]@{
Name = "Replace with assignments (Preview)"
Value = "replace_with_assignments"
},
[PSCustomObject]@{ [PSCustomObject]@{
Name = "Update (Preview)" Name = "Update (Preview)"
Value = "update" Value = "update"
} }
) )
$script:lstConditionalAccessState = @(
[PSCustomObject]@{
Name = "As Exported - Change On to Report-only"
Value = "AsExportedReportOnly"
},
[PSCustomObject]@{
Name = "As Exported"
Value = "AsExported"
},
[PSCustomObject]@{
Name = "Report-only"
Value = "enabledForReportingButNotEnforced"
},
[PSCustomObject]@{
Name = "Off"
Value = "disabled"
}
)
$script:lstGraphPageSize = @(
[PSCustomObject]@{
Name = "Graph API Default"
Value = "0"
},
[PSCustomObject]@{
Name = "5"
Value = "5"
},
[PSCustomObject]@{
Name = "20"
Value = "20"
},
[PSCustomObject]@{
Name = "50"
Value = "50"
},
[PSCustomObject]@{
Name = "100"
Value = "100"
},
[PSCustomObject]@{
Name = "All"
Value = "All"
}
)
# Bit 1: Bulk export
# Bit 2: Manual export
# Bit 3: Bulk import
# Bit 4: Manual import
$script:lstClearCacheTypes = @(
[PSCustomObject]@{
Name = "Bulk export (Default)"
Value = "1" # Bulk export only
},
[PSCustomObject]@{
Name = "Bulk and manual export"
Value = "3"
},
[PSCustomObject]@{
Name = "Bulk export/import"
Value = "7" #
},
[PSCustomObject]@{
Name = "Bulk and manual import/export"
Value = "15" # Both bulk and manual
}
)
# Make sure MS Graph settings are added before exiting before App Id and Tenant Id is missing # Make sure MS Graph settings are added before exiting before App Id and Tenant Id is missing
Write-Log "Add settings and menu items" Write-Log "Add settings and menu items"
@@ -195,6 +268,13 @@ function Invoke-InitializeModule
Description = "Login with specified app in the UI. Note: Change will require app restart" Description = "Login with specified app in the UI. Note: Change will require app restart"
}) "GraphSilent" }) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "TenantId"
Key = "GraphAzureTenantId"
Type = "String"
Description = "Tenent Id used when logging in with App in UI"
}) "GraphSilent"
Add-SettingsObject (New-Object PSObject -Property @{ Add-SettingsObject (New-Object PSObject -Property @{
Title = "Refresh Objects after copy" Title = "Refresh Objects after copy"
Key = "RefreshObjectsAfterCopy" Key = "RefreshObjectsAfterCopy"
@@ -235,6 +315,59 @@ function Invoke-InitializeModule
Description = "This will use production verionof graph, v1.0. Note: Thot officially supported since this can have unpredicted results. Some parts will require Beta version of Graph." Description = "This will use production verionof graph, v1.0. Note: Thot officially supported since this can have unpredicted results. Some parts will require Beta version of Graph."
}) "GraphGeneral" }) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "API Page Size"
Key = "GraphPageSize"
Type = "List"
ItemsSource = $script:lstGraphPageSize
DefaultValue = "100"
Description = "How many items load at a time"
}) "GraphGeneral"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Default Conditional Access Policy State"
Key = "ConditionalAccessState"
Type = "List"
ItemsSource = $script:lstConditionalAccessState
DefaultValue = "disabled"
Description = "Define the default option of the Conditional Access policy state. It is recommended to have this to disabled to avoid accidental tenant lock out"
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Sort Json Properties"
Key = "SortJsonProperties"
Type = "Boolean"
DefaultValue = $false
Description = "This will use sorted JSON properties when exporting JSON data. Making sure that properties are in the same order in each export."
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Clear Cache Before Export"
Key = "ClearCacheBeforeExportImport"
Type = "List"
ItemsSource = $script:lstClearCacheTypes
DefaultValue = "1"
Description = "Specifies when objects should be cleared from cache.<LineBreak />" +
"<Bold>Bulk export (Default)</Bold> - Clear objects from cache before bulk export.<LineBreak />" +
"<Bold>Bulk and manual export</Bold> - Clear objects from cache before bulk and manual export.<LineBreak />" +
"<Bold>Bulk export/import</Bold> - Clear objects from cache before bulk export or import.<LineBreak />" +
"<Bold>Bulk and manual export/import</Bold> - Clear objects from cache before bulk or manual export or import.<LineBreak /><LineBreak />" +
"<Bold>Note:</Bold> - Only Entra objects are cleared by default. Enable <Bold>Clear all objects from cache</Bold> to clear MigTable etc.."
}) "ImportExport"
Add-SettingsObject (New-Object PSObject -Property @{
Title = "Clear all objects from cache"
Key = "ClearAllObjectsFromCache"
Type = "Boolean"
DefaultValue = $false
Description = "This will clear all objects from cache e.g. groups, MigTabole etc.<LineBreak />" +
"This can be used if objects have been changed outside of the application to make sure the latest info e.g.<LineBreak />" +
"* New groups added<LineBreak />" +
"* New dependencies added<LineBreak />" +
"<Bold>Note:</Bold> - Clearing all cached object might cause import/export to take long timw or even reimport deleted policies/groups etc."
}) "ImportExport"
} }
function Get-GraphAppInfo function Get-GraphAppInfo
@@ -453,7 +586,8 @@ function Invoke-GraphRequest
do do
{ {
$ret = Invoke-RestMethod -Uri $Url -Method $HttpMethod @params $ret = Invoke-RestMethod -Uri $Url -Method $HttpMethod @params
if($? -eq $false) $callSucceeded = $?
if($callSucceeded -eq $false)
{ {
throw $global:error[0] throw $global:error[0]
} }
@@ -489,7 +623,6 @@ function Invoke-GraphRequest
if($_.Exception.Response.StatusCode -eq 429 -and $retryCount -le $retryMax) if($_.Exception.Response.StatusCode -eq 429 -and $retryCount -le $retryMax)
{ {
# NOT OK - Should use the date property but could not replicate the issue # NOT OK - Should use the date property but could not replicate the issue
$retryCount++
$retryRequest = $true $retryRequest = $true
Write-Log "429 - Too many requests received. Wait 5 s before retry" 2 Write-Log "429 - Too many requests received. Wait 5 s before retry" 2
Start-Sleep -Seconds 5 Start-Sleep -Seconds 5
@@ -554,7 +687,9 @@ function Get-GraphObjects
[switch] [switch]
$SingleObject, $SingleObject,
[string] [string]
$filter) $filter,
[int]
$pageSize = -1)
$params = @{} $params = @{}
if($objectType.ODataMetadata) if($objectType.ODataMetadata)
@@ -589,6 +724,10 @@ function Get-GraphObjects
{ {
#Use default page size or use below for a specific page size for testing #Use default page size or use below for a specific page size for testing
#$params.Add("pageSize",5) #!!! #$params.Add("pageSize",5) #!!!
if ($pageSize -gt 0)
{
$params.Add("pageSize", $pageSize)
}
} }
elseif($SingleObject -ne $true -and $SinglePage -ne $true) elseif($SingleObject -ne $true -and $SinglePage -ne $true)
{ {
@@ -717,7 +856,7 @@ function Add-GraphObjectProperties
function Show-GraphObjects function Show-GraphObjects
{ {
param($filter, [switch]$ObjectTypeChanged) param($filter, [switch]$ObjectTypeChanged, $FromGraphObjects)
$global:curObjectType = $global:lstMenuItems.SelectedItem $global:curObjectType = $global:lstMenuItems.SelectedItem
@@ -747,7 +886,7 @@ function Show-GraphObjects
{ {
$requiredPermissions = "" $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:txtNotLoggedIn.Content = "You don't have the required permissions to access $($global:curObjectType.Title).$($requiredPermissions)`n`Missing permissions: $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:grdNotLoggedIn.Visibility = "Visible"
$global:grdData.Visibility = "Collapsed" $global:grdData.Visibility = "Collapsed"
return return
@@ -760,7 +899,9 @@ function Show-GraphObjects
if(-not $global:lstMenuItems.SelectedItem) { return } if(-not $global:lstMenuItems.SelectedItem) { return }
Write-Status "Loading $($global:curObjectType.Title) objects" if(-not $FromGraphObjects) {
Write-Status "Loading $($global:curObjectType.Title) objects"
}
if($global:lstMenuItems.SelectedItem.ShowForm -ne $false) if($global:lstMenuItems.SelectedItem.ShowForm -ne $false)
{ {
@@ -776,7 +917,45 @@ function Show-GraphObjects
$script:nextGraphPage = $null $script:nextGraphPage = $null
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -SinglePage -Filter $filter $params = @{}
$pageSize = 0
if($global:curObjectType.PageSize)
{
$tmpPageSize = $global:curObjectType.PageSize
}
else {
$tmpPageSize = Get-SettingValue "GraphPageSize"
}
if($global:curObjectType.SupportsPageSize -eq $false) {
# Do nothing - use default page size from API
}
elseif ($tmpPageSize -eq "All")
{
$params.Add("AllPages", $true)
}else
{
if($tmpPageSize) {
try {
$pageSize = [int]$tmpPageSize
}
catch {}
}
if($pageSize -gt 0)
{
$params.Add("PageSize", $pageSize)
}
$params.Add("SinglePage", $true)
}
if($FromGraphObjects) {
[array]$graphObjects = $FromGraphObjects
}
else {
[array]$graphObjects = Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType -Filter $filter @params
}
$dgObjects.AutoGenerateColumns = $false $dgObjects.AutoGenerateColumns = $false
$dgObjects.Columns.Clear() $dgObjects.Columns.Clear()
@@ -854,7 +1033,9 @@ function Show-GraphObjects
} }
else else
{ {
$dgObjects.ItemsSource = $null $ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new()
$dgObjects.ItemsSource = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList)
#$dgObjects.ItemsSource = $null
} }
@@ -1047,6 +1228,34 @@ function Start-GraphPreImport
} }
} }
function Remove-GraphODataProperties
{
param($obj)
# Remove OData properties
foreach($odataProp in ($obj.PSObject.Properties | Where { $_.Name -like "*@*" }))
{
$removeProperties += $odataProp.Name
}
foreach($prop in $removeProperties)
{
Remove-Property $obj $prop
}
foreach($prop in ($obj.PSObject.Properties))
{
if($obj."$($prop.Name)"."@odata.type")
{
foreach($childObj in ($obj."$($prop.Name)"))
{
Remove-GraphODataProperties $childObj
}
}
}
}
function Get-GraphMetaData function Get-GraphMetaData
{ {
if(-not $global:metaDataXML) if(-not $global:metaDataXML)
@@ -1428,7 +1637,14 @@ function Start-GraphObjectExport
$script:exportRoot = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text") $script:exportRoot = Expand-FileName (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
Write-Log "Export root folder: $script:exportRoot" Write-Log "Export root folder: $script:exportRoot"
$global:AADObjectCache = $null if((Get-SettingValue "ClearAllObjectsFromCache"))
{
Invoke-GraphAuthenticationUpdated
}
else
{
$global:AADObjectCache = $null
}
foreach($item in $script:exportObjects) foreach($item in $script:exportObjects)
{ {
@@ -1725,6 +1941,20 @@ function Show-GraphImportForm
Add-XamlEvent $script:importForm "btnImportSelected" "add_click" { Add-XamlEvent $script:importForm "btnImportSelected" "add_click" {
Write-Status "Import objects" Write-Status "Import objects"
#Get-GraphDependencyDefaultObjects #Get-GraphDependencyDefaultObjects
$clearCacheValue = ?? ((Get-SettingValue "ClearCacheBeforeExportImport" "1") -as [int]) 1
if($clearCacheValue -band 8)
{
if((Get-SettingValue "ClearAllObjectsFromCache"))
{
Invoke-GraphAuthenticationUpdated
}
else
{
$global:AADObjectCache = $null
}
}
$allowUpdate = $true $allowUpdate = $true
$filesToImport = $global:dgObjectsToImport.ItemsSource | Where Selected -eq $true $filesToImport = $global:dgObjectsToImport.ItemsSource | Where Selected -eq $true
if($global:curObjectType.PreFilesImportCommand) if($global:curObjectType.PreFilesImportCommand)
@@ -1935,6 +2165,19 @@ function Start-GraphObjectImport
$tmpFolder = Expand-FileName (Get-XamlProperty $script:importForm "txtImportPath" "Text") $tmpFolder = Expand-FileName (Get-XamlProperty $script:importForm "txtImportPath" "Text")
Write-Log "Import root folder: $tmpFolder" Write-Log "Import root folder: $tmpFolder"
$clearCacheValue = ?? ((Get-SettingValue "ClearCacheBeforeExportImport" "1") -as [int]) 1
if($clearCacheValue -band 4)
{
if((Get-SettingValue "ClearAllObjectsFromCache"))
{
Invoke-GraphAuthenticationUpdated
}
else
{
$global:AADObjectCache = $null
}
}
$importedObjects = 0 $importedObjects = 0
$txtNameFilter = $global:txtImportNameFilter.Text.Trim() $txtNameFilter = $global:txtImportNameFilter.Text.Trim()
@@ -2001,7 +2244,7 @@ function Start-GraphObjectImport
ImportedObject = $importedObj ImportedObject = $importedObj
} }
} }
$arrImportedObjects = $importedObj $arrImportedObjects += $importedObj
$importedObjects++ $importedObjects++
$importedObjectsCurType++ $importedObjectsCurType++
@@ -2353,7 +2596,10 @@ function Reset-GraphObject
# Clone the object before removing properties # Clone the object before removing properties
$obj = $fileObj.Object | ConvertTo-Json -Depth 50 | ConvertFrom-Json $obj = $fileObj.Object | ConvertTo-Json -Depth 50 | ConvertFrom-Json
Start-GraphPreImport $obj $objectType Start-GraphPreImport $obj $objectType
Remove-Property $obj "Assignments" if ($global:cbImportType.SelectedValue -ne "replace_with_assignments"){
# will use the assignments from the file for "replace_with_assignments" type
Remove-Property $obj "Assignments"
}
Remove-Property $obj "isAssigned" Remove-Property $obj "isAssigned"
if($global:cbImportType.SelectedValue -eq "update") if($global:cbImportType.SelectedValue -eq "update")
@@ -2417,7 +2663,7 @@ function Reset-GraphObject
} }
return $true return $true
} }
elseif($global:cbImportType.SelectedValue -eq "replace") elseif($global:cbImportType.SelectedValue -in @("replace","replace_with_assignments"))
{ {
$replace = $true $replace = $true
$import = $true $import = $true
@@ -2466,8 +2712,13 @@ function Reset-GraphObject
} }
} }
} }
if ($global:cbImportType.SelectedValue -eq "replace")
Import-GraphObjectAssignment $newObj $objectType $curObject.Object.Assignments $fileObj.FileInfo.FullName -CopyAssignments | Out-Null {
Import-GraphObjectAssignment $newObj $objectType $curObject.Object.Assignments $fileObj.FileInfo.FullName -CopyAssignments | Out-Null
}
else {
Import-GraphObjectAssignment $newObj $objectType $obj.Assignments $file.FileInfo.FullName | Out-Null
}
if($delete) if($delete)
{ {
@@ -2942,17 +3193,7 @@ function Get-GraphMigrationObjectsFromFile
{ {
$groupName = $migTableGroupName $groupName = $migTableGroupName
Write-Log "No group object found for $groupName. Creating a cloud group with default settings" 2 Write-Log "No group object found for $groupName. Creating a cloud group with default settings" 2
$dateStr = ((Get-Date).ToString("yyMMddHHmmss")) $nickName = (New-Guid).Guid.SubString(0,10)
if(($groupName.Length + $dateStr.Length) -gt 64)
{
$nickName = $groupName.Substring(0,(64-$dateStr.Length))
}
else
{
$nickName = $groupName
}
$nickName = $nickName + $dateStr
$groupJson = @" $groupJson = @"
{ {
@@ -3143,6 +3384,19 @@ function Export-GraphObjects
$objectType = $global:curObjectType $objectType = $global:curObjectType
Write-Status "Export $($objectType.Title)" Write-Status "Export $($objectType.Title)"
$clearCacheValue = ?? ((Get-SettingValue "ClearCacheBeforeExportImport" "1") -as [int]) 1
if($clearCacheValue -band 2)
{
if((Get-SettingValue "ClearAllObjectsFromCache"))
{
Invoke-GraphAuthenticationUpdated
}
else
{
$global:AADObjectCache = $null
}
}
$script:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text") $script:ExportRoot = (Get-XamlProperty $script:exportForm "txtExportPath" "Text")
$folder = Get-GraphObjectFolder $objectType $script:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked") $folder = Get-GraphObjectFolder $objectType $script:ExportRoot (Get-XamlProperty $script:exportForm "chkAddObjectType" "IsChecked") (Get-XamlProperty $script:exportForm "chkAddCompanyName" "IsChecked")
@@ -3673,6 +3927,11 @@ function Import-GraphObject
{ {
$params.Add("AdditionalHeaders",$ret["AdditionalHeaders"]) $params.Add("AdditionalHeaders",$ret["AdditionalHeaders"])
} }
if($ret.ContainsKey("JSON"))
{
$obj = $ret["JSON"] | ConvertFrom-Json
}
} }
} }
@@ -3973,8 +4232,8 @@ function Show-GraphObjectInfo
return return
} }
# Save settings here... # Save settings here...
$nameProp = (?? $global:dgObjects.SelectedItem.Object.NameProperty "displayName") $nameProp = (?? $global:dgObjects.SelectedItem.ObjectType.NameProperty "displayName")
$idProp = (?? $global:dgObjects.SelectedItem.Object.IDProperty "id") $idProp = (?? $global:dgObjects.SelectedItem.ObjectType.IDProperty "id")
$updateObj = [PSCustomObject]@{ $updateObj = [PSCustomObject]@{
$idProp = $global:dgObjects.SelectedItem.Object."$idProp" $idProp = $global:dgObjects.SelectedItem.Object."$idProp"
@@ -4136,9 +4395,10 @@ function local:Add-ObjectColumnInfoClass
} }
$classDef = @" $classDef = @"
using System;
using System.ComponentModel; using System.ComponentModel;
public class ObjectColumnInfo : INotifyPropertyChanged public class ObjectColumnInfo : System.ComponentModel.INotifyPropertyChanged
{ {
public string Property { get { return _property; } set { _property = value; NotifyPropertyChanged("Property"); } } public string Property { get { return _property; } set { _property = value; NotifyPropertyChanged("Property"); } }
private string _property = null; private string _property = null;
@@ -4164,8 +4424,14 @@ function local:Add-ObjectColumnInfoClass
} }
"@ "@
[Reflection.Assembly]::LoadWithPartialName("System.ComponentModel") | Out-Null try {
Add-Type -TypeDefinition $classDef -IgnoreWarnings -ReferencedAssemblies @('System.ComponentModel') Add-Type -TypeDefinition $classDef -IgnoreWarnings #-ReferencedAssemblies @('System.ComponentModel')
}
catch
{
Write-LogError "Failed to add type ObjectColumnInfo" $_.Exception
}
} }
function Local:Show-ObjectDefaultColumnsSettings function Local:Show-ObjectDefaultColumnsSettings
@@ -4394,7 +4660,12 @@ function Save-GraphObjectToFile
{ {
param($obj, $fileName) param($obj, $fileName)
$json = $obj | ConvertTo-Json -Depth 50 if(((Get-SettingValue "SortJsonProperties") -eq $true)) {
$json = $obj | ConvertTo-JsonSortedGraph -Depth 50
}
else {
$json = $obj | ConvertTo-Json -Depth 50
}
if($global:Organization.Id) if($global:Organization.Id)
{ {
@@ -4490,3 +4761,141 @@ function Confirm-GraphMatchFilter
} }
return $true return $true
} }
function Invoke-SortJsonGraphObject {
param(
[Parameter(Mandatory)]
$InputObject
)
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IList]) {
$new = @()
foreach ($item in $InputObject) {
$new += Invoke-SortJsonGraphObject $item
}
return ,$new
}
if ($InputObject -is [System.Collections.IDictionary] -or
$InputObject -is [System.Management.Automation.PSCustomObject]) {
$props =
if ($InputObject -is [System.Collections.IDictionary]) {
$InputObject.Keys
} else {
$InputObject.PSObject.Properties.Name
}
$baseGroups = @{}
foreach ($p in $props) {
if ($p -match '^(.+?)@(.+)$') {
$base = $matches[1]
if (-not $baseGroups.ContainsKey($base)) {
$baseGroups[$base] = @{
Base = $null
Meta = New-Object System.Collections.ArrayList
}
}
[void]$baseGroups[$base].Meta.Add($p)
}
}
foreach ($p in $props) {
if ($baseGroups.ContainsKey($p)) {
$baseGroups[$p].Base = $p
}
}
$atProps = @() # starts with @
$hashProps = @() # starts with #
$normal = @() # everything else
foreach ($p in $props) {
if ($p.StartsWith('@')) {
$atProps += $p
continue
}
if ($p.StartsWith('#')) {
$hashProps += $p
continue
}
# If in a baseGroup, skip for now (added later)
if ($baseGroups.ContainsKey($p)) {
continue
}
$normal += $p
}
$atProps = $atProps | Sort-Object
$normal = $normal | Sort-Object
$hashProps = $hashProps | Sort-Object
$orderedNames = @()
$orderedNames += $atProps
foreach ($base in ($baseGroups.Keys | Sort-Object)) {
$meta = $baseGroups[$base].Meta | Sort-Object
foreach ($m in $meta) {
$orderedNames += $m
}
if ($null -ne $InputObject.$base) {
$orderedNames += $base
}
}
$orderedNames += $normal
$orderedNames += $hashProps
$result = [ordered]@{}
foreach ($p in $orderedNames) {
$value =
if ($InputObject -is [System.Collections.IDictionary]) {
$InputObject[$p]
} else {
$InputObject.$p
}
if($null -ne $value) {
$result[$p] = Invoke-SortJsonGraphObject $value
}
else {
$result[$p] = $null
}
if($InputObject.$p -is [Array] -and $result[$p] -isnot [Array]) {
if($result[$p] -eq $null) {
$result[$p] = @()
}
else {
$result[$p] = @($result[$p])
}
}
}
return [pscustomobject]$result
}
return $InputObject
}
function ConvertTo-JsonSortedGraph {
param(
[Parameter(ValueFromPipeline, Mandatory)]
$InputObject,
[int]$Depth = 50
)
$sorted = Invoke-SortJsonGraphObject $InputObject
return $sorted | ConvertTo-Json -Depth $Depth
}
+53 -1
View File
@@ -10,7 +10,6 @@ See GitHub repository [MSAL for .Net](https://github.com/AzureAD/microsoft-authe
MSAL uses OAuth2 to authenticate to an Application in Azure. This script has two applications pre-defined in Settings: MSAL uses OAuth2 to authenticate to an Application in Azure. This script has two applications pre-defined in Settings:
- Microsoft Intune PowerShell (d1ddf0e4-d672-4dae-b554-9d5bdfd93547)
- Microsoft Graph PowerShell (14d82eec-204b-4c2f-b7e8-296a70dab67e) - Microsoft Graph PowerShell (14d82eec-204b-4c2f-b7e8-296a70dab67e)
Microsoft Intune PowerShell is the same application as the Intune PowerShell module uses and this is the default application for the script. Microsoft Intune PowerShell is the same application as the Intune PowerShell module uses and this is the default application for the script.
@@ -21,6 +20,59 @@ The script will detect if the selected app is missing permissions and prompt for
A Custom application can be specified in Settings. This could theoretically be a custom created app in Azure. However, if an App is registered in Azure, it will be single tenant only. This can be used to backup an existing environment but the Azure App cannot be used to import data in another tenant. Use Enterprise Apps and Common/Organizations authority to allow access to multiple tenants. A Custom application can be specified in Settings. This could theoretically be a custom created app in Azure. However, if an App is registered in Azure, it will be single tenant only. This can be used to backup an existing environment but the Azure App cannot be used to import data in another tenant. Use Enterprise Apps and Common/Organizations authority to allow access to multiple tenants.
## Create Custom Application ##
Documentation by Microsoft: [Quickstart: Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)
Steps:
* Go to the Entra Portal
* Register a new App registration in Entra
Note Application Id
* Add Delegated permissions
* Microsoft Graph
For full support of the app requires:<br />
Application.Read.All<br />
Agreement.ReadWrite.All<br />
CloudPC.ReadWrite.All<br />
DeviceManagementApps.ReadWrite.All<br />
DeviceManagementConfiguration.ReadWrite.All<br />
DeviceManagementManagedDevices.ReadWrite.All<br />
DeviceManagementRBAC.ReadWrite.All<br />
DeviceManagementScripts.ReadWrite.All<br />
DeviceManagementServiceConfig.ReadWrite.All<br />
Organization.ReadWrite.All<br />
Policy.ReadWrite.ConditionalAccess<br /><br />
It will also need User.ReadWrite.All,Group.ReadWrite.All but you could set these to read only unless you will let the app create Groups.<br /><br />
**Note:** Change all **ReadWrite** to **Read** in the permissions above to create an Entra App with Read Only access.
* Grant permissions for the environment
* Go to Authentication
* Click **+ Add platform**
* Click on **Mobile and desktop applications**
* Check **https://login.microsoftonline.com/common/oauth2/nativeclient**<br />
msal value can also be used
* Start the Tool
* Go to Settings
* Change Application in Endpoint Manager/Intune section
* Set drop down to Empty. It will only use custom app if drop down is empty
* Specify App Id from the Entra App created earlier
* Specify Redirect URL to https://login.microsoftonline.com/common/oauth2/nativeclient<br />
This must match the setting in the Entra App.
* Save Settings
* Restart app
## Token ## Token
The MSAL authentication will create a token that is used when calling APIs in Microsoft Graph. This token is cached in an encrypted **msalcahce.bin3** file in the **%LOCALAPPDATA%\CloudAPIPowerShellManagement** folder. The file can only be decrypted by the same user. Caching the token can be disabled in Settings. The MSAL authentication will create a token that is used when calling APIs in Microsoft Graph. This token is cached in an encrypted **msalcahce.bin3** file in the **%LOCALAPPDATA%\CloudAPIPowerShellManagement** folder. The file can only be decrypted by the same user. Caching the token can be disabled in Settings.

Some files were not shown because too many files have changed in this diff Show More