To enroll your device install the free microsoft intune company portal app

The Company Portal provides access to corporate apps and resources from almost any network. Your company must already subscribe to Microsoft Intune, and your IT admin must set up your account before you can use this app.

Features:
• Enroll to access corporate resources
• Browse and install company apps
• View and manage all your enrolled devices
• View IT department contact information
• Change your work account password
• Unenroll or remotely wipe devices

Important: This app requires you to use your work account to enroll in Intune. Some functionality is unavailable in certain countries. If you have issues with this app or questions about its use (including your company’s privacy policy) contact your IT administrator and not Microsoft, your network operator, or your device manufacturer.

https://docs.microsoft.com/Intune/EndUser/using-your-android-device-with-intune

How to uninstall Company Portal:
Before you can uninstall Company Portal, you need to unenroll your device from Intune first. Here are the steps:

1) Follow these directions to unenroll: https://docs.microsoft.com/intune/enduser/unenroll-your-device-from-intune-android
2) Now, you can uninstall Company Portal like you would any other app

Use Intune Company Portal to enroll your Windows 10 device under your organization’s management. This article describes how to enroll devices with Windows 10 version 1607 and later, and Windows 10 version 1511 and earlier. Before you begin, make sure you verify the version on your device so that you can follow the correct steps.

The Microsoft 365 roadmap provides estimated release dates and descriptions for commercial features. All information is subject to change. As a feature or product becomes generally available, is cancelled or postponed, information will be removed from this website. The GA date on the Microsoft 365 roadmap indicates Targeted Release (as the start of General Availability rollout followed by General Availability) for those features that include Targeted Release.

Because of the popularity of my first blog post Deep dive Microsoft Intune Management Extension – PowerShell Scripts, I’ve decided to write a second post regarding Intune Management Extension to further explain some architecture behind this feature and upcoming question from the community. A deeper understanding helps to successful troubleshoot the feature.

Table of content for easy navigation

  • Details of the MSI deployment of the Intune Management Extension agent?
  • Be aware of the log files regarding sensitive data!
  • Getting content of scripts once they are uploaded to Intune?
  • What about return codes (exit codes) of PowerShell scripts?
  • Where can I find a helpful PowerShell script template to start with?
  • Script execution retry interval when failed?
  • Can we schedule scripts?
  • Integrated HealthCheck of Intune Management Extension agent?
  • User interaction and timeout

Details of the MSI deployment of the Intune Management Extension agent?

Please read the first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts, to get an understanding of the MSI install job.

The EnterpriseDesktopAppManagement CSP takes care of this task and delivers the MSI to the device and starts the execution. The CSP provides some helpful information in registry for troubleshooting.

In the registry at HKLM\SOFTWARE\Microsoft\EnterpriseDesktopAppManagement\<SID>\<MSI-ProductCode> you can find helpful information for troubleshooting:

To enroll your device install the free microsoft intune company portal app

Highlighted value names are described in detail here:

CurrentDownloadUrl: URL to the MSI install file.

EnforcementRetryCount: The number of times the download and installation operation will be retried before the installation will be marked as failed.

EnforcementRetryIndex: The current number of retry.

EnforcementRetryInterval: Amount of time, in minutes between retry operations.

EnforcementStartTime: Start time of enforcement.

EnforcementTimeout: Amount of time, in minutes that the installation process can run before the installer considers the installation may have failed and no longer monitors the installation operation.

LastError: Error after last execution.

Status: The Status can have the following values according to the EnterpriseDesktopAppManagement CSP documentation:

Value = Status
10 = Initialized
20 = Download In Progress
25 = Pending Download Retry
30 = Download Failed
40 = Download Completed
48 = Pending User Session
50 = Enforcement In Progress
55= Pending Enforcement Retry
60 = Enforcement Failed
70 = Enforcement Completed

In case of no sidecar agent on the device the status may indicate an error or it is still in progress of downloading. Try to figure out this status. Correlate the status with your device and environment. There may be a proxy issue?

According to the screenshot above the CSP will try it 3 times with a timeout of 10 min and then it will be marked as failed. Is there a retry after x days, I assume yes but I don’t have some documentation for it. As soon as I have more information I will update the article accordingly.

You might think what about the script execution retry interval when failed and how to enforce a retry, see section Script execution retry interval when failed? Also a very comprehensive article about MSI deployment with Intune can be found here: Support Tip: Troubleshooting MSI App deployments in Microsoft Intune

Be aware of the log files regarding sensitive data!

The following script below will create a local user account with a specified static password. It is a working script, but be aware that it should not be used in production! The whole script content will be logged to the IntuneManagementExtension.log file. There you will find the clear text static password as defined in the script. As an example I have copied and marked the particular log file entries below the script to show that. Disk encryption technologies like BitLocker are lowering the risks a bit, but even then this is not a concept to be used in production environments! An attacker can read the log files with standard user permissions and get the sensitive data. Without BitLocker encryption this can be done even offline!

Again: I do NOT recommend transferring sensitive data like passwords via this approach! I know it’s often done. There is a similar approach for on-prem AD which is often used. The GPO preferences for local user management tasks uses a simple xml file with passwords base64 encoded -> this is not secure! Please consider something that was build for that purpose. Admin account management should be done via LAPS or other third party. I know there is no equivalent solution like LAPS for a cloud only environment right now from Microsoft.

# Author: Oliver Kieselbach
# Date: 01/03/2018
# Description: Create a local user account.

# REMARK: DO NOT USE IN PRODUCTION, Password will not be unique and be visible in clear text in log file!

# The script is provided "AS IS" with no warranties.

Param([switch]$Is64Bit = $false)

Function Restart-As64BitProcess
{
If ([System.Environment]::Is64BitProcess) { return }
$Invocation = $($MyInvocation.PSCommandPath)
if ($Invocation -eq $null) { return }
$sysNativePath = $psHome.ToLower().Replace("syswow64", "sysnative")
Start-Process "$sysNativePath\powershell.exe" -ArgumentList "-ex bypass -file `"$Invocation`" -Is64Bit" -WindowStyle Hidden -Wait
}

if (!$Is64Bit) { Restart-As64BitProcess }
else
{
Start-Transcript -Path "$env:temp\CreateLocalUser.log"

$password = ConvertTo-SecureString "SecretP@ssw0rd!" -AsPlainText -Force
New-LocalUser "John" -AccountNeverExpires:$true -FullName "John Doe" -Password $password

Stop-Transcript
}

To demonstrate the problem with this approach, here is the corresponding log file part after script execution with the complete script and static password in clear text:

To enroll your device install the free microsoft intune company portal app

Getting content of scripts once they are uploaded to Intune?

The Intune Azure Portal does not provide any UI element to show the uploaded script again. Thanks to the GitHub repository Intune PowerShell Samples we do not script something by our own. We can use a script provided from there called DeviceManagementScripts_Get.ps1. It will get all uploaded scripts, including script content, and details from the Intune API via Microsoft Graph API.

Get it from here:
https://github.com/microsoftgraph/powershell-intune-samples/blob/master/DeviceConfiguration/DeviceManagementScripts_Get.ps1

Save it locally and run it with PowerShell and provide your Intune Administrator credentials when asked for:

To enroll your device install the free microsoft intune company portal app

UPDATE: see my blog post about Get back your Intune PowerShell Scripts

What about return codes (exit codes) of PowerShell scripts?

At the moment the Intune Management Extension will gather various results, but the Intune Azure portal does not show them in an UI element (if it will change in the future and we have something available, I will update the post accordingly). As for now scripts can be executed through the Intune agent and the Intune UI will show just the execution state success or failure. The status is related to successful agent execution, like no hash mismatch, no script content problem, and no error output… it does not reflect the script exit code.

Scripts like this, I called it “failscript.ps1” are handled as success at the moment:

[Environment]::Exit(-1)

See here the results in Intune Azure Portal:

To enroll your device install the free microsoft intune company portal app

Perhaps Intune will show us script exit codes in the UI sometime, then we could verify this easily with the failscript from above.

If we use Write-Error cmdlet in our scripts then Intune will pick up the error output. Here an example:

Write-Error -Message "Could not write regsitry value" -Category OperationStopped

This gives us a failed status in the monitoring section of the PowerShell scripts:

To enroll your device install the free microsoft intune company portal app

Where can I find a helpful PowerShell script template to start with?

I have made a simple script template which:

  1. Enforces execution in x64 PowerShell (restart of PowerShell as x64 process)
  2. Generates a log file in C:\Windows\temp when run in system context
    or %LocalAppData%\temp when run in user context
  3. Has exit code handling (exit code is even gathered when restarted as x64 process)
  4. Uses Write-Error to signal Intune a failed execution and makes sure we have reporting reflecting our script execution success (standard error is even gathered when restarted as x64 process)

For ongoing maintenance it is provided via GitHub Gist:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters

<#Version: 1.1Author: Oliver KieselbachScript: IntunePSTemplate.ps1Description:Intune Management Extension - PowerShell script template with logging,error codes, standard error output handling and x64 PowerShell execution.Release notes:Version 1.0: Original published version.Version 1.1: Added standard error output handling.The script is provided "AS IS" with no warranties.#>$exitCode = 0if (![System.Environment]::Is64BitProcess){# start new PowerShell as x64 bit process, wait for it and gather exit code and standard error output$sysNativePowerShell = "$($PSHOME.ToLower().Replace("syswow64", "sysnative"))\powershell.exe"$pinfo = New-Object System.Diagnostics.ProcessStartInfo$pinfo.FileName = $sysNativePowerShell$pinfo.Arguments = "-ex bypass -file `"$PSCommandPath`""$pinfo.RedirectStandardError = $true$pinfo.RedirectStandardOutput = $true$pinfo.CreateNoWindow = $true$pinfo.UseShellExecute = $false$p = New-Object System.Diagnostics.Process$p.StartInfo = $pinfo$p.Start() | Out-Null$exitCode = $p.ExitCode$stderr = $p.StandardError.ReadToEnd()if ($stderr) { Write-Error -Message $stderr }}else{# start logging to TEMP in file "scriptname".logStart-Transcript -Path "$env:TEMP\$($(Split-Path $PSCommandPath -Leaf).ToLower().Replace(".ps1",".log"))" | Out-Null# === variant 1: use try/catch with ErrorAction stop -> use write-error to signal Intune failed execution# example:# try# {# Set-ItemProperty ... -ErrorAction Stop# }# catch# {# Write-Error -Message "Could not write regsitry value" -Category OperationStopped# $exitCode = -1# }# === variant 2: ErrorVariable and check error variable -> use write-error to signal Intune failed execution# example:# Start-Process ... -ErrorVariable err -ErrorAction SilentlyContinue# if ($err)# {# Write-Error -Message "Could not write regsitry value" -Category OperationStopped# $exitCode = -1# }Stop-Transcript | Out-Null}exit $exitCode

view raw IntunePSTemplate.ps1 hosted with ❤ by GitHub

Script execution retry interval when failed?

The PowerShell scripts are executed via agent on the target device. If an execution fails, the agent tries to run the script again during next check-in. Current check-in interval is every 60 minutes. This procedure is limited to 3 attempts!

This is tracked in registry at:

HKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Policies\UserGUID\ScriptGUID

The DownloadCount also means execution count and the result is tracked as Success or Failed.

To enroll your device install the free microsoft intune company portal app

If we change the run as account (user/system), signature check or script content, the DownloadCount will be reset, and the agent will try another 3 attempts to execute the script.

If a script should be enforced to run again, we can simply reset DownloadCount and ErrorCode to 0 and set Result and ResultDetails to nothing (empty string). After this we just restart the Microsoft Intune Management Extension Service (IntuneManagementExtension) and the script will rerun again on this device.

Can we schedule scripts?

No we do not have a run schedule at the moment. For example the agent does not execute the script every x hours. The agent checks every 60 minutes for new policies in the backend – during this no re-run of scripts occurs once a script is successful executed. If scheduling of scripts is needed I suggest to register the script as a scheduled tasks via PS commands. That’s the only way at the moment (as soon as we have something available for scheduling I will update the post accordingly).

Below a script to copy the scheduled script to a certain folder like C:\ProgramData\CustomScripts\myScript.ps1 and then register a scheduled task to run it periodically:

# Author: Oliver Kieselbach
# Date: 01/31/2018
# Description: install ps script and register scheduled task

# The script is provided "AS IS" with no warranties.

# define your PS script here
$content = @"
Out-File -FilePath "C:\Windows\Temp\test.txt" -Encoding unicode -Force -InputObject "Hello World!"
"@

# create custom folder and write PS script
$path = $(Join-Path $env:ProgramData CustomScripts)
if (!(Test-Path $path))
{
New-Item -Path $path -ItemType Directory -Force -Confirm:$false
}
Out-File -FilePath $(Join-Path $env:ProgramData CustomScripts\myScript.ps1) -Encoding unicode -Force -InputObject $content -Confirm:$false

# register script as scheduled task
$Time = New-ScheduledTaskTrigger -At 12:00 -Daily
$User = "SYSTEM"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ex bypass -file `"C:\ProgramData\CustomScripts\myScript.ps1`""
Register-ScheduledTask -TaskName "RunCustomScriptDaily" -Trigger $Time -User $User -Action $Action -Force

Here some documentation regarding PowerShell and scheduled tasks:
https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/register-scheduledtask?view=win10-ps

But you need to think about a strategy how to track all this or how to modify in the future. Once set you may want to have a modification script to change schedules or even delete it from the device again.

Integrated HealthCheck of Intune Management Extension agent?

The Intune Management Extension creates a scheduled task which will run a Health Check once a day.

To enroll your device install the free microsoft intune company portal app

If familiar with ConfigMgr and the ConfigMgr agent, there we have the same concept. The health check involves 4 files:

ClientHealthEval.exe and ClientHealthEval.exe.config: The binary which runs the health check.

HealthCheck.xml: The xml with all rules to run to perform the health check.

HealthReport.json: The json report with results of the rules defined by the xml.

The tests are defined in the xml file to check the agent registered service, startup type, service status and memory usage.

User interaction and timeout?

When using a scripts with the typical user interaction (like shown as an example in my first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts), be advised that this script is getting executed and showing a dialog which blocks the script from finishing, until the user interacts with the dialog and then let the script finish. This can lead to timeouts and then scripts are getting marked as failed even when successfully ran.

The current default script timeout is 30 minutes for execution which is currently not adjustable.

PowerShell scripts execution without user logon?

Since 22th of October the end users are no longer required to be logged in on the device to execute PowerShell scripts.