Auto-commit: 2025-10-31 08:59:02
This commit is contained in:
218
API/RBAC_CreateComputerGroup_graphql.ps1
Normal file
218
API/RBAC_CreateComputerGroup_graphql.ps1
Normal file
@@ -0,0 +1,218 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create or delete a Tanium Computer Group via Gateway GraphQL.
|
||||
|
||||
.DESCRIPTION
|
||||
- CREATE: filter "Computer Name STARTS_WITH <Prefix>" (usable as Computer Management Group; optional Content Set).
|
||||
- DELETE: delete a Computer Group by its Tanium ID.
|
||||
- Reads URL/token from config.json (same folder) unless -Url/-Token are provided.
|
||||
- Optional TLS bypass for lab with -SkipCertCheck.
|
||||
|
||||
.USAGE (examples)
|
||||
# Create a group (no defaults; you MUST pass -GroupName and -Prefix)
|
||||
.\Create-ComputerGroup.ps1 -GroupName "LAB - starts with LAB" -Prefix "LAB" -MrEnabled:$true
|
||||
.\Create-ComputerGroup.ps1 -GroupName "LAB - starts with LAB" -Prefix "LAB" -ContentSetName "My Content Set"
|
||||
|
||||
# Delete by ID
|
||||
.\Create-ComputerGroup.ps1 -Delete -Id "12345"
|
||||
|
||||
# Override URL/token
|
||||
.\Create-ComputerGroup.ps1 -Url tanium.pp.dktinfra.io -Token 'token-xxxx' -GroupName "LAB ..." -Prefix "LAB"
|
||||
|
||||
# Raw JSON (debug)
|
||||
.\Create-ComputerGroup.ps1 -GroupName "LAB ..." -Prefix "LAB" -Raw
|
||||
#>
|
||||
|
||||
param(
|
||||
[string]$Url,
|
||||
[string]$Token,
|
||||
[switch]$SkipCertCheck,
|
||||
|
||||
# CREATE params (no defaults; both required for creation)
|
||||
[string]$GroupName,
|
||||
[string]$Prefix,
|
||||
[bool] $MrEnabled = $true,
|
||||
[string]$ContentSetName,
|
||||
|
||||
# DELETE params
|
||||
[switch]$Delete,
|
||||
[string]$Id,
|
||||
|
||||
[switch]$Raw
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } catch {}
|
||||
|
||||
function Show-ShortHelp {
|
||||
Write-Host ""
|
||||
Write-Host "Create mode (requires -GroupName and -Prefix):" -ForegroundColor Cyan
|
||||
Write-Host " .\Create-ComputerGroup.ps1 -GroupName 'LAB - starts with LAB' -Prefix 'LAB' [-MrEnabled:`$true] [-ContentSetName 'My Content Set']" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "Delete mode (requires -Delete and -Id):" -ForegroundColor Cyan
|
||||
Write-Host " .\Create-ComputerGroup.ps1 -Delete -Id '12345'" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "Common options: -Url <host> -Token <token> -SkipCertCheck -Raw" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
# ---------- Helpers ----------
|
||||
function Get-GatewayUri {
|
||||
param([Parameter(Mandatory)][string]$HostLike)
|
||||
$h = $HostLike.Trim()
|
||||
if ($h -match '^https?://') { $h = $h -replace '^https?://','' }
|
||||
$h = $h.TrimEnd('/')
|
||||
if ([string]::IsNullOrWhiteSpace($h)) { throw 'TaniumUrl empty after normalization.' }
|
||||
"https://$h/plugin/products/gateway/graphql"
|
||||
}
|
||||
|
||||
# TLS bypass for Windows PowerShell 5.1 (temporary, restored after call)
|
||||
$script:__oldCb = $null
|
||||
function Enter-InsecureTls {
|
||||
param([switch]$Enable)
|
||||
if (-not $Enable) { return }
|
||||
$script:__oldCb = [System.Net.ServicePointManager]::ServerCertificateValidationCallback
|
||||
$cb = [System.Net.Security.RemoteCertificateValidationCallback]{ param($s,$c,$ch,$e) $true }
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $cb
|
||||
}
|
||||
function Exit-InsecureTls {
|
||||
if ($script:__oldCb -ne $null) {
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $script:__oldCb
|
||||
$script:__oldCb = $null
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- Load config if needed ----------
|
||||
$BaseDir = if ($PSScriptRoot) { $PSScriptRoot } else { $pwd.Path }
|
||||
$configPath = Join-Path $BaseDir 'config.json'
|
||||
if (-not $Url -or -not $Token) {
|
||||
if (-not (Test-Path $configPath)) {
|
||||
throw "Missing -Url/-Token and config.json not found: $configPath"
|
||||
}
|
||||
$cfg = Get-Content -Path $configPath -Raw | ConvertFrom-Json
|
||||
if (-not $Url) { $Url = [string]$cfg.TaniumUrl }
|
||||
if (-not $Token) { $Token = [string]$cfg.TaniumApiToken }
|
||||
if (-not $PSBoundParameters.ContainsKey('SkipCertCheck')) { $SkipCertCheck = [bool]$cfg.SkipCertificateCheck }
|
||||
}
|
||||
|
||||
# ---------- Endpoint & headers ----------
|
||||
$gateway = Get-GatewayUri -HostLike $Url
|
||||
$headers = @{ 'Content-Type' = 'application/json'; session = $Token }
|
||||
|
||||
# ---------- GraphQL mutations ----------
|
||||
$Create_WithContentSet = @'
|
||||
mutation createGroup($name: String!, $mrEnabled: Boolean!, $prefix: String!, $contentSetName: String!) {
|
||||
computerGroupCreate(
|
||||
input: {
|
||||
name: $name
|
||||
managementRightsEnabled: $mrEnabled
|
||||
contentSetRef: { name: $contentSetName }
|
||||
filter: {
|
||||
sensor: { name: "Computer Name" }
|
||||
op: STARTS_WITH
|
||||
value: $prefix
|
||||
}
|
||||
}
|
||||
) {
|
||||
group { id name }
|
||||
error { message }
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
$Create_NoContentSet = @'
|
||||
mutation createGroup($name: String!, $mrEnabled: Boolean!, $prefix: String!) {
|
||||
computerGroupCreate(
|
||||
input: {
|
||||
name: $name
|
||||
managementRightsEnabled: $mrEnabled
|
||||
filter: {
|
||||
sensor: { name: "Computer Name" }
|
||||
op: STARTS_WITH
|
||||
value: $prefix
|
||||
}
|
||||
}
|
||||
) {
|
||||
group { id name }
|
||||
error { message }
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
$Delete_ById = @'
|
||||
mutation deleteComputerGroup($id: ID!) {
|
||||
computerGroupDelete(ref: { id: $id }) {
|
||||
id
|
||||
error { message }
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
# ---------- Mode selection & validation ----------
|
||||
if ($Delete) {
|
||||
if ([string]::IsNullOrWhiteSpace($Id)) {
|
||||
Write-Warning "Missing -Id for deletion."
|
||||
Show-ShortHelp
|
||||
return
|
||||
}
|
||||
$Query = $Delete_ById
|
||||
$Variables = @{ id = $Id }
|
||||
$OpName = 'deleteComputerGroup'
|
||||
}
|
||||
else {
|
||||
if ([string]::IsNullOrWhiteSpace($GroupName) -or [string]::IsNullOrWhiteSpace($Prefix)) {
|
||||
Write-Warning "Missing -GroupName and/or -Prefix for creation."
|
||||
Show-ShortHelp
|
||||
return
|
||||
}
|
||||
$useCS = -not [string]::IsNullOrWhiteSpace($ContentSetName)
|
||||
$Query = if ($useCS) { $Create_WithContentSet } else { $Create_NoContentSet }
|
||||
$Variables = @{ name = $GroupName; mrEnabled = $MrEnabled; prefix = $Prefix }
|
||||
if ($useCS) { $Variables.contentSetName = $ContentSetName }
|
||||
$OpName = 'createGroup'
|
||||
}
|
||||
|
||||
# ---------- Execute ----------
|
||||
$bodyObj = @{ query = $Query; variables = $Variables; operationName = $OpName }
|
||||
$bodyJson = $bodyObj | ConvertTo-Json -Depth 10
|
||||
|
||||
$resp = $null
|
||||
$ps7 = ($PSVersionTable.PSVersion.Major -ge 7)
|
||||
if ($ps7 -and $SkipCertCheck) {
|
||||
$resp = Invoke-RestMethod -SkipCertificateCheck -Method Post -Uri $gateway -Headers $headers -ContentType 'application/json' -Body $bodyJson
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Enter-InsecureTls -Enable:$SkipCertCheck
|
||||
$resp = Invoke-RestMethod -Method Post -Uri $gateway -Headers $headers -ContentType 'application/json' -Body $bodyJson
|
||||
}
|
||||
finally { Exit-InsecureTls }
|
||||
}
|
||||
|
||||
# ---------- Output ----------
|
||||
if ($Raw) { $resp | ConvertTo-Json -Depth 12; return }
|
||||
|
||||
if ($resp.errors) {
|
||||
Write-Error ("GraphQL errors: " + (($resp.errors | ForEach-Object { $_.message }) -join '; '))
|
||||
return
|
||||
}
|
||||
|
||||
if ($Delete) {
|
||||
$del = $resp.data.computerGroupDelete
|
||||
if ($del.error -and $del.error.message) {
|
||||
Write-Error ("Delete failed: {0}" -f $del.error.message)
|
||||
} elseif ($del.id) {
|
||||
Write-Host ("Deleted group ID: {0}" -f $del.id) -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "No confirmation returned. Use -Raw to inspect the full response."
|
||||
}
|
||||
}
|
||||
else {
|
||||
$crt = $resp.data.computerGroupCreate
|
||||
if ($crt.error -and $crt.error.message) {
|
||||
Write-Error ("Create failed: {0}" -f $crt.error.message)
|
||||
} elseif ($crt.group) {
|
||||
Write-Host ("Created group: {0} (ID: {1})" -f $crt.group.name, $crt.group.id) -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "No group returned. Use -Raw to inspect the full response."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user