Deploying Win32 app BGInfo with Intune

Deploying the well known Sysinternals tool BGInfo is popular since a very long time. Often people use it for more visibility of vital OS parameter to end users. It is used mostly to support in-house help desk personal. Today I’m using this approach, to provide a handy solution for your development or test environment to quickly identify your devices and logged on user including their permissions (local admin or standard user) in that session like this:

The undiscovered need for this was there all the time, e.g. during intensive testing in my development environments with a lot of virtual test devices and during class room training’s to make student life’s easier. I often test various features so Windows Version and Edition is important to know for me. As a nice addition I added the local permissions of the logged on user. Following an user logged on to an Autopilot device with standard user permission and a device without Autopilot and local administrator permissions:

Now you know my intention for this blog post. I was inspired by Nick Hogarth blog post (Intune – Win32 app Deploying BGInfo) about this and re-discovered my need 🙂 and took his solution and developed it a little further for my needs (thanks Nick!). I can recommend to read his blog as well as he has a nice walk through how to create and upload the Intunewin package for Intune and trace the installation itself. Like Nick I only focus on the x64 Edition of BGInfo64 as I’m not dealing with x86 devices for a long time now.

First I had to came up with a way to identify if the user is a local admin. BGInfo supports various ways to get OS information and one option is to use vbs scripts. So I wrote a short vbs script to verify local Administrators group membership. To handle this in a way to be language independent I’m resolving the local Administrators group SID S-1-5-32-544 (read about well known SIDs here) to the localized display name to finally enumerate account membership. 

Dim WshShell, colItems, objItem, objGroup, objUser
Dim strUser, strAdministratorsGroup, bAdmin
bAdmin = False
On Error Resume Next
Set WshShell = CreateObject("WScript.Shell")
strUser = WshShell.ExpandEnvironmentStrings("%Username%")
winmgt = "winmgmts:{impersonationLevel=impersonate}!//"
Set colItems = GetObject(winmgt).ExecQuery("Select Name from Win32_Group where SID='S-1-5-32-544'",,48)
For Each objItem in colItems
strAdministratorsGroup = objItem.Name
Next
Set objGroup = GetObject("WinNT://./" & strAdministratorsGroup)
For Each objUser in objGroup.Members
If objUser.Name = strUser Then
bAdmin = True
Exit For
End If
Next
On Error Goto 0
If bAdmin Then
Echo "Admin"
Else
Echo "User"
End If
GitHub Listing – CheckAdmin.vbs

The vbs script is dynamically written by the install script as CheckAdmin.vbs to the BGInfo install folder (C:\Program Files\BGInfo) during install. This way I do not have to maintain several files, only my install script. I followed the same way and created an install.ps1 to install BGInfo64.exe with the custom background information file custom.bgi. In addition I modified the startup shortcut creation to create the shortcut with the ActiveX object WScript.Shell in the PowerShell install script. The startup shortcut is needed to always have actual information on the background. Following the complete install.ps1:

<#
Version: 1.0
Author: Oliver Kieselbach (oliverkieselbach.com)
Date: 15.12.2018
Description:
Install BGInfo64 with custom background scheme where hostname and logged on user incl. membership (Admin|User) is shown.
It is especially usefull when dealing with virtual test environments where different devices, users, and different
Autopilot profiles are used. It enhanced viability of hostname, username and available permissions of the user.
Thanks to Nick Hogarth for inspiring me with his initial version. I basically extended his solution.
His version can be found here: https://nhogarth.net/2018/12/14/intune-win32-app-deploying-bginfo/
Release notes:
Version 1.0: Original published version.
The script is provided "AS IS" with no warranties.
#>
New-Item -ItemType Directory -Force -Path "c:\Program Files\BGInfo" | Out-Null
#Start-BitsTransfer -Source "https://live.sysinternals.com/Bginfo64.exe&quot; -Destination "C:\Program Files\BGInfo"
Copy-Item -Path "$PSScriptRoot\Bginfo64.exe" -Destination "C:\Program Files\BGInfo\Bginfo64.exe"
Copy-Item -Path "$PSScriptRoot\custom.bgi" -Destination "C:\Program Files\BGInfo\custom.bgi"
$Shell = New-Object -ComObject ("WScript.Shell")
$ShortCut = $Shell.CreateShortcut("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BGInfo.lnk")
$ShortCut.TargetPath="`"C:\Program Files\BGInfo\Bginfo64.exe`""
$ShortCut.Arguments="`"C:\Program Files\BGInfo\custom.bgi`" /timer:0 /silent /nolicprompt"
$ShortCut.IconLocation = "Bginfo64.exe, 0";
$ShortCut.Save()
$CheckAdminScript = @"
Dim WshShell, colItems, objItem, objGroup, objUser
Dim strUser, strAdministratorsGroup, bAdmin
bAdmin = False
On Error Resume Next
Set WshShell = CreateObject("WScript.Shell")
strUser = WshShell.ExpandEnvironmentStrings("%Username%")
winmgt = "winmgmts:{impersonationLevel=impersonate}!//"
Set colItems = GetObject(winmgt).ExecQuery("Select Name from Win32_Group where SID='S-1-5-32-544'",,48)
For Each objItem in colItems
strAdministratorsGroup = objItem.Name
Next
Set objGroup = GetObject("WinNT://./" & strAdministratorsGroup)
For Each objUser in objGroup.Members
If objUser.Name = strUser Then
bAdmin = True
Exit For
End If
Next
On Error Goto 0
If bAdmin Then
Echo "Admin"
Else
Echo "User"
End If
"@
$CheckAdminScript | Out-File -FilePath "C:\Program Files\BGInfo\CheckAdmin.vbs" -Encoding utf8 -Force -Confirm:$false
Return 0
GitHub Listing – install.ps1

To also provide uninstall capabilities I created the small uninstall.ps1 as well:

<#
Version: 1.0
Author: Oliver Kieselbach (oliverkieselbach.com)
Date: 15.12.2018
Description:
Uninstall BGInfo64. User has to switch background to the original one by his own.
Release notes:
Version 1.0: Original published version.
The script is provided "AS IS" with no warranties.
#>
Remove-Item Path "C:\Program Files\BGInfo" Recurse Force Confirm:$false
Remove-Item Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BGInfo.lnk" Force Confirm:$false
Return 0
GitHub Listing – uninstall.ps1

The custom background information file custom.bgi was adjusted to present all information needed. Especially the CheckAdmin.vbs is referenced to get the user permission information:

For completeness I list the two registry keys I used for displaying the complete Version string e.g. 10.0.17763.194 (1809) 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId

-> Windows Release e.g. 1809

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UBR

 -> Patchlevel e.g. 194

All files for the complete Intune Win32 app package can be found in my GitHub account here:
https://github.com/okieselbach/Intune/tree/master/Win32/BGInfo64

As always when dealing with Intune Win32 apps we need to package it as .intunewin and upload the package to Intune. Use the Packaging tool from here: https://github.com/Microsoft/Intune-Win32-App-Packaging-Tool. The complete conversion can be done in an one liner when the conversion tool is in the same folder structure level as the BGInfo folder with all needed files:

.\IntuneWinAppUtil -c .\BGInfo -s Bginfo64.exe -o .\ -q

For more details regarding packaging see my post: Part 3 Deep Dive Microsoft Intune Management Extension Win32 Apps. As soon as we have the BGInfo64.intunewin package we can upload it and specify the install and uninstall command lines with the install behavior System:

powershell -ex bypass -file install.ps1
powershell -ex bypass -file uninstall.ps1

As the detection rule we use a simple file exists for BGInfo64.exe in the install folder:

C:\Program Files\BGInfo
Bginfo64.exe

Finally you can assign it to your devices or users. I assigned it to all my devices as I like to have it on all my test devices:

If successfully installed you should see the following files:

Because it is installed in System context we need to logon once to trigger the startup shortcut to finally execute BGInfo in user context and create the background information. If everything runs fine you should get nice information about the device you are currently using and in which context you are running (admin or user permission).

I hope it may help you as it helps me and gives you an idea how to dynamically get OS parameters for BGInfo and display them.

Happy tattooing you backgrounds!