B2B Solution/Windows

PowerShell에서 Active Directory accountExpires 속성 다루기: FILETIME에서 사람이 읽을 수 있는 날짜로

SangPedia 2025. 6. 24. 14:15
반응형

accountExpires

 

Active Directory 관리 업무를 하다 보면 사용자 계정의 만료 날짜를 확인해야 할 때가 있습니다. Get-ADUser cmdlet을 사용해서 accountExpires 속성을 조회하면 131416668000000000과 같은 이상한 숫자가 나오는데, 이게 도대체 뭘까요?

FILETIME 형식이란?

PowerShell에서 accountExpires 속성이 긴 숫자로 표시되는 이유는 FILETIME(Win32 FILETIME) 형식으로 저장되어 있기 때문입니다.

# 일반적인 조회 결과
PS> Get-ADUser "sanghyeon.kim" -Properties accountExpires | Select-Object Name, accountExpires

Name     accountExpires
----     --------------
jing.jin 131416668000000000

FILETIME의 특징

  • 기준점: 1601년 1월 1일 UTC 자정
  • 단위: 100나노초 간격
  • 형식: 64비트 정수값
  • 용도: Windows 시스템 전반에서 시간 저장용

이 형식은 컴퓨터에겐 효율적이지만 사람이 읽기엔 전혀 직관적이지 않죠. 

실전 변환 방법

1. 기본 변환 스크립트

# 단일 사용자 계정 만료일 확인
Get-ADUser -Identity "jing.jin" -Properties accountExpires | ForEach-Object {
    $expiresValue = $_.accountExpires
    
    if ($expiresValue -eq 0 -or $expiresValue -eq 9223372036854775807) {
        Write-Host "$($_.Name): Never expires"
    } else {
        $expirationDate = [datetime]::FromFileTimeUtc($expiresValue)
        Write-Host "$($_.Name): Expires on $($expirationDate.ToString('yyyy-MM-dd HH:mm:ss')) UTC"
    }
}

2. 테이블 형태로 깔끔하게 출력

# 여러 사용자의 만료일을 테이블로 정리
Get-ADUser -Filter * -Properties accountExpires | 
    Select-Object SamAccountName, 
        @{Name="AccountExpirationDate"; Expression={
            if ($_.accountExpires -eq 0 -or $_.accountExpires -eq 9223372036854775807) {
                "Never"
            } else {
                [datetime]::FromFileTimeUtc($_.accountExpires).ToString('yyyy-MM-dd HH:mm:ss')
            }
        }} | 
    Format-Table -AutoSize

3. 함수로 만들어서 재사용

function Get-ADUserExpiration {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Identity
    )
    
    $user = Get-ADUser -Identity $Identity -Properties accountExpires
    $expiresValue = $user.accountExpires
    
    if ($expiresValue -eq 0 -or $expiresValue -eq 9223372036854775807) {
        return [PSCustomObject]@{
            UserName = $user.SamAccountName
            ExpirationDate = "Never"
            Status = "Active"
        }
    } else {
        $expirationDate = [datetime]::FromFileTimeUtc($expiresValue)
        $status = if ($expirationDate -lt (Get-Date)) { "Expired" } else { "Active" }
        
        return [PSCustomObject]@{
            UserName = $user.SamAccountName
            ExpirationDate = $expirationDate.ToString('yyyy-MM-dd HH:mm:ss')
            Status = $status
        }
    }
}

# 사용 예시
Get-ADUserExpiration -Identity "jing.jin"

핵심 포인트 정리

🔑 중요한 값들

  • 0: 계정 만료 없음 (Never expires)
  • 9223372036854775807: 64비트 정수 최대값, 만료 없음을 의미
  • 기타 숫자: 실제 만료 날짜를 FILETIME으로 표현

🛠️ 변환 메서드 선택

  • [datetime]::FromFileTime(): 로컬 시간대로 변환
  • [datetime]::FromFileTimeUtc(): UTC 기준으로 변환 (권장)

💡 실무 팁

  1. 배치 처리: 많은 사용자를 한번에 처리할 때는 Format-Table이나 Export-Csv 활용
  2. 에러 처리: try-catch 블록으로 잘못된 FILETIME 값 처리
  3. 성능 최적화: 필요한 속성만 -Properties에 지정

마무리

FILETIME 형식은 Windows 환경에서 자주 마주치는 데이터 형식입니다. Active Directory뿐만 아니라 이벤트 로그, 파일 시스템 등에서도 사용되므로 변환 방법을 알아두면 다양한 상황에서 유용하게 활용할 수 있습니다.

다음번에 이상한 숫자를 만나더라도 당황하지 말고 FromFileTimeUtc()로 변환해보세요! 🚀

반응형