Skip to main content

Implement WebJEA for self-service Start/Stop of Azure Virtual Machines

· 15 min read

WebJEA allows you to build web forms for any PowerShell script dynamically. WebJEA automatically parses the script at page load for description, parameters and validation, then dynamically builds a form to take input and display formatted output!

The main goals for WebJEA:

  • Reduce delegation of privileged access to users
  • Quickly automate on-demand tasks and grant access to less-privileged users
  • Leverage your existing knowledge in PowerShell to build web forms and automate on-demand processes
  • Encourage proper script creation by parsing and honouring advanced function parameters and comments

Because WebJEA is simply a Self-Service Portal for PowerShell scripts, anything you can script with PowerShell you can run through the Portal! Opening a lot of opportunities for automation without having to learn third party automation toolsets! Anyone who knows PowerShell can use it! Each script can be locked down to specific users and AD groups!

You can read more about WebJEA directly on the GitHub page:

This guide will concentrate on setting up WebJEA for self-service Azure VM management. However, WebJEA can be used to enable much more than what this blog article covers, from things such as new user onboarding, to resource creation.

WebJEA - Start/Stop

We will use a Windows Server 2019, running in Microsoft Azure, to run WebJEA from.


  • Domain Joined server running Windows 2016+ Core/Full with PowerShell 5.1
  • The server must have permission to go out over the internet to Azure and download PowerShell modules.
  • CPU/RAM Requirements will depend significantly on your usage, start low (2-vCPU/4GB RAM) and grow as needed.

I've created a Standard_B2ms (2vCPU, 8GB RAM) virtual machine, called: WEBJEA-P01 in an Azure Resource Group called: webjea_prod

This server is running: Windows Server 2019 Datacenter and is part of my Active Directory domain; I've also created a service account called: webjea_services.

Setup WebJEA

Once we have a Windows Server, now it's time to set up WebJEA!

Setup Self-Signed Certificate

If you already have a certificate you can use, skip this step. In the case of this guide, we are going to use a self-signed certificate.

Log into the WebJEA Windows server using your service account (in my case, it is: luke\webjea_services).

Open PowerShell ISE as Administrator, and after replacing the DNS name to suit your own environment, run the following to create the Root CA and Self-Signed certificate:

Now that the Root CA is created and trusted, we want to create the actual self-signed certificate:

#Create RootCA
$rootCA = New-SelfSignedCertificate -Subject "CN=MyRootCA" `
-KeyExportPolicy Exportable `
-KeyUsage CertSign,CRLSign,DigitalSignature `
-KeyLength 2048 `
-KeyUsageProperty All `
-KeyAlgorithm 'RSA' `
-HashAlgorithm 'SHA256' `
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
-NotAfter (Get-Date).AddYears(10)

#Create Self-Signed Certificate
$cert = New-SelfSignedCertificate -Subject "" `
-Signer $rootCA `
-KeyLength 2048 `
-KeyExportPolicy Exportable `
-DnsName, WEBJEA, WEBJEA-P01 `
-KeyAlgorithm 'RSA' `
-HashAlgorithm 'SHA256' `
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
-NotAfter (Get-Date).AddYears(10)
$certhumbprint = $cert.Thumbprint

#Add Root CA to Trusted Root Authorities
New-Item -ItemType Directory 'c:\WebJea\certs' -Force
Export-Certificate -Cert $rootCA -FilePath "C:\WebJEA\certs\rootCA.crt" -Force
Import-Certificate -CertStoreLocation 'Cert:\LocalMachine\Root' -FilePath "C:\WebJEA\certs\rootCA.crt"

Write-Host -ForegroundColor Green -Object "Copy this: $certhumbprint - The Thumbprint is needed for the DSCDeploy.ps1 script"

Copy the Thumbprint (if you do this manually, make sure it is the Thumbprint of the certificate, not the Trusted Root CA certificate); we will need that later.

Setup a Group Managed Service Account

This is the account we will use to run WebJEA under; it can be a normal Active Directory user account if you feel more comfortable or want to assign permissions to.

I am using a normal AD (Active Directory) service account in this guide because I am using Microsoft Entra ID Domain Services as my Domain Controller, and GMSA is not currently supported. I have also seen some scripts require the ability to create and read user-specific files. However, it's always good to follow best practices where possible.

Note: Group Managed Services accounts automatically renew and update the passwords for the accounts; they allow for additional security. You can read more about them here: Group Managed Service Accounts Overview.

#Create A group MSA account
Add-kdsrootkey -effectivetime ((get-date).addhours(-10))
New-ADServiceAccount -name webjeagmsa1 -dnshostname (get-addomaincontroller).hostname -principalsallowedtoretrievemanagedpassword

#Create AD Group
New-ADGroup -Name "WebJEAAdmins" -SamAccountName WebJEAAdmins -GroupCategory Security -GroupScope Global -DisplayName "WebJEA - Admins" -Description "Members of this group are WebJEA Admins"

Install-adserviceaccount webjeagmsa1
Add-ADGroupmember -identity "\WebJEAAdmins" -members (get-adserviceaccount webjeagmsa1).distinguishedname

Add the WebJEAAdmins group to the Administrators group of your WebJEA server.

Install WebJEA

Download the latest release package (zip file) onto the WebJEA Windows server

Extract it, and you should have 2 files and 2 folders:

  • Site\

  • StarterFiles\


  • DSCDeploy.ps1

    Open PowerShell ISE as Administrator and open DSCDeploy.ps1

WebJEA uses PowerShell DSC (Desired State Configuration) to set up a lot of the setup.

DSC will do the following for us:

  • Install IIS
  • Create the App Pool and set the identity
  • Create and migrate the Site files to the IIS website folder
  • Configure SSL (if we were using it)
  • Update the WebJEA config files to point towards the script and log locations

Even though most of the work will be automated for us by Desired State Configuration, we have to do some configurations to work in our environment.

I am not using a Group Managed Service Account. Instead, I will use a normal AD account as a service account (i.e. webjea_services), but if you use a GMSA, you need to put the username in the AppPoolUserName; no credentials are needed (make sure the GMSA has access to the server).

Change the following variables to suit your setup; in my case, I have moved WebJEA resources to their own folder, so it's not sitting directly on the OS drive, but until its own Folder.

NodeNameThis is a DSC variable, leave this.
WebAppPoolNameWebApp Pool Name, it may be best to leave this as: WebJEA, however you can change this.
AppPoolUserNameAdd in your GMSA or Domain Service account username
AppPoolPasswordIf using a Domain Account, add the password in here, if GSMA leave bank
WebJEAIISURIThis is the IIS URL, ie server/WebJEA. You can change this if you want.
WebJEAIISFolderIIS folder location, this can be changed if you wanted to move IIS to another drive or location.
WebJEASourceFolderThe source folder, this is the source folder for the WebJEA files when they are first downloaded and extracted (ie Downloads directory)
WebJEAScriptsFolderThis is where the scripts folder will be placed (ie WebJEA installed)
WebJEAConfigPathThis is where the config file will be placed (ie WebJEA installed - it needs to be the same location as the Scripts folder)
WebJEALogPathWebJEA log path
WebJEA_Nlog_LogFileWebJEA system log location
WebJEA_Nlog_UsageFileWebJEA usage log location


One thing to note is that the DSCDeploy.ps1 is calling (dot sourcing) the DSCConfig deploy script; by default, it is looking for it in the same folder as the DSCDeploy.ps1 folder.

If you just opened up PowerShell ISE, you may notice that you are actually in C:\Windows\System32, so it won't be able to find the script to run; you can either change the script to point directly to the file location, or you can change the directory you are into to match the files, in my case in the Script pane I run the following:

cd 'C:\Users\webjea_services\Downloads\webjea-'

Now run the script and wait.

If you get an error saying that the script is not digitally signed, run the following in the script pane:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

This is because the PowerShell execution policy hasn't been set; depending on the scripts you are running, you may have to update the execution policy for the entire system, but for now, we will set it to Bypass for this process only, now re-run the script again, you should see DSC kick-off and start your configuration and setup of IIS and the WebJEA site.


You should also see the files/folders starting to be created!

Note: If you need to make a configuration change, please change it in the DSCDeploy.ps1, DSC will ensure that the configuration is applied as per your configuration and rerun the script, i.e. if you need to replace the certificate from a self-signed certificate to a managed PKI certificate.

Once DSC has been completed, your server should now be running IIS and the WebJEA site

To add the IIS Management Tool, this is not required but will help you manage IIS, run the following PowerShell cmdlet:

Enable-WindowsOptionalFeature -Online -FeatureName IIS-ManagementConsole

Open an Internet Browser and navigate to (your equivalent of):

If you need assistance finding the Website path, open the Internet Information (IIS) Manager, installed and uncollapse Sites, Default WebSite, right-click WebJEA, Manage Application and select Browse.


If successful, you should get a username and password prompt:


That's normal - it means you haven't been given access and now need to configure it.

Configure WebJEA

Now that WebJEA has been set up, it is time to configure it; the first thing we need to do is create a Group for WebJEA admins (see all scripts).

Create an Active Directory group for:

  • WebJEA-Admins
  • WebJEA-Users

Add your account to the: WebJEA-Admins group.

Navigate to your WebJEA scripts folder; in my case, I set it up under c:\WebJEA\Scripts:

WebJEA - Scripts

Before we go any further, take a Backup of the config.json file, rename it to "config.bak".

I recommend using Visual Studio Code to edit the config.json to help avoid any syntax issues.

Now right click config.json and open it to edit

This file is the glue that holds WebJEA together.

We are going to make a few edits:

  • Feel free to update the Title to match your company or Teams
  • Add in the WebJEA-Admins group earlier (include the Domain Name) into the permitted group's session - this controls access for ALL scripts.

Note the: \\ for each path that is required. If you get a syntax error when attempting to load the WebJEA webpage, this is most likely missing.

WebJEA - Demo

Save the config file and relaunch the WebJEA webpage. It should now load without prompting for a username and password.

Set the PowerShell execution policy on the machine to Unrestricted so that you can run any PowerShell scripts on it:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine

WebJEA - Demo

If you get an: AuthorizationManager check failed error, it is because the PowerShell scripts are still in a blocked state from being downloaded from the internet, run the following command to unblock them, then refresh the WebJEA webpage:

Get-ChildItem -Path 'C:\WebJEA\scripts\' -Recurse | Unblock-File

You now have a base WebJEA install! By default, WebJEA comes with 2 PowerShell files:

  • overview.ps1
  • validate.ps1

You may have noticed these in the config.json file; WebJEA has actually run the overview.ps1 file as soon as the page loads, so you can have scripts run before running another one, which is handy when you need to know the current state of something before taking action.

The validate.ps1 script is an excellent resource to check out the parameter types used to generate the forms.

Setup Azure Virtual Machine Start/Stop

Now that we have a working WebJEA install, it's time to set up the Azure VM Start/Stop script for this demo.

On the WebJEA server, we need to install the Azure PowerShell modules, run the following in Powershell as Administrator:

Install-Module Az -Scope AllUsers

Create Service Principal

Once the Az PowerShell modules are installed, we need to set a Service Principal for the PowerShell script to connect to Azure to manage our Virtual Machines.

Run the following PowerShell cmdlet to connect to Azure:


Now that we are connected to Azure, we now need to create the SPN, run the following:

$sp = New-AzADServicePrincipal -DisplayName WebJEA-AzureResourceCreator -Role Contributor
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret)
$UnsecureSecret = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

Now you have created an SPN called: WebJEA-AzureResourceCreator. We now need to grab the Tenant ID, run the following:

Get-AzContext | Select-Object Tenant

Now that we have the SPN and Tenant ID, it's time to test connectivity.

# Login using service principal 
$Secret = ConvertTo-SecureString -String 'SECRETSTRINGHERE' -AsPlainText -Force
$Credential = [System.Management.Automation.PSCredential]::New($ApplicationId, $Secret)
Connect-AzAccount -ServicePrincipal -Credential $Credential -TenantId $TenantId

Copy the TenantID into the TenantID section



To retrieve the ApplicationID created from the SPN in the previous step and add it into the ApplicationID part.

Type in:


To retrieve the Secret, created in the SPN and add it to the String.

Now run the snippet, and you should be successfully connected to Azure.

Create Get-VM script

One of the features of WebJEA is the ability to run scripts on page load. So, we will get the current Power State of our Azure VMs, in the WebJEA scripts directory to create a new PS1 file called: Get-VM.ps1.

Add the following script to it:

# Login using service principal 
$Secret = ConvertTo-SecureString -String 'SECRETSTRINGHERE' -AsPlainText -Force
$Credential = [System.Management.Automation.PSCredential]::New($ApplicationId, $Secret)
Connect-AzAccount -ServicePrincipal -Credential $Credential -TenantId $TenantId
Get-AzVM -Status | Select-Object Name, PowerState, ResourceGroupName

Save the file.

Create Set-VM script

Now, it's time to create the Script to Start/Stop the Virtual Machine. In the WebJEA scripts directory, create a new PS1 file called: Set-VM.ps1

Add the following script to it:

[Parameter(Position=1, mandatory=$true,
HelpMessage='What is the name of the Azure Virtual Machine?')]
[Parameter(Position=2, mandatory=$true,
HelpMessage='What is the name of the Azure Resource Group that the Virtual Machine is in?')]
[Parameter(Position=3, mandatory=$true,
HelpMessage='What action do you want to do?')]
# Login using service principal
$Secret = ConvertTo-SecureString -String 'SECRETSTRINGHERE' -AsPlainText -Force
$Credential = [System.Management.Automation.PSCredential]::New($ApplicationId, $Secret)
Connect-AzAccount -ServicePrincipal -Credential $Credential -TenantId $TenantId
Get-AzVM -Status | Select-Object Name, PowerState, ResourceGroupName
if ($VMAction -eq "Start")
Start-AzVM -Name $VMName -ResourceGroupName $RGName -Confirm:$false -Force
elseif ($VMAction -eq "Stop")
Stop-AzVM -Name $VMName -ResourceGroupName $RGName -Confirm:$false -Force

Save the file.

Set VM in WebJEA Config

Now that the scripts have been created, it's time to add them to WebJEA to use.

Navigate to your scripts file and make a backup of the config.json file, then edit: config.json

On the line beneath the "onloadscript": "overview.ps1" file, add:


Then add in:

"id": "StartStopAzVM",
"displayname": "StartStop-AzVM",
"synopsis": "Starts or Stops Azure Based VMs",
"permittedgroups": [".\\Administrators", "\\WebJEAAdmins"],
"script": "Set-VM.ps1",
"onloadscript": "Get-VM.ps1"

So your config.json should look similar to:


"Title": "Luke Web Automation",
"defaultcommandid": "overview",
"basepath": "C:\\WebJEA\\scripts",
"LogParameters": true,
"permittedgroups": [".\\Administrators", "\\WebJEAAdmins"],
"commands": [
"id": "overview",
"displayname": "Overview",
"synopsis": "Congratulations, WebJEA is now working! We've pre-loaded a demo script that will help you verify everything is working. <br/><i>Tip: You can use the synopsis property of default command to display any text you want. Including html.</i>",
"permittedgroups": [".\\Administrators"],
"script": "validate.ps1",
"onloadscript": "overview.ps1"
"id": "StartStopAzVM",
"displayname": "StartStop-AzVM",
"synopsis": "Starts or Stops Azure Based VMs",
"permittedgroups": [".\\Administrators", "\\WebJEAAdmins"],
"script": "Set-VM.ps1",
"onloadscript": "Get-VM.ps1"


Test Azure Virtual Machine Start/Stop

Now that the scripts have been created open the WebJEA webpage.

Click on the StartStop-AzVM page (it may take a few seconds to load, as it is running the Get-VM script). You should be greeted by a window similar to below:

WebJEA - Demo

Congratulations, you have now set up WebJEA and can Start/Stop any Azure Virtual Machines using self-service!

Additional Notes

  • There is room for improvement around error checking, doing more with the scripts, such as sending an email when triggered, etc., to remind the server to be powered off.
  • Because most of the configuration is JSON/PowerShell files, you could have the entire scripts folder in a git repository to make changes, roll back and keep version history.
  • Remove any hard coding of any secrets to connect to Azure (as an example) from the scripts and implement a password management tool with API access or even the Windows Credential Manager. You want a system where you can easily update the passwords of accounts, limit access and prevent anything from being stored in plain text.
  • Using the permitted group's section of the config.json file, you can restrict the ability for certain groups to run scripts this way, and you can set granular control on who can do what.
  • If you use a normal Active Directory user account as the service account - then for added security, make sure that the WebJEA server is the only device that - that account can be logged in as and only has the permissions assigned that it needs to, look at implementing PIM (Privilaged Access Management) for some tasks so it only has access at the time that it needs it.

Well-Architected Framework Azure infrastructure review with PSRule for Azure

· 6 min read

Imagine if you could validate that your Azure Resources are deployed per the Well-Architected Framework (WAF).. just imagine!

Of a way of validating your services are secure and deployed following the Azure Architecture framework, both before and after the resources have been created!

Imagine no longer! There is a PowerShell module designed specifically for that purpose: PSRule for Azure.

PSRule - Azure

PSRule is a suite of rules to validate resources and infrastructure as code (IaC) using PSRule, and the Azure component uses the base PSRule module.

Features of PSRule for Azure include:

  • Leverage over 200 pre-built rules across five WAF pillars:
    • Cost Optimization
    • Operational Excellence
    • Performance Efficiency
    • Reliability
    • Security
  • Validate resources and infrastructure code pre or post-deployment using Azure DevOps or Github!
  • It runs on macOS, Linux, and Windows.

With over 200 inbuilt rules (and you can add your own), there is a lot of resource types covered, such as (but not limited to):

  • Azure App Service
  • Azure Key vault
  • Azure Virtual Machine
  • Azure Storage
  • Azure Network
  • Azure Public IP

Azure PSRules has been in development since 2019 and is under constant updates and fixes.

PSRule for Azure provides two methods for analyzing Azure resources:

  • Pre-flight - Before resources are deployed from Azure Resource Manager templates.
  • In-flight - After resources are deployed to an Azure subscription.

Pre-flight validation is used to scan ARM (Azure Resource Manager) templates before services are deployed and allow for quality gaps and better information in pull requests to improve and implement your infrastructure as code components.

The in-flight method can also be used in Azure DevOps for validation of Terraform resource deployments etc. Still, in this demo, I will run you through installing the Module and doing an export and scan from your PowerShell console!

We are going to install the PSRule.Azure (based on the Well-Architected Framework & Cloud Adoption Framework).

I recommend keeping the Modules (and as such the in-built rules) up-to-date and do scans at least every quarter or after a major deployment or project to help verify your resources are set up according to some best-practice rules. This does not replace Security Center and Azure Advisor; this is intended to be a supplement.

Install PSRule.Azure

  1. Open PowerShell console and run the following commands:

    #The main Module and base rules to validate Azure resources..
    Install-Module PSRule.Rules.Azure -Scope CurrentUser

Install-Module PSRule 2. Press 'Y' to accept PSGallery as a trusted repository; just a note, you can prevent the confirmation prompt when installing Modules from the PSGallery, by classifying it as a 'Trusted Repository' by running the following. Just be wary that won't get rechallenged:

   Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted

3. You should now have the following modules installed:

  • PSRule
  • PSRule.Rules.Azure

Extract Azure Subscription PSRule JSON files

Now that PSRule has been installed, it's time to log in to Azure and extract information regarding your Azure resources for analysis; these extracted files are JSON files containing information, such as your resource names, subscription ID, etc. resource groups in plain text.

As you can see from the screenshot below, we can target specific Subscriptions, Tenancies (yes, as long as the account you have access to has access to the subscription, you can export those as well), Resource Groups and Tags.


Because I want to get the most data available across all resources, I will target everything with the '-All' parameter.

  1. First, we need to connect to the Azure subscription and then connect to the Azure subscription we have access to or are targeting by running the following:


    Get-AzSubscription | ogv -PassThru | Set-AzContext
  2. Now that you have connected its time to export the Azure resource information, run the following PowerShell cmdlet, and point it towards an empty folder:

    Export-AzRuleData -OutputPath c:\temp\AzRuleData -All
  3. If the folder doesn't exist, don't worry - the Export command will create it for you. Depending on how many resources and subscriptions you are extracting, this may take a few minutes.

You should see the JSON files appearing if you open one of these. In addition, you should be able to see information about the resources it has extracted.

Run PSRule across your JSON files

Now that you have extracted the JSON files of your Azure resources, it's now time to analyse them following Microsoft Cloud Adoption and Well Architectured framework and the rules builtin into PSRule.Azure!

You don't need to be connected to Azure; for this analysis, have the PSRule modules installed and access the JSON files.

PSRule.Azure has a few baselines; these baselines contain the rules used to analyse your resources and range from Preview to newly released rules; again, we will target ALL rules, as we are after all recommendations.

  1. In PowerShell, run the following:

    Assert-PSRule -Module 'PSRule.Rules.Azure' -InputPath 'C:\temp\AzRuleDataExport\*.json' -Baseline 'Azure.All'
  2. This will trigger PSRules to scan your extracted JSON files with the ALL rules, and you will get output like below:

  3. Invoke-PSRules

  4. Although it is good being able to see a high level, I prefer to look at it all at once in Excel, so run the following to export the rules to a CSV:

    Invoke-PSRule -Module 'PSRule.Rules.Azure' -InputPath 'C:\temp\AzRuleDataExport\*.json' -Baseline 'Azure.All' | Export-csv C:\temp\AzRuleDataExport\Exported_Data.csv
  5. You should now have a CSV file to review and look for common issues, concerns and work on improving your Azure infrastructure setup!

PS Rules Azure - Export CSV

Note: The export contains the Subscription/Resource Names, so you can definitely see what resources can improve upon; however, I removed it from my screenshot.

Congratulations! You now have more visibility and, hopefully, some useful recommendations for improving your Azure services!

If you want to get a good understanding of the type of data rules, check out my extracted CSV 'here'.

Additional Resources

  • If you found PSRules.Azure interesting; how about getting any Failed rules? How about getting any failed rules pushed to Azure Monitor?

PSRule to Azure Monitor

  • If you are interested in the CI (Continous Integration) options, check out the links below:

Azure DevOps Pipeline & Github Actions

  • Extend the PSRules to include Cloud Adoption Framework as well?

PSRule for Cloud Adoption Framework

  • And finally, creating Custom Rules for your organisation, including Tagging, Naming conventions etc.?

PSRule.Azure Custom Rules

Configure Azure Virtual Desktop Monitoring Insights

· 5 min read

Microsoft has now added a built-in Monitoring workbook for Azure Virtual Desktop performance monitoring; this monitoring includes dashboards related (but not limited to):

  • Session host diagnostics
  • Connection performance
  • Host performance
  • User login events
  • Remote Desktop client versions

To configure, we first need to create a Log Analytics workspace that both the Host Pool and Workspace will connect to.

Create a Log Analytics workspace

You can use a Log Analytics workspace if it already exists; if not, we will have to create one.

  1. Log in to the Azure Portal
  2. Click on + Create a Resource
  3. Search for: Log Analytics workspace
  4. Click Create
  5. Azure Portal - Log Analytics Marketplace
  6. Here we can select the Resource Group, Name and Location of the Log Analytics workspace we will create.
  7. I am going to create a new Resource Group called: aad_mgmt
  8. I click Create New and enter in the name of the Resource Group
  9. Under Instance Details, make sure you select a name that adheres to your naming governance.
  10. Note: the name of your Log Analytics workspace is now scoped to the Resource Group, so you can have Log Analytics workspaces with the same name, as long as they are indifferent resource groups.
  11. Azure Portal - Create Log Analytics
  12. Click on: Next: Pricing Tier
  13. Select the applicable pricing tier, I only have Pay-as-you-go (Per GB 2018), so I will select that.
  14. Note: You can view the Pricing for Log Analytics on the Pricing Calculator: look at the Pay-As-You rates.
  15. Azure Portal - Create Log Analytics
  16. Click Next: Tags
  17. Enter in any applicable tags, such as Creator, Who it may get billed to, Project ID etc. that’s relevant and select Review + Create
  18. Review the configuration and click Create to create your Log Analytics workspace! (It should take less than a minute.)

Configure Azure Virtual Desktop Insights

  1. Log in to the Azure Portal

  2. Search for: Azure Virtual Desktop

  3. Click on Insights

  4. A Workbook blade should now greet you

  5. This is where we will configure the Azure Virtual Desktop Insights. You can see on the lower right-hand side that we will be deploying Azure Monitor for 'Windows Virtual Desktop v1.0.4' (however, this will be managed by Microsoft, but it is handy to know the version in case of support later on).

  6. Azure Virtual Desktop - Insights

  7. Click on Open Configuration Workbook

  8. Here, select the Log Analytics workspace you created earlier (or want to use)

  9. Select Configure host pool

  10. Azure Virtual Desktop - Insights

  11. Click on Deploy (make sure all your Session Hosta are started so that Azure can deploy and configure the Log Analytics agent on the Virtual Machines)

  12. You can select View Template and Parameters if you want to confirm the host pool and workspace configured.

  13. Azure Virtual Desktop - Insights

  14. While the Diagnostic host pool settings are being configured, click on Configure workspace.

  15. Click on: Deploy

  16. Once the Workspace and Host Pool deployments are done, click on Refresh.

  17. Azure Virtual Desktop - Insights

  18. Confirm that Enabled is: True

  19. Azure Virtual Desktop

  20. The journey is not over yet; now that the Host Pool and Workspace have been configured, we need to add the Session Hosts and configure the performance counters to the same workspace!

  21. Click on: Session host data settings.

  22. Select your Log Analytics workspace

  23. Select Add hosts to workspace

  24. Azure Virtual Desktop

  25. Confirm the Deployment and click Deploy

  26. Wait until the deployment has succeeded, or you may get API errors, then select:

  27. Navigate down and click Configure performance counters

  28. Azure Virtual Desktop

  29. Click on Apply config.

  30. Wait until the deployment has succeeded, or you may get API errors, then select:

  31. Navigate down and click on Configure events

  32. Azure Virtual Desktop

  33. Click on Deploy

    Now click on: Refresh, and you should see 'No missing performance counters', 'No missing events found'.

  34. Azure Virtual Desktop

  35. You have now configured Azure Virtual Desktop Insights!

    It may take a few minutes to an hour to populate and collect the data for some of the events and counters.

  36. Azure Virtual Desktop

    On the plus side, all the data is also in Log Analytics so that it can be queried, and you can set up Alert rules against it and get more visibility into your Azure Virtual Desktop environment and use.

    Azure Virtual Desktop

How to create a Free Azure Log Analytics Workspace using PowerShell

· 2 min read

When you create a Log Analytics workspace using the Azure Portal, you only get the Pricing or 'Pay-as-you-go' tiers to select.

You used to create a 'Free' tier using the Azure Portal; however, since 2018; they removed it with a change in plans and it became a legacy offering.

However, using PowerShell, you can still create a Log Analytics Free SKU!

The Free pricing tier is a legacy pricing tier that is available for trying Azure Log Analytics. It has a data cap of 500 MB/day and only 7 days of data retention, so it is intended only for testing and is not to be used for production deployments.

You can change a Free Tier Log Analytics workspace to a Pay-as-you-go or commitment tier later.

You cannot change a Log Analytics workspace created on a higher tier back to Free, even using PowerShell, due to adjustments in 2018 around the Log Analytics billing and plans.

Azure Log Analytics - Free

Create a 'Free Tier' Log Analytics using PowerShell

Change the script's variables below to suit your environment, connect to Azure and run the script to create your Log Analytics workspace.

Note: I tested this script on an MSDN subscription, which I've had for a few years and a recent one created a few months back (2021), but there may be limitations on other subscription types that I haven't tested - see blurb below the script.

#Connect to Azure

#Set Variables
$ResourceGroup = 'aad_mgmt'
$Location = 'australiaeast'
$LogAnalyticsName = 'la-free'
$SKU = 'Free'

#Creates Log Analytics Workspace
New-AzOperationalInsightsWorkspace -Location $Location -Name $LogAnalyticsName -Sku $SKU -ResourceGroupName $ResourceGroup

If you get an error: Error Message: Pricing tier doesn't match the subscription's billing model. Read for more details, unfortunately it means that your Subscription is under a different Billing model, and may have been created recently are you are unable to use the 'Free' tier, instead you may have to create it using 'standard' instead.

Azure Log Analytics - Free

How to set a Log Analytics Daily Data Cap

· One min read

This is just an additional configuration that may help with sizing and pricing Log Analytics, you can set a 'Daily cap' for the amount of Data you ingest per day, to help restrict cost.

The downside of this is if you reach the cap, you will no longer collect any data, until the following day, meaning you may miss key events or issues.

This is something that I would recommend ONLY to do if you run into any financial constraints, giving you more time time to work through, of course, situation depending.

This is a pretty quick 'How To' so let's get straight into it:

  1. Log in to the Azure Portal
  2. Search for your Log Analytics Workspace
  3. Select Usage and estimated costs
  4. Click on Daily Cap
  5. Set your cap in GB (I put 0.166 as my thinking was 5GB per free each month, so 166MB a day, should cap my Log Analytics workspace, although useful for this demo/lab, it's not a number I would recommend for Production)
  6. Click Ok

Log Analytics - Set Daily Cap