アイキャッチ

実装・エラー解決

ADから取得した時刻(NTタイムエポック)をDateコマンドでUnixTimeに変換する

この記事の内容

  • Active Directoryの pwdLastSet をUnix秒に換算し、UTCの日時として表示します。

ポイント

  • 値の単位は100ナノ秒です。Unix秒へ換算してから、LinuxとmacOSで異なるdateの書式を使います。

手順

Active Directoryの pwdLastSet は、1601年1月1日 00:00:00 UTCからの経過を100ナノ秒単位で表します。属性値が0の場合は通常の更新時刻として換算せず、属性の状態として扱います。

まずは時刻計算

1秒は100ナノ秒の10,000,000個分です。10,000,000で整数除算して秒に直し、1601年から1970年までの差の11,644,473,600秒を引きます。この例では秒未満を切り捨てます。

133093204093978353 / 10000000 - 11644473600 = 1664846809

次にDateコマンド実行

GNU dateでは date -u --date "@1664846809"、macOSのdateでは date -u -r 1664846809 と指定します。次のスクリプトは使用環境に合わせて切り替えます。

#!/bin/bash
set -eu

if (( $# != 1 )) || [[ ! $1 =~ ^[0-9]{1,19}$ ]]; then
    printf '%s\n' 'usage: bash pwd-last-set.sh FILETIME' >&2
    exit 2
fi

ticks=$1
if [[ ${#ticks} -eq 19 && $ticks > 9223372036854775807 ]]; then
    printf '%s\n' 'FILETIME is outside the signed 64-bit range' >&2
    exit 2
fi
if (( 10#$ticks == 0 )); then
    printf '%s\n' 'pwdLastSet is 0; handle it as an attribute state' >&2
    exit 2
fi

seconds=$((10#$ticks / 10000000 - 11644473600))
printf 'Unix seconds: %s\n' "$seconds"
if date --version >/dev/null 2>&1; then
    date -u --date "@$seconds" '+%Y-%m-%d %H:%M:%S UTC'
else
    date -u -r "$seconds" '+%Y-%m-%d %H:%M:%S UTC'
fi
bash pwd-last-set.sh 133093204093978353
Unix seconds: 1664846809
2022-10-04 01:26:49 UTC

日本時間では2022年10月4日 10:26:49です。116444736000000000 を入れるとUnix秒0になります。これは pwdLastSet 自体が0の場合とは別です。

出典 MicrosoftのpwdLastSet属性仕様

-実装・エラー解決
-