Public/New-VMetricDeployment.ps1
|
function New-VMetricDeployment { <# .SYNOPSIS Deploys a Bicep template. .DESCRIPTION New-VMetricDeployment runs a deployment template: every resource it declares is created when its name is absent and updated when present; resources it does not name are never touched. The engine checks every permission first and writes nothing when one is missing. The template is validated first, and an invalid one is refused with its diagnostics. With -WhatIf the engine's what-if shows what the deployment would create and change, property by property, and nothing is deployed; -Confirm shows the same and asks. It waits for the deployment to end, showing its progress operation by operation, and writes the deployment (VirtualMetric.Deployment); a failed or canceled one is also reported as an error. -AsJob runs it in a background job instead (Receive-Job gives the deployment), and -NoWait returns as soon as it has started. One deployment runs at a time in an organization: while another runs, the module waits up to 30 seconds before it gives up. .PARAMETER TemplateFile The Bicep file to deploy. Files can be piped from Get-ChildItem. .PARAMETER Template The Bicep text to deploy. .PARAMETER TemplateParameterObject The template's parameters, such as @{ deviceName = 'syslog-tcp'; port = 1514 }. Give a secure parameter's value as a SecureString; it is sent only in the request. .PARAMETER TemplateParameterFile A JSON parameters file: {"parameters": {"name": {"value": ...}}} or a plain object of values. Values in -TemplateParameterObject win over the file's. .PARAMETER Name The deployment's name (at most 128 characters). The server names it deploy-YYYYMMDD-HHMMSS otherwise. .PARAMETER Wait Wait for the deployment to end. This is the default; the switch lets a script say so. .PARAMETER NoWait Return as soon as the deployment has started (status running). Follow it with Get-VMetricDeployment -Id. .PARAMETER AsJob Run the deployment in a background thread job and return the job. .EXAMPLE New-VMetricDeployment -TemplateFile ./syslog.bicep -TemplateParameterObject @{ deviceName = 'syslog-tcp' } .EXAMPLE New-VMetricDeployment -TemplateFile ./syslog.bicep -WhatIf Shows what the deployment would change without deploying. .EXAMPLE $job = New-VMetricDeployment -TemplateFile ./fleet.bicep -Name fleet-rollout -AsJob $job | Receive-Job -Wait .EXAMPLE New-VMetricDeployment -TemplateFile ./director.bicep -TemplateParameterObject @{ adminPassword = (Read-Host -AsSecureString) } .OUTPUTS VirtualMetric.Deployment, or a job with -AsJob. .LINK Test-VMetricDeployment .LINK Get-VMetricDeployment .LINK Stop-VMetricDeployment .LINK Export-VMetricTemplate #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'File')] [OutputType('VirtualMetric.Deployment')] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'File', ValueFromPipelineByPropertyName)] [Alias('FullName')] [ValidateNotNullOrEmpty()] [string] $TemplateFile, [Parameter(Mandatory, ParameterSetName = 'Text')] [ValidateNotNullOrEmpty()] [string] $Template, [System.Collections.IDictionary] $TemplateParameterObject, [ValidateNotNullOrEmpty()] [string] $TemplateParameterFile, [ValidateLength(1, 128)] [string] $Name, [switch] $Wait, [switch] $NoWait, [switch] $AsJob ) process { $deployment = $null try { if ($Wait -and $NoWait) { throw (New-VMetricException -Message '-Wait and -NoWait cannot be used together.' -Code 'InvalidArguments' -Category InvalidArgument) } if ($AsJob -and $NoWait) { throw (New-VMetricException -Message '-AsJob already returns at once; leave out -NoWait.' -Code 'InvalidArguments' -Category InvalidArgument) } $session = Get-VMetricSession $text = Get-VMetricTemplateText -Cmdlet $PSCmdlet -TemplateFile $TemplateFile -Template $Template $parameters = Get-VMetricTemplateParameter -Cmdlet $PSCmdlet -ParameterObject $TemplateParameterObject -ParameterFile $TemplateParameterFile $secrets = Get-VMetricSecretText -InputObject $parameters $null = Assert-VMetricTemplateValid -Cmdlet $PSCmdlet -Template $text -Parameters $parameters -Session $session -Secret $secrets $description = if ($TemplateFile) { "Deploy template '$(Split-Path -Path $TemplateFile -Leaf)'" } else { 'Deploy the template' } if ($Name) { $description += " as '$Name'" } $impact = Get-VMetricConfirmImpact -Cmdlet $PSCmdlet if (Test-VMetricPromptActive -Cmdlet $PSCmdlet -ConfirmImpact $impact) { $whatIf = Invoke-VMetricRequest -Method POST -Path '/deployments/what-if' -Session $session ` -Body ([ordered]@{ template = $text; parameters = $parameters }) $refused = Write-VMetricPreviewDiagnostic -Cmdlet $PSCmdlet -Preview $whatIf -Secret $secrets -TargetObject $description $lines = Format-VMetricWhatIfText -Result $whatIf -Secret $secrets $description = "${description}:" + [Environment]::NewLine + (($lines | ForEach-Object { " $_" }) -join [Environment]::NewLine) if ($refused -and -not (Test-VMetricWhatIf -Cmdlet $PSCmdlet)) { return } } if (-not (Test-VMetricShouldProcess -Cmdlet $PSCmdlet -Description $description -Warning "$description$([Environment]::NewLine)Continue?" -Caption 'Deploy')) { return } if ($AsJob) { Start-VMetricDeploymentJob -Session $session -Name $Name -Template $text -Parameters $parameters return } $raw = Invoke-VMetricDeploymentRun -Session $session -Name $Name -Template $text -Parameters $parameters -NoWait:$NoWait $deployment = ConvertTo-VMetricDeploymentObject -InputObject $raw } catch { if (Test-VMetricFlowControl -ErrorRecord $_) { throw } $record = Hide-VMetricSecretInError -ErrorRecord $_ -Secret (Get-VMetricSecretText -InputObject $TemplateParameterObject) Write-VMetricCmdletError -Cmdlet $PSCmdlet -ErrorRecord $record return } Hide-VMetricSecretInObject -InputObject $deployment -Secret $secrets $deployment Write-VMetricDeploymentOutcome -Cmdlet $PSCmdlet -Deployment $deployment -Secret $secrets } } |