#requires -Version 7.0 <# .SYNOPSIS Affiche les rôles par UTILISATEUR (hors "Tanium Internal*") et/ou par GROUPE, avec filtres -User et -Group. Sections affichées selon les filtres. #> [CmdletBinding()] param( [string[]]$User, # filtre sur display name / username (substring ou wildcard) [string[]]$Group # filtre sur nom du groupe (substring ou wildcard) ) $ErrorActionPreference = 'Stop' try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } catch {} # --- Auth depuis config.json --- $ConfigPath = Join-Path $PSScriptRoot 'config.json' if (-not (Test-Path $ConfigPath -PathType Leaf)) { throw "Config introuvable: $ConfigPath (attendu: { `"TaniumUrl`", `"TaniumApiToken`" })" } $cfg = Get-Content -Path $ConfigPath -Raw | ConvertFrom-Json $baseUrl = ($cfg.TaniumUrl -replace '/+$',''); if ($baseUrl -notmatch '^https?://') { $baseUrl = "https://$baseUrl" } $headers = @{ 'Accept' = 'application/json' 'Content-Type' = 'application/json' } if ($cfg.TaniumApiToken) { $headers['X-Api-Token'] = $cfg.TaniumApiToken $headers['session'] = $cfg.TaniumApiToken } function Invoke-TaniumApi { param( [Parameter(Mandatory)][ValidateSet('GET','POST','PATCH','PUT','DELETE')] [string]$Method, [Parameter(Mandatory)][string]$Path, [hashtable]$Query, [object]$Body ) $b = [System.UriBuilder]("$baseUrl$Path") if ($Query) { $nv = [System.Web.HttpUtility]::ParseQueryString([string]::Empty) foreach ($k in $Query.Keys) { $nv[$k] = [string]$Query[$k] } $b.Query = $nv.ToString() } $uri = $b.Uri.AbsoluteUri if ($PSBoundParameters.ContainsKey('Body')) { Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -Body ($Body | ConvertTo-Json -Depth 20) } else { Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers } } function Get-TaniumItems { param([Parameter(Mandatory)][object]$Response) if ($Response.items) { ,@($Response.items) } elseif ($Response.data) { ,@($Response.data) } elseif ($Response.users) { ,@($Response.users) } elseif ($Response.user_groups) { ,@($Response.user_groups) } else { ,@($Response) } } # helper: match substring/wildcard, case-insensitive function Test-Match { param([string]$Text, [string[]]$Patterns) if (-not $Patterns -or $Patterns.Count -eq 0) { return $true } foreach ($p in $Patterns) { if ([string]::IsNullOrWhiteSpace($p)) { continue } $pat = $p if ($pat -notmatch '[\*\?\[\]]') { $pat = "*$pat*" } # ajoute wildcards si absent if ($Text -like $pat -or $Text -like $pat.ToLower() -or $Text -like $pat.ToUpper()) { return $true } } return $false } # Déterminer quelles sections afficher $hasUserFilter = $PSBoundParameters.ContainsKey('User') -and $User -and $User.Count -gt 0 $hasGroupFilter = $PSBoundParameters.ContainsKey('Group') -and $Group -and $Group.Count -gt 0 if ($hasUserFilter -and -not $hasGroupFilter) { $showUsers = $true; $showGroups = $false } elseif ($hasGroupFilter -and -not $hasUserFilter) { $showUsers = $false; $showGroups = $true } else { $showUsers = $true; $showGroups = $true } # aucun filtre OU les deux => montrer les deux # --- Rôles (nécessaire pour libellés) --- Write-Host ">> Récupère la liste des rôles..." -ForegroundColor Cyan $rolesAll = Get-TaniumItems (Invoke-TaniumApi -Method GET -Path '/api/v2/content_set_roles' -Query @{ limit = 5000 }) $roleIndex = @{}; foreach ($r in $rolesAll) { if ($null -ne $r.id) { $roleIndex[[int]$r.id] = [string]$r.name } } function Format-RoleLabel { param([int]$Id, [string]$Name) if ([string]::IsNullOrWhiteSpace($Name)) { $Name = $roleIndex[$Id] } if ([string]::IsNullOrWhiteSpace($Name)) { "RoleID:$Id" } else { "RoleID:$Id ($Name)" } } # --- Utilisateurs (+ memberships) -------------------------------------------- $usersWithRoles = @() if ($showUsers) { Write-Host ">> Récupère les utilisateurs..." -ForegroundColor Cyan $usersAll = Get-TaniumItems (Invoke-TaniumApi -Method GET -Path '/api/v2/users' -Query @{ limit = 5000 }) $users = $usersAll | Where-Object { $disp = $_.display_name ?? $_.displayName ?? $_.name ?? $_.username -not ($disp -like 'Tanium Internal*') -and ( (Test-Match -Text $disp -Patterns $User) -or (Test-Match -Text $_.username -Patterns $User) ) } Write-Host ">> Récupère les memberships (User<->Role)..." -ForegroundColor Cyan $userRoleMships = Get-TaniumItems (Invoke-TaniumApi -Method GET -Path '/api/v2/content_set_role_memberships' -Query @{ limit = 50000 }) # Index users $userIndex = @{} foreach ($u in $users) { $userIndex[[int]$u.id] = [pscustomobject]@{ ID = [int]$u.id Name = $u.display_name ?? $u.displayName ?? $u.name ?? $u.username Username = $u.username Email = $u.email } } # Rôles par user $rolesByUser = @{} foreach ($m in $userRoleMships) { if ($null -eq $m.user -or $null -eq $m.content_set_role) { continue } $uid = [int]$m.user.id if (-not $userIndex.ContainsKey($uid)) { continue } # filtré/exclu $rid = [int]$m.content_set_role.id $rname = [string]$m.content_set_role.name $label = Format-RoleLabel -Id $rid -Name $rname if (-not $rolesByUser.ContainsKey($uid)) { $rolesByUser[$uid] = @() } $rolesByUser[$uid] += $label } $usersWithRoles = $userIndex.GetEnumerator() | ForEach-Object { $uid = $_.Key $info = $_.Value $roles = @() if ($rolesByUser.ContainsKey($uid)) { $roles = $rolesByUser[$uid] | Where-Object { $_ } | Sort-Object -Unique } [pscustomobject]@{ ID = $info.ID Nom = $info.Name Username = $info.Username RolesCount = $roles.Count Roles = ($roles -join ', ') } } | Sort-Object -Property Nom } # --- Groupes (+ memberships) -------------------------------------------------- $groupsWithRoles = @() if ($showGroups) { Write-Host ">> Récupère les groupes..." -ForegroundColor Cyan $groupsAll = Get-TaniumItems (Invoke-TaniumApi -Method GET -Path '/api/v2/user_groups' -Query @{ limit = 5000 }) $groups = $groupsAll | Where-Object { $gname = $_.name ?? $_.display_name ?? $_.displayName Test-Match -Text $gname -Patterns $Group } Write-Host ">> Récupère les memberships (Group<->Role)..." -ForegroundColor Cyan $groupRoleMships = Get-TaniumItems (Invoke-TaniumApi -Method GET -Path '/api/v2/content_set_user_group_role_memberships' -Query @{ limit = 50000 }) # Index groupes $groupIndex = @{} foreach ($g in $groups) { $groupIndex[[int]$g.id] = [pscustomobject]@{ ID = [int]$g.id Name = $g.name ?? $g.display_name ?? $g.displayName } } # Rôles par groupe $rolesByGroup = @{} foreach ($m in $groupRoleMships) { if ($null -eq $m.user_group -or $null -eq $m.content_set_role) { continue } $gid = [int]$m.user_group.id if (-not $groupIndex.ContainsKey($gid)) { continue } # filtré/exclu $rid = [int]$m.content_set_role.id $rname = [string]$m.content_set_role.name $label = Format-RoleLabel -Id $rid -Name $rname if (-not $rolesByGroup.ContainsKey($gid)) { $rolesByGroup[$gid] = @() } $rolesByGroup[$gid] += $label } $groupsWithRoles = $groupIndex.GetEnumerator() | ForEach-Object { $gid = $_.Key $g = $_.Value $roles = @() if ($rolesByGroup.ContainsKey($gid)) { $roles = $rolesByGroup[$gid] | Where-Object { $_ } | Sort-Object -Unique } [pscustomobject]@{ ID = $g.ID Groupe = $g.Name RolesCount = $roles.Count Roles = ($roles -join ', ') } } | Sort-Object -Property Groupe } # --- Affichage conditionnel --- if ($showUsers) { Write-Host "" Write-Host "=== ROLES PAR UTILISATEUR (hors 'Tanium Internal*') ===" -ForegroundColor Green $usersWithRoles | Format-Table -Property ID,Nom,Username,RolesCount,Roles -AutoSize } if ($showGroups) { Write-Host "" Write-Host "=== ROLES PAR GROUPE ===" -ForegroundColor Green $groupsWithRoles | Format-Table -Property ID,Groupe,RolesCount,Roles -AutoSize } # --- Sortie exploitable (ne s’affiche que si tu ne l’assignes pas) --- [pscustomobject]@{ UsersWithRoles = $usersWithRoles GroupsWithRoles = $groupsWithRoles }