Functions/Start-CBOrder.ps1


function Start-CBOrder 
{
    <#
    .SYNOPSIS
    Starts an order in CloudBolt.
 
    .DESCRIPTION
    The `Start-CBOrder` function creates an order in CloudBolt and submits/starts it. You can use `Wait-CBOrder` to wait for the order to complete.
 
    Pass a session object to the CloudBolt instance to use to the `Session` parameter (use `New-CBSession` to create a session object). Pass the ID of the group making the order to the `GroupID` parameter. Pass the blueprint ID to order to the `BlueprintID` parameter. If the build item being run by the blueprint has any parameters, pass them as a hashtable to the `BuildItemParameter`. Pass a name for the order to the `Name` parameter. Pass the name of the blueprint's resource (if any) to the `ResourceName` parameter. Pass any resource parameters as a hashtable to the `ResourceParameter` function.
 
    The request body generated by this function is visible in debug output. Set `$DebugPreference = 'Continue'` to see it.
 
    This function returns an order object that you can pass to `Wait-CBOrder` to block/wait for the order to complet before continuing your script.
 
    .EXAMPLE
    Start-CBOrder -Session $session -GroupID 389 -BlueprintID 392
 
    Demonstrates how to create and start an order by group `389` that uses bluerint `392`. This blueprint has no parameters/resources.
 
    Start-CBOrder -Session $session -GroupID 389 -BlueprintID 393 -BuildItemParameter @{ 'fubar' = @{ 'snafu' = 'ufans' } } -ResourceName 'some_resource' -ResourceParameter @{ 'fizz' = 'buzz' }
 
    Demonstrates how co create and submit an order that requires build and resource parameters. In this example, the request body will look something like this:
 
        {
            "group": "/api/v2/groups/389",
            "items": {
                "deploy-items": [
                    {
                        "blueprint": "/api/v2/blueprints/393",
                        "blueprint-items-arguments": {
                            "build-item-fubar": {
                                "parameters": {
                                    "snafu": "ufans"
                                }
                            }
                        },
                        "resource-name": "some_resource",
                        "resource-parameters": {
                            "fizz": "buzz"
                        }
                    }
                ]
            },
            "submit-now": "true"
        }
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)]
        [object]
        # The session/connecton to the CloudBolt instance to use. Use `New-CBSession` to create a session object.
        $Session,

        [Parameter(Mandatory)]
        [int]
        # The group ID making the order.
        $GroupID,

        [Parameter(Mandatory)]
        [int]
        # The blueprint ID to order.
        $BlueprintID,

        [hashtable]
        # Any build item parameters. The keys should be the names of the items (without the `build-item` prefix). The values should be a hashtable of name/value pairs to send to that action/item.
        $BuildItemParameter,

        [string]
        # A name for the order.
        $Name,

        [string]
        # The resource name used by the blueprint, if any.
        $ResourceName,

        [hashtable]
        # The resource parameter for the blueprint's resource, if any.
        $ResourceParameter
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $blueprintArgs = @{}
    if( $BuildItemParameter )
    {
        foreach( $buildItemName in $BuildItemParameter.Keys )
        {
            $argName = 'build-item-{0}' -f $buildItemName
            $argValue = [pscustomobject]@{
                                            parameters = [pscustomobject]$BuildItemParameter[$buildItemName]
                                        }
            $blueprintArgs[$argName] = $argValue
        }
    }
    
    $order = [pscustomobject]@{
                                'name' = $Name;
                                'group' = ('/api/v2/groups/{0}' -f $GroupID);
                                'items' = [pscustomobject]@{
                                    'deploy-items' = @(
                                        [pscustomobject]@{
                                            'blueprint' = ('/api/v2/blueprints/{0}' -f $BlueprintID)
                                            'blueprint-items-arguments' = [pscustomobject]$blueprintArgs
                                            'resource-name' = $ResourceName;
                                            'resource-parameters' = [pscustomobject]$ResourceParameter;
                                        }
                                    )
                                };
                                'submit-now' = $true;
                            } | ConvertTo-Json -Depth 100

    $order = Invoke-CBRestMethod -Session $Session -Method Post -ResourcePath 'orders/' -Body $order |
                Add-CBTypeName -Order -PassThru

    $submitInfo = $order._links.actions | 
                        Where-Object { $_ | Get-Member 'submit' } | 
                        Select-Object -ExpandProperty 'submit'
    
    Write-Verbose -Message $submitInfo.title
    if( $submitInfo.href -notmatch '(\borders/.*)' )
    {
        Write-Error -Message ('Unable to find order submit URI from "{0}".' -f $submitInfo.href)
        return
    }

    $submitUri = $Matches[1]
    if( -not $submitUri.EndsWith('/') )
    {
        $submitUri = '{0}/' -f $submitUri
    }

    Invoke-CBRestMethod -Session $Session -Method Post -ResourcePath $submitUri |
        Add-CBTypeName -Order -PassThru
}