SCMDM 2008 – Web Services – Introduction

Also known as “Building A Simple Helpdesk Tool – Part I” 🙂

I’ve been doing some experimentation in my lab recently performing enrollments, and when I was going through the pre-enrollment wizard yet again I thought – “This doesn’t make sense – it’s got to be a better way!” Yes, I know, I could resort to PowerShell, but I was thinking something that was really easy 🙂

And a couple of other things occurred to me at the same time… We’re not going to have the poor SCMDM admin guy create all enrollment requests in a real environment are we? Yes, there is the self service page, but picture this: User is traveling, loses phone, calls helpdesk to wipe/block device, buys new phone, calls helpdesk again to enroll the device.

There’s bound to be a few of those calls. So I decided to create a small helpdesk application to solve these small issues. Ok, to be honest, the motivation that made me actually create this application was learning more about the web services in SCMDM 2008. If it was just annoying I could have lived with it 🙂 If someone ends up using it for actual helpdesk purposes that’s just an added bonus.

At this point maybe you’re thinking “what about customizing the self service portal from the resource kit?”. Good point. I have looked at the self service portal, and tested using it. I have not however tried customizing it yet. Maybe that is a better solution than what I’m trying to do here. I don’t know yet…Maybe we’ll try that avenue later.

Still being a sucker for the learning-by-doing approach I thought combining the web service walkthrough with creating this utility might make for interesting reading.

So what should this tool be able to do? I’m having the following features in mind to start with:
– Create Pre-Enrollment Requests.
– List current Pre-Enrollment Requests.
– Cancel Pre-Enrollment Requests.
– Wipe device.

So I did a quick mock-up of the UI, and I’m thinking something like this (I’ll work on the design elements later):

image

image

image

This could obviously be created as a web app instead of a stand-alone app, but as a personal preference I like creating prototypes as stand-alone.

To answer a question up-front right away; you will notice that there are no downloads at the end of this article. There are a couple of reasons for this:
– I have not written all the code yet that is needed behind this “sophisticated” GUI.
– Service Pack 1 for SCMDM is right around the corner, and I will not make a release available of this tool until I have tested it with SP1.
– Since I have only performed some simple tests so far I might run run into problems later that needs some extra work to solve 🙂

Maybe you’re also thinking “I’m not a programmer so I’ll just skip this until the tool is released”. Well, obviously everything I type on to this little site of mine is voluntary reading 🙂 But I will try to both show some of the code required, and show some of the details that could be of interest to those who just wants to get to know SCMDM a little better. (Let me know if I’m failing these objectives.)

The first thing we need to understand is what we mean by web services in this context, and what it means to SCMDM. A web service is a way to expose methods/functions in a program publicly through an HTTP interface. This means that you can interact with whatever language you choose across different platforms, and if implemented properly (by those providing the web service), you can extend the functionality of a program with very little fuss. Hit http://en.wikipedia.org/wiki/Web_service for a more detailed (and possibly more understandable) explanation.

SCMDM 2008 follows a trend Microsoft has showed the past couple of years where interaction between different components are exposed as web services, and the bits and bytes are based on managed code (C#). So when you are enrolling your device – you’re using a web service. When creating a new enrollment – you’re using a web service. Wiping a device? Yes, there’s a web service for that as well.

Obviously there are some background processes not exposed publicly – interacting with the SQL database, doing some work that needs to be done in C++, doing “secret” things. But that’s the great thing; if I execute a device wipe I don’t need to know the details, I just want to have this available to me as an option.

When you are using the SCMDM Admin Console you are essentially viewing a GUI interacting with the SCMDM web services in the background. So what web services do we have access to? Here’s a screenshot of IIS Manager on an SCMDM server running the Enrollment and Device Management roles.

image

The SCMDM web services are EnrollmentAdmin, Enrollment, MobileDeviceManagerAdmin, and MobileDeviceManager.

And there’s a web service on the Gateway Server as well:
image

If we browse to the “Enrollment” web service it might look like this:
image

We see from this that there are three operations exposed in this web service. Let’s look at “ShouldEnroll”:
image

This one is easy to test in the web browser, and does not need any programming. When you try to enroll a device this is the first thing the device checks to see if it is eligible for enrollment. (After you have entered your e-mail address, and the server is located, e-mail is provided as ownerIdentity. See my previous article The Enrollment Process in SCMDM2008 – A Closer Look for further details regarding enrollment.)

So we provide “1.0.0.0”, (applies to SCMDM 2008 RTM), in the version field, and “andreas@mobilitydojo.net” in the ownerIdentity field.

image

XML is returned indicating a true or false value (located in the hr tag element):
image

The other web services work in a similar way, but some of them you will only be able to use programmatically.

An important detail that might not be clear from the screen shots above is that there are access controls in place. Most of the web services requires you to authenticate, and be a member of a specific security group (the Enrollment service is a special case). And through IIS restrictions most of them are not accessible outside of the LAN.

The title of this post included the word “Introduction”. I had a “worklog posting” sequence in mind, and I’ll delve into more of the details in upcoming posts. Stay tuned for more web service adventures 🙂

Windows Mobile 6.1 – How do I encrypt my device?

You might have read in white papers and product sheets that Windows Mobile 6.1 supports local device encryption. (Windows Mobile 6.0 featured encryption of storage cards, which is still also supported.) And you might have wondered – where is the setting for enabling it? Well, unless the device manufacturer has provided an interface, you can’t enable it. At least not in an easily accessible way.

The reasoning behind this is probably that it’s considered an “Enterprise feature”. Many enterprises are requesting encryption, but you don’t hear that many concerned end-users requesting it. So to use this feature you may for instance use Exchange 2007 SP1 on the server side, and ActiveSync configured on your device.

The following is a screenshot from the Exchange Admin Console:

image

You’ll notice that it’s not very fine-grained – you either have encryption enabled or you have it disabled. (The encryption ties in with the password requirements though as you need to password protect your device to encrypt it.)

The other option from the Microsoft perspective is System Center Mobile Device Manager 2008, (or SCMDM for short), where you can also enable encryption on the device. This is specified through Group Policies:

image

You’ll notice that this also gives you the additional option to specify inclusions and exclusions which is handy if you have a few gigabytes of mp3 files you don’t want to waste cpu cycles encrypting.

So this is all nice and dandy. If you have servers installed that is. What if you want to use this without servers, or you want to perform some testing without connecting to the servers? The encryption functionality is a feature of Windows Mobile 6.1, and the server tools just enable it. It’s all on the device – you just need a front-end.

With this in mind I created a small utility/application for this purpose.

Note: This tool is not designed for deployment in Enterprise environments. I recommend that in a deployment either the server solutions above, or similar third-party products, are used. This utility is intended for lab purposes, and single users who don’t have the opportunity/possibility of using said server products.

Disclaimer:
This is not an implementation of encryption itself. It uses the encryption that is built into Windows Mobile 6.1, and merely provides an interface for controlling this feature. I take no responsibility for the actual implementation or the details thereof. Currently the encryption in Windows Mobile is based on AES-128.

The use is sort of self-explanatory;
– “Encryption On/Off” refers to whether the feature itself is enabled or disabled.
– “Exclusions” means you can exclude certain files/folders or file types from being encrypted. – “Inclusions” means you can include additional files for encryption. This does however bring up another question – isn’t the entire device encrypted already? No, it isn’t…

The following items are encrypted by default:
– User documents
– Email
– PIM data
– Email attachments and related data
– Internet cache
For more info: http://msdn.microsoft.com/en-us/library/bb964600.aspx

Now, there’s two ways around this: modify the system default (items that will be encrypted when encryption is enabled), or add inclusions after the device is encrypted. This application does not modify the system default, and thus relies on you to enable encryption first.

The exclusion list actually works the same way, you have a system default, and you have the exclusions you add later. I don’t recommend you exclude any of the items from the list above however, with the exception that you might be storing your mp3s under “\My Documents\”.

A few hints when it comes to exclude/include;
– Do not encrypt \…\* (entire device)! You’ll also encrypt the system files that are needed for booting…bad thing.
– Special formatting “…” = all subdirectories, “*” = all files, “*.ext” = all files with specified extension.
– All items must start with “\”; so to exclude all mp3s you would add “\…\*.mp3”. Adding a single file would be “\file.txt”.

So what does it look like?
image
“Encryption On/Off”-tab.
Either it’s enabled or it’s not. Please note – before you add inclusions/exclusions, encryption should be enabled first.

image
“Exclusion”-tab.
Either browse to select individual files or type in file/folder/extension. Remember to add the “\” in front.

image
“Inclusion”-tab.
Works pretty much the same way as the aforementioned tab.

Known issues:
– No icon and/or shortcut yet. Must be started from “\Program Files\DojoCrypt”.
– I do some simple error checking, but if you try you may be able to crash the app. It should however not be able to do any harm other than you having to start the program over again.
– No regexing or parsing checking that your inputs are correct when it comes to exclusions & inclusions. If you type it wrong, it will not work 🙂
– Applying an ExcludeList or IncludeList will require you to reboot the device between each list applied. (Technically you can choose “Later” to postpone it – results untested yet but probably no worries). So you can’t setup both lists and then be prompted to reboot. No biggie, but I am aware of it.
– No possibility to see what currently is on your lists – might implement this later on.
– It’s designed for portrait mode. It will work in landscape mode but does look kinda unoptimized. Fully aware of this, and considering a more slick solution (knowing that one often types with the qwerty keyboard in landscape mode).
– Only tested on Windows Mobile 6.1 Professional. Don’t know if it will work on Windows Mobile 6.1 Standard (probably not because of UI elements).
– Versions prior to Windows Mobile 6.1 is not, and will not be supported.
– While not an issue with this utility itself you may have problems on some devices if there’s a two-tier lock on the device, or some other security restrictions imposed that prevents this utility from working like designed.

I have not had the opportunity to do extensive bug testing, but I’ll replace the link in the download if I make any improvements/fixes.

If there’s any bugs you are welcome to post them in the comments section, but I make no guarantee when I will get around to fixing it 🙂

Download: http://mobilitydojo.net/files/DojoCrypt_090.cab

19.nov.2008 Update:
There’s a new version that fixes some of the known issues.
Download: http://mobilitydojo.net/files/DojoCrypt_10.cab

Provisioning Owner Info

Unless you’ve only used the newer HTC models with TouchFLO that monopolizes almost your entire today screen you’ve probably noticed the field that provides information about the owner of the device. While entering this info, possibly for time number x after another hard reset of your device, you might have been thinking “it shouldn’t be necessary typing this manually every time”. And in a corporate environment you might want to have a company standard for what goes into the fields so users don’t type in “Owner: Batman, Address: Gotham City”.

Owner_01

And, yes, there is a way to do this in a more automated fashion. I’ll present one option here.

Your first step would probably be guessing that this is stored in the registry – and you’d be right. You’ll find some keys in HKCU\ControlPanel\Owner. (You’ll also find HKLM\ControlPanel\Owner – ignore this key.) Unfortunately it’s not as easy as setting the appropriate key “Name”, etc. You see that binary key called ”Owner” – that’s where you want to insert all the info, and the other keys are derived from this. (“Owner Notes” is the “Notes” tab in the configuration on the device.)

Owner_02

If you double click “Owner” you’ll see a pattern:
Owner_03

The solution I will show you here is creating a small C# app that will generate an xml-file that can be provisioned to the device. You could add a step that generates a cab-file for you as well, but for automatic deployment you’d also need to sign it. (A step that could also be automated.) What makes more sense for your scenario depends on whether you have a device management solution, and what options this system allows for provisioning. Maybe you just want to generate cabs and distribute to your users for them to run. With a decent device management solution you should be able to get the system to run the application when the device connects for the first time. Without a DM solution it becomes more of an academic exercise.

If you’re not comfortable with C# it can be done with VBScript as well although I find that to be more of a hassle. (You have to create your own Base64-encoding since it’s not included in VBScript.)

The application takes the username of the device owner as a parameter and fetches the rest of the info from Active Directory. So if you don’t have any info in AD, you’ll have to modify the solution to acquire the info from another source.

So first things first – let’s grab that info from AD:

string outputFile = “ownerinfo.xml”; Stream xmlFile = new FileStream(outputFile, FileMode.OpenOrCreate); StreamWriter output = new StreamWriter(xmlFile);     String ldapPath = “LDAP://dc/CN=Users;DC=Contoso;DC=com”; DirectoryEntry ldapDir = new DirectoryEntry(ldapPath); ldapDir.AuthenticationType = AuthenticationTypes.Secure; DirectorySearcher ldapSearch = new DirectorySearcher(ldapDir); ldapSearch.Filter = “(&(objectCategory=Person)(objectClass=user)(sAMAccountName=” + sAMAccount + “))”; ldapSearch.SearchScope = SearchScope.Subtree; SearchResult ldapResult = ldapSearch.FindOne();

Yes, call me lazy for not implementing a better solution than hard coding the LDAP path 🙂 Create variables for the fields in the User object we care about (obviously it’s recommended you use try-catch for those user objects that turn out to have something missing):

String ownerName = “”; String ownerCompany = “”; String ownerAddress = “”; String ownerPhone = “”; String ownerMail = “”; DirectoryEntry ldapUser = ldapResult.GetDirectoryEntry(); ownerName = ldapUser.Properties[“name”].Value.ToString(); ownerCompany = ldapUser.Properties[“company”].Value.ToString(); ownerAddress = ldapUser.Properties[“streetAddress”].Value.ToString(); ownerPhone = ldapUser.Properties[“mobile”].Value.ToString(); ownerMail = ldapUser.Properties[“mail”].Value.ToString();

The properties are LDAP properties, and you can find the ones you’re interested in using either ADSIEdit or a suitable LDAP browser.

And this is the part you’ll want to take note of if you want to implement this is VBScript or any other choice of script/language. How to prepare the variables, and create an xml-file containing provisioning xml.

// We need to zero-pad the variable. The numbers are taken from a registry that have been populated // by typing in owner info manually. char pad = (char)0; ownerName = ownerName.PadRight(36,pad); ownerCompany = ownerCompany.PadRight(36,pad); ownerAddress = ownerAddress.PadRight(186,pad); ownerPhone = ownerPhone.PadRight(25,pad); ownerMail = ownerMail.PadRight(34,pad); String ownerTotal = ownerName + ownerCompany + ownerAddress + ownerPhone + ownerMail; //We want Unicode and Base64 UnicodeEncoding ownerByte = new UnicodeEncoding(); Byte[] workArray = ownerByte.GetBytes(ownerTotal); String ownerInfo = Convert.ToBase64String(workArray); // Write to file output.WriteLine(“<wap-provisioningdoc>”); output.WriteLine(“<characteristic type=\”Registry\”>”); output.WriteLine(“<characteristic type=\”HKCU\\ControlPanel\\Owner\”>”); output.WriteLine(“<parm name=\”Owner\” value=\”” + ownerInfo + “\” datatype=\”binary\”/>”); output.WriteLine(“</characteristic>”); output.WriteLine(“</characteristic>”); output.WriteLine(“</wap-provisioningdoc>”); output.Close();

The sample code here isn’t performing any error-checking – so if it isn’t working you don’t get any wiser before you include some sanity checks.

Putting it together to a working sample I fire up the command line, run “BuildOwnerXML andreas” and get a file called “OwnerInfo.xml”. For testing purposes I generate a cab file; “makecab _setup.xml OwnerInfo.cab”. (Renaming the xml-file so it follows the documented format for makecab. Makecab is included if you have Visual Studio installed, but is also available as a separate free download from MS.)

Copy cab to device, run cab, accept warning (it’s not signed), and you’re done!