Legitimate non-MFA protection


There is no doubt that multi-factor authentication (MFA) is the great thing for the majority of accounts. It is probably the best protection against account compromise, however are there times that perhaps, MFA doesn’t make sense?

Security is about minimising, not eliminating risk. This means that it is a compromise and never an absolute. Unfortunately, MFA is a technology and all technologies can fail. If MFA did fail, or be unavailable for any reason, then accounts would be unavailable. This could be rather a bad thing if such an issue persisted for an extended period of time.

In such a situation, it would be nice to be able to turn off MFA for accounts, so users could get back to work, and re-enable it when the MFA service is restored. However, today’s best practice is to have all accounts, especially administrators, protected by MFA.

A good example is the baseline policies that are provided for free in Microsoft 365 as shown above.


You’ll see that such a policy requires MFA for all admin roles.


And yes, there is a risk for admin accounts that don’t have it enabled but there is also a risk if it is enabled and MFA is not working for some reason.

The challenge I have with these types of policies is that they are absolute. It is either on (good) or off (bad), and in the complex world of security that is not the case.

I for one, suggest there is the case for a ‘break glass’ administration account, with no MFA, that be used in the contingency that MFA is unavailable to get into accounts and re-configure them if needed. Such an account, although it has no MFA, is protected by a very long and complex pass phrase along with other measures. Most importantly, it is locked away and never used, except in case of emergency. There should also be additional reporting on this account, so it’s actions are better scrutinised.

Unfortunately, taking such an approach means that you can’t apply such absolute policies. It also means that you won’t be assessed as well in things like Secure Score. However, I think such an approach is more prudent that locking everything under MFA.

As I said initially, security is a compromise, however it would be nice to see the ability to make at least on exception to the current absolute approach because service unavailability can be just as impactful as account compromise for many businesses.

Connecting to Cloud App Security API

As I have said previously, I believe Microsoft Cloud App Security is a must have for every tenant:

A great security add on for Microsoft 365

You can also manipulate it via an API and PowerShell. Most of this manipulation is currently mainly to read not set information but that is still handy. Here’s how to set that up.


You’ll firstly need to go to the Microsoft Cloud App Security console and select the COG in the upper right corner of the screen. From the menu that appears, select Security Extensions as shown.


The option for API tokens should be selected, if not select this. Now select the + button in the top right to generate a new token.


Enter a name for this new token and select the Generate button.


Your API token should be generated as shown. Copy both the token and the URL and select the Close button. Note, you’ll need to take a copy of you token here as it won’t be available once you move forward.


You should now see the token listed in the Microsoft Cloud App Security portal as shown above.

This token can now be utilised to access Microsoft Cloud App Security via PowerShell. I have created a basic script for you to use here:


that will basically return all of the data current in there.

You’ll then need enter the values from this configuration into the script prior to running it:


but in essence what that script does is take the token and uri and apply to the invoke-rest method to get a response. That return response contains a whole range of data from Microsoft Cloud App Security.


To see what you can and can’t do with the API visit the Microsoft Cloud App Security portal again and select the Question mark in the upper right this time. Select API documentation from the menu that appears.


In there you’ll find a range of information about the API.

As I said, most of the available command current just “get” information. Hopefully, commands that “set” information aren’t too far away.

Retrieving credentials securely with PowerShell

In a recent article I highlighted how you can securely save credential from PowerShell to a local file using the Export-Clixml command here:

Saving credentials securely with PowerShell

The idea with saving credentials securely is that you can now get to them quickly and easily. Just as easily in fact as embedding them into your PowerShell (which is a major no-no). So how do you do that?

You basically use the the import-clixml command like so:

$clientidcreds = import-clixml -path .\clientid.xml

to retrieve them. This will open the client.xml in the current directory, read in the encrypted values (username and password) and store them in the variable $clientidcreds.

Now $clientidcreds.password is a secure string, which means it can’t easily be used as a normal string in PowerShell. No problemo, now jus run the command:

$clientid = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($clientIdcreds.password))

and $clientid will have the plain text variable you initially saved and exported to the secure  XML file.

This is pretty neat eh? It allows you to securely save items such as oAuth and API keys in a secure file on you machine and then recall them quickly and easily with the above commands and use them in your PowerShell code.

Saving credentials securely with PowerShell

There are times when you want to securely save and retrieve information in PowerShell. Saving things like passwords and other credentials to plain text is not a good idea at all. To avoid that, you can use the Secure string feature of PowerShell. The most common way to do this is via the command:

$Secure = Read-Host –AsSecureString

This creates a secure string. After you enter the command, any characters that you type are converted into a secure string and then saved in the $secure variable. With this command, the characters you enter are not displayed on the screen.


Because the $secure variable contains a secure string, PowerShell displays only the System.Security.SecureString text when you try and view it. So the information to be secured is now saved as a protected variable called $secure in PowerShell. How can this now be written securely to a file so that it can be re-used later and still remain protected, even on the disk?

You can use the command Export-Clixml because a valuable use of this on Windows computers is to export credentials and secure strings securely as XML.

Thus, a better way to capture the value you want to save securely is probably via:

$Secure = get-credential -credential ClientID


Which will prompt you for the information as shown above. You will note that the User name filed has already been created thanks to the –credential parameter.

This will then give you a variable with a username (here ClientID) and a secure string that is a PowerShell credential.

You can then save the information via:

$clientid | Export-CliXml -Path .\clientid.xml


If the Export-Clixml is used to save that variable to a file (here clientid.xml), it will save it like shown above. You will note that the Password field is encrypted. This is where the secure information is kept, which is great, since it is now encrypted on disk.

The other great thing about using Export-Clixml is that:

The Export-Clixml cmdlet encrypts credential objects by using the Windows Data Protection API. The encryption ensures that only your user account on only that computer can decrypt the contents of the credential object. The exported CLIXML file can’t be used on a different computer or by a different user.


Thus, if the file with the saved and encrypted information is copied and used by another login on the same machine or on a different machine, you get the above result. Basically, it can’t be decrypted.

Of course, this isn’t perfect, but it does mean that once you have saved the information using the above technique the only way it can be decrypted is via the same logon on to the same machine. This means you don’t need to have secure variables saved as plain text inside scripts or in unprotected files on disk that can be copied and work anywhere. With this technique you can ensure that information saved to a file is encrypted and cannot be used by any other user or by any other machine. Thus, if someone got hold of the file, the information couldn’t be viewed or decrypted and thus access would be denied.

Hopefully, that should allow you to develop more secure PowerShell scripting.

Bringing colour to PowerShell


I like to use colour in PowerShell via the –foreground and –background options to imp0rove the legibility of my scripts. However, with a range of colours to select from it became hard to work out what any combination looked like. I’d like to aim for a standard that looks good on most screens. Problem was I couldn’t really find an easy way to view all these options quickly and easily.

I therefore decided to create my own solutions here:


that you can also use. It will basically spit out a line of text for each colour combination so you can see what it actually looks like. This makes it much easier to see which combinations of foreground and background colours work.

Hopefully, this helps others brighten their PowerShell output.

Capturing ALL Microsoft Secure Score items


Ok, so you are telling me you have time on your hands and want to improve the security of your Microsoft 365 tenant? Ok, if you are only kind of serious, I’d tell you to go to:


and select the Improvement actions as shown above.


That will show you a filtered view of items based on what hasn’t yet been completed in the tenant. In the case above, that equates to 67 items.

Oh, you want more to do you say?


Ok, if you remove that filter you’ll see the number in the list increase. In this case up from 67 to 84. That’s 36% increase in things you can address. Enough?

What? You want even more? Are you sure? Really sure?


Well, if you are, then the good news is that I have written a script for you that uses the Microsoft Graph to go in and grab all, and I mean ALL, of the secure score items. You’ll find the script in my Office 365 GitHub repo:


Now before you run this scripts, you’ll need to follow the instructions I have written about before:

Access the Microsoft Graph with a script

and set yourself up an OAuth token to access your tenant. You only need to do this once.

You’ll then need enter the values from this configuration into the script prior to running it:


You get these three items from the oAuth token set up I set out.


When run, the script will connect to the Microsoft Graph and start reading information from the Secure Score of YOUR tenant. It will also save the output to a text file in the parent directory. Why you ask?


Well, as you can see from the output from my tenant above, there are now potentially 6,972 items that I can go look at and configure to make my tenant more secure. That’s a 8,200% increase in things to keep you busy.

Remember, you did ask for more after all.

Improved SharePoint Online List creation discovery!


The traditional way that I had been creating lists in a SharePoint Online site was to select the COG in the top right hand corner of the site and selecting Add an app from the menu that appears as shown above.


From there I’d select Custom List and follow the bouncing ball and create a list is one column and then have to go in and customised it. Hard work.


However, if you go to Site Contents and then select New and List you get a COMPLETELY different and much, much better experience!


The above options appear. Even better, if you select From an existing list on the left you get:


a list of every site across your WHOLE SharePoint Online experience! WOW! All you need to do is pick a list that is the same and bamm, you’ll get a new one just like it!

I can’t tell you how much time this saved me once I discovered it. I wonder how I missed the memo?

CIAOPS Need to Know Microsoft 365 Webinar–October


The October webinar is here. This month we’ll take a closer look at the various options available to manage tasks in Microsoft 365. You’ll learn how tasks can be completed using SharePoint, Planner and Microsoft To-Do as well as when to use each service. There will also be the latest Microsoft Cloud news as well as Q and A plus loads more. I’d love if you’d come along and be part of this.

You can register for the regular monthly webinar here:

October Webinar Registrations

The details are:

CIAOPS Need to Know Webinar – October 2019
Thursday 31st of October  2019
10.30am – 11.30am Sydney Time

All sessions are recorded and posted to the CIAOPS Academy.

There of course will also be open Q and A so make sure you bring your questions for me and I’ll do my best to answer them.

The CIAOPS Need to Know Webinars are free to attend but if you want to receive the recording of the session you need to sign up as a CIAOPS patron which you can do here:


or purchase them individually at:


Also feel free at any stage to email me directly via director@ciaops.com with your webinar topic suggestions.

I’d also appreciate you sharing information about this webinar with anyone you feel may benefit from the session and I look forward to seeing you there.