Ext JS に関しては,新しい記事は Sunvisor Lab. ExtJS 別館 にあります。そちらもよろしくお願いいたします。

Active Directoryのユーザ管理 (2)

Active Directoryのユーザ管理 (1) で作成したクラスを使って実際のユーザー管理をしてゆく。

実際のユーザー管理

ドメインユーザを追加するとともに,ホームディレクトリを作り,そのホームディレクトリをH:ドライブに割り当てるようにする。という仕様でやってみる。ドメインなどの仕様は次の通りとする。

ドメイン名 hogedom.local
ドメインコントローラ domainserver
ファイルサーバ hogeserver
home共有 \\hogeserver\home以下に置く
home共有のサーバ上の位置 D:\home

次のような感じのExcelの表があり,その表の中のデータを登録する手続を記述する。

部署 職員番号 ID グループ グループ PW
内野 F008 mac 金子 fighters naiya abcd1234
外野 F001 hichori 森本 稀哲 fighters gaiya efgh5678
投手 F021 hisashi 武田 fighters pitcher vwxy9876

ユーザーの追加

Sub cmdAddUsers_Click()
    Dim vID As String
    Dim iCol As Integer
    Dim iRow As Integer
    Dim ADSI As CADSI
    Dim User As TADUser
    Dim vGroup
    
    Set ADSI = New CADSI
    ADSI.OpenDomain _
        "hogeserver.hogedom.local", "dc=hogedom,dc=local", "hogedom\administrator", "password"
    iRow = 2
    vID = Cells(iRow, 3)
    Do While Len(vID) > 0
        'Debug.Print vID
        User.UserID = vID
        User.LastName = Cells(iRow, 4)
        User.FirstName = Cells(iRow, 5)
        User.DisplayName = User.LastName + " " + User.FirstName
        User.Description = User.DisplayName
        User.PasswordMustChange = False
        User.ScriptPath = "logon.vbs"
        User.UserPrincipalName = vID & "@hogedom.local"
        User.Password = Cells(iRow, 8)
        ADSI.AddUser User, "ou=Persons"
        For iCol = 6 To 7
            vGroup = Cells(iRow, iCol)
            If Len(vGroup) > 0 Then
                ADSI.AddToGroup "ou=Persons", vID, "ou=Groups", Cells(iRow, iCol)
            End If
        Next iCol
        ADSI.SetHomeFolder vID, "ou=Persons", "H:", "\\hogeserver\home\%username%"
        MakeFolder vID
        iRow = iRow + 1
        vID = Cells(iRow, 3)
    Loop
    Set ADSI = Nothing
End Sub

CADSIのSetHomeFolderメソッドを使って,ホームディレクトリを設定している。ドメインコントローラ上の「Active Directoryユーザとコンピュータ」にてユーザ設定をする際に,このコードのように //hogeserver/home/%username% のように指定すると自動的にフォルダが作成されるがADSIを使ってコードで設定した場合には自動作成されないようだ。

ホームフォルダの作成

ADSIを利用したユーザー管理プログラムでアカウントを作成するのであれば,ホームフォルダの作成機能は必須となる。ここでは,//hogeserver/home という共有フォルダの下に各個人のホームディレクトリを作成し,そのアカウントに対してのみフルコントロールのアクセス権を付与する仕様を目指した。

上記のコード中で呼び出されているMakeFolder手続で,ホームディレクトリを作成している。

Sub MakeFolder(AID As String)
    Dim FSO As FileSystemObject
    
    Set FSO = New FileSystemObject
    FSO.CreateFolder "\\hogeserver\home\" & AID
    SetSecurityHomeDirectory "domainserver", "hogeserver", AID, "D:\home\" & AID
    Set FSO = Nothing
End Sub

FileSystemObjectオブジェクトでフォルダをサーバ上に作成し,SetSecurityHomeDirectoryで権限を設定して いる。NTFSの権限を設定するにはコマンドラインではcaclsというツールがあったり,xcacls.vbsというツールをMicrosoftが提供 してくれていたりするが,なんとかExcelのVBA上でやりたかった。WMIを使って権限を設定するのは可能だが,とっても難しく面倒くさい。いくつか のサイトを覗いたが,このSetSecurityHomeDirectoryは,中の技術日誌ブログに あった同名の手続を改造して作った。用途がもろに僕のやりたいこと「ユーザのホームディレクトリの設定」と一致していたためだ。この手続では,指定した ユーザのフルコントロールのアクセス権をフォルダに与える。以下のコードはまんまパクリです。中さんのコードですのでそこのとこはよろしくです。

Function SetSecurityHomeDirectory(strDomainControler, strComputer, strUser, HomePath)
    Dim objWMIService
    Dim wmiAccounts
    Dim wmiAccount
    Dim wmiTrustee
    Dim wmiTrusteeClass
    Dim wmiSID
    Dim wmiACE
    Dim wmiACEClass
    Dim wmiFileSecSetting
    Dim wmiSecurityDescriptor
    Dim DictACE
    Dim obj
    Dim RetVal
    Dim i
    
    Set objWMIService = GetObject( _
        "winmgmts:{impersonationLevel=impersonate}!\\" & strDomainControler & "\root\cimv2")
    SetSecurityHomeDirectory = False
    'アカウント取得
    Set wmiAccounts = _
        objWMIService.ExecQuery("select * from Win32_Account where Name='" & strUser & "'")
    For Each obj In wmiAccounts
      Set wmiAccount = obj
      Exit For
    Next
    
    'Trusteeに変換する
    Set wmiTrusteeClass = objWMIService.Get("Win32_Trustee")
    Set wmiTrustee = wmiTrusteeClass.spawnInstance_()
    Set wmiSID = objWMIService.Get("Win32_SID.SID='" & wmiAccount.sid & "'")
    wmiTrustee.DOMAIN = wmiSID.ReferencedDomainName
    wmiTrustee.Name = wmiSID.AccountName
    wmiTrustee.sid = wmiSID.BinaryRepresentation
    wmiTrustee.sidLength = wmiSID.sidLength
    wmiTrustee.sidString = wmiSID.sid
    'ACEオブジェクトを作成する
    Set wmiACEClass = objWMIService.Get("Win32_ACE")
    Set wmiACE = wmiACEClass.spawnInstance_()
    wmiACE.AccessMask = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 65536 _
        + 131072 + 262144 + 524288 + 1048576 ' 2032127
    wmiACE.Trustee = wmiTrustee
    wmiACE.AceType = 0
    wmiACE.AceFlags = 3
    
    '対象フォルダのセキュリティデスクリプタを取得する
    'Set wmiFileSecSetting = GetObject( _
        "winmgmts:Win32_LogicalFileSecuritySetting.path='" & HomePath & "'")
    Set wmiFileSecSetting = GetObject( _
        "winmgmts:\\" & strComputer & "\root\cimv2:Win32_LogicalFileSecuritySetting='" & _
        HomePath & "'")
    RetVal = wmiFileSecSetting.GetSecurityDescriptor(wmiSecurityDescriptor)
    If (RetVal <> 0) Then
        MsgBox "GetSecurityDescriptorに失敗しました:" & RetVal
        Exit Function
    End If
    
    'ディクショナリにDACLを転記する
    Set DictACE = CreateObject("Scripting.Dictionary")
    For i = LBound(wmiSecurityDescriptor.DACL) To UBound(wmiSecurityDescriptor.DACL)
        If (Not wmiSecurityDescriptor.DACL(i).AceFlags And 16) Then
            Call DictACE.Add(i, wmiSecurityDescriptor.DACL(i))
        End If
    Next
    
    '設定する新しいACEオブジェクトを最後に足す
    Call DictACE.Add("NewUser", wmiACE)
    
    'DACLに書き戻す
    wmiSecurityDescriptor.DACL = DictACE.Items
    
    '対象フォルダのセキュリティデスクリプタを設定する
    RetVal = wmiFileSecSetting.SetSecurityDescriptor(wmiSecurityDescriptor)
    If (RetVal <> 0) Then
      MsgBox "SetSecurityDescriptorに失敗しました:" & RetVal
      Exit Function
    End If
    SetSecurityHomeDirectory = True
End Function

最初の引数は,ドメインコントローラのサーバ名を指定する,2つめの引数はhomeフォルダが存在するサーバ名,3つめの引数はユーザID,4つめの引数はhomeフォルダのサーバ上での絶対パスを指定する。

オリジナルではサーバ名は一つ渡せばよい構造だったが,当方の場合ではドメインコントローラとファイルサーバが別物だったので引数が増えた。改造したのはその部分のみ。

セキュリティディスクリプタを取得する時には,UNCではうまく動作しなかったので,サーバ上でのローカルパス名を渡さなければならない。

ユーザの削除

削除の方は登録よりも簡単。

Sub cmdDelUsers_Click()
    Dim vID As String
    Dim iRow As Integer
    Dim ADSI As CADSI
    
    Set ADSI = New CADSI
    
    ADSI.OpenDomain "hogeserver.hogedom.local", "dc=hogedom,dc=local", "hogedom\administrator", "password"
    iRow = 2
    vID = Cells(iRow, 3)
    Do While Len(vID) > 0
        'Debug.Print vID
        ADSI.DeleteUser vID, "ou=Persons"
        RemoveFolder vID
        iRow = iRow + 1
        vID = Cells(iRow, 3)
    Loop
    Set ADSI = Nothing
End Sub

Sub RemoveFolder(AID As String)
    Dim FSO As FileSystemObject
    
    Set FSO = New FileSystemObject
    FSO.DeleteFolder "\\hogeserver\home\" & AID, True
    Set FSO = Nothing
End Sub

ユーザをドメインから削除した後に,ホームディレクトリを削除しているだけ。

 

トラックバック


URL から "-MoIyadayo" を削除してトラックバックを送信してください。
トラックバックは承認後に表示されます。