マイナーでもいいよね??

殆どVB系、でも .NET じゃない VB は知らないよん

目次

Blog 利用状況

書庫

日記カテゴリ

Active Directoryデータのプロパティ出力のCOM対応版(VB)

以前書いた Active Directory データのプロパティ出力(VBC#スライド) の COM 対応版です。

※2013/12/10 Trustee はユーザやグループの名前部分のみ出力、AceType は値とその列挙体文字列を出力するよう修正しました。

※2013/12/11 GetValue メソッドの name パラメータを削除しました。

なんで "大きい整数" 対応版にしてないかというと、"大きい整数" で表される IADsLargeInteger のほかにも COM(ADSI オブジェクト)があるからです。

それはセキュリティ記述子です。これの属性は nTSecurityDescriptor で IADsSecurityDescriptor として扱え、値をこのインターフェイスにキャストできます。

nTSecurityDescriptor 属性は通常のプロパティ(DirectoryEntry.Properties)で取得できます。オプションのプロパティでは取得できません。

 

以前からの変更点

 ・セキュリティ記述子を見やすい形で出力する

 ・"大きい整数" を数値や日付で出力する

 ・構造化例外処理を使わないで値がないかを確認する

 ・COM じゃない値(バイト配列や日付)も正しく出力する

 

説明は別途ということで まずはコードを。

 

Public Shared Sub OutputProperties(entry As DirectoryEntry, filePath As String)

  Dim props = entry.Properties.PropertyNames.Cast(Of String)().OrderBy(Function(s) s).ToList()  'プロパティ名のリスト

  Using writer As New StreamWriter(filePath, False, Encoding.UTF8)

    For Each pname In props   'プロパティ数分

      Dim val = entry.Properties.Item(pname).Value

      If TypeOf val Is Byte() Then  'バイト配列の時

        Dim pstr = GetByteValue(pname, DirectCast(val, Byte()))   'バイト値を取得

        writer.WriteLine("{0}:{1}", pname, pstr)

      ElseIf TypeOf val Is IADsSecurityDescriptor Then  'セキュリティ記述子の時

        Dim sd = DirectCast(val, IADsSecurityDescriptor)

        Dim aceGroups = DirectCast(sd.DiscretionaryAcl, IADsAccessControlList).Cast(Of IADsAccessControlEntry)().OrderBy(

          Function(ace) Path.GetFileName(ace.Trustee)).ThenBy(Function(ace) ace.AccessMask).ThenBy(

          Function(ace) ace.AceFlags).ThenBy(Function(ace) ace.AceType).ThenBy(Function(ace) ace.Flags).GroupBy(

          Function(ace) String.Format("{0}|{1}|{2}|{3}|{4}",

            ace.Trustee, ace.AccessMask, ace.AceFlags, ace.AceType, ace.Flags)).ToList()  'プロパティ値でグループ化したACE

        Dim ctr = 0

        writer.WriteLine(pname)

        For Each aceGroup In aceGroups  'ACE数分

          Dim ace = aceGroup.First()

          ctr += 1

          writer.WriteLine(" {0:D2}. Trustee   :{1}", ctr, Path.GetFileName(ace.Trustee))

          writer.WriteLine(" {0:D2}. AccessMask:{1}", ctr, ToEnumValueText(ace.AccessMask, GetType(ADS_RIGHTS_ENUM)))

          writer.WriteLine(" {0:D2}. AceFlags  :{1}", ctr, ToEnumValueText(ace.AceFlags, GetType(ADS_ACEFLAG_ENUM)))

          writer.WriteLine(" {0:D2}. AceType   :{1}", ctr, ToEnumValueText(ace.AceType, GetType(ADS_ACETYPE_ENUM)))

          writer.WriteLine(" {0:D2}. Flags     :{1}", ctr, ToEnumValueText(ace.Flags, GetType(ADS_FLAGTYPE_ENUM)))

        Next

      ElseIf TypeOf val Is IADsLargeInteger Then  '大きい整数の時

        Dim li = GetLargeIntegerValue(pname, DirectCast(val, IADsLargeInteger))  '大きい整数値を取得

        writer.WriteLine("{0}:{1}", pname, li)

      Else  'それ以外の時

        For Each pval In entry.Properties.Item(pname)   '値数分

          Dim value = GetValue(pval)  '値を取得

          writer.WriteLine("{0}:{1}", pname, value)

        Next

      End If

    Next

  End Using

End Sub

 

Public Shared Sub OutputOptionalProperties(entry As DirectoryEntry, filePath As String)

  Dim schema = DirectCast(entry.SchemaEntry.NativeObject, IADsClass'スキーマ オブジェクト

  Dim props = DirectCast(schema.OptionalProperties, Object())   'オプションのプロパティ

  Using writer As New StreamWriter(filePath, False, Encoding.UTF8)

    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  '値がない時

        writer.WriteLine("{0}:<未設定>", pname)

        Continue For

      End If

 

      If TypeOf pvcol.Value Is Byte() Then  'バイト配列の時

        Dim bstr = GetByteValue(pname, DirectCast(pvcol.Value, Byte()))   'バイト値を取得

        writer.WriteLine("{0}:{1}", pname, bstr)

      ElseIf TypeOf pvcol.Value Is IADsLargeInteger Then  '大きい整数の時

        Dim li = GetLargeIntegerValue(pname, DirectCast(pvcol.Value, IADsLargeInteger))  '大きい整数値を取得

        writer.WriteLine("{0}:{1}", pname, li)

      Else  'それ以外の時

        For Each pval In pvcol  '値数分

          If TypeOf pval Is Byte() Then  'バイト配列の時

            Dim pstr = GetByteValue(pname, DirectCast(pval, Byte()))   'バイト値を取得

            writer.WriteLine("{0}:{1}", pname, pstr)

          Else  'バイト配列以外の時

            Dim value = GetValue(pval)  '値を取得

            writer.WriteLine("{0}:{1}", pname, value)

          End If

        Next

      End If

    Next

  End Using

End Sub

 

'バイト値を取得

Private Shared Function GetByteValue(name As String, value As Byte()) As String

  If name.Equals("objectSid") Then

    Return New SecurityIdentifier(value, 0).ToString()

  ElseIf name.Equals("objectGUID") Then

    Return New Guid(value).ToString()

  Else

    Return BitConverter.ToString(value)

  End If

End Function

 

'大きい整数値を取得

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   '明示的にロック解除又はロックアウト期間が過ぎてログオン成功しているので値は0

  End If

 

  If IsInteger(name, lval) Then   '整数の時

    Return lval

  End If

  If (lval = 0) OrElse (lval = Int64.MaxValue) Then

    Return "(なし)"

  End If

  Return DateTime.FromFileTime(lval)  'eq. #1/1/1601#.AddTicks(lval).ToLocalTime()

End Function

 

'整数かどうか

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 False

End Function

 

'値を取得

Private Shared Function GetValue(value As Object) As Object

  If (TypeOf value Is Date) = False Then  '日付ではない時

    Return value

  End If

 

  Dim d = Convert.ToDateTime(value)

  Return If(d.Date.Equals(#1/1/1601#), d, d.ToLocalTime())

End Function

 

'列挙体のプロパティ値をテキスト化

Private Shared Function ToEnumValueText(value As Integer, enumType As Type) As String

  If enumType Is GetType(ADS_ACETYPE_ENUM) Then   'AceTypeの時

    Return String.Format("{0}({1})", value, [Enum].ToObject(enumType, value))

  End If

 

  Dim selector = Function(e As Integer) [Enum].ToObject(enumType, e).ToString()

  Dim values = [Enum].GetValues(enumType).Cast(Of Integer)().Where(

    Function(e) (value And e) = e).OrderBy(selector).Select(selector).ToList()  '設定されている値の列挙体文字列

 

  If values.Count = 0 Then  '設定されている値がない時

    Return value.ToString()

  End If

  Return String.Format("{0}({1})", value, String.Join(" | ", values))

End Function

投稿日時 : 2013年12月4日 23:27

コメントを追加

# Illikebuisse eagqj 2021/07/04 13:47 www.pharmaceptica.com

tadalafil cost https://pharmaceptica.com/

# Illikebuisse asqxj 2021/07/05 0:20 pharmaceptica

hydroxyquine medication https://www.pharmaceptica.com/

# re: Active Directory????????????COM???(VB) 2021/07/07 19:13 hcq drug

malaria skin rash https://chloroquineorigin.com/# malaria usmle

# re: Active Directory????????????COM???(VB) 2021/07/13 21:07 hydroxocloroquine

sulfur effects on body https://chloroquineorigin.com/# what is hcq drug

# re: Active Directory????????????COM???(VB) 2021/07/24 9:17 is hydroxychloroquine safe to take

is chloroquine available over the counter https://chloroquineorigin.com/# hydroxide chloroquine

# kcltiigradxt 2021/11/30 11:20 dwedaycdpc

https://chloroquinesop.com/

# hydroxychloroquine canada 2022/12/26 19:49 MorrisReaks

how to get hydroxychloroquine prescription http://hydroxychloroquinex.com/

# ブランド偽物 2023/03/22 7:14 yffqrnuh@nifty.com

母へのプレゼントとして利用しました。男性なので女性物の品揃えがよいかどうかは分からないので「品揃え」は3点としましたが、ほかはずべて5点です。
私は注文からいかに早く発送していただくかを一番重視しておりますが、注文日の翌日にすぐ発送され、お礼のメールも届きましたのでネット通販としては十分な対応だと思います。
また何かあれば利用したいと思います。
ブランド偽物 https://www.gmt78.com/product/category/244/

タイトル
名前
URL
コメント