Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Rugby-Ball/f78bbbff0a1ee8e38493129d511260e1 to your computer and use it in GitHub Desktop.

Select an option

Save Rugby-Ball/f78bbbff0a1ee8e38493129d511260e1 to your computer and use it in GitHub Desktop.
Pull the AWS cloud trail activity for selected users, does this accross all AWS Regions. Exports to a CSV file. #Utility #Public #Security #AWS #AWS_CloudTrail
# aws-user-CloudTrail-report-all-aws-regions.ps1
<#
Description: Pull the AWS cloud trail activity for selected users, does this accross all AWS Regions. Exports to a CSV file.
Written: Ed Walsh
PowerShell.Core tested: Yes
Version: 1.0.0
Create Date : 5/30/2024
Revised Date: 5/30/2024
#>
# Import the AWS Tools for PowerShell module
# Import-Module AWS.Tools.CloudTrail
# Import-Module AWS.Tools.Common
# or use the FULL Module that has all of the AWS Tools modules in one.
#Import-Module AWSPowerShell.NetCore
#
#Setup File Name attributes
$timestamp = get-date -format yyyyMMddHHmmss
$subfolder = if (($PSVersionTable.PSEdition) -eq "Core") { if ( $True -eq $iswindows ) { "\Documents\" } Else { "" } } Else { "\Documents\" }
$mydocuments = $home + $subfolder
$fileName = "aws-user-CloudTrail-report-all-aws-regions_" + [string]$timestamp + ".csv"
$filePath = Join-Path $mydocuments $fileName
#
#Start Timer and let user know. Need to push the Write host below the Progress bar, or it will be obscured.
Clear-Host
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()
$stopwatch.Start()
Write-Host @"
.
.
.
.
.
.
.
.
Script started on $(Get-Date -f "MM-dd-yyyy hh:mm:ss tt")
This script might take sometime to run, please be patient.
"@ -ForegroundColor Yellow -BackgroundColor Red
#
# The IAM users to search for.
$users = @("user1","user2")
# Date range, the max CloudTrail retains is 90 days.
$StartDate = (Get-Date).AddDays(-90)
$EndDate = (Get-Date)
# Initialize an array to store the results
$results = @()
# Get all available AWS regions
$regions = Get-EC2Region -RegionToCall us-east-1 <# -RegionToCall used because of https://github.com/aws/aws-tools-for-powershell/issues/46 #> | Select-Object -ExpandProperty Region
# Initialize counters for progress bars
$totalRegions = $regions.Count
$currentRegionIndex = 0
# Loop through each region
foreach ($region in $regions) {
$currentRegionIndex++
$regionPercentComplete = ($currentRegionIndex / $totalRegions) * 100
Write-Progress -Activity "Scanning AWS Regions" -Status "Region: $region ($currentRegionIndex of $totalRegions)" -PercentComplete $regionPercentComplete
# Initialize counters for user progress bar
$totalUsers = $users.Count
$currentUserIndex = 0
# Loop through each user and find their CloudTrail events in the current region
foreach ($user in $users) {
$currentUserIndex++
$userPercentComplete = ($currentUserIndex / $totalUsers) * 100
Write-Progress -Activity "Scanning AWS Regions" -Status "Region: $region, User: $user ($currentUserIndex of $totalUsers)" -PercentComplete $userPercentComplete -ParentId 1
# Need the first query run for each user to have no token. Will pick up the token if there is more data to pull. CloudTrail caps at 50 rows per call.
$nextToken = $null
do {
try {
# You have to put in a date range, with out it CloudTrail defaults to last 7 days.
$events = Find-CTEvent -StartTime $StartDate -EndTime $EndDate -LookupAttribute @{AttributeKey="Username"; AttributeValue=$user} -Region $region -NextToken $nextToken
$results += $events
#This is the call to see if there is any more data to pull. If there is a token, then it will pull the next batch of data using the token.
$nextToken = $AWSHistory.LastServiceResponse.NextToken
} catch {
Write-Error "Error retrieving events for user $user in region $region : $_"
break
}
} while ($null -ne $nextToken)
}
}
# Process each object
$combinedOutput = $results | ForEach-Object {
# Convert the JSON field to a PowerShell object
$jsonconverted = $_.CloudTrailEvent | Convertfrom-json
# Create a new custom object combining some of the original fields in $results and the JSON fields from $jsonconverted.
[pscustomobject]@{
AWSAccountID = $jsonconverted.recipientAccountId
awsRegion = $jsonconverted.awsRegion
UserName = $_.username
EventTime = $_.eventtime
EventSource = $jsonconverted.EventSource
EventName = $jsonconverted.EventName
ResourcesType = ($_.Resources).ResourceType -join ' , ' # There could be more than one, so we break them out and seperate them by a comma using the -join flag.
ResourcesName = ($_.Resources).resourcename -join ' , ' # There could be more than one, so we break them out and seperate them by a comma using the -join flag.
SourceIPAddress = $jsonconverted.SourceIPAddress
userAgent = $jsonconverted.userAgent
errorCode = $jsonconverted.errorCode
ErrorMessage = $jsonconverted.ErrorMessage
eventType = $jsonconverted.eventType
eventCategory = $jsonconverted.eventCategory
tlsDetails = $jsonconverted.tlsDetails
sessionCredentialFromConsole = $jsonconverted.sessionCredentialFromConsole
responseElements= $jsonconverted.responseElements
CreateDate = $jsonconverted.createDate
requestParameters = $jsonconverted.requestParameters
UserIdentity = $jsonconverted.UserIdentity
}
}
# Output results to a CSV file.
$combinedOutput | Export-Csv -NoTypeInformation -Path $filepath
Write-Output "Exported to: $filePath"
Write-Output "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|||||||////////////////////////////////////"
# End timer and display.
$stopwatch.Stop()
$time = $stopwatch.Elapsed
Write-Host "Script finished on $(Get-Date -f "MM-dd-yyyy hh:mm tt"), Elapsed time to run script (HH:MM:SS.MS): $Time" -ForegroundColor Red -BackgroundColor Green
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment