Getting the Job ID of an Executing Azure Runbook

If you’re calling an Azure runbook, it is sometimes useful to be able to get the Job ID, say, to report back and update the source that initiated the call to a runbook. This is a quick post on how to access that ID in PowerShell.

You can access it via the following:



And the output:


Getting the Plain Text Value of an Azure Key Vault Secret with PowerShell

Related imageAzure’s Key Vault is a great way to store certificates, usernames, passwords, for use in your Azure applications, infrastructure operations, and more.

This is just a quick post to tell you how you can get at the value of a stored Secret in the Key Vault with PowerShell and the Azure module.

You can see, I have a Key Vault named gvkeyvault, and a secret named geoffv


Now, to get it, we can use the Get-AzureKeyVaultSecret cmdlet. By giving it our VaultName and our key Name, we can see the key. However, that does not get us the value of our Secret.


To do that, we need to get the SecretValueText property of the Key Vault Secret.

(Get-AzureKeyVaultSecret –VaultName “gvkeyvault” –Name “geoffv”).SecretValueText


You can see we get the value out of “12345”…


Now I need to go change the combination of my luggage.

Slides from February 13, 2018 BASPUG Meeting

Thank you all who came out last night to see my presentation at the Boston Area SharePoint Users Group last night!

As promised, here are my slides from the presentation, hosted on SlideShare:

And here is a link to the blog post which contains all of the steps we demoed during the presentation:

Delete All Versions of a SharePoint File Using PowerShell

There may be instances where you need to remove all previous versions of a file. Well, this is the PowerShell script to do it. This will only work for SharePoint on-premises however.

[string] $UrlToFile

$Site = New-Object -Type Microsoft.SharePoint.SPSite -ArgumentList $UrlToFile
$Web = $Site.OpenWeb()
$SPFile = $Web.GetFile($UrlToFile)

Write-Host “Deleting all versions for file $($UrlToFile)…”

# Remove all versions for file…

# Dispose of the web object

# Dispose of the site object

Save this off as something rememberable, such as Remove-FileVersions.ps1, and pass it the full URL to the file you wish to remove all versions from, for example:

.\Remove-FileVersions.ps1 “”


Loading this assembly would produce a different grant set from other instances

I was trying to get to the root of an issue for a client’s environment that was mysteriously down (SharePoint 2013, March 2017 CU). IIS was up and running, disk space was fine, SQL was also fine, but the sites were just loading blank pages. I checked the error logs, on both the application servers, as well as the web front ends, and they all had this same error message. "An exception occurred when trying to issue security token: Loading this assembly would produce a different grant set from other instances". This is a new one on me, I’ve not seen this error before. (Surprise, it’s SharePoint!)


After a bit of searching, I found this article on TechNet, which advised in setting the trust level to full for the web.config files, clearing out ASP.NET temporary files, and a few other things. None of these solutions worked. However, in the comments of the same article, someone had noted to setting the following registry setting, adding a DWORD (32-bit) value of 1 under a new key named LoaderOptimization in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework. And also doing the same under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework.

Rebooted the servers, although I am sure an IIS reset, and a manual restart of all of the services would have done the trick, but the Farm was down, so a reboot wasn’t an issue to perform.

I found more information on the issue from CA, on this page, under the heading "Defect DE46408 (Formerly 369408) – Application Errors When Instrumenting SharePoint", it states:

"This situation usually happens when the SharePoint site web.config is set to use the legacy CAS model. The legacy CAS model was introduced in .NET version 4, and provokes the error. Refer to for a reference of CAS changes in ASP.NET 4."

I am not exactly sure what prompted this issue, except that there were some recent security updates applied, but this did the trick. I’ll have to dig into this deeper as time permits and see if I can determine the root cause.

PowerShell Script to Get HTTP Headers

Quick script to grab HTTP headers from a given URL.

I named the script Get-HTTPHeaders.ps1, you can save it as whatever you’d like, or, incorporate it into your script as a function, or not even read this post… whatever you want to do. I just find it handy, and wanted to share it.

    [string] $Url

$request = [System.Net.WebRequest]::Create( $Url )
$headers = $request.GetResponse().Headers
$headers.AllKeys |
     Select-Object @{ Name = "Key"; Expression = { $_ }},
     @{ Name = "Value"; Expression = { $headers.GetValues( $_ ) } }

All you have to do is pass it a URL as a parameter. See the example below:


Boston Area SharePoint Users Group February 13, 2018 Meeting

Hey, guess what? I’m speaking at the BASPUG in February… come join me! We’ve moved to a new night – Tuesday, works better for everyone who helps out with the group.

Read the below for more information, and click here to register!

The Boston Area SharePoint Users Group (BASPUG) was founded to bring together like minds to network and share their experiences, triumphs, and tribulations around Microsoft SharePoint, to provide a community platform for Boston area SharePoint users, administrators, developers, architects, of all experience levels, even brand new to SharePoint, to share their knowledge with the community.

Geoff Varosky will be presenting “Easily Integrating a Chat Bot into SharePoint”

Session Abstract

​Chat Bots are very commonplace these days. They have been around for years, but advances in AI technology have allowed for a large growth and advances in this area. Microsoft has in preview a service called QnA Maker, that will allow you to create and build a Chat Bot that you can easily integrate into SharePoint using the Azure Bot Framework, all without writing a single line of code. Join me, and I’ll walk you through step-by-step on this process, along with discussing how and where Chat Bots can be used to provide better adoption and support to your users.

About the Speaker

​Geoff Varosky is a Senior Architect for BlueMetal, a division of Insight, based out of Watertown, MA. He has been architecting and developing web based applications his entire career, and has been working with SharePoint for the past 13 years. Geoff is an active member of the SharePoint community, Co-Founder and Co-Organizer of the Boston Area SharePoint Users Group, co-founder for the Boston Office 365 Users Group, co-organizer for SharePoint Saturday New England.


​Modern technology, craftsman quality. We’re an interactive design and technology architecture firm matching the most experienced consultants in the industry to the most challenging business and technical problems facing our clients. We seek to understand your business strategy and technical foundation to craft modern applications that holistically blend strategic vision, creative design, architecture, and innovation, to exactly meet your needs and ensure your success.​​


Food and beverages will be provided at the meeting free of charge from our meeting sponsor. Food arrives at about 6PM. We generally have pizza (with and without meat), as well a salad, water, and sodas.​​


We will be handing out raffle tickets at the BASPUG meetings.


The meeting will be held at the BlueMetal Boston Office at 9 Galen St, Suite 300, Watertown, MA.​ Parking is FREE, and available in the main lot, and behind the building along the river.
Walk in the main building entrace (not the side of the bus stop), go to the back, take the elevator up to the 3rd floor, and the BlueMetal office is right in front of the elevator.

Join our group on LinkedIn today to connect with the rest of the BASPUG members, and spread the word!

We are also on facebook!!/pages/Boston-Area-SharePoint-User-Group/113652405354617
Follow news about the Boston Area SharePoint Users Group on twitter by following us @BASPUG, and by using the hashtag #BASPUG
Visit the Boston Area SharePoint Users Group website at
Event meetings are organized by Geoff Varosky of BlueMetal and James Restivo of Crow Canyon Systems.


Please visit The Boston SharePoint Area Users Group page for more event details!

Creating Runbooks in Azure and Calling Them from SharePoint Using Webhooks and Flow

AzureFlowSharePointAutomationRunbooks are a feature of Azure Automation that allow you to execute workflows from within Azure or remotely to automate processes.

To give an example, lets say you have a script that monitors an Azure service every 5 minutes to see if it is running or not. The script, will test and see the status of an Azure App Service. If it tests the site, and does not get the HTTP 200/OK message, then it triggers an alert, creates a ticket, and now someone has to go recycle the Azure App Service. If this can happen frequently, then it is something you would look to automate.

In comes the Azure Automation Runbook. You create a PowerShell script that is hosted in Azure (a Runbook), and when your script detects that the service is not responding, it makes a call out to a URL, and the URL runs the Runbook, which restarts the Azure App Service. The monitoring script then runs again, sees that the service is back up, and the appropriate steps are taken.

This might seem like a lot of extra work, but, if you are, say, connecting in through a VPN to manage an Azure environment, it can be quite time consuming just to restart a service.

However, we are not using that as our working example in this article. That was just to give you an idea of the kinds of things that can be done using Runbooks. In this article, we will be showing you how to create a Runbook, and call it from SharePoint, using Microsoft Flow. It will not be a real exciting example either, but, it will show you how to do all this, so you can do more on your own!


This article assumes the following:

  • You have an Azure subscription. If you do not, you can get one here for free to play around
  • You have SharePoint Online

Creating an Azure Automation Account

Before we can create our Runbook, we need to create an Azure Automation Account. Login into the Azure Portal, click on New > Monitoring + Management > Automation


Configure the following settings for your Automation Account:

  • Name: What are you going to call it?
  • Subscription: Select the subscription to use
  • Resource Group: Either create a new one, or, use an existing.
  • Location: Which Azure region should this run in? I am using East US 2… since I’m in the East US.
  • Create Azure Run As account: This is not needed for our test, but, if you’re doing anything in Azure with your runbooks, you will want to configure this. For more information, visit:


Then press Create.

It’ll take a moment while this deploys…


Once done… access it either by the Automation Accounts blade on the left side, or, via the Notifications link Go to resource once its done deploying.


And you will be brought to the landing page for your Automation Account, AutomationTest


Creating an Azure Automation Runbook

Now that we have our Automation Account, we need to create our runbook. From within the Automation Account, click on Runbooks under Process Automation on the left hand side.


Then click Add a runbook at the top of the runbooks dashboard


Click on Quick Create / Create a new runbook


Fill in the details

  • Name: Check-Website
    Give your runbook a name
  • Type: PowerShell
    You can also choose Python 2, Graphical, PowerShell Workflow, and Graphical PowerShell Workflow
  • Description: Check the status of a website
    Enter in a description for the runbook

Then click on Create


And viola! Your runbook has been created!


It doesn’t do anything yet, so, we will need to add code. Click on Edit at the top of the dashboard.

Here is where we will type out, or paste in our PowerShell code for the runbook.


NOTE: Do not use Write-Host, there is no “host” per-say to write to. Instead, ensure all output is written using Write-Output

Let’s add the following code to test if Google is up and running…

Function OutputStatus($type,$status) {
    Write-Output "$type | $status";

Function Get-HTTPSStatus($url,$type) {
    $HTTPSStatus = Invoke-WebRequest $url -Method Get –UseBasicParsing
    if ($HTTPSStatus.StatusCode -eq "200") {
        return OutputStatus -type $type -status "Success"
    } else {
        return OutputStatus -type $type -status "Error"

Get-HTTPSStatus "" "Google Website"


Click on Save


Now lets test it…click on Test pane


Click on Start


You will see a message that it is being submitted


You can then see that it gets queued


And finally, we see the status and the output displayed


Pretty neat!

Now, lets say we want to add some parameters to our script, so we can specify the input… and not have it statically set as just “” as the site, and “Google Website” as the description. Let’s update the code with some parameters…

To get back to your code, click on Edit PowerShell Runbook in the breadcrumb navigation at the top


Update our code with the parameters $Site and $Description, and then Save, and then go back on over to the Test pane


You can now see we have two fields for Site and Description under Parameters. Fill those out…


And run the script again…


Looks good! Now… we can do this all day from within Azure… but remember way back to the start of this article, I mentioned calling this from Microsoft Flow from within SharePoint? To do that… we’re going to need to make a change to our script, as well as create a webhook.

First, lets change our script. You know how we just added parameters? Well, when calling a webhook, we’re going to be making a REST call to a URL. We cannot pass in parameters like we just did to the script. That is good for running within Azure itself… in order to pass parameters to our runbook via a webhook… we need to change the parameters. We will be passing in an object called WebhookData (or whatever else you want to call it). Which will be the JSON data sent along with the REST call. So, let’s update our code to this:


We will then parse out the Site and Description name/value pairs from that and pass it into our script from the $WebhookData object.

The code for the above is here:

Param (

Function OutputStatus($type,$status) {
    Write-Output "$type | $status";

function Get-HTTPStatus($url,$type) {
    $HTTPStatus = Invoke-WebRequest $url -Method Get –UseBasicParsing
    if ($HTTPStatus.StatusCode -eq "200") {
        return OutputStatus -type $type -status "Success"
    } else {
        return OutputStatus -type $type -status "Error"

if ($WebhookData -ne $null) {
    Get-HTTPStatus $WebhookData.RequestHeader.Site $WebhookData.RequestHeader.Description
} else {
    Write-Error "No data received in webhook call."

We need to Publish it first before creating the webhook. Go back to the code view, and click on Publish


It will prompt you to confirm, click Yes, and it’ll be published.


Now that we’ve got that straightened out… let’s move on to creating our webhook.

Creating a Runbook Webhook

From our runbook Dashboard, click on Webhook at the top of the dashboard


Click on Webhook – Create a new webhook


Then give it a name, and an expiration date, and if it should be enabled or not…


Now… notice the big warning sign at the top of this screen…


See? Now… copy and paste that URL at the bottom, and save it somewhere. There is no way to get this URL once the webhook has been created.


Once you have done that, click OK

Then click on Parameters and run settings and then click OK there


Then click Create at the bottom of the form. Until you do that, you can still get the webhook URL…

Ok… now what? Let’s call it from PowerShell, since we need to do a POST to access it.


We can see in the Content section of the output, we are given a JobId of 4164eb1f-57ba-41c3-a7cb-2f556652e9ad

In our runbook, if we go to Jobs under Resources


We can see that a job successfully ran


Click on it, and we can see the status, and you will see the JobId matches what we got from the call from Invoke-WebRequest


You will see there were errors… because we didn’t actually send any data along with it. We just called it directly. But now that we have it… we can move on to SharePoint and Flow.

Creating a Flow to Call our Webhook from SharePoint

Now that we’ve gone through the meat an potatoes of this project… let’s look at linking at all together with SharePoint and Flow.

Log into your SharePoint Online tenant… and lets create a new list.

I’ve got a basic custom list called Flowtest


Now… once created, in the Modern interface… click on Flow > Create a flow


Click on See your flows at the bottom, because we’re going to create a brandy-new one…


Click on + Create from blank at the top of the page


Click on Search at the bottom of the next screen, and search for SharePoint created… we want to add a trigger for when a new item is created in our list.


Select SharePoint – When an item is created

Select your SharePoint Online site from the list, or, enter in the URL, then select the list… in this case, we’re using Flowtest


Then click + New step > Add an action


Click on HTTP under Connectors


Choose HTTP – HTTP


Then fill out the details…

  • Method: POST
  • Uri: The URL we copied when we created our webhook
  • Headers
    Description: Google’s Website (FROM SHAREPOINT!)


And then click on Save Flow

Also… don’t forget to give your flow a name Smile


You should now see your Flow


Now… open a new window, and go back to your list, and create a new item…


And if you check back on your flows…


You will see one succeeded!

Clicking on it will give you the breakdown of the flow run (which is one of the more awesome features of Flow… over IFTTT IMHO FWIW YK?)


Now… let’s go check Azure…

If we look at the jobs for our Runbook… we’ll see a new one in there…


Click on it, and then click on the output



It worked!

Now… let’s make this a bit more functional. Go back to your list settings in SharePoint


I’ve changed the Title field to URL, and added a field called Description as a single line of text.


Now, let’s go back to our Flow…

And edit the HTTP step


Edit the values for Site and Description, and then select the corresponding Site and Description values from the Dynamic Content list that pops up to the right. See what we’re doing here?


Let’s run our Flow… create a new list item, passing in a URL and Description…


and check the status…


It worked! It’s a day of miracles people! While this is not a really exciting example, it shows how to use Azure Runbooks and Webhooks, and how they can be accessed remotely to do a specific task.

What sort of cool things are you doing or have you done with Flow and Runbooks, if anything?

Resources and References

%d bloggers like this: