Reporting Web Service for Office 365

There’s an interesting web service that could be used to pull reporting data from Office 365, assuming you can authenticate using your tenancy’s service admin. Here the URL for the service:

Microsoft provide a plug-in to Excel that uses this service and it can be used to pull mail protection statistics from your Office 365 tenancy:

File extension for Windows Language Packs

For some reason I have a mental block and can’t seem to remember this, but instead of using dism to install language packs on Windows 7 or above, like this…

dism /online /add-package /packagepath:<path to language pack .cab file>

…you can also simply rename the .cab language pack file to have the .mlc file extension and double-click it.

There’s yet another way too, and that’s to run the lpksetup.exe utility and point it at your .cab file I think. Haven’t tried that though as I think the .mlc method is easier.

Blocking the Outlook App for iOS or Android from Exchange Using IIS or TMG

We’ve recently seen the arrival of Microsoft Outlook for iOS and Android. The software was created by Acompli and then acquired by Microsoft, and I suppose rebranded. As it happens it’s a pretty good mail client, but, unfortunately it has a nasty trick up its sleeve that happens to violate my employer’s acceptable use policy – and many other company’s security policies too. It turns out that when you sign-in to the app and add an account, it automatically stores the Exchange user credentials and server name in a service running on Azure. They are then used to poll the exchange CAS servers for mail updates on behalf of the user, and to perform a sync when requested. The issue here is that the data is retrieved for the user by a service and not by the app on their mobile device, whether or not the device is on. This was first reported here and later again here.

To see this in action all you have to do is look at the IIS logs on the CAS servers and look for the User-Agent in the traffic, looking specifically for “Outlook-iOS-Android/1.0” – you’ll see usernames in the query strings and a bunch of unusual IP addresses – which it turns out are Azure datacentre IPs. So there we see traffic coming from Azure using credentials that users have provided and retrieving mail data. So the credentials are being stored at rest somewhere completely unexpectedly. Apparently they are encrypted, doubley-so, but just storing those credentials is the worst thing possible!

OK what to do about all this. Answer: tell your users to remove their accounts from the app and then stop using the app for Exchange related usage. That would be easy if everyone did as they are told but that’s not always the case. We can do this with IIS Request Filtering (explained at the end) but what I did as well was make use of signature blocking in TMG to prevent all traffic with the specific user-agent provided by the app.

Block Using TMG

1. Open your TMG server configuration MMC (or ISA if you’re still using that for some crazy reason) and find the rule that covers the path for the ActiveSync folder in OWA, and right-click it.
2. Select “Configure HTTP”, open that and switch to the “Signatures” tab.
3. Click Add… and create a new signature as shown below.
Name: Outlook for iOS/Android 1.0
Description: Block Outlook for iOS/Android 1.0
Search in: Request headers
HTTP header: User-Agent:
Signature: Outlook-iOS-Android/1.0

4. Then click ok and Apply the change.

You can then monitor your traffic going through TMG and should start to see ActiveSync traffic being blocked where the Outlook-iOS-Android/1.0 user-agent is involved. You can actually detect exactly who is using the app in your environment by monitoring looking at the logs again for the same user-agent. Looking at the query string you should be able to see the usernames in the ?User= part of the string. You can then use these to communicate with the relevant people in your organisation to hopefully prevent help desk calls.

If you want to prevent ‘new’ sign-ups using this client without worrying about existing users so as to not interrupt your users and again cause more unnecessary work for your help desk you can be more selective with your blocking and a probably create a new rule that exclusively filters based on the &Cmd=Provision component of the path as well as the signature:


The rule would need to be an allow rule and simply specify the path as above, along with the http signature to block, but prevent authentication. This should stop new users from being able to connect. I haven’t tried it but I think the theory is sound. You might be better of doing it with IIS Request Filtering though as that’s a lot more powerful…

Block using IIS Request Filtering

If you wanted to use IIS Request Filtering instead this would be both easier and harder, as of course you need to implement it on all of your CAS servers, but of course it doesn’t rely on you having TMG, and you’ll always have IIS.

1. Find the IIS applets for the “Microsoft-Server-ActiveSync” virtual folder and double-click the “Request Filtering” applet on the right.

2. In the Request Filtering options choose the Rules tab and click “Add Filtering Rule…” from the actions pane.

3. Add new rule using the following options:

  • Name: Agent Rule
  • Scan url: unchecked
  • Scan query string: checked
  • Header: User-Agent
  • Deny Strings: Outlook-iOS-Android/1.0

Then just repeat that for each CAS server.

If you’d like more details here’s a useful blog post discussing uses for Request Filtering in IIS:

Quickest Way to Shut Down / Restart in Server 2012 or Windows 8

I really don’t know why they did it but in Server 2012 and Windows 8 Microsoft have decided to make it really difficult to shut down and restart. And if you are in a remote desktop session it’s even harder than when you’re on the console.

Fortunately there’s a handy key-press they haven’t gotten rid of yet, namely good old Alt+F4. Just click on an empty space on the desktop, give that particular two-fingered salute and you get the following dialog:

Shut Down Windows dialog

So there we go. To be honest I was surprised it worked in an RDP session – I fully expected my session to get killed instead, but no it does indeed work as it needs to.

Secrets of configuring DHCP policies for Lync handsets alongside other vendors

After battling with a non-Microsoft DHCP server to get it to configure multiple vendors of handset I figured out some very useful undocumented ‘habits’ of Lync handsets which might help someone else…

1. Lync handsets (e.g. the Polycom CX600) use TWO vendor IDs during their DHCP requests

The first vendor ID that is used during negotiation of an IP address is “CPE-OCPHONE”. This is the legacy ID that was used during the OCS 2007 days. Despite being legacy it is actually the first one that appears on the wire. Knowing this if you are struggling with getting Lync handsets to do vlan tagging you’ll hopefully realise that CPE-OCPHONE is the vendor ID you need to be using in option 60 for the vlan tagging configuration policy in DHCP.

The second vendor ID used is the modern Lync handset ID, namely “MS-UC-Client”. This is the one you use in option 60 when you provide the configuration to the phones.

2. If you have to use a non-Microsoft DHCP server (e.g. QIP) and you are in the middle of migrating from an IP-PBX (e.g. Alcatel) over to Lync but need to use the same voice vlans for both handset vendors, make life easy and use Vendor Class policies.

Using Vendor Class policies assigned to your voice networks means you can have multiple DHCP policies available on a single subnet! This way you can have non-voice clients that get a standard policy, and multiple vendor handsets that can get their own configuration sets. You could configure each individual IP address to have a single DHCP policy and statically assign phones to pre-configured IPs, but that doesn’t scale and it’s horrible to deal with.

Microsoft use vendor classes, and for good reason, so make sure you do your best to configure your non-Microsoft DHCP to use them too. Having to use multiple vendors’ phones is a pretty rare thing so you may not be able to get much support from anywhere.

3. Get hold of a simple network hub and use this with wireshark on a laptop to monitor DHCP traffic. It’s much easier than guessing what settings are (or are not) working.

4. If your network switches support LLDP-MED for goodness sake use it!

LLDP-MED is so much easier to handle and can be assigned to all ports on a switch instead of having to assign a specific voice vlan for a specific port. That and if you can use LLDP-MED you will not need to configure the phone to know what vlan to use for tagging because the LLDP protocol will do that for you.

5. When you’re stuck with a non-Microsoft DHCP server, read this article and this one from TechNet. The info you’ll need is there, they just haven’t really explained it too well.

I plan to do a deep dive into the stages a Lync handset goes through at boot-up and initial configuration in a later article, so if you find any of this of use you may wish to watch out for it.

A way to run a 64-bit process from a 32-bit script (like add a registry key)

Say you have a need to add a registry key into the 64-bit registry hive but you’re stuck with doing it from a vbscript running in a 32-bit process. For example SCCM always runs vbscript in a 32-bit process, even on a 64-bit Windows machine! If you try this normally Windows 7 64-bit will redirect the key to the virtual 32-bit hive. So running in a 32-bit process if we want to add a key to HKLM\Software\ you will find it will always end up in HKLM\Software\Wow6432Node\ no matter what you do.

I couldn’t find a way to do it directly using vbscript in the short time I spent looking into it, but I did find a sneaky indirect way. My method is to execute a command to add a scheduled task into Windows that will do it for you!

I’ve written a bit of vbscript which will create a run-once self-deleting scheduled task that can be used to run a command such as REG ADD which will be running as a 64-bit process, assuming you use it on Windows x64. The only thing you need to have is admin rights, the rest will happen automatically.

You could use it for all sorts of things, like getting access to an area of the OS that needs LOCAL SYSTEM rights for example. You must remember though it’s just for firing off a command that you don’t need a response from. You need to test whatever you fire-off because you can’t check what you’ve done from within the script!

Click here to see my function on pastebin

To use the vbscript function you need to call the CreateJob() function and pass it the command that you want to run. For example if we call the following…

CreateJob("REG ADD HKLM\Software\64BitKey /v 64BitValue /d 64BitData /f")

…then my function will create a scheduled task that runs the command between the quotes 1 minute after it is created. Once the task completes it will then delete itself automatically, whether it succeeds or fails. The command in my example will create a registry key HKLM\Software\64BitKey with a new REG_SZ value 64BitValue which has the string data 64BitData.

I’ve commented the code as best I can. Basically the scheduled task that is created will have a unique name every time due the use of a guid string for the name. The task will work on XP, Vista and Windows 7, and on 32-bit or 64-bit, but it will always be in ‘XP mode’ so that it will delete itself after it is executed.

Here’s a slightly generic example of use:

Adding a registry key HKLM\Software\RegKey with KeyName that has a DWORD value of 000000FF:
CreateJob("REG ADD HKLM\Software\RegKey /v KeyName /t REG_DWORD /d 0xFF /f")
Notice here the use of 0xFF to specify the hex value, and the /f switch to force the key to add. If we don’t use /f and the value is already there then the command will perpetually wait for a response.

Here are some screenshots proving it works…

1. running the script in an Admin CMD prompt running in 32-bit mode on a 64-bit machine

2. proving the script is running as a 32-bit process

3. showing the scheduled task about to run

4. and finally the registry key after it has been created, definitely in the 64-bit hive!

For more info about the REG ADD command either go here, try typing reg add /? in the command-line, or you could Google it.

The right way to do my precise example is use WMI as mentioned here but my way is more flexible because you can do other stuff like run apps in a 64-bit process as well…

Anyway, here’s my function. Have fun with it, and don’t forget, you’re running as the SYSTEM account when you use this, so please be careful!

Function CreateJob(strCommand)
    Const SHELL_WAIT = True
    Const SHELL_HIDE = 0
    CreateJob = False
    ' Get date & time 1 minute in advance
    ' And it must be at least 1 minute
    ' Source: w3schools, & mikeblas on
    Dim strDateTime : strDateTime = DateAdd("n", 1, Now())
    Dim strDate     : strDate = LEFT(strDateTime, InStr(strDateTime, " ")-1)
    Dim strTime     : strTime = MID(strDateTime, InStr(strDateTime, " ")+1)

    ' define the command we will run to create the once-only scheduled task
    ' uses a new guid for the name each time so it will be a unique task
    Dim strJobCmd   : strJobCmd = "schtasks.exe /Create /TN " & _
        getGuid & " /RU SYSTEM /ST " & _
        strTime & " /SD " & _
        strDate & " /SC ONCE /TR """ & _
        strCommand & """"
        ' on Vista/Win7 must create task as XP-readable type using /V1
        ' this is so it will delete itself propely (bug in schtasks) using /Z
        If onVistaWin7 Then strJobCmd = strJobCmd & " /Z /V1"
    WScript.echo strJobCmd
    Dim oJobShell : Set oJobShell = CreateObject("WScript.Shell")
    Dim jobRet : jobRet = oJobShell.Run(strJobCmd, SHELL_HIDE, SHELL_WAIT)
    If jobRet = 0 Then CreateJob = True
    ' here we tried to make the task and get the result to a variable
    ' if the return is non-zero then the creation of the task errored
    Set oJobShell = Nothing
End Function

Function getGuid
    ' this functions gets a unique guid and returns it as a string
    Dim TypeLib : Set TypeLib = CreateObject("Scriptlet.TypeLib")
    getGuid = Left(CStr(TypeLib.Guid),38)
    ' above line also removes some strageness at the end
    Set TypeLib = Nothing
End Function

Function onVistaWin7
    ' this function returns true on Vista or above (incl. Srv2008)
    Dim colOSver, objOSver
    onVistaWin7 = False
    Set colOSver = GetObject("WinMgmts:root\cimv2").ExecQuery _
        ("Select Version from Win32_OperatingSystem")
    For Each objOSver In colOSver
        If Left(objOSver.Version,1) >= 6 Then onVistaWin7 = True
    Set colOSver = Nothing
End Function

Protecting yourself from tracked advertising

On-line privacy is getting harder and harder as more and more services and shops go on-line. As a person highly concerned with privacy tracked advertising is just one of the many things that I despise.

Not sure how I missed this one but I’ve just discovered a way of opting-out of a lot of tracked advertising, and it involves setting special opt-out cookies…

Here’s the link to get you started:

Use a D-Link DIR-825 to automatically IPv6 your network

(Please note this article is now somewhat out of date as D-Link have started to trickle out a new version of software for this router which changes its ipv6 functionality and completely fixes the ipv6 router advertisement issue – here is an EU beta version that I found after scouring the d-link forums: DIR-825 2.05EU, and I think the US version is available from the US ftp site too.)

My cable router died recently so I took the opportunity to replace it with something good. I grabbed a D-Link DIR-825 (revision B) since I knew it supported IPv6 natively after doing lots of research and finding an excellent list on It was a bit pricey (£120) but I believe it was worth it for the massive feature set – including the quad-band wireless which has prooved excellent so far.

Set-up was super easy. As with most cable setups, just plug it in to the modem and you’re away since there’s no mess with internet credentials, at least in my case anyway.

Now the IPv6 bit. I have a subnet obtained from Hurrican Electric’s Tunnel Broker and when you’re given a subnet they offer you a /64 subnet, and a routed /48 subnet as well. You should only need the /64 subnet, but you can get the /48 as well if you like, we won’t use it here.

Assuming you’ve signed up at HE and acquired an IPv6 subnet, keep the tunnel details page handy so you can use them in the admin interface of the router.

In the advanced section of the DIR-825 switch to the IPv6 page. Then change the connection type to “IPv6 in IPv4 tunnel”. Now we start entering addresses…
The remote and local addresses match up with the addresses on the tunnel details page, so for the Remote IPv4 address use the “Server IPv4 address” from the tunnel details page, Remote IPv6 address is the “Server IPv6 address”, and so on for the local addresses, using the “Client” addresses.

Key here is making sure you don’t include the “/64” bit and also remember to not use the short notation for the v6 addresses. For example if you have a server ipv6 address that says: “2001:470:1234:567::1/64” you should instead enter “2001:470:1234:567:0:0:0:1″. That’s because IPv6 addresses are usually given in a more human-readable format and they miss out the pointless bits, like the zero-sections at the end (where shorthand like :: is used to mean :0:0:0: ). Do the same for the client IPv6 address too.

Now you want to type in your routed /64 address in to the LAN IPv6 Address for the router. The tunnel details page will just give you a subnet notation (e.g. 2001:470:1235:567::/64) so stick a 1 on the end before the /64 and that’ll be your router’s internal LAN address, (e.g. 2001:470:1235:567:0:0:0:1). Notice that the  3rd section of the address will be 1 number higher than your client IPv6 subnet.

Finally in the address autoconfiguration section, check the enable autoconfiguration box and switch to Stateful (DHCP v6). This will give IPv6 addresses to your clients that support DHCPv6. I believe you don’t have to do this, and you can use stateless to do it aswell, but I wanted fully public IPv6 address, so I’ve gone for stateful in my case.

And so finally we click the Save Settings button at the top, and you’re done! Time to test it out. Try for starters 🙂
Ocassionally it doesn’t work. If not check on the site and make sure you router’s wan ip address is listed on the tunnel details page. If it isn’t you need to get that filled in, so click the link next to the client ipv4 address entry and fill it in. Hopefully you have a static IP don’t you…! There does seem to be a way of dynamically updating the client ipv4 address with hurricane electric, but that would still mean updating the config on the router which would be annoying of course.

Here’s a sanitised screen-shot of my router config for reference:

Added on 20th Feb 2011: I realised recently that IPv6 wasn’t quite working all of the time on my computers served by my router and after extensive investigation I discovered that the router wasn’t advertising it’s link-local address often enough (or at all). As a result my IPv6 clients were finding they didn’t have the necessary routes to talk IPv6 to the internet.
The solution turned out to be to add a persistent static route to the IPv6 internet via the internal Link-Local address of the router.
Here’s the fix, just run it from an admin cmd prompt, and replace the [link-local address] section with your router’s link-local address (which you can find on the ipv6 config page):

route -p add ::/0 [link-local address]

Get your own IPv6 address range

IPv6 Certification Badge for njfclarkI recently decided to learn about IPv6 and signed up to get my own IPv6 address range. It’s all free and your learn loads in the process.

Just visit sign-up and get learning about IPv6!

They provide a free PPTP VPN tunnel service so you can set your laptop to have its own static IPv6 address no matter where you’re connecting to the internet from. Plus you get free DNS management and rDNS too!!!

I have to say, it’s pretty cool to be able to give my laptop a static forward and reverse AAAA record.
Oh and if you do it soon you might get a free T-shirt too. Just make sure you put in your correct home address details and T-shirt size in the personal details section. It’s all to aid promoting the switch to IPv6.

— A follow-up post on how to use your new IPv6 range on a D-Link DIR-825 cable-router to give your whole network IPv6 automatically is here