I saw a recent post by Damien van Robaeys on creating a system tray (aka notification area) app with a context menu and I was reminded of a project I’ve been working on for a while for an app which minimizes to a tray icon with a context menu – except that I wanted a Windows 10-style context menu. After all, got to keep up with the times, right?!
Take, for example, the context menu style for the Windows 10 Start:
Or in the notification area we have the Windows Security tray icon with the same context menu style:
So I set out to recreate that style in WPF and more or less managed it. Here’s an example:
The main challenges were creating the style resources in XAML for the different menu and submenu items, getting the menu to appear at the correct location, and handling the element events like mouseover and mouseleave, correctly.
It’s not perfect – the submenu still doesn’t handle quite as fluently as I would like, but it’s a pretty close style reproduction.
Below is the code to create the example menu above. You can customise the menu items in the StackPanel section of the XAML code. Just be sure to use the appropriate static resource, ie MainMenuitem, SubMenuParentitem or SubMenuitem, and use a Popup for a submenu.
Note: If you’re on a mobile device and can’t see the code below, use a desktop.
Recently I tweeted a picture of the custom Windows 10-style splash screen I’m using in an implementation of Windows as a Service with SCCM (aka in-place upgrade), and a couple of people asked for the code, so here it is!
A while ago a blogged about a custom splash screen I created to use during the Windows 10 upgrade process. Since then, I’ve seen some modifications of it out there, including that of Gary Blok, where he added the Windows Setup percent complete which I quite liked. So I made a few changes to the original code as follows:
Added a progress bar and percentage for the Windows Setup percent complete
Added a timer so the user knows how long the upgrade has been running
Prevent the monitors from going to sleep while the splash screen is displayed
Added a simple way to close the splash screen in a failure scenario by setting a task sequence variable
Re-wrote the WPF part into XAML code
Another change is that I call the script with ServiceUI.exe from the MDT toolkit instead of via the Invoke-PSScriptasUser.ps1 as this version needs to read task sequence variables so must run in the same context as the task sequence.
I haven’t added things like looping the text, or adding TS step names as I prefer not to do that, but check out Gary’s blog if you want to know how.
To use this version, download the files from my Github repo. Make sure you download the v2 edition. Grab the ServiceUI.exe from an MDT installation and add it at top-level (use the x64 version of ServiceUI.exe if you are deploying 64-bit OS). Package these files in a package in SCCM – no program needed.
To call the splash screen, add a Run Command Line step to your upgrade task sequence and call the main script via Service UI, referencing the package:
To close the screen in a failure scenario, I add 3 steps as follows:
The first step kills the splash screen simply by setting the task sequence variable QuitSplashing to True. The splash screen code will check for this variable and initiate closure of the window when set to True.
The second step just runs a PowerShell script to wait 5 seconds for the splash screen to close
The last step restores the taskbar to the screen
For that step, run the following PowerShell code:
# Thanks to https://stackoverflow.com/questions/25499393/make-my-wpf-application-full-screen-cover-taskbar-and-title-bar-of-window
$Source = @"
public class Taskbar
private static extern int FindWindow(string className, string windowText);
private static extern int ShowWindow(int hwnd, int command);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
protected static int Handle
return FindWindow("Shell_TrayWnd", "");
// hide ctor
public static void Show()
public static void Hide()
Add-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $Source -Language CSharp
# Restore the taskbar
Today I encountered an unexpected issue installing the ConfigMgr Integration for MDT. The scenario was an environment with several SMS providers and 2 site servers in a high availability configuration (active / passive). The MDT ConfigMgr Integrations ran successfully on each of the SMS Provider servers, but on the passive site server the BDD_* WMI classes were not created under ROOT\sms\site_XYZ, even though the ConfigMgr Integration wizard completed successfully and reported no error. I ran the wizard with the option to install the task sequence actions to the local server in each case.
Without the WMI classes in place, you get the error “Failed to load class properties and qualifiers for class BDD_*** in task sequence.” when viewing or editing a task sequence containing MDT steps:
The solution was simply to manually compile the MOF file that comes with MDT, which is called Microsoft.BDD.CM12Actions.mof. After the Integration wizard has run, the MOF file be found in Program Files\Microsoft Configuration Manager\AdminConsole\bin. It can also be found in the MDT installation directory Program Files\Microsoft Deployment Toolkit\SCCM.
You need to edit the first line of the MOF file so that it is pointing to the local server, and contains the correct WMI location to install the classes to, eg:
Usually when querying the logon history of a Windows system you might query the Security event log or a domain controller. But if you’re using SCCM, the SCCM client also logs user logon events and stores them in WMI. Here’s a quick PowerShell script to retrieve those events and translate them into meaningful values.
You can run it against the local or a remote computer and optionally specify the maximum number of events to retrieve.
Note that for remote computers the date/time values will be displayed in your local time zone, not necessarily the timezone of the remote system.
Did you know you can send a custom toast notification to a remote computer? Call it poor man’s IM, but if you’re using Windows 10 with PowerShell remoting enabled it might be a good way to annoy your colleagues if you can’t find a more constructive use!
Try the following code, which creates a notification like this on your mate’s computer:
If you’re like me you are too lazy busy to regularly check the component status of an SCCM Site Server for any issues, so why not get PowerShell to do it for you?
The code below will email an html-formatted report of any site components that are currently in an error or warning status, together with the last few error or warning status messages for each component. Run it as a scheduled task or with your favorite automation tool to keep your eye on any current issues. Whether you get annoyed because you now created more work for yourself, or get happy because you can stay on top of issues in your SCCM environment, I leave to you!
The report will display the components that are marked as either critical or warning with the current number of messages:
It will then display the last x status messages for each component for a quick view of what the current issue/s are:
Run the script either on the site server or somewhere where the SCCM console is installed, and set the required parameters in the script.
This is a little tool I created for testing the required TCP ports on SCCM client systems. It will check that the required inbound ports are open and that the client can communicate to its management point, distribution point and software update point on the required ports. It also includes a custom port checker for testing any inbound or outbound port.
The default ports are taken from the Microsoft documentation, but these can be edited in the case that non-default ports are being used, or additional ports need to be tested.
To use the tool, extract the ZIP file, right-click the ‘ConfigMgr Client TCP Port Tester.ps1′ and run with PowerShell.
Checking Inbound Ports
Select Local Ports in the drop-down box and click GO to test the required inbound ports.
Checking Outbound Ports
Select the destination in the drop-down box (ie management point, distribution point, software update point).
Enter the destination server name if not populated by the defaults and click GO. The tool will test ICMP connectivity first, then port connectivity.
Custom Port Checking
To test a custom port, select Custom Port Test from the drop-down box. Enter the port number, direction (ie Inbound or Outbound) and destination (Outbound only). Click Add to add the test to the grid. You can add several tests. Click GO.
Adding Default Servers
You can pre-populate server names by editing the Defaults.xml file found in the defaults directory. For example, to add a default management point: