diff --git a/Hawk/changelog.md b/Hawk/changelog.md index 223a63c..c8b6386 100644 --- a/Hawk/changelog.md +++ b/Hawk/changelog.md @@ -88,3 +88,7 @@ - Updated Get-HawkTenantEDiscoveryConfiguration to use non-deprecated means of collecting / analyzing eDiscovery role assignments. - Updated Change Log URI. - Removed improperly formatted JSON from Get-HawkTenantAdminInboxRuleHistory, Get-HawkTenantAdminInboxRuleRemoval, Get-HawkTenantRBACChange, Get-HawkUserAdminAudit, Search-HawkTenantEXOAuditLog + +## 3.X.X (2025-X-XX) + +- Implemented UTC timestamps to avoid using local timestamps diff --git a/Hawk/internal/functions/Initialize-HawkGlobalObject.ps1 b/Hawk/internal/functions/Initialize-HawkGlobalObject.ps1 index 82d35ba..a502195 100644 --- a/Hawk/internal/functions/Initialize-HawkGlobalObject.ps1 +++ b/Hawk/internal/functions/Initialize-HawkGlobalObject.ps1 @@ -1,41 +1,41 @@ Function Initialize-HawkGlobalObject { <# -.SYNOPSIS - Create global variable $Hawk for use by all Hawk cmdlets. -.DESCRIPTION - Creates the global variable $Hawk and populates it with information needed by the other Hawk cmdlets. - - * Checks for latest version of the Hawk module - * Creates path for output files - * Records target start and end dates for searches -.PARAMETER Force - Switch to force the function to run and allow the variable to be recreated -.PARAMETER SkipUpdate - Skips checking for the latest version of the Hawk Module -.PARAMETER DaysToLookBack - Defines the # of days to look back in the availible logs. - Valid values are 1-90 -.PARAMETER StartDate - First day that data will be retrieved -.PARAMETER EndDate - Last day that data will be retrieved -.PARAMETER FilePath - Provide an output file path. -.OUTPUTS - Creates the $Hawk global variable and populates it with a custom PS object with the following properties - - Property Name Contents - ========== ========== - FilePath Path to output files - DaysToLookBack Number of day back in time we are searching - StartDate Calculated start date for searches based on DaysToLookBack - EndDate One day in the future - WhenCreated Date and time that the variable was created -.EXAMPLE - Initialize-HawkGlobalObject -Force - - This Command will force the creation of a new $Hawk variable even if one already exists. -#> + .SYNOPSIS + Create global variable $Hawk for use by all Hawk cmdlets. + .DESCRIPTION + Creates the global variable $Hawk and populates it with information needed by the other Hawk cmdlets. + + * Checks for latest version of the Hawk module + * Creates path for output files + * Records target start and end dates for searches (in UTC) + .PARAMETER Force + Switch to force the function to run and allow the variable to be recreated + .PARAMETER SkipUpdate + Skips checking for the latest version of the Hawk Module + .PARAMETER DaysToLookBack + Defines the # of days to look back in the availible logs. + Valid values are 1-90 + .PARAMETER StartDate + First day that data will be retrieved (in UTC) + .PARAMETER EndDate + Last day that data will be retrieved (in UTC) + .PARAMETER FilePath + Provide an output file path. + .OUTPUTS + Creates the $Hawk global variable and populates it with a custom PS object with the following properties + + Property Name Contents + ========== ========== + FilePath Path to output files + DaysToLookBack Number of day back in time we are searching + StartDate Calculated start date for searches based on DaysToLookBack (UTC) + EndDate One day in the future (UTC) + WhenCreated Date and time that the variable was created (UTC) + .EXAMPLE + Initialize-HawkGlobalObject -Force + + This Command will force the creation of a new $Hawk variable even if one already exists. + #> [CmdletBinding()] param ( @@ -73,9 +73,9 @@ [CmdletBinding(SupportsShouldProcess)] param([string]$RootPath) - # Create a folder ID based on date + # Create a folder ID based on UTC date [string]$TenantName = (Get-MGDomain | Where-Object { $_.isDefault }).ID - [string]$FolderID = "Hawk_" + $TenantName.Substring(0, $TenantName.IndexOf('.')) + "_" + (Get-Date -UFormat %Y%m%d_%H%M).tostring() + [string]$FolderID = "Hawk_" + $TenantName.Substring(0, $TenantName.IndexOf('.')) + "_" + (Get-Date).ToUniversalTime().ToString("yyyyMMdd_HHmm") # Add that ID to the given path $FullOutputPath = Join-Path $RootPath $FolderID @@ -200,24 +200,24 @@ $StartRead = 90 } - # Calculate our startdate setting it to midnight - [DateTime]$StartDate = ((Get-Date).AddDays(-$StartRead)).Date - Write-Information ("Start Date: " + $StartDate + "") + # Calculate our startdate setting it to midnight UTC + [DateTime]$StartDate = ((Get-Date).ToUniversalTime().AddDays(-$StartRead)).Date + Write-Information ("Start Date (UTC): " + $StartDate + "") } elseif (!($null -eq ($StartRead -as [DateTime]))) { #### DATE TIME Provided #### - # Convert the input to a date time object - [DateTime]$StartDate = (Get-Date $StartRead).Date + # Convert the input to a UTC date time object + [DateTime]$StartDate = (Get-Date $StartRead).ToUniversalTime().Date # Test to make sure the date time is > 90 and < today - if ($StartDate -ge ((Get-date).AddDays(-90).Date) -and ($StartDate -le (Get-Date).Date)) { + if ($StartDate -ge ((Get-date).ToUniversalTime().AddDays(-90).Date) -and ($StartDate -le (Get-Date).ToUniversalTime().Date)) { #Valid Date do nothing } else { Write-Information ("Date provided beyond acceptable range of 90 days.") Write-Information ("Setting date to default of Today - 90 days.") - [DateTime]$StartDate = ((Get-Date).AddDays(-90)).Date + [DateTime]$StartDate = ((Get-Date).ToUniversalTime().AddDays(-90)).Date } } else { @@ -234,15 +234,15 @@ if ($Null -eq ($EndRead -as [DateTime])) { #### Not a Date time #### - # if we have a null entry (just hit enter) then set startread to the default of 90 + # if we have a null entry (just hit enter) then set startread to the default of today if ([string]::IsNullOrEmpty($EndRead)) { - [DateTime]$EndDate = ((Get-Date).AddDays(1)).Date + [DateTime]$EndDate = ((Get-Date).ToUniversalTime().AddDays(1)).Date } else { - # Calculate our startdate setting it to midnight - Write-Information ("End Date: " + $EndRead + " days.") + # Calculate our enddate setting it to midnight UTC + Write-Information ("End Date (UTC): " + $EndRead + " days.") # Subtract 1 from the EndRead entry so that we get one day less for the purpose of how searching works with times - [DateTime]$EndDate = ((Get-Date).AddDays( - ($EndRead - 1))).Date + [DateTime]$EndDate = ((Get-Date).ToUniversalTime().AddDays( - ($EndRead - 1))).Date } # Validate that the start date is further back in time than the end date @@ -250,30 +250,29 @@ Write-Error "StartDate Cannot be More Recent than EndDate" -ErrorAction Stop } else { - Write-Information ("End Date: " + $EndDate + "`n") + Write-Information ("End Date (UTC): " + $EndDate + "`n") } } elseif (!($null -eq ($EndRead -as [DateTime]))) { #### DATE TIME Provided #### - # Convert the input to a date time object - [DateTime]$EndDate = ((Get-Date $EndRead).AddDays(1)).Date + # Convert the input to a UTC date time object + [DateTime]$EndDate = ((Get-Date $EndRead).ToUniversalTime().AddDays(1)).Date # Test to make sure the end date is newer than the start date if ($StartDate -gt $EndDate) { Write-Information "EndDate Selected was older than start date." Write-Information "Setting EndDate to today." - [DateTime]$EndDate = ((Get-Date).AddDays(1)).Date + [DateTime]$EndDate = ((Get-Date).ToUniversalTime().AddDays(1)).Date } - elseif ($EndDate -gt (get-Date).AddDays(2)) { - Write-Information "EndDate to Far in the furture." + elseif ($EndDate -gt (Get-Date).ToUniversalTime().AddDays(2)) { + Write-Information "EndDate too far in the future." Write-Information "Setting EndDate to Today." - [DateTime]$EndDate = ((Get-Date).AddDays(1)).Date + [DateTime]$EndDate = ((Get-Date).ToUniversalTime().AddDays(1)).Date } - Write-Information ("Setting EndDate by Date to " + $EndDate + "`n") + Write-Information ("End Date (UTC): " + $EndDate + "`n") } - else { Write-Error "Invalid date information provided. Could not determine if this was a date or an integer." -ErrorAction Stop } @@ -303,10 +302,10 @@ $Output = [PSCustomObject]@{ FilePath = $OutputPath DaysToLookBack = $Days - StartDate = $StartDate - EndDate = $EndDate + StartDate = $StartDate + EndDate = $EndDate AdvancedAzureLicense = $AdvancedAzureLicense - WhenCreated = (Get-Date -Format g) + WhenCreated = (Get-Date).ToUniversalTime().ToString("g") } # Create the script hawk variable @@ -314,6 +313,7 @@ New-Variable -Name Hawk -Scope Script -value $Output -Force Out-LogFile "Script Variable Configured" -Information Out-LogFile ("Hawk Version: " + (Get-Module Hawk).version) -Information + # Print each property of $Hawk on its own line foreach ($prop in $Hawk.PSObject.Properties) { # If the property value is $null or an empty string, display "N/A" @@ -325,9 +325,7 @@ Out-LogFile ("{0} = {1}" -f $prop.Name, $value) -Information } - #### End of IF } - else { Write-Information "Valid Hawk Object already exists no actions will be taken." } diff --git a/Hawk/internal/functions/Out-LogFile.ps1 b/Hawk/internal/functions/Out-LogFile.ps1 index 9ba305a..5d8a73f 100644 --- a/Hawk/internal/functions/Out-LogFile.ps1 +++ b/Hawk/internal/functions/Out-LogFile.ps1 @@ -106,8 +106,8 @@ $ScreenOutput = -not $NoDisplay $LogOutput = $true - # Get the current date - [string]$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + # Get the current date in UTC + [string]$timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss UTC") [string]$logstring = "" # Build the log string based on the type of message