---
title: "Run Custom Availability Tests using PowerShell and Azure Application Insights, even on-premises"
excerpt: "The built-in availability tests in Azure Application Insights are great but very basic. You can create your own custom availability test. Learn how to create a custom availability test using PowerShell and Application Insight's .NET SDK."
publishDate: "2021-02-04T00:00:00"
createDate: "2021-02-04T04:51:07.893"
updateDate: "2021-02-04T19:36:41.517"
category: "azure"
categoryName: "Azure"
tags: ["Azure","Application Insights","APM","PowerShell",".NET"]
permalink: "/blog/azure/run-availability-tests-using-powershell-and-azure-application-insights"
canonical: "/blog/azure/run-availability-tests-using-powershell-and-azure-application-insights"
image: {"src":"/media/rjzpj2op/powershell-and-azure-application-insights-long.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"Banner","width":1120,"height":400,"coordinates":null}]}
imageAlt: "PowerShell and Application Insights logo with title: Run custom availability tests using PowerShell and Azure Application Insights"
imageBackgroundColor: "#0c0c0c"
thumbnailImage: {"src":"/media/1yeolfae/powershell-and-azure-application-insights-square.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"thumbnail","width":250,"height":250,"coordinates":null}]}
thumbnailImageAlt: "PowerShell and Azure Application Insights logo"
metaTitle: "Run custom availability tests using PowerShell and Azure Application Insights, even on-premises"
metaDescription: "If the built-in availability tests in Azure Application Insights are too basic, you can create your own custom test. Let's do that using PowerShell and Application Insight's .NET SDK"
ogTitle: "Run custom availability tests using PowerShell and Azure Application Insights, even on-premises"
ogDescription: "The built-in availability tests in Azure Application Insights are great but very basic. You can create your own custom availability test. Learn how to create a custom availability test using PowerShell and Application Insight's .NET SDK."
ogImage: {"src":"/media/t1mfnfxq/powershell-and-azure-application-insights-social.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"OpenGraph","width":1200,"height":630,"coordinates":null}]}
ogImageAlt: "PowerShell and Application Insights logo with title: Run custom availability tests using PowerShell and Azure Application Insights"
relatedPostKeys: ["182ba17c5b7c4fb294a5c9a328708daa","ac3db7ced0ae4f8abc312d1b5b166568","24671abe31fd460abce121678b19c3ef"]
noIndex: false
noFollow: false
sitemapExclude: false
source: {"nodeId":1413,"contentKey":"94f25a68406640798b58d7d8bed80cea","sortOrder":80}
---


Application Insights (part of Azure Monitor) is an Application Performance Management (APM) service. You can monitor your applications on Azure, on-premises, and anywhere else to get key insights into the performance and usage of your applications. One feature of Application Insights (AI) which is often overlooked but key to many applications is <strong>Availability tests</strong>. 




## Application Insights Availability Tests {#application-insights-availability-tests}

The Availability features within Application Insights allow you to create tests to verify the availability of your applications. Here's a screenshot of the Availability blade in the Azure Portal:

<picture>
  <img src="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/zyqle5f5/availability-tests-cropped.png" srcset="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=430/media/zyqle5f5/availability-tests-cropped.png 430w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=645/media/zyqle5f5/availability-tests-cropped.png 645w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=718/media/zyqle5f5/availability-tests-cropped.png 718w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=860/media/zyqle5f5/availability-tests-cropped.png 860w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1077/media/zyqle5f5/availability-tests-cropped.png 1077w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/zyqle5f5/availability-tests-cropped.png 1120w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1436/media/zyqle5f5/availability-tests-cropped.png 1436w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1680/media/zyqle5f5/availability-tests-cropped.png 1680w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=2240/media/zyqle5f5/availability-tests-cropped.png 2240w" sizes="(max-width: 480px) 430px, (max-width: 768px) 718px, 1120px" width="1120" height="697" alt="Screenshot of Azure Application Insights Availability blade" loading="lazy" decoding="async">
</picture>

The 3 tests in the screenshot are configured to test the availability of my application in different ways and the results are plotted in the graph above.


You can configure simple <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/monitor-web-app-availability">URL tests</a> that will send HTTP requests to the specified URL and verify the HTTP response. You can also configure <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/availability-multistep">multi-step web tests</a> for more complicated scenarios which you can build using Visual Studio Enterprise. <br>Both types of availability tests can be configured to run at a frequency of your choice. But one of the coolest features in my opinion is that <strong>you can configure these tests to run from 16 different locations</strong>. This way you not only verify the availability of your application from one location, but you can <strong>verify the availability from all over the world</strong> and compare the performance between locations. Once the tests are configured, you can set up Azure Monitor Alerts to notify you using SMS, phone, emails, and push notifications.


The built-in Availability features of Application Insights are great, but

- what if you don't have Visual Studio Enterprise, or don't want to use this proprietary testing software?
- what if your application is <strong>hosted on-premises</strong> or inside a <strong>locked-down VNET</strong>? The <strong>built-in tests can only test publicly available applications</strong>
- what if you already have scripts to verify availability, but still want to integrate with Application Insights for its data storing, querying, dashboards, and alerting capabilities?

In that case, you can develop your own custom availability tests and send the data to Azure using the Application Insights SDK or send it to the Azure API directly.

## Create a Custom Availability Test using PowerShell {#create-a-custom-availability-test-using-powershell}

The easiest way to send availability data to Application Insights is to use the Application Insights SDK. For PowerShell, you can use the .NET version of the SDK since PowerShell can natively interop with .NET. Follow the steps below to create a custom availability test using PowerShell.

Open a PowerShell shell and create a folder to store all your files:

<pre style="color:#000000;background:#ffffff;"><span style="color:#005fd2; ">mkdir</span> <span style="color:#0000e6; ">PowerShellAiAvailability</span>&#10;<span style="color:#005fd2; ">cd</span> <span style="color:#0000e6; ">PowerShellAiAvailability</span>&#10;</pre>




If on Windows, use the NuGet CLI ([download page](https://www.nuget.org/downloads)) to install the [Application Insights SDK NuGet package](https://www.nuget.org/packages/Microsoft.ApplicationInsights/):




<pre style="color:#000000;background:#ffffff;"><span style="color:#005fd2; ">nuget</span> <span style="color:#0000e6; ">install</span> <span style="color:#0000e6; ">Microsoft.ApplicationInsights</span> <span style="color:#074726; ">-Version</span> <span style="color:#008000; ">2.16</span><span style="color:#0000e6; ">.0</span> <span style="color:#074726; ">-o</span> <span style="color:#0000e6; ">Dependencies</span>&#10;</pre>




This command will create the '<em>Dependencies</em>' folder, and then download and unpack the required packages to the folder. 





There are other ways to install NuGet packages, but you can always fall back to downloading the package manually from the NuGet gallery. To download the package, navigate to the [NuGet package page](https://www.nuget.org/packages/Microsoft.ApplicationInsights) and click on the link "Download package". The extension of the file will be "nupkg", but this is a simple zip-archive. Rename the extension to "zip" and unzip the archive. The DLL's can be found in the '*lib*' subfolder.





Now that you have the AI SDK DLL's, create a PowerShell file '*CheckAvailability.ps1*' with the following contents:




<pre style="color:#000000;background:#ffffff;">$MyInvocation.MyCommand.Path <span style="color:#7f0055; font-weight:bold; ">|</span> Split-Path <span style="color:#7f0055; font-weight:bold; ">|</span> Push-Location;&#10;&#10;<span style="color:#3f7f59; "># Update the path if you install a different version of AI NuGet package</span>&#10;Add-Type -Path <span style="color:#2a00ff; ">.\Dependencies\Microsoft.ApplicationInsights.2.16.0\lib\netstandard2.0\Microsoft.ApplicationInsights.dll</span>;&#10;&#10;$InstrumentationKey = $Env:APPINSIGHTS_INSTRUMENTATIONKEY;&#10;<span style="color:#3f7f59; "># If your resource is in a region like Azure Government or Azure China, change the endpoint address accordingly.</span>&#10;<span style="color:#3f7f59; "># Visit </span><span style="color:#3f3fbf; ">https://docs.microsoft.com/azure/azure-monitor/app/custom-endpoints#regions-that-require-endpoint-modification</span>&#10;$EndpointAddress = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://dc.services.visualstudio.com/v2/track</span><span style="color:#2a00ff; ">"</span>;&#10;&#10;$Channel = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.Channel.InMemoryChannel]</span>::new();&#10;$Channel.EndpointAddress = $EndpointAddress;&#10;$TelemetryConfiguration = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration]</span>::new(&#10;    $InstrumentationKey,  &#10;    $Channel&#10;);&#10;$TelemetryClient = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.TelemetryClient]</span>::new($TelemetryConfiguration);&#10;&#10;$TestName = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">AvailabilityTestFunction</span><span style="color:#2a00ff; ">"</span>;&#10;$TestLocation = $Env:COMPUTERNAME; <span style="color:#3f7f59; "># you can use any string for this</span>&#10;$OperationId = (New-Guid).ToString(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">N</span><span style="color:#2a00ff; ">"</span>);&#10;&#10;$Availability = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry]</span>::new();&#10;$Availability.Id = $OperationId;&#10;$Availability.Name = $TestName;&#10;$Availability.RunLocation = $TestLocation;&#10;$Availability.Success = <span style="color:#7f0055; font-weight:bold; ">$False</span>;&#10;&#10;$Stopwatch =  <span style="color:#7f0055; font-weight:bold; ">[System.Diagnostics.Stopwatch]</span>::New()&#10;$Stopwatch.Start();&#10;&#10;$OriginalErrorActionPreference = $ErrorActionPreference;&#10;<span style="color:#7f0055; font-weight:bold; ">Try</span>&#10;{&#10;    $ErrorActionPreference = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Stop</span><span style="color:#2a00ff; ">"</span>;&#10;    <span style="color:#3f7f59; "># Run test</span>&#10;    $Response = Invoke-WebRequest -Uri <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://swimburger.net</span><span style="color:#2a00ff; ">"</span>;&#10;    $Success = $Response.StatusCode -eq 200;&#10;    <span style="color:#3f7f59; "># End test</span>&#10;    $Availability.Success = $Success;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">Catch</span>&#10;{&#10;    <span style="color:#3f7f59; "># Submit Exception details to Application Insights</span>&#10;    $Availability.Message = $_.Exception.Message;&#10;    $ExceptionTelemetry = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry]</span>::new($_.Exception);&#10;    $ExceptionTelemetry.Context.Operation.Id = $OperationId;&#10;    $ExceptionTelemetry.Properties[<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">TestName</span><span style="color:#2a00ff; ">"</span>] = $TestName;&#10;    $ExceptionTelemetry.Properties[<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">TestLocation</span><span style="color:#2a00ff; ">"</span>] = $TestLocation;&#10;    $TelemetryClient.TrackException($ExceptionTelemetry);&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">Finally</span>&#10;{&#10;    $Stopwatch.Stop();&#10;    $Availability.Duration = $Stopwatch.Elapsed;&#10;    $Availability.Timestamp = <span style="color:#7f0055; font-weight:bold; ">[DateTimeOffset]</span>::UtcNow;&#10;    &#10;    <span style="color:#3f7f59; "># Submit Availability details to Application Insights</span>&#10;    $TelemetryClient.TrackAvailability($Availability);&#10;    <span style="color:#3f7f59; "># call flush to ensure telemetry is sent</span>&#10;    $TelemetryClient.Flush();&#10;    $ErrorActionPreference = $OriginalErrorActionPreference;&#10;}&#10;&#10;Pop-Location;&#10;</pre>

Let's dissect the code:

<pre style="color:#000000;background:#ffffff;">$MyInvocation.MyCommand.Path <span style="color:#7f0055; font-weight:bold; ">|</span> Split-Path <span style="color:#7f0055; font-weight:bold; ">|</span> Push-Location;&#10;</pre>

If you execute the script while your current working directory (CWD) is in a different location, this line will change the CWD to the folder location of the script file. This will make sure relative paths will point to the correct files. <br>At the end of the script, `Pop-Location` is used to change CWD back to the original location.

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; "># Update the path if you install a different version of AI NuGet package</span>&#10;Add-Type -Path <span style="color:#2a00ff; ">.\Dependencies\Microsoft.ApplicationInsights.2.16.0\lib\netstandard2.0\Microsoft.ApplicationInsights.dll</span>;&#10;</pre>

The `Add-Type` command will load the specified DLL which is the Application Insights SDK. Make sure the path is correct in case you installed a different version or if you need to support a different [target framework moniker](https://docs.microsoft.com/en-us/dotnet/standard/frameworks) (TFM). Depending on the version of PowerShell and .NET on your machine, you may need to pick a different TFM.

<pre style="color:#000000;background:#ffffff;">$InstrumentationKey = $Env:APPINSIGHTS_INSTRUMENTATIONKEY;&#10;</pre>




The above command fetches the Application Insights Instrumentation Key from the environment variables. **This env variable will be configured later.**




<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; "># If your resource is in a region like Azure Government or Azure China, change the endpoint address accordingly.</span>&#10;<span style="color:#3f7f59; "># Visit </span><span style="color:#3f3fbf; ">https://docs.microsoft.com/azure/azure-monitor/app/custom-endpoints#regions-that-require-endpoint-modification</span>&#10;$EndpointAddress = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://dc.services.visualstudio.com/v2/track</span><span style="color:#2a00ff; ">"</span>;&#10;&#10;$Channel = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.Channel.InMemoryChannel]</span>::new();&#10;$Channel.EndpointAddress = $EndpointAddress;&#10;$TelemetryConfiguration = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration]</span>::new(&#10;    $InstrumentationKey,&#10;    $Channel&#10;);&#10;$TelemetryClient = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.TelemetryClient]</span>::new($TelemetryConfiguration);&#10;</pre>

The above snippet creates and configures the telemetry client which will be used to send the telemetry to Application Insights.

<pre style="color:#000000;background:#ffffff;">$TestName = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">AvailabilityTestFunction</span><span style="color:#2a00ff; ">"</span>;&#10;$TestLocation = $Env:COMPUTERNAME; <span style="color:#3f7f59; "># you can use any string for this</span>&#10;$OperationId = (New-Guid).ToString(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">N</span><span style="color:#2a00ff; ">"</span>);&#10;</pre>

The following variables will be sent for every piece of telemetry:

- <strong>TestName</strong>: Pick any meaningful name, this will be shown in the availability dashboard
- <strong>TestLocation</strong>: The out of the box availability tests will put their Azure region in there, but you can put anything in there that's meaningful to you. In this case, the variable is set to the computer's name also referred to as the hostname. This way you could identify which server or computer ran the test.
- <strong>OperationId</strong>: Use a GUID to ensure this is a unique identifier, the output of <code>(New-Guid).ToString("N")</code> looks like '4832d6822c4b4d378ffa566cc0fe28e0'.<br>You could use other ways to generate ID's, but I haven't tried it.



<pre style="color:#000000;background:#ffffff;">$Availability = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry]</span>::new();&#10;$Availability.Id = $OperationId;&#10;$Availability.Name = $TestName;&#10;$Availability.RunLocation = $TestLocation;&#10;$Availability.Success = <span style="color:#7f0055; font-weight:bold; ">$False</span>;&#10;</pre>

This snippet creates an `AvailabilityTelemetry` object and configures it with the variables you just created. This is the object you need to submit to Application Insights.

<pre style="color:#000000;background:#ffffff;">$Stopwatch = <span style="color:#7f0055; font-weight:bold; ">[System.Diagnostics.Stopwatch]</span>::New()&#10;$Stopwatch.Start();&#10;</pre>

The snippet above creates a stopwatch and starts it. The stopwatch will be used to measure the time it takes to verify the availability.

<pre style="color:#000000;background:#ffffff;">$OriginalErrorActionPreference = $ErrorActionPreference;&#10;<span style="color:#7f0055; font-weight:bold; ">Try</span>&#10;{&#10;   $ErrorActionPreference = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Stop</span><span style="color:#2a00ff; ">"</span>;&#10;</pre>




The <code>$ErrorActionPreference</code> is a variable always available in PowerShell and it determines the default error action preference for PowerShell commands which defaults to "Continue". When the error action preference is set to "Continue", it will output errors to the console, but just continue as if nothing happened. As a result, it won't jump to the <code>catch</code> clause which is undesired in this section of the script. Therefore the error action preference is changed to "Stop" which will make the script jump to the <code>catch</code> clause on error. 





To undo the change to `$ErrorActionPreference` later, you need to store the original value in `$OriginalErrorActionPreference`.




<pre style="color:#000000;background:#ffffff;">  <span style="color:#3f7f59; "># Run test</span>&#10;  $Response <span style="color:#2a00ff; ">=</span> <span style="color:#2a00ff; ">Invoke-WebRequest</span> -Uri <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://swimburger.net</span><span style="color:#2a00ff; ">"</span>;&#10;  $Success = $Response.StatusCode -eq 200;&#10;  <span style="color:#3f7f59; "># End test</span>&#10;  $Availability.Success = $Success;&#10;}&#10;</pre>

Between the "Run test" and "End test" comment, you should perform whatever checks you need to verify the availability of your application. The verification in the above test is a simple HTTP request to my website and verifying whether the response status code is 200. That's essentially the same as what the built-in URL Ping test does, but you could replace this with selenium UI tests, database connection tests, etc. Whatever you can do with PowerShell you could use to verify availability.

If an error occurs, the script jumps to the following catch clause:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Catch</span>&#10;{&#10;  <span style="color:#3f7f59; "># Submit Exception details to Application Insights</span>&#10;  $Availability.Message = $_.Exception.Message;&#10;  $ExceptionTelemetry = <span style="color:#7f0055; font-weight:bold; ">[Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry]</span>::new($_.Exception);&#10;  $ExceptionTelemetry.Context.Operation.Id = $OperationId;&#10;  $ExceptionTelemetry.Properties[<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">TestName</span><span style="color:#2a00ff; ">"</span>] = $TestName;&#10;  $ExceptionTelemetry.Properties[<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">TestLocation</span><span style="color:#2a00ff; ">"</span>] = $TestLocation;&#10;  $TelemetryClient.TrackException($ExceptionTelemetry);&#10;}&#10;</pre>

In the catch clause, an `ExceptionTelemetry` object is created and initialized with the exception which just occurred. You have to use the same `$OperationId` for the `ExceptionTelemetry` so that Application Insights can relate telemetry instances with each other.<br>Finally, the invocation of `$TelemetryClient.TrackException` will queue the data submission to Application Insights.

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Finally</span>&#10;{&#10;  $Stopwatch.Stop();&#10;  $Availability.Duration = $Stopwatch.Elapsed;&#10;  $Availability.Timestamp = <span style="color:#7f0055; font-weight:bold; ">[DateTimeOffset]</span>::UtcNow;  &#10;  &#10;  <span style="color:#3f7f59; "># Submit Availability details to Application Insights</span>&#10;  $TelemetryClient.TrackAvailability($Availability);&#10;  <span style="color:#3f7f59; "># call flush to ensure telemetry is sent</span>&#10;  $TelemetryClient.Flush();&#10;  $ErrorActionPreference = $OriginalErrorActionPreference;&#10;}&#10;&#10;Pop-Location;&#10;</pre>

Whether there was an error or not, the script will always run the statements inside the `Finally` clause. The stopwatch is stopped and the duration of the test is stored in the `Duration` property. The current time is also pushed into the `AvailabilityTelemetry` via the `Timestamp` property. The invocation of `$TelemetryClient.TrackAvailability` will queue the data submission to Application Insights. The data may or may not have been transmitted to Application Insights, but calling `$TelemetryClient.Flush()` will ensure it is sent.

Finally, the error action preference is reversed to its original value and the CWD is reset to the original CWD.

## Testing out the custom PowerShell Availability Test {#testing-out-the-custom-powershell-availability-test}




You will need the instrumentation key to send any Telemetry to Application Insights. To find this key, navigate to the Overview blade of your Application Insights resource and **copy the "Instrumentation Key":**




<picture>
  <img src="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/khol4xqo/ai-blade-edited.png" srcset="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=430/media/khol4xqo/ai-blade-edited.png 430w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=645/media/khol4xqo/ai-blade-edited.png 645w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=718/media/khol4xqo/ai-blade-edited.png 718w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=860/media/khol4xqo/ai-blade-edited.png 860w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1077/media/khol4xqo/ai-blade-edited.png 1077w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/khol4xqo/ai-blade-edited.png 1120w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1436/media/khol4xqo/ai-blade-edited.png 1436w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1680/media/khol4xqo/ai-blade-edited.png 1680w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=2240/media/khol4xqo/ai-blade-edited.png 2240w" sizes="(max-width: 480px) 430px, (max-width: 768px) 718px, 1120px" width="1120" height="281" alt="Screenshot of the Application Insights home blade where you can find the instrumentation key" loading="lazy" decoding="async">
</picture>

Set the key as a temporary environment variable in your shell:

<pre style="color:#000000;background:#ffffff;">$Env:APPINSIGHTS_INSTRUMENTATIONKEY = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">[INSERT_KEY_HERE]</span><span style="color:#2a00ff; ">"</span>&#10;</pre>



<p class="panel panel--warning"><strong>Once you close your shell, the environment variable will not be available anymore</strong>. Refer to this <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables#saving-changes-to-environment-variables">documentation if you want to save the environment variables permanently</a>.</p>

Invoke the script like this:

<pre style="color:#000000;background:#ffffff;">.\CheckAvailability.ps1&#10;</pre>

Run the script a couple of times to get multiple data points. Then navigate to the "Availability" blade of Application Insights in the Azure Portal and confirm the data is showing up:

<picture>
  <img src="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/5tbi0gwx/ai-blade-custom.png" srcset="https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=430/media/5tbi0gwx/ai-blade-custom.png 430w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=645/media/5tbi0gwx/ai-blade-custom.png 645w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=718/media/5tbi0gwx/ai-blade-custom.png 718w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=860/media/5tbi0gwx/ai-blade-custom.png 860w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1077/media/5tbi0gwx/ai-blade-custom.png 1077w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1120/media/5tbi0gwx/ai-blade-custom.png 1120w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1436/media/5tbi0gwx/ai-blade-custom.png 1436w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=1680/media/5tbi0gwx/ai-blade-custom.png 1680w, https://swimburger.net/cdn-cgi/image/format=auto,quality=90,width=2240/media/5tbi0gwx/ai-blade-custom.png 2240w" sizes="(max-width: 480px) 430px, (max-width: 768px) 718px, 1120px" width="1120" height="626" alt="Screenshot of Azure Application Insights Availability blade with a custom availability test" loading="lazy" decoding="async">
</picture>



<p class="panel panel--warning">Note: <strong>it can take a couple of minutes for the data to show up</strong>.</p>

You probably want the availability test to run on a recurring basis. On Windows, you can configure a recurring Windows Task and on Linux, you can use the built-in crontab functionality.<br>Alternatively, you could turn the script into an infinite loop with a 30-second sleep in between iterations. Just make sure you're using a non thread blocking sleep or you'll be wasting unnecessary resources.

## Resources {#resources}



- Learn more about <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview">Application Insights in the Microsoft Docs</a>.
- The PowerShell script in this article is based on the following <a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/availability-azure-functions#sample-code">C# Azure Function provided in the Microsoft Docs</a>.
- To learn how to UI test web applications using .NET Core, check out "<a href="https://swimburger.net/blog/dotnet/how-to-ui-test-using-selenium-and-net-core-on-windows-ubuntu-and-maybe-macos">How to UI test using Selenium and .NET Core on Windows, Ubuntu, and maybe MacOS?</a>".
