Intune Client-Side Logs in Windows 10

Note to self (and anyone interested!) about the client-side location of logs and management components of Intune on a Windows 10 device.

Diagnostic Report

A diagnostic report can be generated client-side from Settings > Access Work and School > Connected to <Tenant>’s Azure AD > Info > Create Report

The report will be saved to:

C:\Users\Public\Public Documents\MDMDiagnostics\MDMDiagReport.html

Intune Management Extension

Information on the parameters for the IME can be found in the registry:

HKLM:\Software\Microsoft\EnterpriseDesktopAppManagement\<SID>\MSI\<ProductCode>

The MSI itself can be found here, together with an installer log:

C:\Windows\System32\config\systemprofile\AppData\Local\mdm

Note: if you disconnect a device from Azure AD and rejoin it again, you will need to reinstall the IME as it will have a different device identifier.

IME logs can be found here:

C:\ProgramData\Microsoft\IntuneManagementExtension\Logs

The logs are:

  • AgentExecutor
  • ClientHealth
  • IntuneManagementExtension

Script Execution

When a PowerShell script is run on the client from Intune, the scripts and the script output will be stored here, but only until execution is complete:

C:\Program files (x86)\Microsoft Intune Management Extension\Policies\Scripts

C:\Program files (x86)\Microsoft Intune Management Extension\Policies\Results

A transcript of the script execution can be found underneath C:_showmewindows (a hidden folder)

The full content of the script will also be logged in the IntuneManagementExtension.log (be careful of sensitive data in scripts!)

The error code and result output of the script can also be found in the registry:

HKLM:\Software\Microsoft\IntuneManagementExtension\Policies\<UserGUID>\<ScriptGUID>

Event Logs

There are a couple of MDM event logs which can be found here:

Applications and Services Logs > Microsoft > Windows > DeviceManagement-Enterprise-Diagnostics-Provider

Services

The IME runs as a service called “Microsoft Intune Management Extension”. You can restart this to force a check for new policies.

Scheduled Task

The IME runs a health evaluation every day as a scheduled task, and logs the results in the ClientHealth.log:

Microsoft > Intune > Intune Management Extension Health Evaluation

If you know of any other log locations, please let me know!

Lots of great info on the IME by Oliver Kieselbach here and here.

Create a Custom Splash Screen for a Windows 10 In-Place Upgrade

A while back I wrote a blog with some scripts that can be used to improve the user experience in a Windows 10 in-place upgrade. The solution included a simple splash screen that runs at the beginning of the upgrade to block the screen to the user and discourage interaction with the computer during the online phase of the upgrade. Since then, I made some improvements to the screen and styled it to look more like the built-in Windows update experience in Windows 10. Using this splash screen not only discourages computer interaction during the upgrade, but also creates a consistent user experience throughout the upgrade process, for a user-initiated upgrade.

The updated screen contains an array of text sentences that you can customise as you wish. Here is an example of what it could look like:

The splash screen is not completely foolproof in that it is still possible to use certain key combinations, like ctrl-alt-del and alt-tab etc, but the mouse cursor is hidden and mouse buttons will do nothing. The intention is simply to discourage the user from using the computer during the online phase. If the computer is locked, it will display the splash screen again when unlocked. If you wish to block user interaction completely, you might consider a more hardcore approach like this or this.

To use the splash screen, download all the files in my GitHub repository here (including the bin directory). Create a standard package in ConfigMgr containing the files (no program needed) and distribute. Then add a Run PowerShell Script step in the beginning of your in-place upgrade task sequence that looks like the following (reference the package you created):

ts

Once the splash screen has been displayed, the task sequence will move on to the next step – the screen will not block the task sequence.

How does it work?

The Invoke-PSScriptAsUser.ps1 simple calls the Show-OSUpgradeBackground.ps1 and runs it in the context of the currently logged-on user so that the splash screen will be visible to the user (task sequences run in SYSTEM context so this is necessary).

The Show-OSUpgradeBackground.ps1 determines your active screens, creates a runspace for each that calls PowerShell.exe and runs the Create-FullScreenBackground.ps1 for each screen.

The Create-FullScreenBackground.ps1  does the main work of displaying the splash screen. It will hide the task bar, hide the mouse cursor and display a full screen window in the Windows 10 update style. I’ve used the excellent MahApps toolkit to create the progress ring. The text displayed in the screen can be defined by placing short sentences in the $TextArray variable. The dispatcher timer will cycle through each of the these every 10 seconds (or whatever value you set) ending with a final sentence “Windows 10 Upgrade in Progress” which will stay on the screen until the computer is restarted into the next phase of the upgrade.

You can test the splash screen before deploying it simply by running the Show-OSUpgradeBackground.ps1 script.

Remember to deselect the option Show task sequence progress in the task sequence deployment to avoid having the task sequence UI show up on top of the window.

Create Disk Usage Reports with PowerShell and WizTree

Recently I discovered a neat little utility called WizTree, which can be used to report on space used by files and folders on a drive. There are many utilities out there that can do that, but this one supports running on the command line which makes it very useful for scripting scenarios. It also works extremely quickly because it uses the Master File Table on disk instead of the slower Windows / .Net methods.

I wanted to create a disk usage report for systems that have less than 20GB of free space – the recommended minimum for doing a Windows 10 in-place upgrade – so that I can easily review it and identify files / folders that could potentially be deleted to free space on the disk. I wanted to script it so that it can be run in the background and deployed via ConfigMgr, and the resulting reports copied to a server share for review.

The following script does just that.

First, it runs WizTree on the command line and generates two CSV reports, one each for all files and folders on the drive. Next, since the generated CSV files contain sizes in bytes, the script imports the CSVs, converts the size data to include KB, MB and GB, then outputs to 2 new CSV files.

The script then generates 2 custom HTML reports that contain a list of the largest 100 files and folders, sorted by size.

Next it generates an HTML summary report that shows visually how much space is used on the disk and tells you how much space you need to free up to drop under the minimum 20GB-free limit.

Finally, it copies those reports to a server share, which will look like this:

fs

The Disk Usage Summary report will look something like this:

dus

And here’s a snippet from the large directories and files reports:

ld

lf

There are also CSV reports which contain the entire list of files and directories on the drive:

csv

To use the script, simply download the WizTree Portable app, extract the WizTree64.exe and place it in the same location as the script (assuming 64-bit OS).  Set the run location in the script (ie $PSScriptRoot if calling the script, or the directory location if running in the ISE), the temporary location where it can create files, and the server share where you want to copy the reports to. Then just run the script in admin context.

PowerShell One-liner to Extract a Windows 10 Upgrade Error Code

Short post – here’s a PowerShell one-liner that will extract the upgrade code from the setupact.log generated by a Windows 10 upgrade. It includes both the result code and the extend code. You could include this in an in-place upgrade task sequence with ConfigMgr to stamp the code to the registry, or WMI, or create a task sequence variable etc.


(Get-Content -ReadCount 0 -Path "$env:SystemDrive\`$Windows.~BT\Sources\Panther\setupact.log" |
    Out-String -Stream |
    Select-String -SimpleMatch "MOUPG  SetupHost: Reporting error event").ToString().Split('>')[1].Replace('[','').Replace(']','').Trim()

Here’s an example containing the code for happiness, 0xC1900210, 0x5001B 🙂

errorcode

 

Find Windows 10 Upgrade Blockers with PowerShell

This morning I saw a cool post from Gary Blok about automatically capturing hard blockers in a Windows 10 In-Place Upgrade task sequence. It inspired me to look a bit further at that, and I came up with the following PowerShell code which will search all the compatibility xml files created by Windows 10 setup and look for any hard blockers. These will then be reported either in the console, or you can write them to file where you can copy them to a central location together with your SetupDiag files, or you could stamp the info to the registry or a task sequence variable as Gary describes in his blog post. You could also simply run the script against an online remote computer using Invoke-Command.

The script is not the one-liner that Gary likes, so to use in a task sequence you’ll need to wrap it in a package and call it.

The console output looks like this:

HardBlock

You should remove the FileAge property if using it in a task sequence as that’s a real-time value and is a quick indicator of when the blocker was reported.

If you use my solution here for improving the user experience in an IPU, you could also report this info to the end user by adding a script using my New-WPFMessageBox function, something like this…


$Stack = New-Object System.Windows.Controls.StackPanel
$Stack.Orientation = "Vertical"

$TextBox = New-Object System.Windows.Controls.TextBox
$TextBox.BorderThickness = 0
$TextBox.Margin = 5
$TextBox.FontSize = 14
$TextBox.FontWeight = "Bold"
$TextBox.Text = "The following hard blocks were found that prevent Windows 10 from upgrading:"

$Stack.AddChild($TextBox)

Foreach ($Blocker in $Blockers)
{
    $TextBox = New-Object System.Windows.Controls.TextBox
    $TextBox.BorderThickness = 0
    $TextBox.Margin = 5
    $TextBox.FontSize = 14
    $TextBox.Foreground = "Blue"
    $TextBox.Text = "$($Blocker.Title): $($Blocker.Message)"
    $Stack.AddChild($TextBox)
}

$TextBox = New-Object System.Windows.Controls.TextBox
$TextBox.BorderThickness = 0
$TextBox.Margin = 5
$TextBox.FontSize = 14
$TextBox.Text = "Please contact the Helpdesk for assistance with this issue."

$Stack.AddChild($TextBox)

New-WPFMessageBox -Title "Windows 10 Upgrade Hard Block" -Content $Stack -TitleBackground Red -TitleTextForeground White -TitleFontSize 18

…which creates a message box like this:

wpf

Thanks to Gary and Keith Garner for the inspiration here!

Fix Http 500.19 Error after Removing WSUS

This post is more of a ‘note to self’ for troubleshooting IIS errors.

Recently I decided to remove the WSUS role from an SCCM distribution point as it was previously being used for patching during OSD, but now we patch only the reference image instead. After removing the WSUS role, I also did some cleanup including deleting the WSUS_Updates directory, the %Program Files%\Update Services directory and removing the WsusPool website and application pool from IIS.

After that, clients using that distribution point failed to get content for packages, returning an Http 500 error:

smsts

Checking the IIS log on the distribution point I found the following corresponding entry:

iis

The error code is 500.19 which translates to ‘Internal Server Error / Configuration data is invalid‘ and is documented in more detail in this Microsoft article. A further clue is found in the 126 windows error code, which translates to ‘The specified module could not be found‘.

Browsing to the website directly, ie http://localhost/SMS_DP_SMSPKG$, gave the following information:

siteerror

The error code 0x8007007e is the same as the windows error code 126 and also means ‘The specified module could not be found”. The module referenced in the error is the DynamicCompressionModule.

To get more detailed information on the error, I decided to enable Failed Request Tracing in IIS and log the 500.19 error. The process for enabling and using Failed Request Tracing is nicely summarised here as well as documented by Microsoft here. Using that, I found that a couple of modules were being referenced that were no longer present.

ftrerror

Following a hint from here, I checked the applicationHost.config file and found a reference to a dll in the %Program Files%\Update Services directory that was installed with WSUS and that I deleted after removing the WSUS role:


<scheme name="xpress" doStaticCompression="false" doDynamicCompression="true" dll="C:\Program Files\Update Services\WebServices\suscomp.dll" staticCompressionLevel="10" dynamicCompressionLevel="0" />

To remove the reference, I ran the following command as admin:


%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-[name='xpress']

You can find more info on IIS modules and how to add/remove/disable/enable here.

After removing the reference to the xpress schema and restarting the W3SVC service, everything was back to normal 🙂

Create Interactive Charts with WPF and PowerShell

So I’m not a big Twitter fan, but I do admit – as an IT professional you can find a lot of useful and pertinent information there. One example was this morning when I happened to notice a tweet from Microsoft about their opensource projects on Github. After a quick perusal, I happened across an interesting project called Interactive Data Display for WPF. According to its description:

Interactive Data Display for WPF is a set of controls for adding interactive visualization of dynamic data to your application. It allows to create line graphs, bubble charts, heat maps and other complex 2D plots which are very common in scientific software. Interactive Data Display for WPF integrates well with Bing Maps control to show data on a geographic map in latitude/longitude coordinates. The controls can also be operated programmatically.

There are some nice-looking chart examples there such as:

sinline

markers

barchart (1)

Since there are no native charting controls in WPF this was of interest, so I fired up my PowerShell ISE and tried to get this working.

I created the following simple example using a bar chart. You can change the X or Y values then click Plot to update the chart.

Chart

The nice thing with this control is that it’s interactive – you can scroll the mouse wheel to zoom in and out, as well as move the axis left and right, and double-click to re-center.

barchartinteractive

Here’s the POSH code for the example:

There are a number of dependency libraries that the script will download for you, or you can also install them via the NuGet gallery as indicated in the project’s readme.

This is just a quick demo, but it’s a pretty cool control!