Presentation: Azure Automation invades your data centre

I recently had the pleasure to present on Azure Automation and hybrid workers to the Melbourne Azure Group. I really want to thank all of those who attended, Chris Padgett for inviting me to present and Microsoft for the use of their facilities.

My presentation, Azure Automation invades your data centre, covered off the ins and outs of Azure Automation and extending its reach to your own data centre with hybrid workers. I also spoke about using web hooks and the Azure Automation Authoring Toolkit.

If you haven’t looked at Azure Automation or hybrid workers, I thoroughly recommend that go and take a look. There are a number of excellent resources out there for you to make a start, including:

You can find the runbooks I used in my presentation up on GitHub, and you can download the slides or view them with SlideShare here.

Kieran Jacobsen

Presentation: Exploiting MS15-034 In PowerShell

Last night I had the opportunity to present at the first Melbourne PowerShell Meetup. I want to thank those who attended and in particular, thank David O’Brien for his work in organising such a great event, thanks also go to Versent and Level 3 for providing the food and the event space.

My presentation, Exploiting MS15-034 and working with TCP connections in PowerShell was first up for the night and extremely well received.

As promised, you can find the PowerPoint slides here, or up on SlideShare. You can find the code from the demonstrations up here on GitHub.

SYSLOG, PowerShell, Pester and the PowerShell Gallery

Out of all of the content on this site, my posts about integrating SYSLOG and PowerShell are by far the most popular. Whilst this might seem peculiar to some, I can definitely see the value that this would bring to an enterprise environment.

I first wrote about my initial integration attempts back in 2014. In fact that post, Sending SYSLOG messages from PowerShell, had been the reigning champ as most popular until very recently, losing its title to my work on MS15-034 and my comments on Skype for Business.

In early 2015, a number of bugs were found in the formatting of the UDP messages it sent. I invested time and energy into resolving these issues, resulting in RFC 3164 and RFC 5424 compliant messages being sent. I discussed the process of resolving them in the post, Revisting SYSLOG in PowerShell.

Well, a few weeks ago, it came to my attention that I hadn’t quite ironed out all of the bugs. I spent some time, worked through some possible fixes and implemented them. The issue turned out that when selecting the hostname to send, there was a chance it would send either the wrong IP address, not a blank hostname. It didn’t take long to come up with some new logic (which I still believe could be better), but I wanted to shake the code and determine if there were any others hiding out.


The best way to repeatedly test PowerShell functions, CMDLets, modules and scripts is through the use of Pester. I will admit, that I hadn’t, until this point, taken a look at Pester and this seemed like a great opportunity.

I started with the low hanging fruit. How about we check the input validation is correct? This shook out some validation bugs, and whilst there I realized I could implement parameter sets to improve things.

Now came the hard part. How do I validate the format of the messages that I am sending?

Well, firstly we need to mock some of the CMDLets that are used, to ensure our output is predictable. Things like Get-Date need to be mocked so we can control the messages being sent. I would also modify some of the environment variables for that execution to ensure things like hostnames were predictable.

But the messages are still sent over UDP, how do we look inside them?

The easiest method I found, well it was a bit of a pain, but it produces repeatable and testable outcomes. I would start by setting up a job using New-Job that had a basic UDP listener. The code simply waits for a UDP packet to come in, and returns as output the contents of that packet. Once I have something listening, all I need to do is run my command, and then get the output (of the now completed job) which will contain the SYSLOG message sent.

It is messy, but it allowed me to shake out another logic issue, which has to be a good thing.

A New Name and a New Home

With all of this work, one last thing has always bugged me about the module, the Name! Whilst PowerShellSyslog is simple and descriptive, it has always felt a little bit crude. Now I suck at coming up with names, so I stuck with what seems to be a habit now and stuck Posh- in front of what it actually does. The module and the GitHub repository have now been renamed to Posh-SYSLOG.

I have been attempting, where possible to move my major GitHub repositories to the PoshSecurity banner. As such, I have moved the Posh-SYSLOG to here:

GitHub creates redirects when you move or rename a repository, so all of your current links and working copies should continue to work.

It’s worth noting that if you are manually importing the module via “import-module PowerShellSyslog”, you will need to update this to reflect the new module name.

Easier Installation via the PowerShell Gallery

PowerShell 5 brings a bunch of improvements and new features. One feature that I am so excited about is the Package Management functionality, as it provides new deployment options for not only conventional installed applications but also for PowerShell modules and scripts. The PowerShell Gallery allows administrators and developers to download, install and share modules and scripts.

I have made Posh-SYSLOG available via the gallery here. I will be working to ensure that the gallery is kept up-to-date with the GitHub repo. If you want to install via the gallery, simply type “install-module –name Posh-SYSLOG”.

Future and Thanks

If you are using the module, and find an issue, please feel free to raise an issue on GitHub, I will respond as quickly as possible. I want to ensure this module is the community’s preferred module for connecting to SYSLOG and are happy for any questions, comments or feedback.

I want to thank all of those who have already provided feedback and have provided assistance in testing.

Kieran Jacobsen

How the Skype team failed at PowerShell

The Skype for Business team recently sent out an email to preview customers with guidance around the Skype Meeting Broadcast feature. As I was away, Readify’s CIO, Tatham Oddie was the one who actioned it. The guidance in this email has a number of issues, leading him to post his thoughts up on Twitter, needless to say, he didn't like their advice!

The instructions were pretty simple, as you can see:

A full copy of the email can be found here.

I was shocked when I saw the guidance, from requiring elevation, to changing the execution policy without informing the user, and then a Lync reference to top it all off. I felt that some things needed a discussion.

Unneeded Elevation

The user is asked to run an elevated PowerShell session on two occasions. This is two too many.

For the first instance, the user is asked to run an elevated PowerShell simply to execute Get-Host. GET-HOST! There is no conceivable reason why you would ever need to be elevated to run this CMDLet. I think Get-Host is probably one of the simplest CMDLets in existence, yet the Skype for Business team felt like it needed to be elevated.

Open PowerShell as an administrator (Right click on icon and click run as administrator)

Now the second elevation attempt is almost legitimate. During the step titled “Connect to your Office 365 tenant through remote PowerShell”, we will be executing Set-ExecutionPolicy. Unfortunately, I will discuss later why this command shouldn’t be here, and hence there is no reason for elevation.

Open PowerShell as an administrator (Right click on icon and click run as administrator) and issue the following cmdlets:

Any time you elevate, you need to be more aware of what you are doing. In most cases, elevation is only required if you are making changes to the local system. Instructions to configure a cloud based service requiring elevation should be ring big honking alarm bells, maybe even giant ones. Why on Earth would I be making changes locally, when configuring a cloud service?

I don’t run as local administrator; my every day account is not a member of the local administrators group. This has the unfortunate side-effect of breaking much of Windows 10 (thanks Gabe), however it dramatically improves your security posture. Even if UAC was bypassed, my account isn’t a member of the group, it doesn’t have the privileges you seek. When I need to elevate, it’s a conscious decision on my part, do I want this app to do this, do I want to make this change? I very much believe that all users, be they home users, developers, or system administrators, should run in this model. As a side note, its painfully obvious that most of the Microsoft development team runs with local admin.

Changing The Execution Policy

Set-ExecutionPolicy Unrestricted

I always get a bit upset when someone or something changes the execution policy and in the guidance, that is exactly what the Skype for Business team want to do. Not only have they decided to make this change for me, but they have picked one of the least secure settings, unrestricted. They haven’t even made an attempt to switch it back and the end of the execution process.

The first thing I want to point out is that the Skype for Business CMDLets will work perfectly on execution policy of AllSigned and RemoteSigned. They are after all signed with a code signing certificate issued to Microsoft. After going through all of the effort to get their modules signed, the Skype team simple went YOLO, let’s set the policy to Unrestricted.

They could have of course gotten the user to run simply that PowerShell session as unrestricted, or they could have recorded what the policy was before they changed it, and switched it back. Like this:

There has also been no attempt at even checking what the execution policy was previously, perhaps all would have been OK? Why not have this as a prerequisite step?

Finally, they have made the assumption that the user receiving this guidance can change the policy. I have worked in a few environments where group policy would step in and prevent setting the execution policy to unrestricted.

What is an Admin with MFA to do?

It would have been great to see a mention of what an admin with MFA enabled, should do to run these commands. Thankfully the Skype for Business team allow the use of App Passwords, unlike their poorly informed and aggravatingly annoying peers in the SharePoint and Exchange online teams who reject app passwords.

Is that a Lync reference?

$LyncSession = New-CsOnlineSession -Credential $credential

I know Tatham and I are being pedantic, but a Lync reference, seriously? Microsoft announced that Lync would be replaced by the Skype for Business branding a year ago!

What the email should have looked like

I don’t like tearing things apart without helping to fix them, so how could the Skype team have done things better?

Well here is one that I prepared:

To get started with Meeting Broadcast please follow these steps:

Setup PowerShell
Open PowerShell

To check your PowerShell version, enter this cmdlet:


You must have version 3 or higher. If you have a lower version, install PowerShell version 4:

To check you have the Skype for Business module installed, enter this command:

Get-Module -ListAvailable -Name SkypeOnlineConnector

If there is no results listed, Install the Skype for Business module:

To check you have the correct execution policy level, enter this command:


If the output is undefined or restricted, please view our guidance on setting the execution policy to RemoteSigned:

Restart your computer (as it may not be prompted to do so).

Connect to your Office 365 tenant through remote PowerShell
Open PowerShell and issue the following cmdlets:

$Credential = get-credential
$Skype4BusinessSession = New-CsOnlineSession -Credential $credential
Import-PSSession $Skype4BusinessSession

Note: If your account has Multi-Factor Authentication enabled, please ensure you use your username and an app password.

As you can see, there are a number of changes.

  • There are no elevation requests in the instructions. We check the prerequisites with no elevation, and the connection instructions no longer require elevation either.
  • There are now appropriate checks to ensure the Skype for Business Online Connector is installed. This is a simple touch, but makes the process much easier for users.
  • Checking what the Execution Policy is, and we link to Microsoft guidance on what the appropriate policy is, and how to change the policy.
  • I removed the Lync reference.
  • Changed the restart wording. Sometimes when you install the module, it doesn’t correctly prompt for a restart, but it does indeed need a restart.
  • Added a note around what to do if MFA is enabled.

None of these changes were very difficult, nor where they very time consuming. I really don’t understand why no one at Microsoft picked up any of these issues prior to the email being sent off. I can’t see any excuses for missing this issues, they were painfully obvious.

Kieran Jacobsen

White-listing Tor in CloudFlare with PowerShell

CloudFlare has been one of those technologies that has dramatically improved the Internet since its arrival. CloudFlare provides a number of amazing features, from DDOS protection, traffic analytics, performance optimizations and even free SSL! To top it all off, CloudFlare off the majority of their features for an amazing price – FREE!

Unfortunately, there are a group of users who have suffered with the rapid adaption of websites being protected by CloudFlare; Tor users. Whilst the majority of us receive the benefits of CloudFlare, it has made life for Tor users extremely miserable.

What is the issue with CloudFlare and Tor?

To understand the issues CloudFlare and Tor, we first need to understand how CloudFlare protects a website. When you visit a protected website, CloudFlare performs a risk assessment of your IP address. If CloudFlare decides that you are friendly, then you get to view the website. If it decides you are suspicious, then you will either be prompted with a CAPTCHA request or, in the extreme cases, it will deny access to the website.

The Tor is an interesting network, developed with the aim to protect privacy and defend against surveillance; the network has become a bit of a hive of scum and villainy. Due to the high use of Tor for malicious activity, CloudFlare is naturally suspicious of any connections coming from a Tor exit node, which results in a high risk assessment for all Tor users accessing protected websites.

A high risk assessment results in lots of CAPTCHA requests for Tor users to complete. Every protected page that a Tor user visits, will result in a CAPTCHA request, whilst most of us don’t mind completing these, consider how you would feel answering one every 15 to 20 minutes. It impacts productivity and your sanity.

What is the solution?

The trust of the matter is that there isn’t a simple solution, there isn’t a magic “trust Tor” button in the CloudFlare. It is down to individual website operators to white-list the Tor exit IP addresses; this isn’t trivial, requiring operators to maintain a white-list as the Tor network changes, adding new exit IP addresses that join the Tor network, whilst removing those that leave.

Now is the best time to point out the risks of white-listing. White-listing isn’t without its own risks! When you white-list an IP address in CloudFlare, you are telling it to ignore how risky the traffic coming from that address might be. Not all Tor users legitimately want to view the content of your website; some Tor users are malicious, they are out for blood. White-listing significantly changes the security protection of your site, and you need to be extremely aware of the risks it introduces.

Set and Forget White-Listing

Donncha O'Cearbhaill developed a Python based script with the aim of providing a “set and forget” mechanism for white-listing Tor exit IPs. Donncha’s Automatic CloudFlare Tor Exit Whitelister takes your CloudFlare API token and email address and does all the hard work. The script will grab the latest listing of the Tor exit IPs, and then updates CloudFlare’s white list as appropriate.

When I saw the script, my immediate reaction was “what an amazing idea”, my next was, “how could this be made more accessible to more website operators?

Turning to PowerShell

The obvious answer to encouraging more web site operators to white-list Tor exit nodes is to provide the process in more accessible formats. For Windows users, the best option is to provide the process as a PowerShell script.

So I sat down, learn some Python, and then worked on developing a PowerShell script with similar functionality as Donncha’s. This was a super fun and interesting process. In the end, I deliberately tried to stick a similar logic flow, similar parameters are supported (via parameter liases), and the scripts default output is similar. I added some additional verbose and debug options and added progress bars for long operations. I haven’t included support for specifying the CloudFlare API token and email address via environment variables.

The final result can be found over at GitHub, at All of the functionality is provided by the Set-CloudFlareWhiteList.ps1 script.

Please feel free to raise pull requests, issues, or provide any feedback that you may have.


I have included comment based help, with examples on how to make use of the script. There are three common usage methods.

  1. Specifying a CloudFlare token and email. This will white-list exit node IP addresses across all of the domains in your CloudFlare account
  2. Specifying a CloudFlare token, email and a DNS zone. This will white-list exit node IP addresses for a specific DNS zone.
  3. Specify a Token, email and optionally a DNS zone, and the -ClearFlags parameter. Remove all Tor specific rules for all domains in your CloudFlare account, or for a specific DNS Zone.

Finishing Up

I want to thank Donncha for his work in developing the original Python script. Without his work, I wouldn’t have been able to develop mine.

If you want to find out more about CloudFlare, Troy Hunt has put together a terrific PluralSight course, Getting Started with CloudFlare™ Security. He covers the basics including migration, SSL configuration and even HSTS.

Kieran Jacobsen