I have been recently adapting a PowerShell script that collects the Microsoft 365 Service Health using the Office 365 Service Communication API publishing the information into ServiceNow to log a support ticket to make the helpdesk aware of a potential issue in the service. The script was working is no issues when run manually out of PowerShell ISE but failed when ran by Azure Automation.
The focus of this post is to show two specific steps for adapting a locally executed PowerShell script for an Azure Automation runbook. In addition to standard work in Automation to add credentials/connections and create parameters where needed, the following changes were required to adapt a local script for my runbook.
1) Add -UseBasicParsing to Web Requests
The Management API script is filled with various requests using Invoke-WebRequest. Initially, I received numerous errors stating that the Internet Explorer engine is not available.
Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, or
Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.
At line:46 char:9
+ $subs = Invoke-WebRequest -Headers $headerParams -Uri "https://manage ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupportedException
+ FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
To overcome this, I needed to add the parameter UseBasicParsing.
Original: $oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-version=1.0 -Body $body
PowerShell shows progress using $ProgressPreference, which defaults to “continue”. For Automation, I needed to change the option to “silently continue” and suppress progress bars. Locally, the progress can be convenient to see, but it was causing issues with
I have been recently working on a solution for a customer whereby they required Microsoft 365 Service Messages to be logged as an incident using a Service Desk tool and publish to Microsoft Teams Channel.
Microsoft Teams – This was the simple bit as a nice person in the community built a PowerShell script available on GitHub.
Now for the publishing the information to SharePoint Online, this has caused quite a few headaches from banging my head on my desk but it now working. The reason for publishing to SharePoint List is so that it can be used / reference as a data source to pulling the information into ServiceNow.
You can bit with Power Automate however the information required and provided is lacking so the route I am going to demostrate provide a lot more details. Just like the Microsoft Teams post
I have been recently working on a solution for a customer whereby they required Microsoft 365 Service Messages to be logged as an incident using a Service Desk tool and publish to Microsoft Teams Channel.
Microsoft Teams – This was the simple bit as a nice person in the community built a PowerShell script available on GitHub.
Now for publishing the information to SharePoint Online, this has caused quite a few headaches from banging my head on my desk but it now works. The reason for publishing to SharePoint List is so that it can be used / reference as a data source to pulling the information into ServiceNow.
You can bit with Power Automate however the information required and provided is lacking so the route I am going to demonstrate provide a lot more details. Just like the Microsoft Teams post
Create the SharePoint Site
The first thing to do is create a SharePoint Site that can be used as the location for the data. This can be simply done by connecting to SharePoint via PowerShell and running the following command.
We now need to gather some information which will be used later in this blog. Using the same PowerShell console run the following cmdlet
Get-PnPList
Make a note of the Id for Health Status as we will need this later on.
We now need to configure the SharePoint List with required columns for receiving the data.
The column used are;
– Title – Status – Severity – Service – Classification – Uri – Message – Reference
Modifying your Azure Automation Account for SharePoint Lists
In this post, I will make an assumption that you have already implemented pushing messages to Microsoft Teams. If you havent, please visit this article.
Launch Microsoft Teams right click a channel within a Team and select Connectors. Search for Incoming Webhook and click Add
Click Add
Specify the name of the Webhook and click Create
Make a note of the URL below as you will need this for the PowerShell script later and click Done
Create Automation Account
Launch your Azure Portal and search for Automation Account to create a new account.
Specify; – Name – Subscription – Resource Group – Location
No should be selected for “Create Azure Run As Account” as this is will enable the Account to run against Office 365. Click Create
Once the resources has successful created, go into the resource
First of all we need to create a number of variables, these variables will use within the PowerShell script we are going to add to the Runbook.
You will need to add the following variables
– AzO365ServiceHealthApplicationID = Client ID – AzO365ServiceHealthApplicationKey = Client Secrey – AzO365TeamsURI = This is the url we created earlier in the post – AzO365TenantDomain = Tenant ID
If you unsure how to obtain these values, please visit this blog post for more details
Select Create a runbook – Provide a name – Runbook Type should equal PowerShell – Description (is optional)
Press Create
I am now going to use the following PowerShell script available from GitHub within my Runbook. https://github.com/einast/PS_M365_scripts. This script has been created for the sole purpose of extracting the Microsoft 365 Service Health using the Office Service Communication API, which I demonstrated how to configure in another post.
Under the “User Defined Variables” you will need to edit;
Mintues to reflect the same time as your schedule.
Pushover notifications and Services to monitor as shown below
# ------------------------------------- USER DEFINED VARIABLES -------------------------------------
$ApplicationID = Get-AutomationVariable -Name 'AzO365ServiceHealthApplicationID'
$ApplicationKey = Get-AutomationVariable -Name 'AzO365ServiceHealthApplicationKey'
$TenantDomain = Get-AutomationVariable -Name 'AzO365TenantDomain'
$URI = Get-AutomationVariable -Name 'AzO365TeamsURI'
$Minutes = '1440'
# Pushover notifications in case Teams is down.
# Due to limitations and readability, the script will only send the title of the incident/advisory to Pushover.
# COMMENT OUT THIS SECTION IF YOU DON'T WANT TO USE PUSHOVER!
#$Pushover = 'yes' # Comment out if you don't want to use Pushover. I use 'yes' for readability.
#$PushoverToken = Get-AutomationVariable -Name 'AzO365PushoverToken' # Your API token. Comment out if you don't want to use Pushover
#$PushoverUser = Get-AutomationVariable -Name 'AzO365PushoverUser' # User/Group token. Comment out if you don't want to use Pushover
#$PushoverURI = 'https://api.pushover.net/1/messages.json' # DO NOT CHANGE! Default Pushover URI. Comment out if you don't want to use Pushover
# Service(s) to monitor
# Leave the one(s) you DON'T want to check empty (with '' ), add a value in the ones you WANT to check (I added 'yes' for readability)
$ExchangeOnline = 'yes'
$MicrosoftForms = 'yes'
$MicrosoftIntune = 'yes'
$MicrosoftKaizala = 'yes'
$SkypeforBusiness = 'yes'
$MicrosoftDefenderATP = 'yes'
$MicrosoftFlow = 'yes'
$FlowinMicrosoft365 = 'yes'
$MicrosoftTeams = 'yes'
$MobileDeviceManagementforOffice365 = 'yes'
$OfficeClientApplications = 'yes'
$Officefortheweb = 'yes'
$OneDriveforBusiness = 'yes'
$IdentityService = 'yes'
$Office365Portal = 'yes'
$OfficeSubscription = 'yes'
$Planner = 'yes'
$PowerApps = 'yes'
$PowerAppsinMicrosoft365 = 'yes'
$PowerBI = 'yes'
$AzureInformationProtection = 'yes'
$SharePointOnline = 'yes'
$MicrosoftStaffHub = 'yes'
$YammerEnterprise = 'yes'
# Classification(s) to monitor
# Leave the one(s) you DON'T want to check empty (with '' ), add a value in the ones you WANT to check (I added 'yes' for readability)
$Incident = 'yes'
$Advisory = 'yes'
# ------------------------------------- END OF USER DEFINED VARIABLES -------------------------------------
You will now need to define a schedule within the Runbook for it to execute.
Once you have done all of the above, you will receive a nice notification in Microsoft Teams about the Service Health Status
In my next article I will show how simple it is too trigger this Runbook using Power Automate.
Send an email when a new message is added in Microsoft Teams couldnt be any easier. Power Automate has a defined template which allows to connect with Microsoft Teams and Office 365 Outlook connectors to provide the required functionality. So from you Power Automate dashboard look for the template and press continue.
Define which Microsoft Team you would like to target and the required channel.
Define the email address you want to send the messages to
Important Note
The email address must be an active mailbox within your organisation.
Save….
The next time a message is posted, an email will be sent to the defined mailboxes.
First of all, we need to create Configuration Profile within Microsoft Endpoint Manager, you’ll need to gather the SharePoint document library ID or ID), for all the locations you would like to publish to your Windows 10 Devices. In this blog I am going to publish the Blogabout Cloud Library to all my devices.
A window will now appear, (if you receive any prompts to open OneDrive ignore it), click Copy library ID, keep this handy.
Creating the Configuration Profile
In order to apply the configuration to your Windows 10 devices that are enrolled into Microsoft Endpoint Manager. Launch Microsoft Endpoint Manager go to Devices –> Configuration Profiles –> Create Profile
Select Windows 10 and Administrative Templates
Press Next
Provide a Name for the profile and brief description as shown below
Under Computer Configuration and OneDrive, look for the setting Configure team site libraries to sync automatically
Click Enable Enter the name you would like to be displayed and the Library ID as shown below
I am now going to recommend a number of other Microsoft OneDrive settings
Setting
Configuration
Silently sign in users to the OneDrive sync app with their Windows credentials
Enabled
Silently move Windows known folders to OneDrive
Enabled
Use OneDrive Files On-Demand
Enabled
Require user to confirm large delete operations
Enabled
Convert synced team site files to online-only files
Enabled
That completes the Configuration Profile setup, deploy this to your test users before deploying to production.
In my next post I am going to be looking leverage Proactive Remediation to decrease the synchronization time of assigned libraries to the Windows 10 device. The Microsoft default is 8 hours before the assigned libraries are published.
Over the coming weeks I am going to be doing Power Automate post to demostrate the ability to automate workloads within Microsoft 365. Today, I am going look at configuring an Approval process for the creation of a Microsoft Teams Channel
Configuring a SharePoint List
I am no expert when it comes to SharePoint but any expert in “Share Pint” as how does love a good drink now and then. So back on topic within your SharePoint Online Site you need to create a new list as shown in the image below.
Give your SharePoint List a name and description for future reference.
As you can see from the below, I have create a number of columns to capture the information I would like to include into the approval process.
Column Name
Column Type
Title
Title used for the Channel Name.
Team Name
Name of the Microsoft Team
Description
Description of the new Channel
Justification
Justification for the request
Configuring Power Automate
Create a new Flow from the SharePoint List > Automate > Power Automate > See your Flows
Click New > Automated from blank. Provide a Flow name, i.e. “Request – New Microsoft Teams Channel Provisioning”,
Select your Site Address and List Name as shown below.
Modify the Start an approval in line with your requirements, for this post I have included the layout I have created for my own tenant.
We now need a Data Operation in order to gather the Teams ID which is required to identify the Teams where the channel will be created.
Create Filter array which looks at the Teams List based on the Team Name against the entry in the SharePoint List.
Next step is to create a channel with uses the apply to each array.
We have now completed the flow, so let’s go and create the request. As shown below.
This will now generate a request to create the team channel automatically in the background and as you can see all the new Project Channels have been created.
Over the coming weeks I am going to be doing Power Automate post to demostrate the ability to automate workloads within Microsoft 365. Today, I am going look demostrate how I take RSS feeds from Microsoft Blogs and distrube to Microsoft Teams / To-Do. If you have been following my blog for a while you will know I am a big avocate for bringing code important data from Microsoft into Microsoft Teams. As an Architect working within the Microsoft 365 stack, there is always developments, releases and updates coming from Microsoft.
So how do we handle all this information from multiple sources into Microsoft Teams.
So as you can see from below, I have a Microsoft Team called “Microsoft Blogs” in this Teams. I have seperate channels for the areas I am most interested in;
For the purpose of this post I am going to be looking at the Microsoft Security and Compliance Blog. This is a blog that I follow today and generates the most noise. So I am going create a new channel called Microsoft Security and Compliance Blog within Microsoft Blogs Teams.
So first of, make sure you create the Channel where you wil be publishing this data. Next we need the RSS URL, so if you click on the RSS button it will open a new tab with the required URL in the address bar
Provide a new for the Flow and select When a feed item is published
Enter the URL for the RSS Feed
Specify the Team and Channel you would like to publish the message. In my message I am providing a link to the Article, the date is was published, the Title and Summary of the post. The reason for this is so that if I am on the move, I can synchronize the content of the blog post to Microsoft Teams or even Microsoft To-Do so I can continue to read on the move.
When there is a new blog post published you will receive a message into your defined channel, just like the below
Why not To-Do?
So as I mentioned, I also push the blog posts to Microsoft To-Do. The reason for this is so I can close the To-Do item once I have read the article so I never miss any important updates.
You dont even how to stop there if you dont want to. You can leverage what ever connector you want in Power Automate to publish the data.
Over the coming weeks I am going to be doing Power Automate post to demostrate the ability to automate workloads within Microsoft 365. Today, I am going look at configuring an Approval process for the creation of a Microsoft Teams Team
Configuring a SharePoint List
I am no expert when it comes to SharePoint but any expert in “Share Pint” as how does love a good drink now and then. So back on topic within your SharePoint Online Site you need to create a new list as shown in the image below.
Give your SharePoint List a name and description for future reference.
As you can see from the below, I have create a number of columns to capture the information I would like to include into the approval process.
Column Name
Column Type
Title
Title used for the Team Name.
Description
Single line of text used to store the project description.
Visibility
Choice with the following options: “Private” and “Public”. Indicates if a team should visible to non-team members.
Owners
Person or Group with Allow multiple selections enabled.
Members
Person or Group with Allow multiple selections enabled.
Justifcation
Multiple line of text used
Configuring Power Automate
Create a new Flow from the SharePoint List > Automate > Power Automate > See your Flows
Click New > Automated from blank. Provide a Flow name, i.e. “Request – New Microsoft Teams Team Provisioning”,
Select the SharePoint “When an item is created” trigger and click “Create”.
Select your Site Address and List Name from the drop down lists
Create a Start and wait for an approval condition. I have populated the below with information that I required within my own tenant.
Select Apply to each condition and select responses
Select Responses Approver response is equal to Approve
This section is now a bit more complex as I have decided to include an email notification if the request was a approved or rejected. If you follow the screenshot below you will see that I am using the SharePoint List items to provide Team Name, Description, Visiability fields and leveraging the list to include information into the email notification. You dont need to add email notifications into your flow but this is how you would do it.
Now we need to apply each Owner and Member to the new Microsoft Teams and this is completed as followed.
We have now completed the flow, so lets go and create the request. As shown below.
This will now generate a request to the approvers email address and when they click approve the team will be created as shown below with all the Owners and Members you defined.
I have been recently looking how to provide the Current Status of the Microsoft 365 stack into an automated process so I could quickly identify any outages. The Office 365 Service Communications API v2 does exactly that and also allows additional options like Power Automate and PowerShell to pull the data. So in this particular article I am going to look at pushing the Current Status into Microsoft Teams so not just myself but anyone who is apart of the Teams is able to see the status.
Prerequisites
You have configured Azure AD App for Office 365 Service Communications API v2
Licensed for Power Automate either;
Per user plan
Per user plan with attended RPA
Per Flow plan
Configuring Power Automate to deliver posts into Microsoft Teams Channel.
You will now need to repeat the above process for client_secret and tenantid
After that, you need to create an HTTP action to query the Office 365 API. Populate the same as below, making sure all 3 variables are used.
Please be aware the HTTP Connector has an associated cost due to being a Premium Connector. This cost can be found at the following link
If you were to run the flow at this point it would return a big output of JSON. It’s best to use the Parse JSON action to make it easier to read. Set the Content as the Body of the previous HTTP action and the Schema below:
Once the data has been parsed, you can loop through each service and check for service status. The next action is to add an Apply to each action for the value variable.
Within the loop, add a Group Condition that Status is equal to ServiceOperational and ServiceRestored.
Under the If No condition, you can add an action because the service is not operational. To demonstrate, I’ve configured steps for posting a message to Microsoft Teams as shown below
This will then be triggered when there is any status that doesn’t match the define ServiceOperational or ServiceRestored within Office 365. As you can see below I have been notified in Microsoft Teams for an issue with Microsoft 365 stack.
I have been recently running a number of PowerShell scripts where I required to elevate the session to Administrator. Ideally I didnt want to have to provide logon details everytime, so the following script removed the need to provide Admin credentials.
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess);
# Exit from the current, unelevated, process
exit
}