• 【Management】Active Directory Recycle Bin(ゴミ箱)を PowerGUI から操作

    TechEdを明日に控え、そろそろ新宿から横浜に移動しようかなと思っていた矢先、こんなツールがリリースされていることを発見してしまいました…。

    Active Directory Recycle Bin PowerPack
    http://www.powergui.org/entry.jspa?externalID=2461&categoryID=21

    おなじみ、Quest Software 社PowerGUI 上で動作する Active Directory Recycle Bin用管理パックです。

    いやー仕事が早いですね…さすがです。

    Active Directory Recycle Bin は、ご存じのとおり、Windows Server 2008 R2 からサポートされたActive Directoryのゴミ箱です。これまで難しかった、間違えて削除してしまったオブジェクトを簡単に復元することができます。

    が!難点が1つ。標準ではGUIが無いんです…。

    そんな悩みを解決するのが、この Active Directory Recycle Bin PowerPack + PowerGUI です。

    せっかくですので、ちょっと使ってみましょう。

    【セットアップ】

    事前に、以下のソフトをセットアップしておく必要があります。

    PowerGUIのインストール時、Active Directoryライブラリをインストールすることを忘れないでください。

    powergui01

    PowerGUIを動作させるのが Win7またはVistaの場合には、RSATのインストールが必要です。

      • Microsoft RSAT(Remote Server Administraton Tools)(Win7用 or Vista用

    加えて、Active Directory Recycle Bin PowerPack をダウンロードして保存しておきます。
    http://www.powergui.org/entry.jspa?externalID=2461&categoryID=21

    なお、ダウンロード後の拡張子がXMLになってしまう場合には、.PowerPack に変更しておいてください。

     【PowerPackの読み込み】

    スタートメニューから PowerGUI を起動します。Script Editorじゃないので注意してください。

    [ファイル]メニューから[PowerPack Management]を選択して開いたダイアログボックスで、[インポート]ボタンをクリックしてください。

    事前にダウンロードしておいた 「ActiveDirectoryRecycleBin.powerpack」を選択してインポートします。

    インポートが成功すると、以下のようにManagementPackが追加されます。

    image

    【Active Directory ライブラリの有効化】

    [ファイル]-[PowerShell ライブラリ]で、「Active Directory」を有効化します。image

    ここまで行って PowerGUIを再起動すれば準備完了です。

    【使ってみる】

    では使ってみます。

    PowerGUIを起動し、左側のノードにある「Active Directory Recycle Bin」をクリックしてください。

    Recycle Binが有効でない場合には、以下のようなメッセージが表示されます。

    powergui02

    Recycle Binにオブジェクトが存在すると、以下のように表示されます。

     image

    削除済オブジェクトを選択し、右側のアクションメニューから「Restore」を選択すれば元の場所に戻ります。

    Restore(recoursive)を使用すれば、OUやコンテナなどの階層構造も一度に復元することができます。

    いかがでしょう。すばらしいツールですね。

    感動して涙が出てきました。

  • 【Management】JoinDomainOrWorkGroup メソッドでドメインに参加させる

    前回、以下の投稿をしました。

    【Management】DMZでのドメイン参加はオフラインドメインジョインで!

    オフライン ドメイン ジョイン 機能を使用することで、書き込み可能なドメインコントローラーと通信することなくドメインに参加させることができます。

    ただ、難点があります。それは、Windows Server 2008 R2 および Windows 7でないと djoinコマンドが使えないということ…。

    じゃ、それ以前のクライアントをRODC環境のドメインに参加させるにはどうしたらよいでしょうか。

    WMIの Win32_ComputerSystem クラスには、JoinDomainOrWorkGroup メソッドが実装されています。でもって、なんと、このメソッドには NETSETUP_JOIN_READONLY = 2048 という大変魅力的な引数が用意されているのです。

    JoinDomainOrWorkgroup Method of the Win32_ComputerSystem Class
    http://msdn.microsoft.com/en-us/library/aa392154(VS.85).aspx

    つまり、きちんと事前に準備を行い、このメソッドを使用したスクリプトを実行すればRODCしか無い環境であってもドメインに参加することができます。

    では手順を以下に示します。

    1)コンピューターアカウントを作成する

    Active Directory ドメインに参加させたいクライアントのコンピューターアカウントを作成します。「Active Directory ユーザーとコンピューター」を使用してもいいですし、net user ComputerName$ /add /domain net computer ComputerName /add(※ すみません間違えました。緒方さんご指摘ありがとうございました!)でも問題ありません。net user コマンドを使用する場合には、コンピュータ名の最後に「$」をつけることを忘れないでください。

    2)コンピューターアカウントのパスワードを設定する

    普段、あまりやらない作業ですが、大した処理ではありません。以下のようにコマンドラインから実行します。ユーザーのパスワードを設定するときと同じです。

    net user ComputerName$ PASSWORD

    3)コンピューターを「Allowed Password Replication Group」グループに所属させる

    Allowed Password Replication Group に所属ているメンバー(ユーザーやコンピューター)は、RODCにパスワードをキャッシュさせることができます。逆に、このグループに所属していないアカウントはRODCにパスワードがキャッシュされません。

    コンピューターアカウントは自分が通信するドメインコントローラにパスワードが保存されている必要があります。なぜならば、定期的にドメインコントローラと通信してパスワードのリセットを行うからです。

    ちなみに、「Allowed Password Replication Group」は既定のグループなので、安全性を高めるには別のグループを作成してパスワードキャッシュを有効にしておくとよいです。

    4)パスワードを同期する

    Allowed Password Replication Group に所属しているアカウントがRODCにパスワードをキャッシュするタイミングは、最初に認証を行った時です。よって、グループに所属しただけだとパスワードはキャッシュされません。

    そこで、[Active Directory ユーザーとコンピュータ]を使用して、[RODCのプロパティ]-[パスワード レプリケーション ポリシー]-[詳細設定]-[パスワードの事前配布] からパスワードキャッシュを手動で行っておきます。

    5)スクリプトを作成する

    JoinDomainOrWorkGroup メソッドを使ってドメインに参加するためのスクリプトを作成します。

    サンプルスクリプト(実際に私が検証したスクリプトなので使えるはずです)を以下に掲載しておきますので、拡張子 vbs で保存してください。

    RODC環境でドメインに参加させるスクリプト
    http://blogs.technet.com/junichia/pages/3276197.aspx

    6)スクリプトを実行する

    スクリプトを参加させたいクライアントに保存し、以下のようにコマンドを入力します。
    ※JoinDomain.vbs というファイル名で保存したとします

    c:\> joindomain.vbs /domain <DomainName> /machinepassword <PASSWORD> /readonly
    • DomainName :参加したいドメイン名
    • PASSWORD:コンピューターに設定したパスワード

    /readonly を付加することを忘れないでください。これを指定すると、JoinDomainOrWorkGroup メソッドに「NETSETUP_JOIN_READONLY = 2048」が渡されるようになっています。

    実行結果例を以下に示します。

    image

    うまくいけば、上の図のように「Welcome to the domain:ドメイン名」と表示されます。

  • RODC環境でドメインに参加させるスクリプト

    RODC環境でドメインに参加するためのスクリプト

    実行書式は以下の通り。/readonly を忘れずに。

    c:\> joindomain.vbs /domain <domainname> /mchinepassword <事前に設定したコンピューターのパスワード> /readonly

    ----------------------------------------------------------------------------------------- 

    ' JoinScript.vbs
    '
    '     Script to join a computer to a domain.
    '    
    '
    '

    sub Usage
       wscript.echo " |------------------------------------------------|"
       wscript.echo " |   Joins a computer to a domain or workgroup    |"
       wscript.echo " |------------------------------------------------|"
       wscript.echo ""
       wscript.echo "Usage: "
       wscript.echo " cscript JoinScript.vbs [/domain <domainname> | /workgroup <workgroupname>]"
       wscript.echo "                        [/unjoin] [user <username>] [/password <password>]"
       wscript.echo "                        [/machinepassword <password>] [/readonly] [/createaccount]"
       wscript.echo "                        [/unsecure]"
       wscript.echo ""
       wscript.echo "domain           Specifies the name of a domain to join"
       wscript.echo "                 This option requires user, password"
       wscript.echo ""
       wscript.echo "workgroup        Specifies the name of a workgroup to join"
       wscript.echo ""
       wscript.echo "unjoin           Unjoin from a domain if currently joined."
       wscript.echo ""
       wscript.echo "disable          Disable the account when unjoining the domain."
       wscript.echo "                 This option requires unjoin, user, and password."
       wscript.echo ""
       wscript.echo "createaccount    Specifies to create the computer account in AD"
       wscript.echo ""
       wscript.echo "machinepassword  Specifies a password which is used to"
       wscript.echo "                 authenticate as the machine account to the DC"
       wscript.echo ""
       wscript.echo "readonly         Specifies the domain join will be read only"
       wscript.echo "                 and will not require a writable DC. This option" 
       wscript.echo "                 requires machinepassword and that an Administrator"
       wscript.echo "                 has pre-created the computer account and set a"
       wscript.echo "                 password matching the machinepassword parameter."
       wscript.echo ""
       wscript.echo "DC               Specifies a DC to use during domain join."
       wscript.echo "                 If readonly is specified this is mandatory, otherwise optional."
       wscript.echo ""
       wscript.echo "OU               Specifies an OU where the machine account is created, this is optional."
       wscript.echo ""
       wscript.echo ""
       wscript.echo "Unsecure         Specifies a an unsecure domain join."
       wscript.echo ""
       wscript.echo " |------------------------------------------------|"
       wscript.echo " |Examples: Run 'cscript JoinScript.vbs <args>'   |"
       wscript.echo " |          <args>: Choose a scenario below       |"
       wscript.echo " | * Note lines have been wrapped for readability |"
       wscript.echo " |------------------------------------------------|"
       wscript.echo ""
       wscript.echo "  Join domain: /domain <domainname> /user <username>"
       wscript.echo "               /password <password> /createaccount"
       wscript.echo ""
       wscript.echo "  Join domain with existing account: /domain <domainname>"
       wscript.echo "                                     /user <username>"
       wscript.echo "                                     /password <password>"
       wscript.echo ""
       wscript.echo "  Unjoin from a domain: /unjoin /user <username> /password <password>"
       wscript.echo "                        "
       wscript.echo ""
       wscript.echo "  Read Only join domain: /domain <domainname> /machinepassword <password>"
       wscript.echo "                         /dc <rodcname> /readonly"
       wscript.echo ""
       wscript.echo "  Join workgroup: /workgroup <workgroupname>"
       wscript.echo ""
       wscript.echo ""
       wscript.quit -1
    end sub


    '
    ' Get the command line arguments
    '
    Set Args = Wscript.Arguments
    'Set ArgCount = Args.Count

    ' Validation and Usage
    if Args.Count = 0 then
       wscript.echo "Help Requested"
       wscript.echo ""
       Usage
    end if

    if Args.Count > 0 then
       if Args(0) = "/?" or Args(0) = "-?" or Args(0) = "help" then
          wscript.echo "Help Requested"
          wscript.echo ""
          Usage
       end if
       if Args.Count < 1 then
          wscript.echo "Help Requested"
          wscript.echo ""
          Usage
       end if
    end if


    ' NetJoinDomain flags
    Const NETSETUP_JOIN_DOMAIN = 1
    Const NETSETUP_ACCT_CREATE = 2
    Const NETSETUP_ACCT_DELETE = 4
    Const NETSETUP_WIN9X_UPGRADE = 16
    Const NETSETUP_DOMAIN_JOIN_IF_JOINED = 32
    Const NETSETUP_JOIN_UNSECURE = 64
    Const NETSETUP_MACHINE_PWD_PASSED = 128
    Const NETSETUP_DEFER_SPN_SET = 256
    Const NETSETUP_JOIN_READONLY = 2048
    Const NETSETUP_INSTALL_INVOCATION = 262144

    ' Local state to track limited parameter validation
    Options = 0
    ReadOnly = 0
    Unsecure = 0
    JoinWorkgroup = 0
    UnjoinDomain = 0
    MachinePassword = 0

    ' Inputs for the join call
    strDC = ""
    strOU = ""
    strDomainName = ""
    strDomainNameAndDC = ""
    strPassword = ""
    strUserName = ""

    ' Collect parameters
    ArgNum = 0

    do while ArgNum < Args.Count

       if Args(ArgNum) = "/domain" or Args(ArgNum) = "/Domain" then
          strDomainName = Args(ArgNum+1)
          Options = Options + NETSETUP_JOIN_DOMAIN
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/user" or Args(ArgNum) = "/User" then
          strUserName = Args(ArgNum+1)
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/password" or Args(ArgNum) = "/Password" then
          strPassword = Args(ArgNum+1)
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/machinepassword" or Args(ArgNum) = "/MachinePassword" then
          strPassword = Args(ArgNum+1)
          MachinePassword = 1
          Options = Options + NETSETUP_MACHINE_PWD_PASSED
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/readonly" or Args(ArgNum) = "/ReadOnly" then
          Options = Options + NETSETUP_JOIN_READONLY
          ReadOnly = 1     
       end if

       if Args(ArgNum) = "/unsecure" or Args(ArgNum) = "/Unsecure" then
          Options = Options + NETSETUP_JOIN_UNSECURE
          Unsecure = 1     
       end if

       if Args(ArgNum) = "/workgroup" or Args(ArgNum) = "/WorkGroup" then
          JoinWorkgroup = 1
          strDomainName = Args(ArgNum+1)
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/dc" or Args(ArgNum) = "/DC" then
          strDC = Args(ArgNum+1)
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/ou" or Args(ArgNum) = "/OU" then
          strOU = Args(ArgNum+1)
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/unjoin" or Args(ArgNum) = "/Unjoin" then
          UnjoinDomain = 1
          ArgNum = ArgNum + 1
       end if

       if Args(ArgNum) = "/disable" or Args(ArgNum) = "/disable" then
          Disable = 1
          Options = Options + NETSETUP_ACCT_DELETE      
       end if

       if Args(ArgNum) = "/createaccount" or Args(ArgNum) = "/CreateAccount" then
          Options = Options + NETSETUP_ACCT_CREATE     
       end if

       ArgNum = ArgNum + 1


    loop             

    ' Error reporting
    if ReadOnly = 1 then
       if MachinePassword = 0 then
           wscript.echo "ReadOnly requires MachinePassword"
           wscript.quit(-1)      
       end if
    end if 

    if Disable = 1 and UnjoinDomain = 0 then
           wscript.echo "Disable is only valid with the unjoin option"
           wscript.quit(-1)      
    end if         


    ' The username is optional and may need to be NULL when passed to the join API below
    if strUserName = "" then optionAux = NULL else optionAux = strUserName

    ' The OU is optional and may need to be NULL when passed to the join API below
    if strOU = "" then optionOU = NULL else optionOU = strOU

    ' Handle the case where this is a domain join and a DC was specified
    if strDC = "" then strDomainNameAndDC = strDomainName else strDomainNameAndDC = strDomainName & "\" & strDC

    wscript.echo strDomainNameAndDC

    Set objNetwork = CreateObject("WScript.Network")
    strComputer = objNetwork.ComputerName

    Set objComputer = GetObject("winmgmts:{impersonationLevel=Impersonate}!\\" & strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" & strComputer & "'")
    'ReturnValue = objComputer.JoinDomainOrWorkGroup(strDomainName, strPassword, strDomainName & "\" & strUserName, NULL, NETSETUP_JOIN_DOMAIN + NETSETUP_JOIN_READONLY + NETSETUP_MACHINE_PWD_PASSED)

    ' Perform the join/unjoin operation
    if UnjoinDomain = 1 then
       ReturnValue = objComputer.UnjoinDomainOrWorkGroup(strPassword, optionAux, Options)
    else
       ReturnValue = objComputer.JoinDomainOrWorkGroup(strDomainNameAndDC, strPassword, optionAux, optionOU, Options)
    end if


    ' Report success messages
    if ReturnValue = 0 then
          if JoinWorkgroup = 1 then
             wscript.echo "Welcome to the workgroup: " & strDomainName
             wscript.quit(0)
          end if

          if UnjoinDomain = 1 then
             wscript.echo "The machine was unjoined from the domain."
             wscript.quit(0)
          end if

          if JoinWorkgroup = 0 then
             wscript.echo "Welcome to the domain: " & strDomainName
             wscript.quit(0)
          end if
    else
        wscript.echo "Error: " & ReturnValue
    end if

     

  • 【Management】DMZでのドメイン参加はオフラインドメインジョインで!

    たとえば、以下のような構成があるとします。

    koseizu

    上記のDMZにある AppSV(アプリケーションサーバー) はActive Directoryドメインに参加していませんが、せっかくDMZにRODCが出来たので、ドメインに参加してアカウントをActive Directoryで一元管理することにしました。

    さて、ドメインに参加するには、絶対に無視できない条件が2つあります。それは、

    • クライアントとドメインコントローラーが通信できること
    • ドメインコントローラーに書き込みができること

    です。

    AppSVと同じセグメントにはRODCがありますが、ご存じのとおりRODCには書き込むことができません。

    一方、FWの向こう側にはRWDC(書き込み可能なドメインコントローラー)がありますが、今回は、AppSVとRWDCの通信は行えないという前提で話を進めましょう。そもそもAppSVから内部ネットワーク、特にドメインコントローラにアクセスさせたくなんて無いですよね。

    つまり、上記2つの条件を全く満たしていないということになります。

    この状態でAppSVをドメインに参加させようとすると、以下のようなエラーが発生します。

    domainjoin 

    このAppSVを内部ネットワークに移動せずにドメインに参加する方法は2つあります。

    方法1:Win32_ComputerSystemクラスの JoinDomainOrWorkgrouopメソッドをする

    事前にコンピューターアカウントのパスワードを明に指定しておく必要があります。

    ※2009/08/24 追記
    本方法を使用した手順については以下をご覧ください。
    【Management】JoinDomainOrWorkGroup メソッドでドメインに参加させる

    ※恐縮なのですが、この方式、検証していません。
    メソッドの詳細は以下をご覧ください。

    JoinDomainOrWorkgroup Method of the Win32_ComputerSystem Class
    http://msdn.microsoft.com/ja-jp/library/aa392154(en-us,VS.85).aspx

    ※サンプルスクリプトを使用したDMZでのドメイン参加については以下をご覧ください(英語です…)

    Deploying RODCs in the Perimeter Network
    http://technet.microsoft.com/ja-jp/library/dd728035(WS.10).aspx


    方式2:オフライン ドメイン ジョイン機能を使用する

    クライアントがWindows 7またはWindows Server 2008 R2 であればオフライン ドメイン ジョイン(以降ODJ:Offline Domain Join)機能を使用して、ネットワークを使わないドメイン参加が可能です。

    ODJの実行イメージは以下の通りです。

    ODJ

    1)プロビジョンを行う

    既にドメインに参加しているクライアント上で以下のコマンドを実行します。

    C:\> djoin /provision /domain DOMAINNAME /machine COMPUTERNAME /savefile BLOBファイルのファイル名

    実行例を以下に示します。

    djoin_provision

    この操作によって、ドメインコントローラ上にコンピュータアカウントが作成され、参加させたいコンピュータに取り込むための「BLOBファイル」が出力されます。

    ちなみに、ここで作成したBLOBファイルとは以下のようなものです。Base64でエンコードはされていますが、暗号化された文字列ではありませんので取り扱いには注意しましょう。

    djoin_blob

    2)ドメインに参加する

    作成したBLOBファイルを、参加させたいクライアント上にコピーし、以下のコマンドを実行します。

    C:\> djoin /requestODJ /loadfile BLOBファイル名 /windowspath %Systemroot%

    実行結果例を以下に示します。

    domainjoin2 

    3)クライアントを再起動する

    あとはクライアント(今回はAppSV)を再起動すればドメイン参加は完了です。

    コンピューターアカウントのパスワード交換はRODCを介して行うことができるので、心配はいりません。

  • 【Management】RODC に DHCPサーバーをインストールするには

    RODC(Read Only Domain Controller:読み取り専用ドメインコントローラー)の最も特筆すべき特徴は、当然ながら「書き込めない」ということです。

    これにより、ドメインコントローラーの安全性がググッと高まることは間違いないのですが、「完璧にうまい話」というのは無いもので、そこにはトレードオフが発生します。

    その1例として挙げられるのが、RODC への DHCPサーバーのインストールです。

    DHCPサーバーを初めてインストールするときには、Active Directoryに以下の2つのドメインローカルグループを作成しようとします。

    • DHCP Users
    • DHCP Administrators

    ※DHCPグループの詳細は、以下を参照してください。

    DHCP グループ
    http://technet.microsoft.com/ja-jp/library/cc737716(WS.10).aspx

    この動作は RODC に DHCPサーバーをインストールしようとしたときも同様です。

    しかしながら、RODCには書き込みができないため、以下のエラーが発生します。

    dhcp01

    対策は2つあります。

    対策1)事前にRWDC側で2つのドメインローカルグループを作成しておき、RODCに複製しておく

    対策2)DHCPサーバーインストール後に2つのドメインローカルグループを作成し、RODCに複製する

    インストールが終わったら、DHCP Users と DHCP Administrators に、必要に応じてメンバーを登録します。ちなみに、ドメインやコンピューターの管理者はDHCPの管理権限も持っているので、メンバーシップを追加する必要はありません。

    それでは、よいManagement生活を!