active directoryデータの "大きい整数"
DESCRIPTION
Active Directory データの "大きい整数"LargeInteger で表される属性値を取得・表示するTRANSCRIPT
Active Directory データの " 大きい整数 "
LargeInteger で表される属性値を取得・表示する
小山 三智男mitchin
2
Active Directory データのプロパティ出力
以前、 Active Directory データのプロパティ出力ということで、ユーザやグループなどの属性とその値の出力のしかたをサンプルコードと共に紹介しました。
http://www.slideshare.net/mitchin227/output-properties
これをサンプルアプリに組み込めば出力できるようになります。
サンプルアプリとスライドはこちら.NET4 用(ユーザ、グループの表示まで実装)http://blogs.wankuma.com/mitchin/archive/2013/08/26/328083.aspx.NET4.5.1 用(ユーザ、グループ、コンピュータの表示まで実装)http://blogs.wankuma.com/mitchin/archive/2013/11/24/328243.aspx
3
Windows Server 2008 で確認
管理ツール「 Active Directory ユーザとコンピュータ」で確認できます。「表示」メニューの「拡張機能」にチェックを入れます。
4
属性エディタ
「属性エディタ」タブを開きます。
5
値が設定されているものだけ表示するには
「フィルタ」ボタンをクリックして「値を持つ属性のみを表示」にチェックを入れます。(フィルタ設定は維持されます)
6
大きい整数は整数も日付も表している
「構文」列が「大きい整数 / 間隔」になっている属性がそうです。
表示は整数
表示は日付lastLogoff は値がない
7
前回の出力
大きい整数未対応時のプロパティ出力の結果です。
8
今回の出力
大きい整数に対応したプロパティ出力の結果です。
9
IADsLargeInteger インターフェイス
前回はマネージ オブジェクトで表すことができる整数や日付、文字列、バイト配列の値は正しく出力できましたが、 COM オブジェクトである " 大きい整数 " には対応していなかったので「 System.__ComObject 」と出力されていました。
" 大きい整数 " は ADSI の IADsLargeInteger として扱えるので、 プロパティの値をこのインターフェイスにキャストできます。
インターフェイスのメンバは HighPart プロパティと LowPart プロパティの 2 つです。 (Int32)この 2 つのプロパティの値から整数や日付を導出します。
10
大きい整数の属性と対象のオブジェクト
属性 表示 User Group Computer OU Printer Volume
accountExpires 日付 ○ ○
badPasswordTime 日付 ○ ○
lastContentIndexed 日付 ○
lastLogoff 日付 ○ ○
lastLogon 日付 ○ ○
lastLogonTimestamp 日付 ○ ○
lockoutTime /日付 整数 ○ ○
maxStorage 整数 ○ ○
msDS-Cached-Membership-Time-Stamp 日付 ○ ○
msDS-LastFailedInteractiveLogonTime 日付 ○ ○
msDS-LastSuccessfulInteractiveLogonTime 日付 ○ ○
msDS-UserPasswordExpiryTimeComputed 日付 ○ ○
pwdLastSet 日付 ○ ○
uSNChanged 整数 ○ ○ ○ ○ ○ ○
uSNCreated 整数 ○ ○ ○ ○ ○ ○
uSNDSALastObjRemoved 整数 ○ ○ ○ ○ ○ ○
uSNLastObjRem 整数 ○ ○ ○ ○ ○ ○
uSNSource 整数 ○ ○ ○ ○ ○ ○
11
プログラムから確認するには
DirectoryEntry.Properties プロパティ( PropertyCollection クラス)からプロパティとその値( PropertyValueCollection クラス)を列挙して取得します。未設定やオプションの属性を取得するには、スキーマ オブジェクト( SchemaEntry プロパティ)のネイティブ ADSI オブジェクト( IADsClass )の OptionalProperties で取得できるプロパティ(属性)をディレクトリ ストアから読み込んで取得します。
サンプルコードは次の名前空間をインポートしています。•ActiveDs ( Active DS Type Library の参照設定が必要)•System.IO•System.Security.Principal•System.Text
12
大きい整数取得 1 呼出し側の抜粋( VB )Public Shared Sub OutputProperties( entry As DirectoryEntry, filePath As String) Dim props = entry.Properties.PropertyNames.Cast( Of String)().OrderBy(Function(s) s).ToList() ' プロパティ名のリスト For Each pname In props ' プロパティ数分 Dim val = entry.Properties.Item(pname).Value If TypeOf val Is Byte() Then ' バイト配列の時 ' バイト値を取得 ElseIf TypeOf val Is IADsLargeInteger Then ' 大きい整数の時 Dim li = GetLargeIntegerValue( pname, DirectCast(val, IADsLargeInteger)) ' 大きい整数値を取得 Else ' それ以外の時 ' 各値を取得 End If NextEnd Sub
13
大きい整数取得 1 呼出し側の抜粋( C# )public static void OutputProperties( DirectoryEntry entry, string filePath) { var props = entry.Properties.PropertyNames. Cast<string>().OrderBy(s => s).ToList(); // プロパティ名のリスト foreach (var pname in props) { // プロパティ数分 var val = entry.Properties[pname].Value; if (val is byte[]) { // バイト配列の時 // バイト値を取得 } else if (val is IADsLargeInteger) { // 大きい整数の時 var li = GetLargeIntegerValue( pname, (IADsLargeInteger)val); // 大きい整数値を取得 } else { // それ以外の時 // 各値を取得 } }}
14
大きい整数取得 2 呼出し側の抜粋( VB )
Public Shared Sub OutputOptionalProperties( entry As DirectoryEntry, filePath As String) Dim schema = DirectCast( entry.SchemaEntry.NativeObject, IADsClass) ' スキーマ オブジェクト Dim props = DirectCast( schema.OptionalProperties, Object()) ' オプションのプロパティ
' プロパティをディレクトリ ストアから読込 entry.Invoke("GetInfoEx", props, 0) For Each pname As String In props ' オプションのプロパティ数分 Dim pvcol = entry.Properties.Item(pname) 'PropertyValueCollection If pvcol.Value Is Nothing Then ' 値がない時 Continue For End If
15
大きい整数取得 2 呼出し側の抜粋( VB )
If TypeOf pvcol.Value Is Byte() Then ' バイト配列の時 ' バイト値を取得 ElseIf TypeOf pvcol.Value Is IADsLargeInteger Then ' 大きい整数の時 Dim li = GetLargeIntegerValue(pname, DirectCast(pvcol.Value, IADsLargeInteger)) ' 大きい整数値を取得 Else ' それ以外の時 ' 各値を取得 End If NextEnd Sub
16
大きい整数取得 2 呼出し側の抜粋( C# )public static void OutputOptionalProperties( DirectoryEntry entry, string filePath) { // スキーマ オブジェクト var schema = (IADsClass)entry.SchemaEntry.NativeObject; // オプションのプロパティ var props = (object[])schema.OptionalProperties;
// プロパティをディレクトリ ストアから読込 entry.Invoke("GetInfoEx", props, 0); foreach (string pname in props) { // オプションのプロパティ数分 var pvcol = entry.Properties[pname]; //PropertyValueCollection if (pvcol.Value == null) { // 値がない時 continue; }
17
大きい整数取得 2 呼出し側の抜粋( C# ) if (pvcol.Value is byte[]) { // バイト配列の時 // バイト値を取得 } else if (val is IADsLargeInteger) { // 大きい整数の時 var li = GetLargeIntegerValue( pname, (IADsLargeInteger)pvcol.Value); // 大きい整数値を取得 } else { // それ以外の時 // 各値を取得 } }}
18
大きい整数値の取得( VB )
Private Shared Function GetLargeIntegerValue( name As String, value As IADsLargeInteger) As Object Dim lval = Convert.ToInt64(value.HighPart.ToString("x8") & value.LowPart.ToString("x8"), 16) If name.Equals("lockoutTime") Then ' ロックアウトしたことがある時 If lval > 0 Then ' ロックアウト中又はロックアウト期間が過ぎただけの時 Return String.Format("{0}({1})", lval, DateTime.FromFileTime(lval)) ' 判り易いよう日付も付ける End If Return lval End If If IsInteger(name, lval) Then ' 整数の時 Return New Guid(value).ToString() End If
19
大きい整数値の取得( VB )
If (lval = 0) OrElse (lval = Int64.MaxValue) Then Return " (なし) " End If Return DateTime.FromFileTime(lval) '#1/1/1601#.AddTicks(lval).ToLocalTime() と同じEnd Function
20
大きい整数値の取得( C# )
private static object GetLargeIntegerValue( string name, IADsLargeInteger value) { var lval = Convert.ToInt64(value.HighPart.ToString("x8") + value.LowPart.ToString("x8"), 16); //(long)((uint)value.LowPart + (((long)value.HighPart) << 32)) と同じ if (name.Equals("lockoutTime")) { // ロックアウトしたことがある時 if (lval > 0) { // ロックアウト中又はロックアウト期間が過ぎただけの時 return String.Format("{0}({1})", lval, DateTime.FromFileTime(lval)); // 判り易いよう日付も付ける } return lval; } if (IsInteger(name, lval)) { // 整数の時 return lval; }
21
大きい整数値の取得( C# )
if ((lval == 0) || (lval == Int64.MaxValue)) { return " (なし) "; } return DateTime.FromFileTime(lval); //new DateTime(1601, 1, 1).AddTicks(lval).ToLocalTime() と同じ}
22
整数かどうかの確認( VB )
Private Shared Function IsInteger( name As String, value As Long) As Boolean
If name.Equals("maxStorage") Then Return True End If If name.StartsWith("msDs-") Then Return False End If
If name.StartsWith("uSN") Then Return True End If Return FalseEnd Function
23
整数かどうかの確認( C# )
private static bool IsInteger(string name, long value) { if (name.Equals("maxStorage")) { return true; } if (name.StartsWith("msDs-")) { return false; }
if (name.StartsWith("uSN")) { return true; } return false;}
24
詳細や関連情報はブログ等で
Active Directory データのプロパティ出力http://blogs.wankuma.com/mitchin/archive/2013/09/19/328123.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/09/20/328126.aspx
大きい整数( LargeInteger )、大きい整数( LargeInteger )の属性http://blogs.wankuma.com/mitchin/archive/2013/11/29/328258.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/12/01/328262.aspx
lockoutTime 属性の値の確認http://blogs.wankuma.com/mitchin/archive/2013/12/02/328265.aspx
大きい整数で表わされる対話型ログオンの属性値の確認http://blogs.wankuma.com/mitchin/archive/2013/12/03/328270.aspx
Active Directory データのプロパティ出力の COM 対応版http://blogs.wankuma.com/mitchin/archive/2013/12/04/328271.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/12/05/328273.aspx
COM 対応版の変更点の説明(大きい整数関連)http://blogs.wankuma.com/mitchin/archive/2013/12/06/328275.aspx