Detecting the Administrative Context in PowerShell

I was writing a PowerShell script and it needed to know whether or not it was running in the administrative context. It’s a bit fiddly but here’s a one-liner that sets a Boolean variable for it:

$adminContext=(New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)

Run that and $adminContext will be True if the script is running as admin, and False if not.

Migrating all Office 365 students/users to the new Education Plus license

Microsoft recently renamed the free license that academic institutions on Office 365 get (if you have an active EA) to “Office 365 Education Plus for students”. At the same time they added in the Office Pro Plus license option to allow our students (and staff) to get Office 2013 (soon to be 2016).

Of course what they didn’t do was give us a simple way to migrate all our users away from the Student Advantage license onto the new licensing option.

So here’s some powershell to help with doing that:

#connect to 365 prompting for credentials
#collect the new license we wish to assign
$newLicense = (Get-MsolAccountSku | ? AccountSkuId -Like "*STANDARDWOFFPACK_IW_STUDENT").AccountSkuId
#find the old Student Advantage license
$oldLicense = (Get-MsolAccountSku | ? AccountSkuId -Like "*OFFICESUBSCRIPTION_STUDENT").AccountSkuId
#find all users with teh Student Advantage license
$needNewLic = (Get-MsolUser -All | Select UserPrincipalName,Licenses | %{if($_.Licenses.AccountSkuId -contains $oldLicense){$_}})
#loop through all users with old license and replace it with new one
$a = 0; foreach ($user in $needNewLic) {$a++; echo "$a of $($needNewLic.Count): $($user.UserPrincipalName)";
Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses ($user.Licenses).AccountSkuId -AddLicenses $newLicense

Some caveats with the above code:
– it doesn’t work for users that already have some element of the new Education Plus license as the code assumes it has not been applied to your users yet
– it removes all existing licenses from the user and adds the new licenses in their place, so if you have extra licenses you want to keep then the code will need to modified to handle that
– as with all these things, I take no responsibility for the above code blatting your tenancy! it worked for me but please test it beforehand on your own ‘test’ tenacy – like we all have one of those…

Copy/Pastable Client Antivirus Exclusions

Here’s a quick block of text that can be used to copy and paste into the excluded file locations dialog of the Microsoft Endpoint Protection client, compiled using KB822158. It is suitable for Windows client machines of any version up to Windows 8.1


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:

Get the latest* SCEP 2012 R2 client easily without updating SCCM

[Updated 2015-03-03]

If you need to get hold of the latest System Center Endpoint Protection 2012 R2 client installer, normally you’d have to download the original installer from the Volume Licensing Center and install from that, then update using the latest cumulative update for SCCM – on your SCCM server – which is really annoying. However there’s a cheeky back-door method that I’ve found. It’s publicly available and I’ve read nothing that says you shouldn’t do it this way.

If you have SCEP installed already, then as of 3rd Feb 2015 when you do a Microsoft Update it will be updated to version – and luckily the installer will be left behind in your SoftwareDistribution folder. Just go here on your updated PC as soon as it finishes installing: C:\Windows\SoftwareDistribution\Download\Install and there you should find the scepinstall.exe installer waiting for you.
If for some reason it’s not there all you need to do is look in your C:\Windows\WindowsUpdate.log file for scepinstall and you’ll find a line in the log where the update system downloaded the install from. It should look like this:

Much easier than it used to be, but still not as easy as it should be.

Here’s the old and much harder way if you’re a bit of a masochist and don’t want the newest version(!):

Basically the answer was to get the March 2014 anti-malware platform update from its KB article and keep extracting its nested contents until you get to the scepinstall.exe file.

Here’s a list of the steps we’ll go through:

  1. Download the ConfigMgrV5 component of KB2952678
  2. Extract the hotfix by double-clicking
  3. Extract the hotfix contents using /extract
  4. Extract the msi using msiexec /a cm12-sp1cu4-qfe-kb2952678-x64-enu.msi TARGETDIR=<path>
  5. Copy and use the scepinstall.exe file

And here’s the detail:

First the latest version of the client as of this post is – and Microsoft are providing an updater for that on Microsoft Update. Unfortunately the updater is purely that, an updater, and does not include all the installation bits we need. However if you go to the KB article for this updater (KB2952678) then we can find a “Hotfix Download Available” button.

Click to get the Hotfix and choose only the item named ConfigMgrV5 with a fix name of ConfigMgr_2012_SP1_CU4_KB2952678_ENU. Do the usual and give it your email address and fill in the captcha. You’ll then get a link to get the update from. To save visitors time the url you’ll get follows:

We now need to extract this 3 times to get to what we want!

Run the .exe file to extract its contents somewhere. You’ll end up with a 26MB file called CM12-SP1CU4-QFE-KB2952678-X64-ENU.exe – we now need to extract this too. Run this in an admin command-prompt using the /extract switch, eg.:

CM12-SP1CU4-QFE-KB2952678-X64-ENU.exe /extract

You’ll be prompted for a place to put it, give the extracter an empty folder somewhere. Now you have a folder with the contents of this supposed ‘hotfix’. The magic we are looking for is buried inside the .msi file that’ll be in the root of the folder… cm12-sp1cu4-qfe-kb2952678-x64-enu.msi

Finally, we have to extract this msi. You might be able to use a universal extract to explode it, but it’s easier to just turn it into an administrative installation point, thusly, from an admin command-prompt:

msiexec /a cm12-sp1cu4-qfe-kb2952678-x64-enu.msi TARGETDIR="<full path to an existing empty folder>"

So, now you have an administrative installation point for the hotfix… and if we have a look inside we see the final target, scepinstall.exe

It’ll have the version we want ( and can be used on 32-bit and 64-bit machine types. Copy that somewhere then tidy up all the bits we had to extract to get to it and you’re done.

Hope that helps.

* Of course this was the latest version available as of the date of this post, so there might be a newer update out there when you read this – it’s up to you to find it and apply this method.