diff --git a/Stackmonkey.ps1 b/Stackmonkey.ps1 index 6b65fbb..792639f 100644 --- a/Stackmonkey.ps1 +++ b/Stackmonkey.ps1 @@ -937,7 +937,157 @@ $script #region Install-DattoRMM - function Install-DattoRMM { +function Install-DattoRMM { + [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] + param ( + [switch]$UseWebhook, + [string]$WebhookPassword, + [string]$WebhookUrl = $Global:DattoWebhookUrl, + [string]$ApiUrl, + [string]$ApiKey, + [string]$ApiSecretKey, + [switch]$FetchSites, + [switch]$SaveSitesList, + [string]$OutputFile = 'datto_sites.csv', + [switch]$PushSiteVars, + [switch]$InstallRMM, + [switch]$SaveCopy, + [string]$SiteUID, + [string]$SiteName + ) + + # Guard: SaveSitesList requires FetchSites + if ($SaveSitesList -and -not $FetchSites) { + Write-LogHybrid "-SaveSitesList requires -FetchSites." "Error" "DattoRMM" -LogToEvent + return + } + + # 1) Optionally fetch credentials from webhook + if ($UseWebhook) { + if (-not $WebhookPassword) { + Write-LogHybrid "Webhook password missing." "Error" "DattoRMM" -LogToEvent + return + } + try { + $resp = Invoke-RestMethod -Uri $WebhookUrl -Headers @{ SVSMSPKit = $WebhookPassword } -Method GET + $ApiUrl = $resp.ApiUrl + $ApiKey = $resp.ApiKey + $ApiSecretKey = $resp.ApiSecretKey + Write-LogHybrid "Webhook credentials fetched." "Success" "DattoRMM" -LogToEvent + } catch { + Write-LogHybrid "Failed to fetch webhook credentials: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + return + } + } + + # 2) Validate API params + if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) { + Write-LogHybrid "Missing required API parameters." "Error" "DattoRMM" -LogToEvent + return + } + + # 3) Acquire OAuth token + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + try { + $publicCred = New-Object System.Management.Automation.PSCredential( + 'public-client', (ConvertTo-SecureString 'public' -AsPlainText -Force) + ) + $tokenResp = Invoke-RestMethod -Uri "$ApiUrl/auth/oauth/token" ` + -Credential $publicCred ` + -Method Post ` + -ContentType 'application/x-www-form-urlencoded' ` + -Body "grant_type=password&username=$ApiKey&password=$ApiSecretKey" + $token = $tokenResp.access_token + Write-LogHybrid "OAuth token acquired." "Success" "DattoRMM" -LogToEvent + } catch { + Write-LogHybrid "OAuth token fetch failed: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + return + } + $headers = @{ Authorization = "Bearer $token" } + + # 4) Fetch site list (optional early-exit) + if ($FetchSites) { + try { + $sitesResp = Invoke-RestMethod -Uri "$ApiUrl/api/v2/account/sites" -Method Get -Headers $headers + $siteList = $sitesResp.sites | ForEach-Object { + [PSCustomObject]@{ Name = $_.name; UID = $_.uid } + } + Write-LogHybrid "Fetched $($siteList.Count) sites." "Success" "DattoRMM" -LogToEvent + + if ($SaveSitesList) { + $desktop = [Environment]::GetFolderPath('Desktop') + $path = Join-Path $desktop $OutputFile + $ext = [IO.Path]::GetExtension($OutputFile).ToLower() + if ($ext -eq '.json') { + $siteList | ConvertTo-Json -Depth 3 | Out-File -FilePath $path -Encoding UTF8 + } else { + $siteList | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8 + } + Write-LogHybrid "Wrote $($siteList.Count) sites to $path" "Success" "DattoRMM" -LogToEvent + } + + return $siteList + } catch { + Write-LogHybrid "Failed to fetch sites: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + return @() + } + } + + # 5) Push site variables (optional) + if ($PushSiteVars) { + try { + $varsResp = Invoke-RestMethod -Uri "$ApiUrl/api/v2/site/$SiteUID/variables" -Method Get -Headers $headers + Write-LogHybrid "Fetched variables for '$SiteName'." "Success" "DattoRMM" -LogToEvent + $regPath = "HKLM:\Software\SVS\Deployment" + if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } + foreach ($v in $varsResp.variables) { + try { + New-ItemProperty -Path $regPath -Name $v.name -Value $v.value -PropertyType String -Force | Out-Null + Write-LogHybrid "Wrote '$($v.name)' to registry." "Success" "DattoRMM" -LogToEvent + } catch { + Write-LogHybrid "Failed to write '$($v.name)': $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + } + } + } catch { + Write-LogHybrid "Variable fetch failed: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + } + } + + # 6) Download & install RMM agent (optional) + if ($InstallRMM) { + if ($PSCmdlet.ShouldProcess("Site '$SiteName'", "Install RMM agent")) { + try { + $dlUrl = "https://zinfandel.centrastage.net/csm/profile/downloadAgent/$SiteUID" + $tmp = "$env:TEMP\AgentInstall.exe" + Invoke-WebRequest -Uri $dlUrl -OutFile $tmp -UseBasicParsing + Write-LogHybrid "Downloaded agent to $tmp." "Info" "DattoRMM" -LogToEvent + Start-Process -FilePath $tmp -NoNewWindow + Write-LogHybrid "RMM agent installer launched." "Success" "DattoRMM" -LogToEvent + } catch { + Write-LogHybrid "Agent install failed: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + } + } + } + + # 7) Save a copy of installer to C:\Temp (optional) + if ($SaveCopy) { + try { + $dlUrl = "https://zinfandel.centrastage.net/csm/profile/downloadAgent/$SiteUID" + $path = "C:\Temp\AgentInstall.exe" + if (-not (Test-Path 'C:\Temp')) { New-Item -Path 'C:\Temp' -ItemType Directory | Out-Null } + Invoke-WebRequest -Uri $dlUrl -OutFile $path -UseBasicParsing + Write-LogHybrid "Saved installer copy to $path." "Info" "DattoRMM" -LogToEvent + } catch { + Write-LogHybrid "Save-copy failed: $($_.Exception.Message)" "Error" "DattoRMM" -LogToEvent + } + } + + # 8) No-op warning + if (-not ($PushSiteVars -or $InstallRMM -or $SaveCopy)) { + Write-LogHybrid "No action specified. Use -FetchSites, -SaveSitesList, -PushSiteVars, -InstallRMM, or -SaveCopy." "Warning" "DattoRMM" -LogToEvent + } +} + [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] param ( [switch]$UseWebhook,