Modules/Public/InventoryModules/Management/DevOpsServiceConnections.ps1
|
<# .Synopsis Inventory for Azure DevOps Service Connections .DESCRIPTION This script consolidates information for all devops/serviceconnections resources, and cross-references Azure Resource Manager connections against the subscriptions in scope so you can see which of your subscriptions are reachable from a pipeline. Excel Sheet Name: ADO Service Connections .Link https://github.com/thisismydemo/azure-scout/Modules/Public/InventoryModules/Management/DevOpsServiceConnections.ps1 .COMPONENT This PowerShell Module is part of Azure Scout (AZSC) .NOTES Version: 1.0.0 Work item: AB#327 Authors: AzureScout Contributors #> <######## Default Parameters. Don't modify this ########> param($SCPath, $Sub, $Intag, $Resources, $Retirements, $Task, $File, $SmaResources, $TableStyle, $Unsupported) If ($Task -eq 'Processing') { $devOpsEndpoints = $Resources | Where-Object { $_.TYPE -eq 'devops/serviceconnections' } if ($devOpsEndpoints) { # Subscription IDs in scope for this scan. A service connection pointing at one of # these is a pipeline with a path into the estate being inventoried; one pointing # elsewhere is a connection into a subscription this report does not cover. $inScopeSubs = @{} foreach ($s in $Sub) { if ($s -and $s.PSObject.Properties.Name -contains 'Id' -and $s.Id) { $inScopeSubs[[string]$s.Id] = if ($s.PSObject.Properties.Name -contains 'Name') { $s.Name } else { '' } } } $tmp = foreach ($1 in $devOpsEndpoints) { $ResUCount = 1 $data = $1.properties $endpointData = if ($data.PSObject.Properties.Name -contains 'data') { $data.data } else { $null } $subId = if ($endpointData -and $endpointData.PSObject.Properties.Name -contains 'subscriptionId') { $endpointData.subscriptionId } else { $null } $subName = if ($endpointData -and $endpointData.PSObject.Properties.Name -contains 'subscriptionName') { $endpointData.subscriptionName } else { $null } $authScheme = if ($data.PSObject.Properties.Name -contains 'authorization' -and $data.authorization) { $data.authorization.scheme } else { $null } $servicePrincipalId = if ($data.PSObject.Properties.Name -contains 'authorization' -and $data.authorization -and $data.authorization.PSObject.Properties.Name -contains 'parameters' -and $data.authorization.parameters -and $data.authorization.parameters.PSObject.Properties.Name -contains 'serviceprincipalid') { $data.authorization.parameters.serviceprincipalid } else { $null } $inScope = if ($subId -and $inScopeSubs.ContainsKey([string]$subId)) { 'Yes' } else { 'No' } # Workload identity federation is the credential-free scheme; anything else on # an ARM connection is a secret or certificate that has to be rotated. $credentialFree = if ($authScheme -eq 'WorkloadIdentityFederation') { 'Yes' } else { 'No' } $isShared = if ($data.PSObject.Properties.Name -contains 'isShared') { [string]$data.isShared } else { $null } $isReady = if ($data.PSObject.Properties.Name -contains 'isReady') { [string]$data.isReady } else { $null } $obj = @{ 'ID' = $1.id; 'Organization' = $1.organization; 'Project' = $data.projectName; 'Connection Name' = $1.name; 'Connection Type' = $data.type; 'Authorization Scheme' = $authScheme; 'Credential Free' = $credentialFree; 'Service Principal ID' = $servicePrincipalId; 'Target Subscription ID' = $subId; 'Target Subscription Name' = $subName; 'Subscription In Scope' = $inScope; 'Shared' = $isShared; 'Ready' = $isReady; 'Resource U' = $ResUCount } $obj } $tmp } } <######## Resource Excel Reporting Begins Here ########> Else { if ($SmaResources) { $TableName = ('ADOServiceConnectionsTable_' + (($SmaResources.'Resource U' | Measure-Object -Sum).Sum)) $Style = New-ExcelStyle -HorizontalAlignment Center -AutoSize -NumberFormat '0' # Column letters follow the $Exc ordering below: F = Credential Free, # J = Subscription In Scope. $condtxt = @() # A connection into a subscription this scan covers is the one worth reviewing. $condtxt += New-ConditionalText -Text 'Yes' -Range J:J -ConditionalType ContainsText -BackgroundColor Yellow # Secret-based ARM connections carry rotation risk that federated ones do not. $condtxt += New-ConditionalText -Text 'No' -Range F:F -ConditionalType ContainsText -BackgroundColor Orange $Exc = New-Object System.Collections.Generic.List[System.Object] $Exc.Add('Organization') $Exc.Add('Project') $Exc.Add('Connection Name') $Exc.Add('Connection Type') $Exc.Add('Authorization Scheme') $Exc.Add('Credential Free') $Exc.Add('Service Principal ID') $Exc.Add('Target Subscription ID') $Exc.Add('Target Subscription Name') $Exc.Add('Subscription In Scope') $Exc.Add('Shared') $Exc.Add('Ready') $Exc.Add('Resource U') [PSCustomObject]$SmaResources | ForEach-Object { $_ } | Select-Object $Exc | Export-Excel -Path $File -WorksheetName 'ADO Service Connections' -AutoSize -MaxAutoSizeRows 100 -TableName $TableName -TableStyle $tableStyle -ConditionalText $condtxt -Style $Style } } |