Category: System Administration

Microsoft Flow Usage Tracking Process Proposal

Assumptions: This proposal is predicated on having some reasonable way to download the Flow usage report that currently needs to be generated from the Flow admin page. Otherwise usage tracking is a manual process kicked off by logging into Flow admin site and downloading the CSV usage detail report.

This proposal is also predicated on the idea that our group is not-for-profit — we are not seeking to recoup O365 licensing cost through Flow usage billback.

Issue: Flow execution is “throttled” when usage exceeds the tenant limits. Per a response from a “Flow Staff” individual to ‘what actually happens when you exceed your allocated cycle limit’, “To clarify what is meant by throttling, flow run usage exceeding your tenant limits may be suspended at Flow’s discretion until the following billing cycle.”. While “at Flow’s discretion” is still vague, a tenant risks having Flow runs suspended when they exceed their allocated cycle limit.

Additional cycles can be purchased to continue Flow execution. As of 26 April 2019, an additional 50,000 runs costs 40$. We should ask Microsoft to clarify “Flow’s discretion”. Are enterprise customers able to have Flow execution continued and be billed for their overage? Do enterprise customers receive a short grace period during which time they can purchase additional execution cycles for upcoming months?

Farther complicating the issue, it is difficult for a manager to assess how many flow cycles are being executed by their subordinates. While Microsoft has added per-workflow usage statistics, even when workflows are maintained under shared spaces, individually checking each Team flow to determine how many times it has executed is cumbersome.

Solution: If we cannot purchase execution cycles after our limit has been reached, we will need to routinely track the number of cycles executed in our tenant to avoid both execution disruption and purchasing additional runs in months where we do not exceed our “free” cycle quota. To determine an appropriate alerting interval, we need to determine the time between identifying that our tenant is approaching its threshold and the activation of newly purchased cycles.

To create a financial incentive to maintain efficient Flow jobs, cycles should be billed back to the business units that are using Flow. Since each Office 365 license includes 2,000 Flow execution cycles, a BU is not charged when they are under their “free” allocation (i.e. # of O365 licensed users in the BU times 2,000). BUs may be charged at a rate of 0.0008$ per cycle over their “free” allocation (question: does this need to be rounded up to avoid fractional pennies? i.e. one cent per 1,250 cycles). In months were the Flow execution cycle limit in the tenant is exceeded, the BUs are charged. Many individuals do not use Flow so there are unused execution cycles. If we are under our tenant limit but a BU has exceeded their allocation, no additional money has been spent so no billback occurs. The BU owner would still be notified with a message that includes “due to low company-wide Flow usage, your overage does not incur any charge this month. This overage could result in a charge of up to {calculatedOverageCost} charged to your BU.”. The message will include the web link to help them understand who is using Flow in their organization.

We would develop a script to update a data table. This table will record each Flow user, the number of cycles used month to date, the number of cycles used during the previous month, the number of cycles used year to date, and the number of cycles used during the previous year. A web interface like https://msteams.windstream.com/usageReporting/index.php (which allows managers to view Teams usage of their sub-organization) would be created to provide visibility into the Flow usage data. We would also develop a script, run at the beginning of each month, that determines the BU for each Flow user, aggregates “previous month” Flow usage data per BU, calculates the total number of O365 licensed accounts per BU, calculates the BU’s cycle overage, notifies BU owners per the previous paragraph, and either initiates the billback process or produces the data which is needed to initiate the billback process.

I additionally suggest we create a “best practices” guide for using Flow. As an example, creating a workflow ‘perform some process every time our shared mailbox receives a message from BOB’ incurs a cycle execution every time the shared mailbox receives a message, regardless of the message source. When creating workflows triggered by e-mail messages, using a dedicated mailbox (research: can an O365 group mailbox be used as a trigger??) avoids non-trigger messages executing a Flow.

Did you know … you can redirect custom URLs to Microsoft Forms?

Microsoft Forms provides a simple framework for creating surveys and polls which can be distributed either to internal users or made publicly available. Including your Form URL in an a href tag is one way to avoid trying to communicate the super-long Form URL … but if you’re looking for a ‘pretty’ URL, something that can be included in print media or provided to someone verbally, you can redirect custom URLs to your Form URL.

Generally, hosting a forwarding URL requires a web server; but URL-shortening services should work. To use a web server, you’ll need to configure a site (or path from a site) to serve an HTTP redirect. I am using 302 (temporary) redirection instead of 301 (permanent redirection) in case I want to forward my custom URL to a different Form.

Apache config

Use the “Redirect” directive in your virtual host config:

<VirtualHost 10.1.2.3:80>
     ServerName customsite.example.com
     ServerAlias customsite.example.com customsite
     Redirect / https://forms.office.com/Pages/DesignPage.aspx#FormID=wbRnJe2w9UCu41....
</VirtualHost>

IIS Config

In the IIS management utility, navigate to your website and select “HTTP Redirect”.

Check the box to redirect requests and paste in your Forms URL. Check the box to redirect all requests to the exact destination.

When your site is accessed, the browser receives the HTTP redirect and displays your Form.

 

IIS Failed Request Tracing

I set up a PHP website with a really strange issue: site/path/index.php worked fine, but site/path threw a generic ‘something failed’ error. I added the suggested lines to web.config and got … another completely generic error.

You can enable Failed Request Tracing in the site to get a clearer picture of what is going on.

You’ll need to create a tracing rule that includes the return code you are seeing. Click “Add …” and create a rule that will capture the exception you are seeing. Once the rule is in place, reproduce the error in your browser. Click “View Trace Logs …” to open the location where the trace logs are stored.

On the local disk, you’ll get a web page with the exception information. Here, I’m seeing an error in ScriptModule-4.0. The ‘Request Details” tab contains more information.

My oddity seems to be related to .NET somehow … I don’t need CLR to manage code execution for my site, so the simple solution was to turn it off – edit the application pool and select “No Managed Code”.

Voila! My site loads using the default document.

 

SPO Guest Access Stops Working

I ran across an interesting issue today — Windstream’s got a really awesome SPO site for SD Project Management – tracking orders, equipment orders, 3rd party cabling installations, etc. The cool part about the site being hosted in SharePoint Online is that a customer can get set up as a federated partner and be granted access to see equipment readiness and installation scheduling within our system.

Guest access is an interesting concept – while I have an account in our tenant that is linked to my Active Directory account in our domain, you can also create links to accounts in other company’s directories. The guest account can then be set up to access our Azure resources – added to Azure groups, added to SharePoint Online groups, invited to join Teams.

A guest user had her computer replaced and could no longer access the site – SPO insisted that she was not a valid user. Looking in Azure AD, the account existed; the audit log even showed successful authentication events. I’m not sure if the computer replacement was a coincidence, the new computer had a different configuration, or if your browser stashes some information that allowed her to avoid authentication failures, but her guest account in our tenant was no longer working.

For companies that don’t have Azure AD, when an individual accepts guest account access … the guest account link in our tenant lists “Microsoft Account” as the source.

But when the company sets up Azure, the auth framework seems to get confused by the Azure AD account. Easy enough solution – we’ve got to delete the guest account that’s linked to their MS Account from Azure AD. Bonus step specific to SPO, a site administrator needs to use <site>/_layouts/15/people.aspx?MembershipGroupId=0 to delete the guest account from the SPO site.

 

Once the “Microsoft Account” guest account has been removed, the guest can be re-invited. They’ll step through the registration process again but the guest account will be linked up to their Azure AD account.

 Re-add the new guest account to whatever they were using & their access will be restored.

 

Quick OpenHAB2 Apt Install In Docker Ubuntu Container

# Set up docker image — exposes OpenHAB web on your port 8080
docker run -p 8080:8080 -dit –name UbuntuOH2 ubuntu:latest

# Shell into the container
docker exec -it UbuntuOH2 /bin/bash

# From within the container, run:
apt update
apt install sudo
apt install vim
apt install wget
apt install gnupg
apt install apt-transport-https

# Repo for Zulu Java
echo ‘deb http://repos.azulsystems.com/debian stable main’ > /etc/apt/sources.list.d/zulu.list

# Repo for OpenHAB2 stable build
wget -qO – ‘https://bintray.com/user/downloadSubjectPublicKey?username=openhab’ | apt-key add –
apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv-keys 0xB1998361219BD9C9
echo ‘deb https://dl.bintray.com/openhab/apt-repo2 stable main’ | tee /etc/apt/sources.list.d/openhab2.list

apt-get update
apt-get install zulu-8
apt-get install openhab2
apt-get install openhab2-addons

/etc/init.d/openhab2 start

# OpenHAB will be accessible on your IP at 8080. E.g. http://10.10.10.123:8080.
# docker start/stop UbuntuOH2

WordPress 5 AutoSave Issue

I upgraded to WordPress 5 back when it was still in preview, and wasn’t shocked to find some issues. When I would create a post, WordPress would go into an auto-saving loop. Now I like the idea of background saves to prevent data loss if by browser falls over … but the instant the auto-save would complete, another would kick off and the editor was basically unusable (copy content / refresh page / paste content / cross fingers that the auto-save loop didn’t happen that time). I tried setting the auto-refresh interval in the config file, but that had no impact.

With the 5.0.0 release, I was dismayed to find the problem lingering but 0.0 releases usually have some quirks too. But two dot-dot releases later, and a lot of frustration that auto-save has caused waaaay more data loss in six months than years worth of browser glitches ever managed, I started researching the problem to find a solution other than “wait for the next release to fix it”.

I came across an issue on GitHub which not only reports the same issue, but included a bit of code to add to the theme functions.php file:

add_filter( 'block_editor_settings', 'jp_block_editor_settings', 10, 2 );

function jp_block_editor_settings( $editor_settings, $post ) {
	$editor_settings['autosaveInterval'] = 2000; //number of second [default value is 10]

	return $editor_settings;
}

And my WordPress is usable again!

Preventing Unauthenticated Binds in Active Directory

There is finally a Windows server-side solution to prevent “unauthenticated bind” requests (detailed in LDAP RFC 4513 section 5.1.2 with a note regarding the subsequent security considerations in section 6.3.1) from allowing unauthorized users to successfully authenticate.

It has always been possible to handle in code (i.e. verify that username and password are both non-null prior to communicating with the directory server) and is my personal preference as a developer cannot predict how individual directory services will be configured.

But for the third-party apps that don’t prevent unauthenticated binds, a setting to disallow unauthenticated bind operations to Active Directory was added in Windows 2019 — in your Configuration partition, open the properties of CN=Directory Service, CN=Windows NT, CN=Services, CN=Configuration — find the msDS-Other-Settings attribute, and add a new entry DenyUnauthenticatedBind=1

Microsoft Graph — Application Registration

The application I am registering will pull report data from Graph for use within existing company systems. I will be assigning application-level permissions and no callback URL is needed.

To register an application, log into http://portal.azure.com and select “Azure Active Directory” from the left-hand navigation column. Then select “App Registrations (preview)”.

Click on “New registration”

Provide a descriptive name for the application — tenant managers can see all of the registered applications and it’s a lot easier if you ask them to approve access for “Specific Application Name For Engineering” than “LJR Test”.

The application will be created and you will be brought to the app overview. Select “API permissions” then click the “Microsoft Graph” hyperlink.

Click on “Application permissions”

And find the permissions you need. For the script I want to run, I need Reports.Read.All. Click “Update permissions” to save your changes.

If you are a tenant admin, you can approve your own rights. Otherwise, you’ll need to contact a tenant admin and have them approve the permissions you have requested. Once the permissions have been acknowledged, you’re ready to go.

You will need the app ID and a secret for use within your code. The application ID is listed on the application “Overview”.

To create a secret, select “Certificates & secrets” then click “New client secret”. This is displayed one time, so copy it into your code now.

Splunk Teams Connector – Followup

We managed to use the stock Teams webhook app in Splunk — just needed to modify the search being used. Adding “|table” and specific fields to be included in the table avoids having to filter the list data within the Python code

There still is a tweak to the code that I prefer — Python lists aren’t in any particular order. I’d like to be able to look the same place in the Teams post to see a particular field. Adding a sort when the facts array is put into the post body ensures the fields are in the same order each time.

        sections=[
            {"activityTitle": settings.get("search_name") + " was triggered"},
            {
                "title": "Details",
                "facts": sorted(facts)
            }
        ],

And I’ve got a Teams post from Splunk with a generic script — desired fields are specified within the search, so can be easily changed.