Deploy Azure WebJob using PowerShell

There are many posts on thema of Azure WebJob deployment using PowerShell. But I try to find the most simple solution possible and it is using the combination of PowerShell and Azure CLI.


Udemy course: Migrate Windows service to Azure

Following PowerShell script deploys Azure WebJob:

param
(
    [string] $buildOutput = $(throw "Directory with build output is required"),
    [string] $resourceGroupName = $(throw "Resource group name is required"),
    [string] $webAppName = $(throw "Web app name is required"),
    [string] $webJobName = $(throw "Web job name is required"),
    [string] $webJobType = "triggered"
)

$currentDir = (Get-Item .).FullName
$tempDir = "$currentDir\Temp"
$webJobDir = "$tempDir\App_Data\jobs\$webJobType\$webJobName"

New-Item $webJobDir -ItemType Directory
Copy-Item "$buildOutput\*" -Destination $webJobDir -Recurse
Compress-Archive -Path "$tempDir\*" -DestinationPath ".\$webJobName.zip"
Remove-Item $tempDir -Recurse -Force

az webapp deployment source config-zip -g $resourceGroupName -n $webAppName --src "$webJobName.zip"

PowerShell script has following parameters:

  • $buildOutput – Azure WebJob build output, in my case it is bin\Release\net472 folder
  • $resourceGroupName – Azure resource group name
  • $webAppName – Azure Web App name running on Azure App Service
  • $webJobName – Azure WebJob name
  • $webJobType – Azure WebJob type (triggered/continuous)

PowerShell creates temp directory and copy build output to the temp directory. The key part here is to use defined directory structure App_Data\jobs\$webJobType\$webJobName to deploy Azure WebJob to valid directory in Azure WebApp. Then create ZIP archive and remove temp directory. Then deploys Azure WebJob using Azure CLI command az webapp deployment to Azure.

If you are interested in Azure WebJobs and how to use them for Windows service migration to Azure, take my Udemy course Migrate Windows service to Azure where you learn more about Azure WebJob implementation, deployment, configuration and monitoring.

Run T-SQL query parallel using PowerShell

T-SQL query can be run parallel using combination of PowerShell Workflows and Invoke-Sqlcmd cmdlet as show in following code:

param
(
    [string] $query = $(throw "Query is required"),
    [string] $database = $(throw "Database name is required"),
    [int] $parallelCount = 10
)

workflow Invoke-SqlcmdParallel
{
    param
    (
        $query,
        $parallelCount,
        $database
    )

    $numbers = [System.Linq.Enumerable]::Range(1, $parallelCount)

    foreach -parallel ($number in $numbers)
    {
        Invoke-Sqlcmd -Database $database -Query $query
    }
}

Invoke-SqlcmdParallel -query $query -parallelCount $parallelCount -database $database

Using this script you can easily simulate concurrency.

If you are interested in PowerShell automation, take my Udemy course Improve your productivity with PowerShell.


Udemy course: Improve your productivity with PowerShell

Create Azure SQL Database using PowerShell cmdlets

Azure SQL Database can be created using UI in Azure Portal, using PowerShell cmdlets or by using Azure Resource Manager template written in JSON. Following PowerShell script creates Azure SQL Database using PowerShell cmdlets:

Udemy course: Improve your productivity with PowerShell

param
(
    $resourceGroup = $(throw "Resource group is required"),
    $location = $(throw "Location is required"),
    $server = $(throw "Server is required"),
    $database = $(throw "Database is required"),
    $adminLogin = $(throw "Admin login is required"),
    $adminPassword = $(throw "Admin password is required"),
    $ipAddress = $(throw "IP address is required")
)

New-AzureRmResourceGroup -Name $resourceGroup -Location $location

$securePassword = ConvertTo-SecureString -String $adminPassword -AsPlainText -Force
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminLogin, $securePassword

New-AzureRmSqlServer -ResourceGroupName $resourceGroup `
    -ServerName $server `
    -Location $location `
    -SqlAdministratorCredentials $credentials

New-AzureRmSqlServerFirewallRule -ResourceGroupName $resourceGroup `
    -ServerName $server `
    -FirewallRuleName "Default" `
    -StartIpAddress $ipAddress `
    -EndIpAddress $ipAddress

New-AzureRmSqlDatabase -ResourceGroupName $resourceGroup `
    -ServerName $server `
    -DatabaseName $database `
    -RequestedServiceObjectiveName "S0"

$result = Invoke-Sqlcmd -ServerInstance "$server.database.windows.net" `
    -Database $database `
    -Username $adminLogin `
    -Password $adminPassword `
    -Query "SELECT @@VERSION AS Version"

$result.Version

PowerShell script creates new resource group, SQL server, configures firewall and than create empty database. At the end new database is queried by simple T-SQL command.

If you are interested in PowerShell automation, take my Udemy course Improve your productivity with PowerShell.

PowerShell unit tests with Pester

Few days ago I have discover interesting PowerShell module Pester for creating unit tests in PowerShell. As a code for testing is used PowerShell script from my previous post dedicated to password generation. PowerShell module Pester is installed using command:

Install-Module -Name Pester -Force -SkipPublisherCheck


Udemy course: Improve your productivity with PowerShell

Installed PowerShell modules can be listed by:

Get-InstalledModule

Unit test of New-AzureSqlPassword.ps1 script is saved to New-AzureSqlPassword.Tests.ps1 file and has following code:

Describe "New-AzureSqlPassword" {
    It "Should return password 32 characters long" {
        $password = .\New-AzureSqlPassword.ps1
        $password.Length | Should -Be 32
    }

    Context "Password complexity" {
        It "Should contain lowercase letters" {
            $password = .\New-AzureSqlPassword.ps1
            $measure = $password.GetEnumerator() | Where-Object { [System.Char]::IsLower($_) } | Measure-Object 
            $measure.Count | Should -BeGreaterThan 0
        }

        It "Should contain uppercase letters" {
            $password = .\New-AzureSqlPassword.ps1
            $measure = $password.GetEnumerator() | Where-Object { [System.Char]::IsUpper($_) } | Measure-Object 
            $measure.Count | Should -BeGreaterThan 0
        }

        It "Should contain digits" {
            $password = .\New-AzureSqlPassword.ps1
            $measure = $password.GetEnumerator() | Where-Object { [System.Char]::IsDigit($_) } | Measure-Object 
            $measure.Count | Should -BeGreaterThan 0
        }

        It "Should contain special characters" {
            $password = .\New-AzureSqlPassword.ps1
            $measure = $password.GetEnumerator() | Where-Object { ($_ -eq '!') -or ($_ -eq '$') -or ($_ -eq '#') -or ($_ -eq '%') } | Measure-Object 
            $measure.Count | Should -BeGreaterThan 0
        }
    }

    Context "Password difference" {
        It "Should return different passwords when calling two times" {
            $password1 = .\New-AzureSqlPassword.ps1
            $password2 = .\New-AzureSqlPassword.ps1
            $password1 -eq $password2 | Should -BeFalse
        }
    }
}

PowerShell script and it’s unit test is placed in the same folder:

PowerShell command line

Unit test is run using command:

Invoke-Pester

Output of unit test is:

PowerShell command line

If you are interested in PowerShell automation, take my Udemy course Improve your productivity with PowerShell.

Generate strong passwords using PowerShell

Few days ago I need to generate set of passwords for Azure SQL Database. Password policy for Azure Active Directory https://docs.microsoft.com/en-us/azure/active-directory/active-directory-passwords-policy and MSSQL https://docs.microsoft.com/en-us/sql/relational-databases/security/password-policy specifies requirements for password generator. PowerShell script for strong password generation:

$specialChars = @("!", "$", "#", "%")

$guid = [System.Guid]::NewGuid().ToString("n")
$sb = New-Object System.Text.StringBuilder

for ($i = 0; $i -lt $guid.Length; $i++)
{
    $c = $guid[$i]

    if (($i % 2 -eq 0) -and [System.Char]::IsLetter($c))
    {
        $c = [System.Char]::ToUpper($c)
    }

    $random = Get-Random -Minimum 1 -Maximum 100

    if ($random % 7 -eq 0)
    {
        $c = Get-Random $specialChars
    }

    $sb.Append($c) | Out-Null
}

$sb.ToString()


Udemy course: Improve your productivity with PowerShell

Password generator is based on the System.Guid.NewGuid() method which generates 32 character length password base containing lowercase letters and numbers. In the next step are some letters transformed to uppercase or replaced by special characters. Passwords generated by script are like this:

B0F13098C34e42729d66%eD!$#41C56d
5aB4%a9cB6Bb4c319!8dB99aC631707%
485488028d5840D0AcA04$34D48a1921

If you are interested in PowerShell automation, take my Udemy course Improve your productivity with PowerShell.