### FILE: scripts/Detect-CompanyPortalRegistration.ps1 <# .SYNOPSIS Proactive Remediation DETECTION script for Company Portal AppX registration state on Windows 24H2. .DESCRIPTION Runs as SYSTEM context under Intune Proactive Remediations. Validates whether Microsoft.CompanyPortal is both provisioned at the machine level AND registered for the currently logged-on user profile(s). 24H2 in-place feature updates can leave the package binaries provisioned while dropping the per-user AppX registration record, causing Company Portal to vanish from Start Menu/taskbar. Exit 0 = Healthy (no remediation needed) Exit 1 = Remediation required (triggers paired Remediate script) .EXAMPLE Deploy under Devices > Scripts and remediations > Create. Run this script using the logged-on credentials: No (runs as SYSTEM) Pair with Remediate-CompanyPortalRegistration.ps1 .NOTES Author: Souhaiel Morhag Company: MSEndpoint.com Blog: https://msendpoint.com Academy: https://app.msendpoint.com/academy LinkedIn: https://linkedin.com/in/souhaiel-morhag GitHub: https://github.com/Msendpoint License: MIT #> $ErrorActionPreference = 'Stop' $logPath = "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs\CP-Detect.log" $packageName = 'Microsoft.CompanyPortal' function Write-Log { param([string]$Message) try { $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content -Path $logPath -Value "[$ts] $Message" -ErrorAction SilentlyContinue } catch { # Logging failures should never break detection logic } } try { Write-Log "=== Detection run started ===" # Step 1: Confirm the package is provisioned at the machine level $provisioned = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq $packageName } if (-not $provisioned) { Write-Log "FAIL: $packageName not found in provisioned packages. Package itself may be missing - requires full Intune redeploy, not re-registration." exit 1 } Write-Log "OK: $packageName found in provisioned packages (Version: $($provisioned.Version))" # Step 2: Check per-user registration across all profiles $userPkg = Get-AppxPackage -AllUsers -Name $packageName -ErrorAction SilentlyContinue if (-not $userPkg) { Write-Log "FAIL: No per-user registration found for $packageName across any profile. Remediation required." exit 1 } # Step 3: Validate InstallLocation and Status for each registered instance $unhealthyInstances = $userPkg | Where-Object { [string]::IsNullOrWhiteSpace($_.InstallLocation) -or $_.Status -ne 'Ok' } if ($unhealthyInstances) { foreach ($instance in $unhealthyInstances) { Write-Log "FAIL: PackageFullName '$($instance.PackageFullName)' has Status '$($instance.Status)' or empty InstallLocation." } exit 1 } Write-Log "OK: $packageName is provisioned and registered correctly for all detected user profiles." Write-Log "=== Detection run completed: HEALTHY ===" exit 0 } catch { Write-Log "ERROR: Unhandled exception during detection - $($_.Exception.Message)" # Fail safe: treat unexpected errors as remediation-required so the self-healing loop can attempt a fix exit 1 } ### FILE: scripts/Remediate-CompanyPortalRegistration.ps1 <# .SYNOPSIS Proactive Remediation REMEDIATION script that re-registers Company Portal's AppX package for all users. .DESCRIPTION Paired with Detect-CompanyPortalRegistration.ps1. Runs as SYSTEM context under Intune Proactive Remediations. Locates the provisioned Company Portal AppXManifest.xml on disk and re-registers it for every local user profile, closing the per-user registration gap left behind by 24H2 in-place feature update servicing. If the provisioned package itself is missing (not just the per-user registration), this script logs the condition and exits non-zero so the failure surfaces for a full Intune app redeploy instead of masking a deeper problem. .EXAMPLE Deploy under Devices > Scripts and remediations > Create. Run this script using the logged-on credentials: No (runs as SYSTEM) Pair with Detect-CompanyPortalRegistration.ps1 .NOTES Author: Souhaiel Morhag Company: MSEndpoint.com Blog: https://msendpoint.com Academy: https://app.msendpoint.com/academy LinkedIn: https://linkedin.com/in/souhaiel-morhag GitHub: https://github.com/Msendpoint License: MIT #> $ErrorActionPreference = 'Stop' $logPath = "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs\CP-Remediate.log" $packageName = 'Microsoft.CompanyPortal' function Write-Log { param([string]$Message) try { $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content -Path $logPath -Value "[$ts] $Message" -ErrorAction SilentlyContinue } catch { # Logging failures should never break remediation logic } } try { Write-Log "=== Remediation run started ===" $provisioned = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq $packageName } if (-not $provisioned) { Write-Log "CRITICAL: $packageName is not provisioned on this device. Re-registration cannot fix a missing package. Escalating to full Intune redeploy." exit 1 } $installLocation = $provisioned.InstallLocation $manifestPath = Join-Path -Path $installLocation -ChildPath 'AppXManifest.xml' if (-not (Test-Path -Path $manifestPath)) { Write-Log "CRITICAL: AppXManifest.xml not found at expected path '$manifestPath'. Package binaries may be corrupted or removed. Escalating to full Intune redeploy." exit 1 }