dsc/Update-AutomationModules.ps1

function Update-AutomationModules {
    param (
        [Parameter(Mandatory = $true)]
        [validatepattern('\A\w\d\Z')]
        [String] $Environment,
        [String] $AAName,
        [String] $RGName,
        [string] $ProjectDirectory = (Get-Location | Select-Object -ExpandProperty Path),
        [Switch] $UpdateLocalDsc,
        [String] $Prefix = "SPZE2"
    )

    if ( -not $AAName) {
        try {
            $GlobalParameters = Get-Content "$ProjectDirectory\global.parameters.json" -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
        }
        catch {
            throw "Could not generate a valid parameters template and/or import the Project's gobal.parameters.json file! Please check the location!`n$_"
        }

        if (-not $Project) {
            if ($GlobalParameters.parameters.Global.value.AppName) {
                $Project = $GlobalParameters.parameters.Global.value.AppName
            }
            else {
                throw "Could not find the Project's name in global.parameters.json!"
            }
        }

        $AAName = $Prefix + $Project + $Environment + 'OMSAutomation'
        if ($Environment -match 's1' -and $Project -match 'atmos') {
            $RGName = 'spze2-atmos-sbx-s1'

        }
        else {
            $RGName = $Prefix + '-' + $Project + '-' + $Environment
        }
    }

    $CommonAAModule = @{
        ResourceGroupName     = $RGName
        AutomationAccountName = $AAName
    }

    # This is our Master list of Modules in the project
    $Modules = @(
        'ComputerManagementDsc'
        'StorageDsc'
        'CertificateDsc'
        'NetworkingDSC'
        'PackageManagement'
        'cChoco'
        'PolicyFileEditor'
        'xDnsServer'
        'PSDscResources'
    )

    # Updating to the newest DSC resource version does not remove the older versions automatically.
    # If more than one version is installed DSC scripts will error out asking for a specific version.
    # This will destructively DELETE any old versions after updating. Be careful! May require admin permissions.
    if ($UpdateLocalDsc) {
        foreach ($Module in $Modules) {
            Install-Module $Module -AllowClobber -Force
            $CurrentModules = Get-Module -ListAvailable $Module
            while ($CurrentModules.Count -gt 1) {
                $OldModule = $CurrentModules | Sort-Object -Property Version | Select-Object -First 1
                try {
                    Remove-Item -Path ($OldModule.Path | Split-Path) -Recurse -Force
                }
                catch {
                    Write-Warning "Version $($OldModule.Version) of Module $Module cannot be removed from ($OldModule.Path | Split-Path)!"
                    Write-Output $_
                }
            }
        }
    }

    #Update your local DSC resources to the latest versions avaliable on the PSGallery which will also update all the DSC resources in Az Automation.
    #Run script as Admin to update.
    #Careful this can break your environment if there are new bugs or breaking features in an a new DSC resource!
    #Make sure to update and test in a dev environment first!



    # Step 2 - Once you have the Modules that you need on your machine, you can upload them to AA
    # This will only upload (new) Modules to AA (that are not the latest)
    # You can run this whole script as it is idempotent.
    # OR if you compile the MOFS, you should also run this second part to ensure all Modules are on AA
    $modules | ForEach-Object {
        $modulename = $_
        $module = Get-Module -Name $modulename -ListAvailable
        $AAModule = Get-AzAutomationModule @CommonAAModule -Name $modulename -Erroraction silentlycontinue
        if ($AAModule) {
            Write-Verbose "Module is found, need to check version" -Verbose
            if ($AAModule.Version) {
                if ($module.Version -match $AAModule.Version) {
                    Write-verbose -Message " --> Module $Modulename has the correct version $($module.version) uploaded" -Verbose
                    $msg = "correct version $($module.version) uploaded"
                }
                else {
                    Write-Verbose " --> Module $Modulename is not the correct version"
                    $Upload = $true
                }
            }
            else {
                Write-Verbose " --> Module $ModuleName has state: $($AAModule.ProvisioningState)" -Verbose
                if ($AAModule.ProvisioningState -eq "Failed") {
                    Write-Verbose " --> --> Module $Modulename provisioningstate failed."
                    $Upload = $true
                }
                else {
                    Write-Verbose " --> --> Module $Modulename provisioningstate $($AAModule.ProvisioningState)"
                    $Upload = $false
                    $msg = "state is $($AAModule.ProvisioningState)"
                }
            }
        }
        else {
            Write-Verbose " --> Module $Modulename is not uploaded yet"
            $Upload = $true
        }
        if (! $Upload) {
            Write-verbose -Message " --> --> Module $Modulename has: $msg" -Verbose
        }
        else {
            Write-Warning -Message " --> --> Need to upload new module $($module.version)"
            $Newmodule = Find-Module -Name $modulename
            $Link = $Newmodule.RepositorySourceLocation + '/package/' + $Newmodule.Name + '/' + $Newmodule.Version
            Write-warning -Message " --> --> Module link: $Link"
            New-AzAutomationModule @CommonAAModule -Name $modulename -ContentLink $Link
        }
        $Upload = $false
        Write-Output "`n"
    }
}