---
title: Real-World Async Functions in PowerShell
description: Improve script performance with asynchronous functions in PowerShell. Learn through real-world examples.
canonical: https://adamtheautomator.com/powershell-async/
---

# Real-World Async Functions in PowerShell

> Improve script performance with asynchronous functions in PowerShell. Learn through real-world examples.

Source: https://adamtheautomator.com/powershell-async/

---

- Real-World Async Functions in PowerShell Tap to hide Home

- Tutorials

- Guidebooks

- Instructors

- Get Paid to Write

- Advertising

- Recommended Resources

- About Adam

                Search for:

-

-

-

-

# Real-World Async Functions in PowerShell

        Published:28 June 2019 - 2 min. read

- PowerShell

          [](https://adamtheautomator.com/author/adam-bertram/)

            [Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)

            Read [more tutorials](https://adamtheautomator.com/author/adam-bertram/) by Adam Bertram!

-

-

        [](https://specopssoft.com/product/specops-password-auditor/?utm_source=adamtheautomator&utm_medium=referral&utm_campaign=adamtheautomator_referral_na&utm_content=display)
        Audit Active Directory for stale users, weak passwords, and other security risks with [Specops Password Auditor](https://specopssoft.com/product/specops-password-auditor/?utm_source=adamtheautomator&utm_medium=referral&utm_campaign=adamtheautomator_referral_na&utm_content=text).

Table of Contents

- Build the Code as Normal
- Build the Function Parameters
- Implement PowerShell Async Job Support
- Provide Support for Synchronous Operation

                XFacebookLinkedIn

The most frequent kind of PowerShell function is a function that executes code and, when finished, returns control back to the console. This is called synchronous code or a PowerShell async function. This means further code execution will not continue until that function's execution is complete.

Related:[PowerShell Multithreading: A Deep Dive](https://adamtheautomator.com/powershell-multithreading/)

There are those times when the code inside of your function may take a while, and you don't feel like waiting around until it's done. In this case, you need to build functions that immediately return control but continue running a thread in the background.

I use asynchronous functions to clean up Azure VMs, for example. The process takes up to 5 minutes because it must bring down the VM, remove the VM and clean up all of the attached disks. It's much easier to simply have my custom function return a background job object and monitor that when I have time.

PowerShell async functions can be written in a few different ways; [workflows](https://docs.microsoft.com/en-us/system-center/sma/overview-powershell-workflows), parallel runspaces, and [jobs](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_jobs) to name a few. Each has its advantages and disadvantages. However, I typically use jobs to run asynchronous code. I do this because they're typically easy to manage and are intuitive to me.

Let's say I have a need for a function that removes an Azure virtual machine. Within this function, I need to remove the VM, which takes a few minutes and does some other cleanup tasks.

I want to build a function that allows me to return a background job object but also give the user the option to wait for the function if they need to.

Always give the option to wait just in case there might be a time when you develop a script that might require that functionality.

## Build the Code as Normal

To remove a VM in Azure is simple with the Azure PowerShell cmdlet Remove-AzVM which requires a few parameters; Name and ResourceGroupName.

This would remove an Azure VM of mine: Remove-AzVM -Name MYVM -ResourceGroupName MYRG.

Related:[How to Delete an Azure VM and Cleanup with PowerShell](https://adamtheautomator.com/azure-vm-delete/)

Done. I now have the "typical" code to remove an Azure VM.

## Build the Function Parameters

To build a function around this to run in the background, I'll need to build it to support the parameters that Remove-AzVm needs so Name and ResourceGroupName.

function Remove-MyAzureRmVM
{
    param (
        [Parameter(Mandatory)]
        [string]$Name,

        [Parameter(Mandatory)]
        [string]$ResourceGroupName
    )
    Remove-AzureRmVm -Name $Name -ResourceGroupName $ResourceGroupName
}

I now have a simple proxy function that passes two parameters to the Remove-AzVm cmdlet. This works, but it's not much good because it's running synchronously. We need to make it into a PowerShell async function and implement PowerShell job support but also give the user the option to run it synchronously if they want.

## Implement PowerShell Async Job Support

To do this, we'll need to put our code into a scriptblock. This allows us to not only pass it to Start-Job but also just to execute it if the user wants to wait for the operation to complete. Since Remove-AzVm requires some parameters from the function, we must also add these parameters to the scriptblock as well.

$scriptBlock = {
    param ($Name,$ResourceGroupName)
    Remove-AzureRmVm -Name $Name -ResourceGroupName $ResourceGroupName
    ## Other stuff here
}

Once the code is in the scriptblock, you can then simply pass it to Start-Job, and you're off to the races! Just be sure to pass in the arguments as necessary.

Start-Job -ScriptBlock $scriptBlock -ArgumentList @($VMName,$ResourceGroupName)

## Provide Support for Synchronous Operation

Since the code is in a scriptblock, we can now also execute this on its own by using the ampersand and passing in the parameters again.

& $scriptBlock -VMName $VMName -ResourceGroupName $ResourceGroupName

So we've now got both ways to execute the code. All we need to do now is provide a way for the function to specify which one we want.

By default, I want the code to be executed in a background job, but I want the option to execute it synchronously if need be. A great way to implement this functionality is to use the Wait parameter as a switch type. This allows me to quickly "turn on" synchronous behavior if I need to.

Remove-MyAzVM -VMName MYVM -ResourceGroupName MYRG -Wait

  Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

  [Explore ATA Guidebooks](https://adamtheautomator.com/ata-guidebooks/)

## More from ATA Learning and Partners

- ### Recommended Resources! Recommended Resources for Training, Information Security, Automation, and more!

- ### Get Paid to Write! ATA Learning is always seeking instructors of all experience levels. Regardless if you’re a junior admin or system architect, you have something to share. Why not write on a platform with an existing audience and share your knowledge with the world?

- ### ATA Learning Guidebooks ATA Learning is known for its high-quality written tutorials in the form of blog posts. Support ATA Learning with ATA Guidebook PDF eBooks available offline and with no ads!

## Categories

- IT Ops

- Cloud

- DevOps

- Home Ops

- Information Security

- Software Development

## Site

- Home

- Tutorials

- Guidebooks

- Instructors

- Get Paid to Write

- Advertising

- Recommended Resources

- About Adam

        Copyright 2026&copy; ATA Learning | [Privacy Policy](https://adamtheautomator.com/privacy/)

                                                        Don't be left behind with the ATA Learning Newsletter!

Looks like you're offline!
