0 Comments Posted in:

One of the challenges of working from home is that if you want to access cloud resources that are protected by IP restrictions, you need to add your own home IP address to the allow list for those services. This can be slow to do manually, especially if your home IP address changes frequently or if there are many services you need to access.

I decided to see if I could automate the Azure CLI to add my home IP address for various Azure Web Apps, Network Security Groups and SQL Servers I needed to access. I've created this as a PowerShell script with a function for each type of rule I wanted to add.

Discovering your home IP address

Here's a handy bit of PowerShell to retrieve your current public IP address:

$myIp = (Invoke-WebRequest -uri "https://ifconfig.me/ip").Content

Add a Web App Access Restriction

We can add a web app access restriction with the az webapp config access-restriction add command. First, I use a JMESPath query to check whether there is already an access restriction for my IP.

function Add-WebAppAccessRestriction {
    Param([String]$Sub, [String]$ResGroup, [String]$WebApp, [String]$IpAddress, [String]$RuleName)
    az account set -s $Sub
    if (!$?) {
        Write-Output "Could not select subscription"
        return
    }
    # to query by name instead use --query "ipSecurityRestrictions[?name=='$ruleName'].name"
    $exists = az webapp config access-restriction show `
        -g $ResGroup -n $WebApp `
        --query "ipSecurityRestrictions[?ip_address=='$IpAddress/32'].name" `
        -o tsv
    if (!$?) {
        Write-Output "Error checking for access restriction"
        return
    }
    if (!$exists) {
        Write-Output "Adding rule to webapp $WebApp";
        az webapp config access-restriction add `
            -g $ResGroup `
            -n $WebApp `
            --rule-name $RuleName `
            --action Allow `
            --ip-address "$IpAddress/32" `
            --priority 65000
        if (!$?) {
            Write-Output "Failed to add webapp rule"
        }
    }
    else {
        Write-Output "Restriction for webapp $WebApp already exists with name '$exists'";
    }
}

Adding a Network Security Group rule

We can follow a similar pattern for adding an NSG rule with az network nsg rule create. I again use a JMESPath query to avoid adding a new rule if my IP address is already configured.

function Add-NsgRule {
    Param([String]$Sub, [String]$ResGroup, [String]$NsgName, [String]$IpAddress, [String]$RuleName)
    az account set -s $Sub
    if (!$?) {
        Write-Output "Could not select subscription"
        return
    }
    $exists = az network nsg rule list `
        --nsg-name $NsgName -g $ResGroup `
        --query "[?sourceAddressPrefix=='$IpAddress/32' || sourceAddressPrefix=='$IpAddress'].name" `
        -o tsv
    if (!$?) {
        Write-Output "Error checking if NSG rule exists"
        return
    }
    if ($exists) {
        Write-Output "Rule for NSG $NsgName already exists with name '$exists'";
    }
    else {
        Write-Output "Adding rule to NSG $NsgName";
        az network nsg rule create -g $ResGroup `
            --nsg-name $NsgName -n $RuleName `
            --priority 4096 --access Allow `
            --source-address-prefixes "$IpAddress/32" `
            --source-port-ranges '*' `
            --destination-address-prefixes '*' `
            --destination-port-ranges '*'
        if (!$?) {
            Write-Output "Failed to add NSG Rule"
        }
    }
}

Adding a SQL Server Firewall Rule

For the SQL Server Firewall rule we need the az sql server firewall-rule create command.

function Add-SqlServerFirewallRule {
    Param([String]$Sub, [String]$ResGroup, [String]$SqlServerName, [String]$IpAddress, [String]$RuleName)
    az account set -s $Sub
    if (!$?) {
        Write-Output "Could not select subscription"
        return
    }
    $exists = az sql server firewall-rule list `
        -s $SqlServerName -g $ResGroup `
        --query "[?startIpAddress=='$IpAddress'].name" `
        -o tsv
    if (!$?) {
        Write-Output "Error checking if SQL Server firewall rule exists"
        return
    }
    if ($exists) {
        Write-Output "Firewall rule for SQL Server $SqlServerName already exists with name '$exists'";
    }
    else {
        Write-Output "Adding firewall rule to SQL Server $SqlServerName";
        az sql server firewall-rule create -g $ResGroup -s $SqlServerName `
                -n $RuleName --start-ip-address $IpAddress --end-ip-address $IpAddress
        if (!$?) {
            Write-Output "Failed to add SQL Server firewall rule"
        }
    }
}

Summary

The Azure CLI is great for automating tedious and repetitive tasks. I have a list of Azure resources that I can now quickly iterate through and allow myself access to. I can of course also automate the removal of those rules when I no longer need access.

By the way, I know my PowerShell skills are not the greatest, so do let me know if I missed any nice tricks to make the PowerShell code simpler.

Want to learn more about the Azure CLI? Be sure to check out my Pluralsight course Azure CLI: Getting Started.

0 Comments

When I set up a new development machine, I like to review all the dev tools I have installed on my current machine and decide which ones are worth keeping. Here's a couple of handy command line tools I found that helped me remember what I have installed, plus a few links to my favourite tools and extensions:

dotnet globally installed tools

dotnet tool list -g

I like dotnet-outdated and Tye

npm globally installed tools

npm list -g --depth=0

I usually have the Vue CLI, Azure Functions Core Tools and HTTP server installed

Visual Studio Code extensions

code --list-extensions

One notable lesser-known favourite to point out is the draw.io integration extension. This makes it super easy to have editable architecture diagrams that automatically appear as SVG or PNG files.

Windows apps

I usually just look at the list of apps in the Add/Remove Programs part of the control panel, but in case you want to automate it this PowerShell provides a fairly comprehensive list.

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName

Summary

Anyway, hope these command lines are useful, and feel free to share others with me in the comments, as well as what your favourite global tools and extensions are. I know some people go to much greater lengths to fully automate the setup of a new machine but I have always been slightly reluctant to do that, as many applications have installation options I like to be in control of.


0 Comments Posted in:

Just a quick update about my plans for a v2 of NAudio. NAudio 2 will have a few small bugfixes, but should mostly be a highly backwards compatible update. Most of the changes will be to do with project organization.

Multiple Assemblies

The biggest change is that NAudio is now a collection of smaller libraries. This is because a lot of NAudio contains platform specific interop wrappers that are not applicable to all users.

  • NAudio.Core is a .NET Standard package which includes all of the cross-platform parts of NAudio. All of the interfaces, lots of helpers plus things like WaveFileReader and WaveFileWriter are in here
  • NAudio.MIDI contains the MIDI events, which can be used cross platform, and also the WinMM MIDI interop which is Windows specific.
  • NAudio.WinMM contains all of the Windows audio API support for the long-standing WinMM APIs. Most notably the WaveInEvent and WaveOutEvent classes which are still often the best choice for audio recording and playback on Windows, plus other old Windows API support such as ACM (codecs) and the mixer.
  • NAudio.WASAPI contains all the interop for the newer Windows audio APIs including WASAPI, DMO (DirectX Media Objects) and MediaFoundation
  • NAudio.WinForms contains anything with a WinForms dependency. This includes the original WaveIn and WaveOut classes which use Windows messages for callbacks. Note that it is totally fine to use these in a WPF application. However, this package is probably not needed in most cases
  • NAudio.Asio contains the interop for ASIO
  • NAudio.Uap contains all the support for the UAP platform, with a new minimum version of 17763 (Windows 10 version 1809). To be honest, most of this is still experimental and I'm tempted to drop it. It was really just a proof of concept I made a few years back and is a pain to maintain.
  • NAudio this still exists as a top-level package that references all of the sub-packages, hopefully making it easy for people who don't want to know or care about what is where. There are a couple of classes that had to go at this layer, which are AudioFileReader since that combines readers from several different sub-assemblies, and Mp3FileReader which by default uses ACM. However a new Mp3FileReaderBase can be used if you want to provide a different MP3 frame decoder (e.g. NLayer)
  • NAudio.Extras - contains some useful helper classes from the demo applications. This is also a potential good place for contributors to add some of their own helper classes that aren't a good fit for the core libraries.

I've kept everything in a monorepo, as this makes life a lot easier testing the code. I might even bring in a few more satellite libraries such as NAudio.SharpMediaFoundation.

Dropped .NET 3.5 support

Note that I've finally dropped .NET 3.5 support. The lowest version NAudio 2 will support is .NET 4.7.2. However you can of course still use NAudio 1 with .NET 3.5 if you are still stuck on a legacy version of the .NET Framework.

Strong Naming

I have also taken this opportunity to strong name the assemblies. This was always a source of controversy, as some people wanted it strong named, and others didn't, and I wasn't sure of the implications of suddenly switching. However, the official guidance from Microsoft has changed over the years, with the recommendation now being that you do strong-name your libraries, and so releasing a new major version seems a good time to introduce it.

Switching to the MIT License

I have also chosen to move away from the MS-PL to the more standard and well-known MIT license. They are both permissive and commercial friendly licenses, so I don't anticipate any problems here.

Azure Pipeline

I also did some work on improving the Azure Pipeline build so it can run the unit tests. The previous build set up was rather unreliable, and this should make it easier to evaluate pull requests.

Feedback

I'd love for you to try out the beta builds of NAudio 2, and let me know if they unexpectedly break anything in your applications. And please give me any feedback on these changes to NAudio. I want to do a bit more testing myself before pushing these changes live, but hopefully it won't be too long.

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.