Public/Sites/Set-RMMSite.ps1
|
<#
Copyright (c) 2025-2026 Robert Faddes SPDX-License-Identifier: MPL-2.0 #> function Set-RMMSite { <# .SYNOPSIS Updates an existing site in the Datto RMM account. .DESCRIPTION The Set-RMMSite function updates properties of an existing site in the authenticated user's account. Due to an API limitation, omitted properties are wiped when updating a site. To prevent unintended data loss, this function preserves existing property values by default: - Pipeline input: When a DRMMSite object is piped, its current properties are used as defaults for any parameters not explicitly specified. - SiteUid input: When a site UID is provided, the function fetches the current site state from the API and uses those values as defaults. To bypass property preservation and send only explicitly specified parameters, use the -OverwriteAll switch. When OverwriteAll is used, Name becomes mandatory and any omitted properties will be reset to their API default values. Note: Proxy settings cannot be updated using this function. Use Set-RMMSiteProxy or Remove-RMMSiteProxy to manage proxy settings. .PARAMETER Site A DRMMSite object to update. Accepts pipeline input from Get-RMMSite. .PARAMETER SiteUid The unique identifier (GUID) of the site to update. .PARAMETER Name The new name for the site. Required when using -OverwriteAll. When a reference site is available (pipeline or fetched), defaults to the existing site name. .PARAMETER Description The new description for the site. .PARAMETER Notes The new notes for the site. .PARAMETER OnDemand Whether the site should be configured as an on-demand site. .PARAMETER SplashtopAutoInstall Whether Splashtop should be automatically installed on devices at this site. .PARAMETER AppendNotes Append the value supplied to -Notes to the site's existing notes, separated by a blank line. Requires -Notes to be specified. Has no effect if -Notes is not provided. Not available with -OverwriteAll because the current site state is unknown in that parameter set. .PARAMETER OverwriteAll Bypass property preservation and send only explicitly specified parameters to the API. When this switch is used, Name becomes mandatory. Properties not explicitly specified will be reset to their API default values. Use this when you intentionally want to clear or reset site properties. .PARAMETER Force Suppress the confirmation prompt. .EXAMPLE Set-RMMSite -SiteUid "a1b2c3d4-e5f6-7890-abcd-ef1234567890" -Name "Updated Site Name" Updates the site name. Other existing properties are preserved by fetching the current site state from the API before updating. .EXAMPLE Set-RMMSite -SiteUid "a1b2c3d4-e5f6-7890-abcd-ef1234567890" -Name "Clean Site" -OverwriteAll Updates the site with only the specified name. All other properties are reset to their API default values because OverwriteAll bypasses property preservation. .EXAMPLE Get-RMMSite -SiteName "Old Name" | Set-RMMSite -Name "New Name" -Description "Updated description" Updates the name and description of a site via pipeline. .EXAMPLE $Site = Get-RMMSite -SiteName "Test Site" Set-RMMSite -Site $Site -Name "Test Site" -OnDemand -Force Enables on-demand for a site without confirmation prompt. .EXAMPLE Get-RMMSite | Where-Object {$_.Name -like "Branch*"} | Set-RMMSite -SplashtopAutoInstall Enables Splashtop auto-install for all sites with names starting with "Branch". .EXAMPLE Get-RMMSite -SiteUid $SiteUid | Set-RMMSite -Notes "Reviewed April 2026" -AppendNotes Appends a note to the site's existing notes, preserving the original content. .INPUTS DRMMSite. You can pipe site objects from Get-RMMSite. You can also pipe objects with SiteUid or Uid properties. .OUTPUTS DRMMSite. Returns the updated site object. .NOTES This function requires an active connection to the Datto RMM API. Use Connect-DattoRMM to authenticate before calling this function. This function does not support updating proxy settings. Use Set-RMMSiteProxy or Remove-RMMSiteProxy for proxy configuration changes. .LINK https://github.com/TheShadowTek/DattoRMM.Core/blob/main/docs/commands/Sites/Set-RMMSite.md .LINK about_DRMMSite .LINK Get-RMMSite .LINK Set-RMMSiteProxy #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'BySiteObject')] param ( [Parameter( ParameterSetName = 'BySiteObject', Mandatory = $true, ValueFromPipeline = $true )] [DRMMSite] $Site, [Parameter( ParameterSetName = 'ByUid', Mandatory = $true )] [Parameter( ParameterSetName = 'ByUidOverwrite', Mandatory = $true )] [Alias('Uid')] [guid] $SiteUid, [Parameter( ParameterSetName = 'ByUid' )] [Parameter( ParameterSetName = 'BySiteObject' )] [Parameter( ParameterSetName = 'ByUidOverwrite', Mandatory = $true )] [string] $Name, [Parameter()] [string] $Description, [Parameter()] [string] $Notes, [Parameter()] [switch] $OnDemand, [Parameter()] [switch] $SplashtopAutoInstall, [Parameter( ParameterSetName = 'BySiteObject' )] [Parameter( ParameterSetName = 'ByUid' )] [switch] $AppendNotes, [Parameter( ParameterSetName = 'ByUidOverwrite', Mandatory = $true )] [switch] $OverwriteAll, [Parameter()] [switch] $Force ) process { # Resolve reference site for property preservation switch ($PSCmdlet.ParameterSetName) { 'BySiteObject' { $SiteUid = $Site.Uid $ReferenceSite = $Site } 'ByUid' { Write-Verbose "Fetching current site properties for preservation: $SiteUid" $ReferenceSite = Get-RMMSite -SiteUid $SiteUid } 'ByUidOverwrite' { $ReferenceSite = $null } } # Preserve existing values for any parameters not explicitly specified if ($ReferenceSite) { $PropertiesToPreserve = @('Name', 'Description', 'Notes', 'OnDemand', 'SplashtopAutoInstall') foreach ($ParamName in $PropertiesToPreserve) { if ($PSBoundParameters.ContainsKey($ParamName)) { continue } switch ($ParamName) { 'Name' {$Name = $ReferenceSite.Name} 'Description' {$Description = $ReferenceSite.Description} 'Notes' {$Notes = $ReferenceSite.Notes} 'OnDemand' {$OnDemand = $ReferenceSite.OnDemand} 'SplashtopAutoInstall' {$SplashtopAutoInstall = $ReferenceSite.SplashtopAutoInstall} } } } # Append new notes to existing notes if requested if ($AppendNotes -and $PSBoundParameters.ContainsKey('Notes')) { if ($ReferenceSite.Notes) { $Notes = $ReferenceSite.Notes + "`n`n" + $Notes } } if (-not $Force -and -not $PSCmdlet.ShouldProcess("Site $(if ($ReferenceSite) {$ReferenceSite.Name} else {$SiteUid})", "Update site properties")) { return } Write-Debug "Updating RMM site: $(if ($ReferenceSite) {$ReferenceSite.Name} else {$SiteUid})" # Build request body if ($ReferenceSite) { # All properties included to prevent API from wiping unspecified values $Body = @{ name = $Name description = $Description notes = $Notes onDemand = [bool]$OnDemand splashtopAutoInstall = [bool]$SplashtopAutoInstall } } else { # No preservation - build body from explicit parameters only $Body = @{ name = $Name } switch ($PSBoundParameters.Keys) { 'Description' {$Body.description = $Description} 'Notes' {$Body.notes = $Notes} 'OnDemand' {$Body.onDemand = $OnDemand.IsPresent} 'SplashtopAutoInstall' {$Body.splashtopAutoInstall = $SplashtopAutoInstall.IsPresent} } } $APIMethod = @{ Path = "site/$SiteUid" Method = 'Post' Body = $Body } $Response = Invoke-ApiMethod @APIMethod if ($Response) { [DRMMSite]::FromAPIMethod($Response) } } } # SIG # Begin signature block # MIIF+wYJKoZIhvcNAQcCoIIF7DCCBegCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBb9bb6WtrypBX4 # j8CsLFd7NsUGL8Y5GYi0aL/fmhN2QKCCA04wggNKMIICMqADAgECAhB464iXHfI6 # gksEkDDTyrNsMA0GCSqGSIb3DQEBCwUAMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRk # ZXMxIzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nMB4XDTI2MDMz # MTAwMTMzMFoXDTI4MDMzMTAwMjMzMFowPTEWMBQGA1UECgwNUm9iZXJ0IEZhZGRl # czEjMCEGA1UEAwwaRGF0dG9STU0uQ29yZSBDb2RlIFNpZ25pbmcwggEiMA0GCSqG # SIb3DQEBAQUAA4IBDwAwggEKAoIBAQChn1EpMYQgl1RgWzQj2+wp2mvdfb3UsaBS # nxEVGoQ0gj96tJ2MHAF7zsITdUjwaflKS1vE6wAlOg5EI1V79tJCMxzM0bFpOdR1 # L5F2HE/ovIAKNkHxFUF5qWU8vVeAsOViFQ4yhHpzLen0WLF6vhmc9eH23dLQy5fy # tELZQEc2WbQFa4HMAitP/P9kHAu6CUx5s4woLIOyyR06jkr3l9vk0sxcbCxx7+dF # RrsSLyPYPH+bUAB8+a0hs+6qCeteBuUfLvGzpMhpzKAsY82WZ3Rd9X38i32dYj+y # dYx+nx+UEMDLjDJrZgnVa8as4RojqVLcEns5yb/XTjLxDc58VatdAgMBAAGjRjBE # MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU # H+B0vf97dYXqdUX1YMcWhFsY6fcwDQYJKoZIhvcNAQELBQADggEBAJmD4EEGNmcD # 1JtFoRGxuLJaTHxDwBsjqcRQRE1VPZNGaiwIm8oSQdHVjQg0oIyK7SEb02cs6n6Y # NZbwf7B7WZJ4aKYbcoLug1k1x9SoqwBmfElECeJTKXf6dkRRNmrAodpGCixR4wMH # KXqwqP5F+5j7bdnQPiIVXuMesxc4tktz362ysph1bqKjDQSCBpwi0glEIH7bv5Ms # Ey9Gl3fe+vYC5W06d2LYVebEfm9+7766hsOgpdDVgdtnN+e6uwIJjG/6PTG6TMDP # y+pr5K6LyUVYJYcWWUTZRBqqwBHiLGekPbxrjEVfxUY32Pq4QfLzUH5hhUCAk4HN # XpF9pOzFLMUxggIDMIIB/wIBATBRMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRkZXMx # IzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nAhB464iXHfI6gksE # kDDTyrNsMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKEC # gAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwG # CisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJxwBFv+dXhTkHzBmVotEqw6BWOB # B8MCvnFpV6VWtjK9MA0GCSqGSIb3DQEBAQUABIIBAGrl7cnhuS6grc3JIFy8aDlG # H+fCoM//m6lLLztD3mFMujeCPDLIDMfnAQ3IbDdaoy1TSEb9NDaop20wfY0AHx6O # xhESbWBgj951u2/ObOUr1RWtR+XhQHn+D1mQgeP+zGDTXBdPSJnBmtkkz4iITYGR # DgCt2tUcXCfvE4RgYY8l2aUY2RW8ywowyBTV5xdj9O1sWJadrAtnQxIRmchiu5H9 # Tlb98tNhwGG1WYoK58Wq40a0Uodze5OefWG1yHCyTwLQejjISQk6kY4TOy9Oq8Z0 # BQdNXxRSUzzokD/0mZJ3FZYdjIigrRlQejKDbjbSeK1mMdq0mRV/1JxblqZJwyU= # SIG # End signature block |