PowerShell Framework Module: Connect-Office365

One of the most common things I use Powershell for is Office 356, this requires the modules be installed and connecting to one of the Office365 sessions, Skype, Exchange or the Security & Compliance center.

Follow this project on GitHub

It’s a fairly common process but including it in a script that is portable and performs environmental checks before running can be a bit of a pain. Having this log to file and be consistent in any script with Office 365 interaction is very useful to me

This script simply puts some belts and braces around importing the Office 365 modules and connecting to the service(s) inline with the Powershell Template


How does it work?

The module can be called for each service (Connect-ExOnline, Connect-SFBOnline, Connect-SCCOnline) or as a single command to connect all services (connect-office365). Assuming you go with the connect all services option it works something like this.

Connect-Office365 calls a number of other functions, First Connect-ExOnline to connect to most Office 365 interfaces then Connect-SFBOnline for the Skype for Business interface and finally Connect-SCCOnline for the security and compliance service.

Because each can run independently the first task each sub-function completes is to check if credentials have been provided and the initial connection has been made to the MSOL service. If not this gets completed and the script prompts for credentials and attempts to connect.

The specific PSSession for the function currently being called will then be created allowing access to any of the commandlets for that service.


All this activity is recorded and stored in the application logs folder, a successful run should look something like this:

Started logging at [10/11/2017 18:27:27].
[10-11-2017 18:27:27] Loading Module: Connect-AD.ps1
[10-11-2017 18:27:27] Loading Module: Connect-Office365.ps1
[10-11-2017 18:27:27] Loading Module: Get-ADFunctions.ps1
[10-11-2017 18:27:27] Loading Module: Get-O365Licenses.ps1
[10-11-2017 18:27:27] Loading Module: Set-O365Licenses.ps1
[10-11-2017 18:27:27] Loading Module: Set-SkypeProfile.ps1
[10-11-2017 18:27:27] 	Importing AD Modules
[10-11-2017 18:27:27] Checking for ActiveDirectory Module
[10-11-2017 18:27:27] 		ActiveDirectory module is already loaded
[10-11-2017 18:27:27] 	Starting Connect-Office365
[10-11-2017 18:27:27] 	Connecting to Exchange Online
[10-11-2017 18:27:28] 		Enter your Office 365 admin credentials
[10-11-2017 18:27:36] 		Creating Exchange Online PS session
[10-11-2017 18:27:40] 			Exchange Online PS session built, connecting...
[10-11-2017 18:27:51] 				Connected
[10-11-2017 18:27:52] 	Connecting to Security & Compliance Center Online
[10-11-2017 18:27:52] 		Creating Security and Compliance Center PS Session
[10-11-2017 18:27:54] 			Security and Compliance Center PS session built, connecting...
[10-11-2017 18:28:01] 				Connected
[10-11-2017 18:28:01] 	Connecting to Skype For Business Online
[10-11-2017 18:28:02] 		SkypeOnlineConnector module loaded
[10-11-2017 18:28:02] 		Creating Skype PS session
[10-11-2017 18:28:02] 			Automatic Skype For Business endpoint discovery failed, trying to use manual 'AdminDomain'
[10-11-2017 18:28:19] 			Skype PS session built, connecting...
[10-11-2017 18:28:27] 				Connected

PowerShell Framework

Writing code that can be maintained by multiple people always requires some sort of structure. A lot of the frameworks I have seen are overly complicated for what is still essentially quite small scripts. So I decided to build my own

My requirements were for a small, extensible framework I can use for quick scripts, everything I found online was overly complicated. All I needed was a simple framework so all my scripts are a similar format, work in a similar way, can be moved around without too much fuss and can be easily debugged by someone else should they have issues.

Follow this project on GitHub

To start off I asked myself what I want;

1 Simplicity; This needs to be simple to read, reproduce and trace issues.

2 Troubleshooting; Tracing a script that’s run automatically in the background that failed should be just as easy to trace the fault as if I were stepping through the code. Logging will need to be important

3 Modular; I want to be able to write other modules that I can just slot in when needed. Re-usable parts from other scripts without having to rewrite bits. Things like a module for connecting to Office 365 or a suite of functions I use often.

4 Consistency: Scripts I have written two weeks ago can be difficult follow, one I wrote last year will be unrecognisable. Structure and framework will be important, I should be able to pick up any script and be able to roughly follow it because they all look and feel the same.



I’ve tried to keep things separated so they are easy to locate, easy to modify and easy to follow.

The “Verb-Driver.ps1” file is the work-horse of the framework, this is the file you run to execute the script or schedule a task to run.

The driver will set up the script environment by calling functions or initializing things.


Firstly the config file will be loaded. The Config.ps1 file by default contains the log folder, naming structure and file name format, it should also contain any variables which may be used every time the script is run.

This could be done with command line arguments, however if every time I run a script I have to enter a particular argument, that’s a waste of time. If the script runs as a scheduled task, it’ll be easier to update the config file than update the scheduled task.

Secondly the Logging module is loaded and initialised, this will trigger the log folder to be created and a log file to be created. If the folder and log file already exist the log file will be appended.

Next, any other modules should be loaded (in the template’s default state the “Sample-Functions.ps1”).

If any of these three sections are to fail for any reason they script will terminate and to avoid causing any potential damage.

Once the script is initialised and ready to perform custom actions the main script block can be run, safe in the knowledge that modules are loaded, the script is logging and config files are loaded.

The main script block is where the specific code for the project/tasks goes, this may be processing data from the config file, processing CSV files and other data and exporting some sort of result.

When writing a main script block use the following structure to write messages to the log file.

Log-write -logpath $Script:LogPath -linevalue "A message"

In it’s default state these messages will be written out to console as well as the file. This can be altered in the config file by changing the $Script:LoggingDebug variable to $false

The resultant log file will look something like this:


The output on the PowerShell console will show the same information


Once the Main script block has completed, any session variables will be cleaned up and the log file finished off.


In future I would like to include some sort of unit testing, perhaps with Pester or something similar but I am still trying to learn this so it might be a while.

The logging script is cobbled together and cribbed from scripts found online. I want to re-write this to be more efficient for how I use it. I would also like to add a syslog option which would be useful for running scripts on schedule.

NOTE: PowerShell below version 4 might have issues using the framework

PowerShell Framework Module: Connect-AD

One of the most common things I use Powershell for requires the ActiveDirectory module. In its self, this isn’t an issue, I know I have it installed and that it will import automatically. The problem comes when sending or transferring the script to someone else.

Follow this project on GitHub

If the device running the script doesn’t have some modules installed or available a script will fall-over.

This script simply puts some belts and braces around importing the ActiveDirectory module inline with the Powershell Framework


How does it work?

The script will check for an RSAT installation


The logs produced should look like this

Started logging at [11/10/2017 15:46:01].

[11/10/2017 15:46:01] Loading Module: Connect-AD
[11/10/2017 15:46:01] 	Importing AD Modules
[11/10/2017 15:46:01] Checking for ActiveDirectory Module
[11/10/2017 15:46:01] 		ActiveDirectory module is already loaded