Public/backup.ps1

# Backup and Recovery: instance backups, backup schedules, backup offerings,
# repositories, and the providers behind them.

function Get-CSBackup {
    <#
    .SYNOPSIS
        Lists instance backups.

    .DESCRIPTION
        Wraps listBackups. Filter by the instance, zone, owner, or the backup
        offering. Accepts VM objects on the pipeline to list one instance's backups.

    .PARAMETER VirtualMachineId
        List the backups of this instance. Binds from a piped VM's id.

    .PARAMETER ZoneId
        Filter by zone ID

    .PARAMETER BackupOfferingId
        Filter by backup offering ID

    .PARAMETER Account
        Filter by account name. Must be used with -DomainId.

    .PARAMETER DomainId
        Filter by domain ID

    .PARAMETER ProjectId
        Filter by project ID

    .PARAMETER ListAll
        List every backup the caller is allowed to see

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSBackup -ListAll
        Lists every backup the caller can see.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Get-CSBackup
        Lists the backups of one instance.
    #>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$VirtualMachineId,

        [string]$ZoneId,

        [string]$BackupOfferingId,

        [string]$Account,

        [string]$DomainId,

        [string]$ProjectId,

        [switch]$ListAll,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    process {
        $apiParams = @{}
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            VirtualMachineId = 'virtualmachineid'; ZoneId = 'zoneid'; BackupOfferingId = 'backupofferingid'; Account = 'account'
            DomainId = 'domainid'; ProjectId = 'projectid'; ListAll = 'listall'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
        })
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackups' -Parameters $apiParams) -Command 'listBackups'
    }
}

function New-CSBackup {
    <#
    .SYNOPSIS
        Creates a backup of an instance.

    .DESCRIPTION
        Wraps createBackup. The instance must already be assigned to a backup
        offering (see Register-CSVMBackupOffering). This is an asynchronous job; use
        -Wait to block until the backup finishes. Accepts VM objects on the pipeline.

    .PARAMETER VirtualMachineId
        The instance to back up. Binds from a piped VM's id.

    .PARAMETER Name
        A name for the backup

    .PARAMETER Wait
        Wait for the async job to finish and return the result

    .EXAMPLE
        New-CSBackup -VirtualMachineId $vmId -Name 'pre-upgrade' -Wait
        Takes a named backup of an instance and waits for it.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | New-CSBackup -Wait
        Backs up an instance piped in by object.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$VirtualMachineId,

        [string]$Name,

        [switch]$Wait
    )

    process {
        $apiParams = @{ virtualmachineid = $VirtualMachineId }
        if ($PSBoundParameters.ContainsKey('Name')) { $apiParams['name'] = $Name }
        if ($PSCmdlet.ShouldProcess("instance $VirtualMachineId", 'Create backup')) {
            Invoke-CSAsyncApiRequest -Command 'createBackup' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Remove-CSBackup {
    <#
    .SYNOPSIS
        Deletes an instance backup.

    .DESCRIPTION
        Wraps deleteBackup. This is an asynchronous job; use -Wait to block until it
        finishes. Accepts backup objects on the pipeline.

    .PARAMETER Id
        The backup to delete. Binds from a piped backup's id.

    .PARAMETER Forced
        Force deletion of the backup

    .PARAMETER Wait
        Wait for the async job to finish and return the result

    .EXAMPLE
        Remove-CSBackup -Id $backupId -Wait
        Deletes a backup and waits for the job.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Get-CSBackup | Where-Object created -lt (Get-Date).AddMonths(-3) | Remove-CSBackup
        Prunes an instance's backups older than three months.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('BackupId')]
        [string]$Id,

        [switch]$Forced,

        [switch]$Wait
    )

    process {
        $apiParams = @{ id = $Id }
        if ($Forced) { $apiParams['forced'] = 'true' }
        if ($PSCmdlet.ShouldProcess("backup $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deleteBackup' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Restore-CSBackup {
    <#
    .SYNOPSIS
        Restores an instance from a backup.

    .DESCRIPTION
        Wraps restoreBackup, restoring an existing stopped or deleted instance from
        one of its backups. This is an asynchronous job; use -Wait to block until it
        finishes. Accepts backup objects on the pipeline.

    .PARAMETER Id
        The backup to restore from. Binds from a piped backup's id.

    .PARAMETER Wait
        Wait for the async job to finish and return the result

    .EXAMPLE
        Restore-CSBackup -Id $backupId -Wait
        Restores an instance from a backup and waits for the job.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Get-CSBackup | Select-Object -First 1 | Restore-CSBackup -Wait
        Restores an instance from its most recent backup.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('BackupId')]
        [string]$Id,

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("backup $Id", 'Restore instance from backup')) {
            Invoke-CSAsyncApiRequest -Command 'restoreBackup' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSBackupSchedule {
    <#
    .SYNOPSIS
        Gets an instance's backup schedule.

    .DESCRIPTION
        Wraps listBackupSchedule. Accepts VM objects on the pipeline.

    .PARAMETER VirtualMachineId
        The instance whose schedule to get. Binds from a piped VM's id.

    .EXAMPLE
        Get-CSBackupSchedule -VirtualMachineId $vmId
        Shows an instance's backup schedule.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Get-CSBackupSchedule
        Gets the schedule of an instance piped in by object.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$VirtualMachineId
    )

    process {
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackupSchedule' -Parameters @{ virtualmachineid = $VirtualMachineId }) -Command 'listBackupSchedule'
    }
}

function New-CSBackupSchedule {
    <#
    .SYNOPSIS
        Creates a backup schedule for an instance.

    .DESCRIPTION
        Wraps createBackupSchedule. The instance must be assigned to a backup
        offering. -Schedule uses CloudStack's interval format: 'MM' hourly,
        'MM:HH' daily, 'MM:HH:DD' weekly (DD 1-7) or monthly (DD 1-28). Accepts VM
        objects on the pipeline.

    .PARAMETER VirtualMachineId
        The instance to schedule backups for. Binds from a piped VM's id.

    .PARAMETER IntervalType
        HOURLY, DAILY, WEEKLY, or MONTHLY

    .PARAMETER Schedule
        The time within the interval (see the interval format above)

    .PARAMETER Timezone
        The IANA time zone the schedule runs in (for example America/Detroit)

    .PARAMETER MaxBackups
        Maximum number of backups to keep

    .PARAMETER QuiesceVM
        Quiesce the instance before taking the backup

    .EXAMPLE
        New-CSBackupSchedule -VirtualMachineId $vmId -IntervalType DAILY -Schedule '30:02' -Timezone 'America/Detroit' -MaxBackups 7
        Schedules a nightly backup at 02:30, keeping seven.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | New-CSBackupSchedule -IntervalType HOURLY -Schedule '15' -Timezone UTC -MaxBackups 24
        Schedules hourly backups for an instance piped in by object.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$VirtualMachineId,

        [Parameter(Mandatory = $true)]
        [ValidateSet('HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY')]
        [string]$IntervalType,

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

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

        [int]$MaxBackups,

        [switch]$QuiesceVM
    )

    process {
        $apiParams = @{ virtualmachineid = $VirtualMachineId; intervaltype = $IntervalType; schedule = $Schedule; timezone = $Timezone }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            MaxBackups = 'maxbackups'; QuiesceVM = 'quiescevm'
        })
        if ($PSCmdlet.ShouldProcess("instance $VirtualMachineId", "Create $IntervalType backup schedule")) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'createBackupSchedule' -Parameters $apiParams) -Command 'createBackupSchedule'
        }
    }
}

function Set-CSBackupSchedule {
    <#
    .SYNOPSIS
        Updates a backup schedule.

    .DESCRIPTION
        Wraps updateBackupSchedule. Only the attributes you supply are changed.
        Accepts backup schedule objects on the pipeline.

    .PARAMETER Id
        The backup schedule to update. Binds from a piped schedule's id.

    .PARAMETER IntervalType
        HOURLY, DAILY, WEEKLY, or MONTHLY

    .PARAMETER Schedule
        The time within the interval ('MM', 'MM:HH', or 'MM:HH:DD')

    .PARAMETER Timezone
        The IANA time zone the schedule runs in

    .PARAMETER MaxBackups
        Maximum number of backups to keep

    .PARAMETER QuiesceVM
        Whether to quiesce the instance before the backup

    .EXAMPLE
        Set-CSBackupSchedule -Id $scheduleId -Schedule '00:03' -MaxBackups 14
        Moves a schedule to 03:00 and keeps fourteen backups.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Get-CSBackupSchedule | Set-CSBackupSchedule -Timezone UTC
        Repoints an instance's schedule to UTC.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [ValidateSet('HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY')]
        [string]$IntervalType,

        [string]$Schedule,

        [string]$Timezone,

        [int]$MaxBackups,

        [Nullable[bool]]$QuiesceVM
    )

    process {
        $apiParams = @{ id = $Id }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            IntervalType = 'intervaltype'; Schedule = 'schedule'; Timezone = 'timezone'; MaxBackups = 'maxbackups'
        })
        if ($PSBoundParameters.ContainsKey('QuiesceVM')) { $apiParams['quiescevm'] = ([bool]$QuiesceVM).ToString().ToLowerInvariant() }
        if ($PSCmdlet.ShouldProcess("backup schedule $Id", 'Update')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'updateBackupSchedule' -Parameters $apiParams) -Command 'updateBackupSchedule'
        }
    }
}

function Remove-CSBackupSchedule {
    <#
    .SYNOPSIS
        Deletes an instance's backup schedule.

    .DESCRIPTION
        Wraps deleteBackupSchedule. With -IntervalType only that interval's schedule
        is removed; without it, all of the instance's schedules are removed. Accepts
        VM objects on the pipeline.

    .PARAMETER VirtualMachineId
        The instance whose schedule to delete. Binds from a piped VM's id.

    .PARAMETER IntervalType
        Delete only this interval's schedule (HOURLY, DAILY, WEEKLY, or MONTHLY)

    .EXAMPLE
        Remove-CSBackupSchedule -VirtualMachineId $vmId
        Removes an instance's backup schedule after confirmation.

    .EXAMPLE
        Get-CSVM -Name 'db-01' | Remove-CSBackupSchedule -IntervalType HOURLY
        Removes just the hourly schedule of an instance.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$VirtualMachineId,

        [ValidateSet('HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY')]
        [string]$IntervalType
    )

    process {
        $apiParams = @{ virtualmachineid = $VirtualMachineId }
        if ($PSBoundParameters.ContainsKey('IntervalType')) { $apiParams['intervaltype'] = $IntervalType }
        $target = if ($IntervalType) { "$IntervalType backup schedule of instance $VirtualMachineId" } else { "backup schedule of instance $VirtualMachineId" }
        if ($PSCmdlet.ShouldProcess($target, 'Delete')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'deleteBackupSchedule' -Parameters $apiParams) -Command 'deleteBackupSchedule'
        }
    }
}

function Get-CSBackupProvider {
    <#
    .SYNOPSIS
        Lists the Backup and Recovery providers.

    .DESCRIPTION
        Wraps listBackupProviders, the backup plugins available (for example nas,
        veeam, networker); the provider name is what other backup commands take as
        -Provider.

    .EXAMPLE
        Get-CSBackupProvider
        Lists the available backup providers.
    #>

    [CmdletBinding()]
    param()

    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackupProviders' -Parameters @{}) -Command 'listBackupProviders'
}

function Get-CSBackupProviderOffering {
    <#
    .SYNOPSIS
        Lists a backup provider's external offerings.

    .DESCRIPTION
        Wraps listBackupProviderOfferings, the backup policies defined on the
        external provider for a zone. Import one into CloudStack with
        Import-CSBackupOffering.

    .PARAMETER ZoneId
        The zone whose provider to query

    .PARAMETER Provider
        The backup provider name

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSBackupProviderOffering -ZoneId $zoneId
        Lists the external backup offerings available in a zone.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$ZoneId,

        [string]$Provider,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    process {
        $apiParams = @{ zoneid = $ZoneId }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            Provider = 'provider'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
        })
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackupProviderOfferings' -Parameters $apiParams) -Command 'listBackupProviderOfferings'
    }
}

function Get-CSBackupOffering {
    <#
    .SYNOPSIS
        Lists the imported backup offerings.

    .DESCRIPTION
        Wraps listBackupOfferings, the backup offerings available for instances to be
        assigned to.

    .PARAMETER Id
        Filter by backup offering ID

    .PARAMETER ZoneId
        Filter by zone ID

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSBackupOffering -ZoneId $zoneId
        Lists the backup offerings in a zone.
    #>

    [CmdletBinding()]
    param(
        [string]$Id,

        [string]$ZoneId,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Id = 'id'; ZoneId = 'zoneid'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackupOfferings' -Parameters $apiParams) -Command 'listBackupOfferings'
}

function Import-CSBackupOffering {
    <#
    .SYNOPSIS
        Imports a backup offering from a provider.

    .DESCRIPTION
        Wraps importBackupOffering, registering one of the external provider's
        offerings (see Get-CSBackupProviderOffering) into CloudStack so instances can
        be assigned to it.

    .PARAMETER ExternalId
        The provider's external ID for the offering

    .PARAMETER Name
        A name for the imported offering

    .PARAMETER Description
        A description for the offering

    .PARAMETER ZoneId
        The zone to import the offering into

    .PARAMETER AllowUserDrivenBackups
        Whether users may take ad-hoc backups against this offering

    .EXAMPLE
        Import-CSBackupOffering -ExternalId 'policy-123' -Name 'Gold' -Description 'Daily, 30-day retention' -ZoneId $zoneId -AllowUserDrivenBackups $true
        Imports an external offering and allows user-driven backups.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$ExternalId,

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

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

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

        [Nullable[bool]]$AllowUserDrivenBackups
    )

    $apiParams = @{ externalid = $ExternalId; name = $Name; description = $Description; zoneid = $ZoneId }
    if ($PSBoundParameters.ContainsKey('AllowUserDrivenBackups')) { $apiParams['allowuserdrivenbackups'] = ([bool]$AllowUserDrivenBackups).ToString().ToLowerInvariant() }
    if ($PSCmdlet.ShouldProcess("backup offering $Name", 'Import')) {
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'importBackupOffering' -Parameters $apiParams) -Command 'importBackupOffering'
    }
}

function Set-CSBackupOffering {
    <#
    .SYNOPSIS
        Updates a backup offering.

    .DESCRIPTION
        Wraps updateBackupOffering. Only the attributes you supply are changed.
        Accepts backup offering objects on the pipeline.

    .PARAMETER Id
        The backup offering to update. Binds from a piped offering's id.

    .PARAMETER Name
        New name

    .PARAMETER Description
        New description

    .PARAMETER AllowUserDrivenBackups
        Whether users may take ad-hoc backups against this offering

    .EXAMPLE
        Set-CSBackupOffering -Id $offeringId -Name 'Gold (30d)'
        Renames a backup offering.

    .EXAMPLE
        Get-CSBackupOffering -ZoneId $zoneId | Where-Object name -eq 'Gold' | Set-CSBackupOffering -AllowUserDrivenBackups $false
        Disables user-driven backups on an offering.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('BackupOfferingId')]
        [string]$Id,

        [string]$Name,

        [string]$Description,

        [Nullable[bool]]$AllowUserDrivenBackups
    )

    process {
        $apiParams = @{ id = $Id }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            Name = 'name'; Description = 'description'
        })
        if ($PSBoundParameters.ContainsKey('AllowUserDrivenBackups')) { $apiParams['allowuserdrivenbackups'] = ([bool]$AllowUserDrivenBackups).ToString().ToLowerInvariant() }
        if ($PSCmdlet.ShouldProcess("backup offering $Id", 'Update')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'updateBackupOffering' -Parameters $apiParams) -Command 'updateBackupOffering'
        }
    }
}

function Remove-CSBackupOffering {
    <#
    .SYNOPSIS
        Deletes a backup offering.

    .DESCRIPTION
        Wraps deleteBackupOffering. Instances must first be removed from the offering
        (see Unregister-CSVMBackupOffering). Accepts backup offering objects on the
        pipeline.

    .PARAMETER Id
        The backup offering to delete. Binds from a piped offering's id.

    .EXAMPLE
        Remove-CSBackupOffering -Id $offeringId
        Deletes a backup offering after confirmation.

    .EXAMPLE
        Get-CSBackupOffering -ZoneId $zoneId | Where-Object name -eq 'Old' | Remove-CSBackupOffering
        Deletes an offering located by name.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('BackupOfferingId')]
        [string]$Id
    )

    process {
        if ($PSCmdlet.ShouldProcess("backup offering $Id", 'Delete')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'deleteBackupOffering' -Parameters @{ id = $Id }) -Command 'deleteBackupOffering'
        }
    }
}

function Get-CSBackupRepository {
    <#
    .SYNOPSIS
        Lists backup repositories.

    .DESCRIPTION
        Wraps listBackupRepositories, the NAS repositories that store backups for the
        NAS backup provider.

    .PARAMETER Id
        Filter by repository ID

    .PARAMETER Name
        Filter by repository name

    .PARAMETER ZoneId
        Filter by zone ID

    .PARAMETER Provider
        Filter by backup provider

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSBackupRepository -ZoneId $zoneId
        Lists the backup repositories in a zone.
    #>

    [CmdletBinding()]
    param(
        [string]$Id,

        [string]$Name,

        [string]$ZoneId,

        [string]$Provider,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Id = 'id'; Name = 'name'; ZoneId = 'zoneid'; Provider = 'provider'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listBackupRepositories' -Parameters $apiParams) -Command 'listBackupRepositories'
}

function Add-CSBackupRepository {
    <#
    .SYNOPSIS
        Adds a backup repository for storing NAS backups.

    .DESCRIPTION
        Wraps addBackupRepository, registering a NAS location (NFS/CIFS) where the
        NAS backup provider stores instance backups.

    .PARAMETER Name
        A name for the repository

    .PARAMETER Address
        The repository address (for example the NFS export path)

    .PARAMETER Type
        The repository type (for example nfs or cifs)

    .PARAMETER Provider
        The backup provider that uses this repository

    .PARAMETER ZoneId
        The zone the repository serves

    .PARAMETER MountOptions
        Mount options for the repository

    .PARAMETER CapacityBytes
        The repository's capacity in bytes

    .EXAMPLE
        Add-CSBackupRepository -Name 'nas-1' -Address '10.0.0.9:/backups' -Type nfs -Provider nas -ZoneId $zoneId
        Registers an NFS backup repository in a zone.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,

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

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

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

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

        [string]$MountOptions,

        [long]$CapacityBytes
    )

    $apiParams = @{ name = $Name; address = $Address; type = $Type; provider = $Provider; zoneid = $ZoneId }
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        MountOptions = 'mountopts'; CapacityBytes = 'capacitybytes'
    })
    if ($PSCmdlet.ShouldProcess("backup repository $Name", 'Add')) {
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'addBackupRepository' -Parameters $apiParams) -Command 'addBackupRepository'
    }
}

function Remove-CSBackupRepository {
    <#
    .SYNOPSIS
        Deletes a backup repository.

    .DESCRIPTION
        Wraps deleteBackupRepository. Accepts backup repository objects on the
        pipeline.

    .PARAMETER Id
        The repository to delete. Binds from a piped repository's id.

    .EXAMPLE
        Remove-CSBackupRepository -Id $repositoryId
        Deletes a backup repository after confirmation.

    .EXAMPLE
        Get-CSBackupRepository -ZoneId $zoneId | Where-Object name -eq 'old-nas' | Remove-CSBackupRepository
        Deletes a repository located by name.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('RepositoryId')]
        [string]$Id
    )

    process {
        if ($PSCmdlet.ShouldProcess("backup repository $Id", 'Delete')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'deleteBackupRepository' -Parameters @{ id = $Id }) -Command 'deleteBackupRepository'
        }
    }
}