PowerShell でフォレストの信頼を作成する
※これは PowerShell Advent Calendar 2014: ATND 9 日目の記事です。
昨今進化が目覚ましく、頻繁に話題を目にするようになった PowerShell ですが、Micorosft の製品を利用/運用しているといまだ PowerShell で簡単に実行できないことがいろいろあることに気づく方も多いのではないかと思います(簡単にとい言うのはいわゆる"動詞-名詞" 形式の命名規則に基づいたコマンドレットの実行のことです)。
今回はその中のうち、フォレストの信頼を PowerShell で実行する方法を紹介しようと思います。ご存知かもしれませんが Active Directory の信頼を作成する方法としては GUI と Netdom
コマンドレットがあります。個人の観測範囲内では Netdom
すらあまり使われているのを見たことはなく GUI とスクリーン ショットのコンボを決めているのが大半かなと思います。。。
それで、まずマウスでポチポチするのはやめましょうか、と考えたときにじゃあ Netdom
を使いましょうか、と思うのですが
Netdom cannot be used to create a forest trust between two AD DS forests. To create a cross forest trust between two AD DS forests, you can either use a scripting solution or the Active Directory Domains and Trusts snap-in. (TechNet | Netdom trust)
要するにフォレスト間の信頼を作成するのに Netdom
は使えません。そんな馬鹿な、誰か反論を。ということで残念ながら現時点では PowerShell にもそれを実現するコマンドレットは存在しません。
Get-ADForest
で、実行した AD フォレストの現時点の情報を取得する→わかる。Get-ADTrust
で、実行したドメインにおける現時点の信頼されたドメイン オブジェクトの情報を取得する→わかる。Get-ADForest
があるということはNew-ADTrust
やCreate-ADTrust
で、特定のドメインもしくはフォレストの間に信頼を作成できそうなのにそういうコマンドレットがない→?!
とは言え、ないものは仕方がありません。幸い PowerShell では .NET Framework を利用できます。利用できますというか PowerShell はいわば .Net Framework アプリケーションですので、今回は不本意(?)ですがその機能を明示的に使っていきたいと思います。
まずどこからか [System.DirectoryServices.ActiveDirectory]
名前空間の Forest
クラス見つけ出します。msdn で Forest
メソッドを確認してみると CreateLocalSideOfTrustRelationship
というメンバーがあります。"Creates the local side of a trust relationship with the specified forest." と書いてあるのでちょうどよさそうです。
一応 PowerShell 上でも確認してみると
PS > $sample = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() PS > $sample | Get-Member TypeName: System.DirectoryServices.ActiveDirectory.Forest Name MemberType Definition ---- ---------- ---------- CreateLocalSideOfTrustRelationship Method void CreateLocalSideOfTrustRelationship(string targ... CreateTrustRelationship Method void CreateTrustRelationship(System.DirectoryServic... DeleteLocalSideOfTrustRelationship Method void DeleteLocalSideOfTrustRelationship(string targ... DeleteTrustRelationship Method void DeleteTrustRelationship(System.DirectoryServic... Dispose Method void Dispose(), void IDisposable.Dispose() Equals Method bool Equals(System.Object obj) FindAllDiscoverableGlobalCatalogs Method System.DirectoryServices.ActiveDirectory.GlobalCata... FindAllGlobalCatalogs Method System.DirectoryServices.ActiveDirectory.GlobalCata... FindGlobalCatalog Method System.DirectoryServices.ActiveDirectory.GlobalCata... GetAllTrustRelationships Method System.DirectoryServices.ActiveDirectory.TrustRelat... GetHashCode Method int GetHashCode() GetSelectiveAuthenticationStatus Method bool GetSelectiveAuthenticationStatus(string target... GetSidFilteringStatus Method bool GetSidFilteringStatus(string targetForestName) GetTrustRelationship Method System.DirectoryServices.ActiveDirectory.ForestTrus... GetType Method type GetType() RaiseForestFunctionality Method void RaiseForestFunctionality(System.DirectoryServi... RepairTrustRelationship Method void RepairTrustRelationship(System.DirectoryServic... SetSelectiveAuthenticationStatus Method void SetSelectiveAuthenticationStatus(string target... SetSidFilteringStatus Method void SetSidFilteringStatus(string targetForestName,... ToString Method string ToString() UpdateLocalSideOfTrustRelationship Method void UpdateLocalSideOfTrustRelationship(string targ... UpdateTrustRelationship Method void UpdateTrustRelationship(System.DirectoryServic... VerifyOutboundTrustRelationship Method void VerifyOutboundTrustRelationship(string targetF... VerifyTrustRelationship Method void VerifyTrustRelationship(System.DirectoryServic... ApplicationPartitions Property System.DirectoryServices.ActiveDirectory.Applicatio... Domains Property System.DirectoryServices.ActiveDirectory.DomainColl... ForestMode Property System.DirectoryServices.ActiveDirectory.ForestMode... GlobalCatalogs Property System.DirectoryServices.ActiveDirectory.GlobalCata... Name Property string Name {get;} NamingRoleOwner Property System.DirectoryServices.ActiveDirectory.DomainCont... RootDomain Property System.DirectoryServices.ActiveDirectory.Domain Roo... Schema Property System.DirectoryServices.ActiveDirectory.ActiveDire... SchemaRoleOwner Property System.DirectoryServices.ActiveDirectory.DomainCont... Sites Property System.DirectoryServices.ActiveDirectory.ReadOnlySi...
大丈夫そうです。ちょっと途切れてしまっていますが、Syntax
は CreateLocalSideOfTrustRelationship(string targetForestName,TrustDirection direction,string trustPassword)
となっていますので、例えば一方向:出力の信頼を作成する場合、
$TargetForestName = "Domain.Name" $TrustPassword = "H0gehQ83" $TrustDirection = "Outbound" $Forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() $Forest.CreateLocalSideOfTrustRelationship($TargetForestName,$TrustDirection,$TrustPassword)
という、なんともすっきりしないコマンドレットを実行することで信頼の作成が可能です。本当に構成ができているのか確認もしておきたいですよね。では、GUI における [検証] ボタンを押すのと同じように検証をしてみます。
PS > $forest.VerifyOutboundTrustRelationship($TargetForestName) PS >
何も出力されません。これで大丈夫なのですが、念のため誤ったドメイン名を変数に入力するとこのようなエラーになります。
PS > $fakeTargetForestName = "contoso.com" PS > $forest.VerifyOutboundTrustRelationship($fakeTargetForestName) Exception calling "VerifyOutboundTrustRelationship" with "1" argument(s): "A forest trust relationship does not exist between "Domain.Name" and "contoso.com"." At line:1 char:1 + $forest.VerifyOutboundTrustRelationship($fakeTargetForestName) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ActiveDirectoryObjectNotFoundException PS >
このように出力されると信頼の作成に失敗していることがよくわかります()一応、信頼の作成ができている状態だと Get-ADTrust
のような形で現在構成されている信頼関係から状態を確認することもできますので、確認してみてもいいのではないでしょうか。こんな感じですね。
PS > Get-ADTrust -Filter * | Format-Table -Property Direction,Name,ObjectClass,TrustAttributes -AutoSize Direction Name ObjectClass TrustAttributes --------- ---- ----------- --------------- Outbound Domain.Name trustedDomain 8 Outbound hogehoge.tokyo trustedDomain 4
ちなみに今回の記事を書くベースになった Automate Forest trust creation に記載がある通り、双方のフォレストの管理者権限をもつアカウントの情報を持っている場合は PowerShell においてもまたちょっと違った方法で信頼を作成する形となります(内容自体は GUI で実施するときと同じです)。