Compare commits

..
2 Commits
Author SHA1 Message Date
Mikael Karlsson 5bb84c8561 Merge Development with Master 2026-05-12 19:50:19 +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
16 changed files with 50 additions and 730 deletions
-39
View File
@@ -1,39 +0,0 @@
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
@@ -1,64 +0,0 @@
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
@@ -1,4 +0,0 @@
# 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
@@ -1,116 +0,0 @@
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
@@ -1,154 +0,0 @@
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
@@ -1,17 +0,0 @@
# 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
@@ -1,71 +0,0 @@
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
@@ -1,47 +0,0 @@
<!--
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.
-->
-2
View File
@@ -11,5 +11,3 @@
Extensions_dev/ Extensions_dev/
.gitignore .gitignore
CloudAPIPowerShellManagement.log CloudAPIPowerShellManagement.log
AGENTS.md
CLAUDE.md
+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.11.0' ModuleVersion = '3.10.3'
# Supported PSEditions # Supported PSEditions
# CompatiblePSEditions = @() # CompatiblePSEditions = @()
+35 -44
View File
@@ -660,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" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true }) Add-XamlEvent $script:dlgAbout "linkSource" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.Uri.AbsoluteUri); $_.Handled = $true })
Show-ModalForm "About" $script:dlgAbout Show-ModalForm "About" $script:dlgAbout
} }
@@ -677,8 +677,6 @@ 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
{ {
@@ -699,11 +697,7 @@ function Show-UpdatesDialog
$params.Add("UseBasicParsing", $true) $params.Add("UseBasicParsing", $true)
} }
# The notes at the newest 3.x release tag, never at the default branch: that $content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/contents/ReleaseNotes.md" @params
# 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)))
@@ -728,37 +722,6 @@ 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)
@@ -777,7 +740,35 @@ function Get-IsLatestVersion
$params.Add("UseBasicParsing", $true) $params.Add("UseBasicParsing", $true)
} }
$gitHubVer = Get-LatestGitHubVersion $params $content = Invoke-RestMethod "https://api.github.com/repos/Micke-K/IntuneManagement/releases/latest" @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)
{ {
@@ -2494,9 +2485,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" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true }) Add-XamlEvent $script:welcomeForm "gitHubLink" "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 "licenseLink" "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 "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.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)
@@ -2531,7 +2522,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" ({ Start-Process $_.Uri.AbsoluteUri; $_.Handled = $true }) Add-XamlEvent $script:oldAzureAppForm "addCustomApp" "Add_RequestNavigate" ({ [System.Diagnostics.Process]::Start($_.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) {
+2 -2
View File
@@ -2906,7 +2906,7 @@ function Start-PostExportApplications
} }
else else
{ {
Write-Log "Could not find encryption file" Write-Log "Cound not find encryption file"
} }
} }
} }
@@ -2966,7 +2966,7 @@ function Add-ScriptExportApplications
function Start-PostGetApplications { function Start-PostGetApplications {
param($obj, $objectType) param($obj, $objectType)
if(($obj.Object.dependentAppCount -as [int]) -gt 0 -or ($obj.Object.supersededAppCount -as [int]) -gt 0) { if($obj.Object.dependentAppCount -is [Int] -and ($obj.Object.dependentAppCount -gt 0 -or $obj.Object.supersededAppCount -gt 0)) {
$relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value $relationships = (Invoke-GraphRequest -Url "/deviceAppManagement/mobileApps/$($obj.Id)/relationships?`$filter=targetType%20eq%20microsoft.graph.mobileAppRelationshipType%27child%27").value
$dependencyApps = @() $dependencyApps = @()
$supersededApps = @() $supersededApps = @()
+3 -55
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.9' '3.9.8a'
} }
$global:msalAuthenticator = $null $global:msalAuthenticator = $null
@@ -137,28 +137,12 @@ function Invoke-InitializeModule
Description = "Use WAM for enhanced login methods" Description = "Use WAM for enhanced login methods"
}) "MSAL" }) "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" $script:MSALUseWAM = Get-SettingValue "UseWAM"
if($script:MSALUseWAM -and $PSVersionTable.PSVersion.Major -lt 7) { if($script:MSALUseWAM -and $PSVersionTable.PSVersion.Major -lt 7) {
Write-Log "WAM is only supported in PowerShell 7 and later. Disabling WAM" 2 Write-Log "WAM is only supported in PowerShell 7 and later. Disabling WAM" 2
$script:MSALUseWAM = $false $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
} }
@@ -947,19 +931,7 @@ function Get-MSALApp
[void]$appBuilder.WithAuthority($authority) [void]$appBuilder.WithAuthority($authority)
# System Browser mode: MSAL's system-browser flow only accepts loopback redirects, if($appInfo.RedirectUri) { [void]$appBuilder.WithRedirectUri($appInfo.RedirectUri) }
# 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)
@@ -1319,15 +1291,6 @@ 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")
{ {
@@ -1383,17 +1346,7 @@ 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
@@ -1414,11 +1367,6 @@ 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
} }
-6
View File
@@ -1,11 +1,5 @@
# IntuneManagement with PowerShell and WPF UI # IntuneManagement with PowerShell and WPF UI
> **Version 4.0 is in beta.** A full rewrite that also runs on macOS and Linux,
> with every operation available as a PowerShell command for automation.
> Try it from the [`v4` branch](../../tree/v4) or the [4.0.0-beta1 pre-release](../../releases/tag/4.0.0-beta1).
> Version 3 stays here and stays supported until 4.0 is final.
> Report version 4 problems with the *Bug report (version 4.0 beta)* form.
<p align="center"> <p align="center">
<a href="https://twitter.com/Micke_K_72"> <a href="https://twitter.com/Micke_K_72">
<img src="https://img.shields.io/twitter/follow/Micke_K_72.svg?style=social" target="_blank" /> <img src="https://img.shields.io/twitter/follow/Micke_K_72.svg?style=social" target="_blank" />
-32
View File
@@ -1,36 +1,4 @@
# Release Notes # Release Notes
## About version 4
Version 4.0 is in beta on the `v4` branch ([4.0.0-beta1](https://github.com/Micke-K/IntuneManagement/releases/tag/4.0.0-beta1)). It is a rewrite: a single PowerShell module
with `IM`-prefixed commands, an Avalonia UI that runs on Windows, macOS and Linux, and a
public automation API. Exports made with 3.x import into 4.0. Version 3 stays supported
here until 4.0 is final. From 3.11.0 the update check only offers 3.x releases; older
3.x installations will be offered 4.0.0 once it is published as a final release.
## 3.11.0 - 2026-09-23
**New features**
- **Sign in with the system browser**<br />
Interactive sign-in can run in your default browser instead of the embedded window,
which is where passkeys, security keys and other phishing-resistant methods work.
Turn on **Use system browser for login** in Settings.<br />
Based on [Issue 435](https://github.com/Micke-K/IntuneManagement/issues/435)
and [Discussion 425](https://github.com/Micke-K/IntuneManagement/discussions/425)<br />
**Fixes**
- Links to GitHub in the About, Updates and Welcome dialogs did not open the browser<br />
Based on [Issue 428](https://github.com/Micke-K/IntuneManagement/issues/428)<br />
- Silent bulk compare failed with an `op_Addition` error and wrote no result CSV when
using the **Exported Files with Intune Objects (Id)** provider<br />
[PR 429](https://github.com/Micke-K/IntuneManagement/pull/429) by McKenzieCo<br />
- Typo in the missing-permissions message<br />
[PR 424](https://github.com/Micke-K/IntuneManagement/pull/424) by BuggyAl<br />
- The update check only offers 3.x releases and reads the release notes of the newest
3.x release, so a version 4 release is never offered to a version 3 installation.<br />
## 3.10.3 - 2026-05-11 ## 3.10.3 - 2026-05-11
**Fixes** **Fixes**
-67
View File
@@ -1,67 +0,0 @@
# Security Policy
## Supported versions
| Version | Branch | Status |
|---|---|---|
| 4.0 beta | `v4` | Pre-release. Fixes go here. |
| 3.x | default branch | Supported until 4.0 leaves beta. Security fixes only after that. |
| 2.x and earlier | - | Not supported. |
## Reporting a vulnerability
**Do not open a public issue for a security problem.**
Use GitHub's private vulnerability reporting: go to the **Security** tab of this
repository and choose **Report a vulnerability**. That opens a private thread
visible only to the maintainer, and it works even though this repository has no
public contact address.
If that is unavailable to you, contact the maintainer through the link in the
repository profile and ask for a private channel before sending any detail.
### What to include
The more of this you can provide, the faster it can be confirmed:
- The version (`4.0.0-beta1`, `3.10.3`, ...) and how you installed it.
- PowerShell edition and version, and the operating system.
- What an attacker can do, not only what looks wrong.
- Steps to reproduce, ideally against a lab tenant.
- Whether it needs an already signed-in session, and what permissions that
session holds.
**Never include real tenant identifiers, access tokens, client secrets,
certificates or exported policy files from a production tenant.** Redact them, or
reproduce against a lab tenant.
### What to expect
This is a single-maintainer project worked on outside business hours. An
acknowledgement usually takes a few days. A fix ships in the next release for
the affected branch, and the release notes credit the reporter unless you ask
otherwise.
## Scope
This is an administrative client that runs on your own machine with credentials
you supply. Reports that are in scope include:
- Credentials, tokens or secrets written somewhere they should not be, or kept
in memory or on disk longer than needed.
- A path where the application sends tenant data anywhere other than the Microsoft
cloud endpoint it is signed in to.
- Code execution from data the application reads: an exported policy file, an
ADMX file, a documentation template or an imported settings file.
- Anything that causes an operation to run against a different tenant than the
one selected.
The following are **not** vulnerabilities in this project:
- An account having more permission in Microsoft Intune than you expected. That
is tenant configuration, not this application.
- Anything requiring an attacker who already controls the machine or the signed-in
session. At that point they can use the Microsoft Graph API directly.
- Missing hardening that Microsoft Entra or Intune is responsible for, such as
token lifetime or conditional access.
- Results from a scanner with no demonstrated impact.