Created
May 31, 2024 14:52
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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