#[Solved] Passing DateTime objects to Set-ADUser from a different time zone

1 messages · Page 1 of 1 (latest)

wicked basin
#

Hey Folks,

Odd problem I've been dealing with at work and I just cannot figure it out. Here's the details and some pseudo code.

Problem: Setting expiration date with Set-ADUser -AccountExpirationDate or Set-ADAccountExpiration with a DateTime object produced by Get-Date uses local time, making expiration time differ on the dc in a different time zone where it's being set. The time should be 00:00.

Details:
Server 2022 running in aws with a UTC time zone. Being used by gitlab pipeline for script execution. DC is located in the EST time zone.

Sample code

# All of this happens on the runner server
$date = "2023-10-15"
$date = Get-Date $date -Hour 0 -Minute 0 -Second 0
$timeZoneConvertedDate = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($date,'Eastern Standard Time')
# This compensates for time difference
if($timeZoneConvertedDate.Hour -ne 0){
  timeZoneConvertedDated = $timeZoneConvertedDated.AddHour((24 - $timeZoneConvertedDate.Hour))
}
$fakeUser | Set-ADAccountExpiration $timeZoneConvertedDate -Server EasternStandardDC.contoso.com

This seems to always set the user with an offset depending on the server time, despite the DateTime object in the pipeline showing 00:00 on the targeted Time Zone.

I noticed the documentation for both Set-ADUser and Set-ADAccountExpiration mention this, but never elaborate!

Time is assumed to be local time unless otherwise specified.
https://learn.microsoft.com/en-us/powershell/module/activedirectory/set-adaccountexpiration?view=windowsserver2022-ps#-datetime

Any ideas?

versed sorrel
#

So you want it to be 00:00 EST but it's being run on a server with UTC time so it's converting to UTC (05:00 UTC)?

wicked basin
#

Yeah. This is a bit simplified as well, because we want to use it for DCs in several countries. I want to avoid manual time manipulation because of DST and the like.

#

My last resort is just setting the server using Set-Timezone, because I'm not sure if it will cause any unintended effects.

versed sorrel
#

Have you messed with the Kind property of the DateTime object?

Gets a value that indicates whether the time represented by this instance is based on local time, Coordinated Universal Time (UTC), or neither.

#

Since the -DateTime parameter says

Time is assumed to be local time unless otherwise specified.

wicked basin
#

Oh, good eye. I have not messed with that. I made a (probably poor) assumption that the object would get converted as appropriate by the SystemTimeInfo method.

versed sorrel
wicked basin
#

Appreciate you taking a look. I'll post an update tomorrow when I get a chance to muck around more.

eager otter
#

I am extremely frustrated that PowerShell never adopted DateTimeOffset 😕

wicked basin
#

@versed sorrel , setting the kind to local or utc didn't help unfortunately. The kind was unspecified, but it seems like AD always tried to perform a conversion of the time zone when setting over it's cmdlets, which is what was causing issues. Even if I had the correct time, it would adjust to the DC server time.

I ended up solving it by doing something similar, funnily enough @eager otter , basically that. It's extremely frustrating this isn't available as a property of the DateTime object.

$date = (New-Object DateTime $year,$month,day,0,0,0,([DateTimeKind]::Utc)).AddDays(1)
$est = [TimeZoneInfo]::GetTimeZoneById('Eastern Standard Time')
$date = $date.AddHours(-($est.GetUtcOffset($date).TotalHours))