Before I’ll start with this blog post I would like to say thank you to Kim Oppalfens, for his great suggestion to look at WMI Eventing. I didn’t know that it was that versatile and powerful! Thanks Kim!
Scenario
The scenario for this post is actually quite simple and is applicable to an environment with Microsoft Intune integrated with ConfigMgr. By default, the device owner of a mobile device is set to Personal and that’s not always the desired value. A lot of customers still provide their employees with (mobile) devices and want the tooling to reflect that information. This blog post will provide an automagic method to set the mobile device owner to Company, by default. The best thing is that it’s still possible to switch a mobile device to Personal if that’s required. Only newly added mobile devices will be automagically set to Company.
Solution
Now let’s start about the solution for this scenario. Initially I thought that I could easily tackle this scenario via a Status Filter Rule, only to find out that there is no status message generated for the creation of a new mobile device object. That was the moment that I needed advice and I got pointed in to the direction of WMI Eventing. In the rest of this blog post I’ll describe the key parts of the scripts that I used to automatigally set the mobile device owner to Company after it’s enrolled. The complete scripts are available for download in the TechNet Galleries.
>> Available via download here on the TechNet Galleries! <<
The action
Before I’ll start with explaining the key parts of the script for using WMI for monitoring and responding to events, I’ll start with a short piece about changing the device owner, similar to this post about changing the device ownership. As mentioned in that post, I can simply use call the WMI method ChangeOwnership, of the SMS_Collection class, by providing the device owner and the resource id. Together that would make the action to change the device owner look like this.
Invoke-WmiMethod -ComputerName $SiteServer ` -Namespace root\SMS\site_$($SiteCode) -Class SMS_Collection ` -Name ChangeOwnership -ArgumentList @($DeviceOwner,$ResourceId) ` -ErrorAction Stop
The event filter
The first thing that I need to create now is the event filter, as shown in the picture. An event filter is a WMI class that describes which events WMI delivers to a physical consumer. It also describes the conditions under which WMI delivers the events. Let’s start with the latter and start with describing the conditions. To do this I use the following hash table that contains the conditions for the event filter.
$PropertyHash = @{ QueryLanguage = "WQL"; Query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 ` WHERE TargetInstance ISA 'SMS_R_System' AND ` TargetInstance.DeviceOwner = '2'"; Name = "DeviceOwnerFilter"; EventNameSpace="root\sms\site_$($SiteCode)" }
The most important part of the conditions is the query. In this query I select the creation, by using __InstanceCreationEvent, of mobile devices, by using TargetInstance ISA ‘SMS_R_System’ AND TargetInstance.DeviceOwner = ‘2’, every 5 seconds, by using WITHIN 5. Effectively this query will run twice every 5 seconds and the differences are my results. I can imagine that running this every 5 seconds might be too aggressive, in that case simply adjust this value to any desired number.
Now, to create an event filter, I need to create a new instance of the __EventFilter class. To do this I can use the New-CimInstance cmdlet together with the just defined hash table, like this.
$InstanceFilter = New-CimInstance -Namespace root\subscription ` -ClassName __EventFilter -Property $PropertyHash -ErrorAction Stop
The event consumer
The next thing that I need to create is the event consumer, as shown in the picture. An event consumer can be used to perform actions based on events. Each consumer takes a specific action after it receives an event notification. Let’s start with describing the actions for the consumer. To do this I use the following hash table that contains the actions for the event consumer.
$PropertyHash =@{ Name = "DeviceOwnerConsumer"; CommandLineTemplate = "PowerShell.exe ` -File $ScriptPath\Change-Ownership.ps1 -SiteServer $SiteServer` -SiteCode $SiteCode -DeviceOwner 1 ` -ResourceId %TargetInstance.ResourceId%" }
The most important part in the defined action is, of course, the location of the script file that performs the action. Almost as important is to get the resource id of the mobile device, as input for the action script. Luckily, every instance creation event contains an embedded object called TargetInstance, which, in this case, is a representation of the created SMS_R_System object. That TargetInstance object is what I can use as input in my script, like this %TargetInstance.ResourceId%.
In this case I choose to use a command line event consumer. That means I need to create a new instance of the CommandLineEventConsumer class. To do this I use the New-CimInstance cmdlet, again, together with the just defined hash table, like this.
$InstanceConsumer = New-CimInstance -Namespace root\subscription ` -ClassName CommandLineEventConsumer -Property $PropertyHash ` -ErrorAction Stop
Binding the filter and the consumer
The last thing that I have to do, is to bind the event filter with the event consumer, as shown in the picture. This will make sure that when an event occurs that matches the specified filter, the action specified by the consumer will occur. To do this I first create the following hash table that contains a reference to the event filter and the event consumer.
$PropertyHash = @{ Filter = [ref]$InstanceFilter; Consumer = [ref]$InstanceConsumer }
Now I need to relate them by creating a new instance of __FilterToConsumerBinding. To do this I use the New-CimInstance cmdlet, one last time, together with the hash table, like this.
$InstanceBinding = New-CimInstance -Namespace root/subscription ` -ClassName __FilterToConsumerBinding -Property $PropertyHash ` -ErrorAction Stop
Result
The result of all of this is an event consumer that will change the device owner of every mobile device that’s found by the event filter. There are multiple way’s to verify that everything is created and working as expected. To check if everything is created in WMI, as scripted, either use PowerShell or simply use a WMI Explorer.
More importantly, to check if the consumer is working as expected, simply check the event viewer. My script to change the device owner writes a 3000 event in the Application log for every successful change and a 3001 event for every failure. Both of them use the SMS Server as source. A good place to check the functionality of the event filter is to look at the SMSProv.log. This log will show a hit, in this case, every 5 seconds as shown in the example below. Every hit will be performed by the SYSTEM account.
More information
For a lot more information about the basics of WMI Eventing and about how this can be used in combination with scripting, have a look at the following great posts:
- All the great posts by Kim Oppalfens about the power of WMI Eventing: http://myitforum.com/cs2/blogs/koppalfens/archive/tags/WMI+Eventing/default.aspx
- Step-by-step example about handling WMI events by using VBScript by Maik Koster: http://myitforum.com/cs2/blogs/maikkoster/archive/2011/05/30/step-by-step-handling-wmi-events-permanently-using-vbscript.aspx
- Use PowerShell and WMI Eventing for monitoring AD Group modifications by Deepak (also known as DexterPOSH): http://www.dexterposh.com/2014/01/powershell-monitor-ad-group-membership.html
- Use PowerShell and WMI Eventing for monitoring CPU speed by Trevor Sullivan: http://trevorsullivan.net/2011/01/17/powershell-wmi-eventing-monitor-cpu-speed/
Discover more from All about Microsoft Intune
Subscribe to get the latest posts sent to your email.
Peter, you are very welcome. Glad you figured out how to do it quickly.
Hello,
Is it still working with CB1602 ? having trouble to get it working
Thanks,
I haven’t tested it yet, but I would expect it to work. What is the issue that you’re running in to?