Public/New-DuneActionAssignment.ps1

<#
.SYNOPSIS
Create or set an action assignment on a deployment/resourcegroup/resource.
 
.DESCRIPTION
POSTs an action-assignment to the action-assignments endpoint. Specify the target via a Deployment, ResourceGroup, or Resource object, or directly via ConfigItemId/ConfigItemType, and provide an ActionId or Action.
 
The action's template parameters are resolved against the Parameters hashtable; any parameter not supplied there is prompted for interactively (Read-Host), falling back to the template default or null for optional parameters when the prompt is left empty.
 
.PARAMETER Deployment
A `DuneDeployment` object to assign the action to (pipeline input supported).
 
.PARAMETER ResourceGroup
A `DuneResourceGroup` object to assign the action to (pipeline input supported).
 
.PARAMETER Resource
A `DuneResource` object to assign the action to (pipeline input supported).
 
.PARAMETER ConfigItemId
The GUID of the config item to assign the action to. Use together with ConfigItemType as an alternative to passing a typed object.
 
.PARAMETER ConfigItemType
The type of the config item referenced by ConfigItemId. Valid values: Deployment, ResourceGroup, Resource.
 
.PARAMETER Name
The name for the action assignment. Required.
 
.PARAMETER ActionId
The GUID of the action to assign. The action is looked up via Get-DuneAction to resolve its template parameters.
 
.PARAMETER Action
A `DuneAction` object to assign (pipeline input supported).
 
.PARAMETER Parameters
A hashtable of parameter values for the action's template parameters, keyed by parameter name. Missing parameters are prompted for interactively; securestring parameters are prompted with masked input.
 
.PARAMETER CronExpression
A cron expression for scheduled execution.
 
.EXAMPLE
PS> New-DuneActionAssignment -Name "backup" -ActionId $actionId -Deployment $dep
Creates an action assignment on a deployment.
 
.EXAMPLE
PS> New-DuneActionAssignment -Name "backup" -ConfigItemId $depId -ConfigItemType Deployment -Action $action -Parameters @{ Retention = 7 }
Creates an action assignment by config item id/type, supplying the action's Retention parameter up front so it is not prompted for.
#>

function New-DuneActionAssignment {
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param(
        [Parameter(ParameterSetName = 'Deployment', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'DeploymentId')]
        [DuneDeployment]$Deployment,

        [Parameter(ParameterSetName = 'ResourceGroup', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'ResourceGroupId')]
        [DuneResourceGroup]$ResourceGroup,

        [Parameter(ParameterSetName = 'Resource', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'ResourceId')]
        [DuneResource]$Resource,

        [Parameter(ParameterSetName = 'ConfigItem')]
        [guid]$ConfigItemId,

        [Parameter(ParameterSetName = 'ConfigItem')]
        [ValidateSet('Deployment','ResourceGroup','Resource')]
        [string]$ConfigItemType,

        [Parameter(Mandatory = $true)]
        [string]$Name,

        [Parameter(ParameterSetName = 'Deployment')]
        [Parameter(ParameterSetName = 'ResourceGroup')]
        [Parameter(ParameterSetName = 'Resource')]
        [Parameter(ParameterSetName = 'ConfigItem')]
        [guid]$ActionId,

        [Parameter(ParameterSetName = 'DeploymentId', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'ResourceGroupId', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'ResourceId', ValueFromPipeline)]
        [Parameter(ParameterSetName = 'ConfigItem', ValueFromPipeline)]
        [DuneAction]$Action,

        [Parameter()]
        [hashtable]$Parameters,

        [Parameter()]
        [string]$CronExpression
    )

    begin {}

    process {
        $Uri = 'action-assignments'

        if ($ActionId) {
            $Action = Get-DuneAction -Id $ActionId -ErrorAction Stop
        }
        if (-not $Action) {
            throw "Unable to resolve the action. Provide -Action or a valid -ActionId."
        }

        $Body = @{
            ActionId = $Action.Id
            Name     = $Name
            Parameters = @()
        }
        
        foreach ($TemplateParameter in $Action.Parameters) {
            $Parameter = @{
                Name        = $TemplateParameter.Name
                Description = $TemplateParameter.Description
                Type        = $TemplateParameter.Type
                Default     = $TemplateParameter.Default
                Optional    = $TemplateParameter.Optional
                Validation  = $TemplateParameter.Validation
            }
            $Value = $Null
            $NullValueSet = $false
            if ($TemplateParameter.Name -in $Parameters.keys) {
                $Value = $Parameters.($TemplateParameter.Name)
            }
            else {
                # while (-not $Value) {
                while ($null -eq $Value -and (-not $NullValueSet)) {
                    $ReadHost = @{
                        Prompt = if ($TemplateParameter.Default) {
                            "{0} (Description: {1}, Type: {2}, Default: {3})" -f $TemplateParameter.Name, $TemplateParameter.Description, $TemplateParameter.Type, $TemplateParameter.Default
                        }
                        else {
                            "{0} (Description: {1}, Type: {2})" -f $TemplateParameter.Name, $TemplateParameter.Description, $TemplateParameter.Type
                        }
                    }
                    if ($TemplateParameter.Type -eq 'securestring') {
                        # -MaskInput requires PS 7.1+; -AsSecureString masks input on all supported editions
                        $ReadHost.AsSecureString = $True
                    }
                    $ReadHostValue = Read-Host @ReadHost
                    if ($ReadHostValue -is [securestring]) {
                        $ReadHostValue = ConvertFrom-DuneSecureString -SecureString $ReadHostValue
                    }
                    if (-not $ReadHostValue) {
                        if ($TemplateParameter.Default) {
                            $Value = $TemplateParameter.Default | ConvertFrom-Json
                        }
                        elseif ($TemplateParameter.Optional) {
                            $Value = $null
                            $NullValueSet = $true
                        }
                    }
                    else {
                        $Value = $ReadHostValue
                    }
                }
            }
            
            $Parameter.Value = if ($TemplateParameter.Type -eq 'Number') {
                $Value
            }
            else {
                ConvertTo-Json -InputObject $Value
            }
            $Body.Parameters += $Parameter
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Deployment' { 
                $Body.ConfigItemId = $Deployment.Id
                $Body.ConfigItemType = "Deployment"
            }
            'ResourceGroup' {
                $Body.ConfigItemId = $ResourceGroup.Id
                $Body.ConfigItemType = "ResourceGroup"
            }
            'Resource' {
                $Body.ConfigItemId = $Resource.Id
                $Body.ConfigItemType = "Resource"
            }
            'ConfigItem' {
                $Body.ConfigItemId = $ConfigItemId
                $Body.ConfigItemType = $ConfigItemType
            }
        }

        if ($PSBoundParameters.ContainsKey('Parameters')) { $Body.Parameters = $Parameters }
        if ($PSBoundParameters.ContainsKey('CronExpression')) { $Body.CronExpression = $CronExpression }

        $Return = Invoke-DuneApiRequest -Uri $Uri -Method POST -Body $Body
        $ReturnObject = if ($Return.Content) { $Return.Content | ConvertFrom-Json | ConvertTo-DuneClassObject -Class DuneActionAssignment }
        return $ReturnObject
    }

    end {}
}