Security Compliance Manager 4.0 – Download Resources

Back in July 2016 Microsoft released Security Compliance Manager 4.0 with support for Windows 10 and Server 2016. For some reason (at the moment) it seems to be hard to find so here are all the bits one might need to get started.

Solution Accelerator Article about SCM4:
Security Compliance Manager (SCM)

A TechNet blog announcing SCM4 availability:
Security Compliance Manager 4.0 now available for download!

An article about the security baselines available and links to download them:
Windows Security Baselines

Download: Windows 10, version 1607 and Windows Server 2016 security baseline
Download: Microsoft Security Compliance Manager 4.0

SQL is needed to install it (yay) and it comes with SQL Express 2008, but here’s a link to SQL 2016 Developer with SP1, which is free now:
MSDN article: Developer Guides for SQL Server
Download: SQL Server Management Studio 16.5.3
Download: SQL 2016 Developer with SP1 (2,590MB ISO)


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:

$currentIdentity = New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
$adminContext = $currentIdentity.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…

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.

Find a computer’s model using PowerShell

Interestingly this blog’s most popular post is one where I demonstrate how to find the serial number of a PC in a batch file so you can write a script that does different things for different computer models.

I pretty much don’t write batch code any more, instead using PowerShell as much as possible. So I thought I’d add a post explaining how to get your computer model in PowerShell as well. If you’ve any experience using PowerShell then you know this could be a very short post…

And the answer?

(Get-WmiObject -Class:Win32_ComputerSystem).Model

Extending that to a specific model to allow us to work on something specific we have many options to play with. My preferred method if I’m only dealing with one model would be to filter at the point of making the query, like so:

Get-WmiObject -Class:Win32_ComputerSystem -Filter:"Model LIKE '%H77ITX%'" -ComputerName:localhost

Notice I’ve filtered the query using the LIKE operator which in WMI queries requires the % character as the wildcard indicator, not *. I’ve also specified the ComputerName as localhost in the above commands. Usually WMI commands operate on network objects, even if you only have the one PC, and as a result can take a little time to respond. If you specify localhost it speeds up the command and ensures you only get a result from the PC where you run your script. Of course if you want to do this on remote PCs then you’d use the ComputerName to specify one or more remote PCs.

Anyway that command is only going to return the object if we are running the query on the right PC model. That’s not too useful on its own so we need to make it return something like True or False, then we can work inside an If statement perhaps. Actually we don’t need to bother! If handles a returned object as if that means True, and no returned object as meaning False.

For example:

If(Get-WmiObject -Class:Win32_ComputerSystem -Filter:"Model LIKE '%H78ITX%'" -ComputerName:localhost)
{ Write-Host "Found an H78ITX model" }
{ Write-Host "Model not found" }

OK so what do we do if we’ve got different models and we want to do different things on different models? Easy, go back to the first command, and use its output with the Switch statement.

$pcModel = (Get-WmiObject -Class:Win32_ComputerSystem).Model
Switch -wildcard ($pcModel)
    "*Latitude*" { # install special apps for a Dell }
    "*Elite*"    { # install special apps for an HP }
    default      { # install other things for everything else }

There’s plenty you can do with the switch statement, even using regex. There’s a good explanation of it here.

Of course you might want to do things for specific models, and also things for all models from a particular vendor. We can achieve that by being less specific with our initial command and just select different properties of the object from the variable like this.

$computerSystem = (Get-WmiObject -Class:Win32_ComputerSystem)
Write-Host $computerSystem.Manufacturer
Write-Host $computerSystem.Model

Hopefully that shows you how to get the model and manufacturer, then you can construct some logic around both.

Finally, something else to consider is that if you want to drill down using the serial number of a machine we need to make use of a different WMI object, namely Win32_BIOS, like this:

(Get-WmiObject -Class:Win32_BIOS).SerialNumber

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.