Using PowerShell as a data source in PowerBI to retrieve Azure VM SKU Retail Pricing

Introduction

In recent months I have been researching Azure native cost optimization and utilization reporting options and how they could be applied to Azure Virtual Desktop environments. In the process I happened upon this gem of a script from Leee Jefferies which wraps the Azure Retail price REST API in a couple of very nifty functions. It really helped me understand the API more than the documentation does and is worth checking out, well worth it and is as simple as copy/paste to use. In the same vein while attempting to cobble together a PowerBI dataset/semantic model that would allow me to visualise those cost optimization and utilization metrics I also found an oldie but a goodie from Scott Senkeresty that presents an innovative way of using PowerShell as a data source in Power BI.

As Leee had had already done the hard work of wrapping the Azure Retail price REST API in a neat and consistent manner and Scott had presented the POC for using PowerShell as a data source in PowerBI it felt like a good opportunity to bring the two ideas together in order to generate a lookup table for my semantic model.

Note: I am 100% sure there is a more sensible ways to retrieve REST API data for PowerBI but I actually understand PowerShell and I can get ChatGPT to hack together an R script so here we are! If someone has a more sensible approach and a walk through feel free to drop a link in the comments.

Continue reading

Deploying a Winget Private Repository with Nerdio

Introduction

For anyone not familiar with Nerdio Unified application manager it is a feature that allows for applications to be deployed to Azure Virtual Desktop (AVD) hosts and host pools, as well as Intune-enrolled Windows devices, including Windows 365 Cloud PCs and physical desktops and laptops. At time of writing, it facilitates integration with SCCM, inTune and my personal favourite, Winget. It is improving every release so keep an eye on the vendor documentation here.

This article is going to focus on the Winget integrations and functionality, in particular the deployment of a Winget Private Repositories. For a broader understanding of Winget in general and Private Repositories in particular you can check out my previous articles:

It is worth nothing the steps in the last article in the list above will help you to deploy a Private Repository using the free-tier options. If you are running a demo environment on a budget this might be a better fit for you but in terms of convenience and for production deployments it is worth checking out the Nerdio managed deployment below.

Continue reading

Managing Monitoring and Reporting data in Azure Virtual Desktop

Introduction

Effective management of Azure Virtual Desktop (AVD) requires IT administrators to be able fully leverage the monitoring capabilities provided natively in Azure. When considering your monitoring and reporting requirements for an Azure Virtual Desktop (AVD) environment there are some technologies and concepts you will need to be familiar with:

Continue reading

Multi-home your AVD Monitoring Data (AMA) with Nerdio Scripted Actions

If you are unfamiliar with the concept of multihoming in the context of Log Analytics Workspaces you can read the introduction article here.

TLDR: At the end of the introduction, I concluded the most likely scenario you would implement in an AVD environment with both operational and security monitoring requirements would be a multihomed setup.

A recap below if you have skipped to the introduction article how to.

In a multihoming scenario:

  1. The AVD operational data is forwarded from the AVD service to a LAW allocated for both operational and security data (Point 1 below)
  2. The AVD operational data is consumed from AVD Insights (Point 2 below)
  3. The LAW sits atop Azure Sentinel (or similar 3rd party product) where the AVD security data can be consumed by your security team. (Point 3 below)

This article will concentrate on the configuration of the Azure Monitoring Agent (AMA) and associated Data Collection Rules (DCRs) (point 3) and while you can deploy the script in a different build/deployment tool it assumes you are using Scripted Actions in Nerdio.

Continue reading

Multi-home your AVD Monitoring Data (MMA) with Nerdio Scripted Actions

If you are unfamiliar with the concept of multihoming in the context of Log Analytics Workspaces you can read the introduction article here.

TLDR: At the end of the introduction, I concluded the most likely scenario you would implement in an AVD environment with both operational and security monitoring requirements would be a multihomed setup.

NOTE: The MMA is retiring on the 31st of August 2024, if you are in a position to move to the AMA or have done already you should follow this guide instead.

A recap below if you have skipped to the introduction article how to.

In a multihoming scenario:

  1. The AVD operational data is forwarded from the AVD service to a LAW allocated for both operational and security data (Point 1 below)
  2. The AVD operational data is consumed from AVD Insights (Point 2 below)
  3. The LAW sits atop Azure Sentinel (or similar 3rd party product) where the AVD security data can be consumed by your security team. (Point 3 below)

This article will concentrate on the configuration of the Microsoft Monitoring Agent (MMA) (point 3) and while you can deploy the script in a different build/deployment tool it assumes you are using Scripted Actions in Nerdio.

Continue reading

Deploying a Winget Private Repository

Just a note before kicking off: If you are comfortable with VSCode ,Github, installation of PS modules and connecting to Azure via PowerShell I would advise skimming the Getting Started section, cloning the working source code from here, and picking up from section 4. If you are not that confident it is worth grabbing a coffee and working through each section in sequence. Its a long one but I hope as a reader you get some value out of the detail.

  1. Introduction
  2. Getting Started
    1. What are we Installing?
    2. What are we trying to achieve?
  3. Prepare your Environment
    1. The Basics
    2. Install the winget-rest-source PS module
  4. Creating a Private Winget Respoitory
    1. Sanity Checking the installation
  5. Conclusion

Introduction

Over the last couple of months I have been getting to grips with Windows Package Manager (aka Winget).

It faces a far more challenging application landscape than its Linux based counterparts, and while it is still a little immature as a technology, it has a lot of potential. I believe it is the future of application deployment and management on Windows and I hope that it gets the attention and adoption that it deserves.

If you have no idea what Winget is I would recommend having a read of two earlier articles I have covered on the topic as this one will be a little more technical.

  1. An Introduction to Windows Package Manager (aka Winget)
  2. An Introduction to Winget Private Repositories

As I mentioned in a previous post if you are considering introducing Winget to your environment you may face governance issues (control over the software distribution process), or technical limitation (compatibility problems with specific enterprise software or systems) In these scenarios you may want to consider hosting a private Winget repository to address those challenges.

The good news is that there is a project that provides a reference implementation for creating a REST based private package source for the Winget client. Details can be found here.

The bad news is that it can be a bit of a challenge to get everything set up without a bit of troubleshooting. For those interested in the nuts and bolts: the issue log provided by a helpful, since deleted Gihub account covers the highlights with the summary below:

  • Errors are widely suppressed making it non-obvious why things might not be working
  • Errors that are not suppressed have little context into what’s failing and why
  • Template files are missing from the expected default path, and the build process does not copy them to the expected path
  • Azure Functions .zip file is not in the expected default path, and the build process does not create it
  • Parameter generation is missing expected values for the Azure Function template
  • ASP template is missing entirely which blocks the script from completing successfully
  • KeyVault creation keys only off the -Name parameter value which may conflict globally

Note: The Functions .zip file issue caught me out when completing this write up, I have left the troubleshooting steps in rather than fixing in place as I felt it would be useful to assisit in understanding how the deployment works

I like to think I am a reasonably competent but this particular challenge found those skills wanting. Luckily I was able to find some backup!

Every story needs a hero this role was filled by Gunnar Óttarsson founder and CTO of Well Advised, Gunnar and his team know Azure inside out, I learned so much working with him and if you need an Azure Infrastructure and Dev-Ops experts I could not recommend them enough.

It is Gunnar’s fork of the project that addressed the most of the previously listed challenges that I am using for this walk through and all credit goes to him for helping me to get up and running.

I would also highly recommend having a read of Léon Bouquiet’s blog on the same subject, this was the best write up I have found outside of the project’s Github notes and really helped my understanding of how it all hangs together.

Getting Started

What are we Installing?

A Winget Private Repository consists of a number of Azure hosted components and the (optional) vendor source download location.

App Service PlanA hosting plan that defines a set of resources available for web apps, APIs, and background jobs
Application InsightsCollects various telemetry data from the app, such as request rates, response times, failure rates, dependencies (like databases and external services your app relies on), this will give you “insight” into issues with your Winget Repository 
Azure FunctionsA serverless computing service that allows us to execute small bits of code, or “functions,” in response to various types of events such including HTTP requests to make REST API calls to read, update, create and delete entries on your Winget Repository 
Azure Cosmos DBA fully managed NoSQL database service used to host your private Winget Repository application manifest data
Key VaultCentralizes the storage of application secrets, allowing you to control their distribution. Used in this instance
Storage AccountContains all storage data objects: blobs, files, queues, tables, and disks necessary for the operation of your Winget Repository
Winget Private Repository Objects

There are two additional components to be aware of that are not part of the actual deployment of which you are likely to use when levering Winget to install from a Private Repository.

Storage AccountA separate storage account that Contains the storage data object(s): blobs or files that you may use to host application sources internally that your Winget Repository can reference for download
Vendor Hosted SourceExternal Download Location that a 3rd party vendor may use to host application sources your Winget Repository can reference for download
Ancillary objects required for a Winget Private Repository

Continue reading

An Introduction to Winget Private Repositories

As per my previous Winget article, the out of the box Public implementation of Winget consists of the following components.

  1. The client-side command-line utility
  2. The Gitub hosted Windows Package Manager Community Repository of Package Manifests
  3. The Download Source Location for the Package Payload
  4. The Microsoft Hosted Winget Content Delivery Network (CDN)
  5. The public Microsoft Store

As we can see a Private Implementation of Winget is a little more involved but does offer more flexibility which I cover in greater detail below

  1. Create a package manifest using Windows Package Manager Manifest Creator or YamlCreate.ps1 OR download the existing YAML files for your chosen application from the Community Repository
  2. Leverage Gunnar’s collection of commands here to convert the YAML manifests to JSON
  3. At this point you can make the changes to the manifest such as changing the download location to an internal/private source OR modifying the metadata for internal consistency with a CMDB
  4. Invoke the REST “POST” method to upload the JSON files to your Private Repository
  5. Run the Source Add command on your windows client to add a REST source for the Winget Package Manager. (I have provided a Winget client install script that can complete this step when the appropriate switches are passed to it, read description of script for more detail)
  6. A user or an administrator can now interact with the Private Repository via client commands to programmatically “discover, install, upgrade, remove and configure applications” that are hosted there in the same way as they can with the CDN or the Microsoft Store with the Public implementation of Winget

Continue reading

An Introduction to Windows Package Manager (aka Winget)

The Windows Package Manager (also known as Winget) is a free and open-source package manager designed by Microsoft for Windows 10 and Windows 11. According to Microsoft Learn Winget is designed to enable “users to discover, install, upgrade, remove and configure applications on Windows 10 and 11 computers”

The standard implementation of Winget consists of the following components

  1. The client-side command-line utility
  2. The Gitub hosted Windows Package Manager Community Repository
  3. The Microsoft Hosted Winget Content Delivery Network (CDN)
  4. The public Microsoft Store

Nicola Suter has written the best article I have seen to date on how it hangs together which is worth a read.

At a high level the work flow for Winget leveraging the Community Repository looks like this:

Continue reading

Running Windows Package Manager (Winget) in the SYSTEM context

I have recently been working on Dev Ops Style image deployments for Azure Virtual Desktop. With AVD or any DaaS product image deployment is unfortunately only half the battle. You have to consider how you will get your applications on there.

While working toward an automation centric AVD design with a little less image management I have been playing around with Winget.

The Background

Winget has tons of potential and I hope that Microsoft give it the love it needs to survive and thrive it has an active Github and is worth checking out the discussions on there if you are interested.

For my use case of deploying applications to AVD Session Hosts at build time my first snag was the inability to run Winget in the SYSTEM context. In a Multi-Session DaaS context this is a hard requirement if Winget is going to become a main stream part of the AVD administrator tool kit. For now, we need a workaround.

Note: Health Warning – Winget does not support running in the SYSTEM context for lots of good reasons, a lot of the applications in the Public Repository are probably not going to install/uninstall gracefully or with the behaviour you expect in the SYSTEM context, use this work around with care and attention and test the applications you plan on deploying in this manner thoroughly before using in a Production context.

Continue reading

The sustainability case for Desktop as a Service (DaaS)

An initial side bar for readers not familiar with the trends in end user compute:

Desktop as a Service (DaaS) is a cloud-based service that provides users with virtual desktops that can be accessed from anywhere with an internet connection. Instead of traditional desktop computers, DaaS delivers virtual desktops to users on their devices, such as laptops, tablets, or smartphones.

A second side bar for the readers not familiar with the trends in the world we live in:

The climate crisis refers to the urgent and severe impacts of climate change, which are already being felt around the world and are expected to worsen in the coming years. The scientific consensus is that the climate crisis is primarily caused by human activities, particularly the burning of fossil fuels such as coal, oil, and gas, which release large amounts of greenhouse gases into the atmosphere.

Continue reading