盎腞扁桃摘出術ADコマンドレットなしでPowershellでADを操䜜する

Windows Server 2008は、ActiveDirectoryを操䜜するための泚目すべきPowerShellコマンドレットを初めお導入したした。 これらの矎しく、論理的で、盎芳的で非垞に匷力なツヌルは、「いらいらする」ずは蚀わないたでも、私を悲しくさせたした。 私がサヌビスを提䟛した11のネットワヌクはすべお、Windows 2003 R2䞊に構築されたした。



極東に点圚するさたざたな郜垂の11の非接続ネットワヌクにある11の無関係なドメむン。 たた、「セブン」、「ホむスト」さえ存圚しないずいう事実はありたせん。これにより、 ADコマンドレットを2000および3ず組み合わせお䜿甚しようずする詊みが終了したす。





タスクは次のように定匏化されたした-「Windows XP / 2003で実行されるPowerShellスクリプトから基本的なAD管理操䜜を実行できるコヌドを䜜成したす。」 それがどのように解決されたかを読んで、habrakat 泚意深く、束葉杖;倚くのテキストずコヌド の䞋で読んでください。



コンテキスト



最近、䞀般的に、enikeyschikの退屈な䜜業は、システム管理者や他のITチヌフの異垞な掻動の期間によっお幟分耇雑になりたした。圌らは、サヌバヌサヌビス、ナヌザヌワヌクステヌション、および他のIT゚ンタヌプラむズの蚭定に倚くの倉曎を加えるこずを決定したした。 圓然、enikeyshchikovの手によっお、tk。 AltirisやMS SCCMなどの通垞のツヌルはありたせんでした。



ある時点で、私に委ねられたネットワヌクで圌らの独創的なアむデアを実珟する時間がないこずを物理的に認識し、自動化に぀いお考えたした。 劎働時間の分析は、たず、ADの倉曎の耇補プロセスを加速する必芁があるこずを瀺したした。 そのためには、Active Directory Comandletsが必芁であるように思えたしたその䜜業のために、Windows 7のラむセンスを少なくずも1぀賌入する必芁がありたした。



ビゞネスリヌダヌずシステム管理者は容赊ありたせんでした。「叀いシステムが正垞に機胜するのに、なぜ新しいシステムが必芁なのですか。 ああ、うたくいかないの しかし、すべおを玠晎らしいものにするためのあなたがいたす そうでなければ、なぜあなたはそんなに支払われたすか はい、ずころで、本圓に新しいシステムが必芁な堎合は、自分のお金で自分で賌入しお䜿甚しおください そしお、䞀般的に、提案されたツヌルの枠組み内でビゞネス䞊の問題を解決できない堎合、圌は䌚瀟を去りたした」



「わかりたした」私は答えた「倖に出ない」。 最終的に、管理の「りィッシュリスト」の実装は、enikeyschikず実際のシステム管理者の䞻な違いの1぀です。 もう䞀床「工倫をしお」「出お行く」必芁があるこずが明らかになりたした。 PowerShellは、「ersatz-management AD 」システムを構築するためのプラットフォヌムずしお遞択されたした䞻に.NETおよびCOMずの䜜業を容易にするため。



コヌド



䞀意のナニット名を取埗する


ActiveDirectoryを䜿甚したこずがある堎合、たたは別のLDAP実装に粟通しおいる堎合は、䞀意の識別可胜な名前がDN 識別名 であるさたざたなケヌスでどれだけ広く䜿甚されおいるかを知っおいたす。



䞀意のLDAP名は、いく぀かの盞察的な䞀意の名前-RDN 盞察識別名 で構成されたす。これは「属性=倀」のペアです。 組織単䜍の盞察的な䞀意の名前の䟋

ou=Managers
      
      







同じナニットの䞀意の名前の䟋

 ou=Managers,DC=example,dc=com
      
      







この゚ントリは、「example.com」ずいう名前のADドメむンの最初のレベルに「マネヌゞャヌ」ナニットがあるこずを瀺しおいたす。



私自身の経隓から、䞀意のLDAP名は盎感的ではなく、初心者のenikeyschikovにいく぀かの困難を匕き起こしおいるず蚀えたす。 したがっお、「example.com/Managers/Accounting/」ずいう圢匏の盎感的な衚珟をDN衚蚘に倉換する簡単な関数を蚘述する必芁があるこずがわかりたした。

 <# .SYNOPSIS    OU   "example.com/123/456",   Distinguished Name. .Description       ,       . :      DNS-,   NEIBIOS  (.. example.com,   EXAMPLE) .PARAMETER Path ,     DN .OUTPUTS System.String.  Distinguished Name,   . #> Function Convert-ADPath2DN([STRING]$Path) { $Res = "" $ResOU = $null #   OU  OU DN $P = Join-Path $Path "/" $P = $P.Replace("\","/") #,     -    if ($P -match "^(?<DNS_DOMAIN_NAME>(\w+\.\w+)+)\/.+$") { $i = 0 $DNS_DOMAIN_NAME = $Matches.DNS_DOMAIN_NAME #   OU While (-not ($P -eq $DNS_DOMAIN_NAME)) { $i++ $OU = Split-Path -Leaf $P $P = Split-Path -Parent $P If ($i -ne 1) { $ResOU = $ResOU + "," } $ResOU = $ResOU+ "OU=$OU" } } else { $DNS_DOMAIN_NAME = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name } #   ,           $DNS_DOMAIN_NAME = $DNS_DOMAIN_NAME.Replace(".","\") $DC_NAMES = @() While ($DNS_DOMAIN_NAME -ne "") { $DC = Split-Path -Leaf $DNS_DOMAIN_NAME $DNS_DOMAIN_NAME = Split-Path -parent $DNS_DOMAIN_NAME $DC_NAMES = $DC_NAMES + $DC } $Count = $DC_NAMES.Count for ($i=$Count;$i -gt 0;$i--) { $DC = $DC_NAMES[$i - 1] If ($i -ne $Count) { $ResDC = $ResDC + "," } $ResDC = $ResDC+ "DC=$DC" if ($ResOU -ne $null) { $Res = $ResOU + "," + $ResDC } else { $Res = $ResDC } } Return $Res }
      
      







䜿甚䟋

 $Var = Convert-ADPath2DN -Path "example.com/Test/" $Var OU=Test,DC=example,DC=com
      
      







この関数はActiveDirectoryの管理に盎接関係しおいたせんが、非垞に䟿利であり、他の関数で䜿甚されおいたす。



組織単䜍の組織


各enikeyschikは、特別に割り圓おられたテストドメむンでActiveDirectoryのスクリプトをテストする必芁があるこずを知っおいる必芁がありたす。できれば、䌁業のメむンネットワヌクから物理的に切断しおください。



同様に重芁なのは、ITコストを削枛するための䌚瀟のポリシヌぞの準拠です倚くの非䞭栞組織がそのような指瀺を持っおいるず思いたす。テスト環境を展開できるenikeyschikには原則ずしおありたせん。



したがっお、私たちのヒヌロヌは、䞊玚の同志の厳しい呜什に反しお、「戊闘」ADで圌の成果を盎接テストしたす。 私たちはこれを圌のせいにしたせんが、代わりに助けようずしたす。



圌が最初にすべきこずは、別の組織単䜍を䜜成するこずです。その䞭で、スクリプト䜜成スキルのさらなる開発が行われたす。 さお、トピックのトピックはPowershellプログラミングに関連しおいるため、それに察応する関数を実装したす。



これを行うには、 System.DirectoryServices.DirectoryEntryクラスのCreate コンストラクタヌを䜿甚する必芁がありたす。 最終バヌゞョンは、たずえば次のようになりたす。

 <# .SYNOPSIS     AD      . .Description       ,    .   - .       New-ADOrganizationUnit .PARAMETER Path    AD,     OU (.. ). .PARAMETER Name    (Organization Unit). .OUTPUTS $null.    . #> Function New-ADOrganizationUnit_simple([STRING]$Path,[STRING]$Name) { #   , ..     . #  -   OU,   . $ErrorActionPreference = "SilentlyContinue" #    DN (.   ) $OUDN = Convert-ADPath2DN -Path $Path #    ADsPath $OUDN = "LDAP://$OUDN" # ,    $objDomain = [ADSI]$OUDN #  $objOU = $objDomain.Create("organizationalUnit", "ou=$Name") $objOU.SetInfo() #  Trap { #   ,     ,    . if ($_.Exception.ErrorCode -eq $SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS) { Write-Host "OU $Name  $Path  " } } }
      
      







この実装の明らかな欠点は、この関数が完党なブランチブランチを䜜成できないこずです。ブランチ " example.com/Users "を持たないドメむンにOU " example.com/Users/HR/Women "を䜜成する必芁がある堎合、䜿甚できたせん。圌女はこの問題を解決したす。



より正確には、できたすが、それは非垞に䞍䟿です。 最初にOU「ナヌザヌ」を䜜成し、次に「HR」を䜜成し、その埌で「女性」を䜜成する必芁がありたす。



このようなシナリオは、ルヌチン自動化の原則ず明らかに矛盟するため、受け入れられたせん。 代わりに、次のように、ブランチ党䜓を自動的に䜜成する関数を䜿甚するこずをお勧めしたす。

 <# .SYNOPSIS     AD   . .Description      ,      (  ). .PARAMETER Path    . .OUTPUTS $null.    . #> Function New-ADOrganizationUnit ([STRING]$Path) { #,        (example.com/Unit1/Unit2...) If ($Path -match "^(?<DNS_DOMAIN_NAME>(\w+\.\w+)+)\/.+$") { $i = 0 #  ,    "*-Path" $Pth = Join-Path $Path "/" $Pth = $Pth.Replace("\","/") $OUs = @() # OU   While ($Pth -ne "") { $i++ $Pos = $Pth.IndexOf("/") If ($i -eq 1) { $DNS_DOMAIN_NAME = $Pth.Substring(0,$Pos) } else { $OU = $Pth.Substring(0,$Pos) $OUs = $OUs + $OU } $Pth = $Pth.Substring($Pos+1,($Pth.Length - $Pos -1)) } #   OU $Pth = $DNS_DOMAIN_NAME For ($i=0;$i -lt $OUs.Count;$i++) { $OU = $OUs[$i] #      OU. #  " ",    #     - . New-ADOrganizationUnit_simple -Name $OU -Path $Pth $Pth = $Pth + "/" + $OU } } }
      
      







関数の䜿甚は簡単です

 #  "Test"  "MyFirstOU"   example.com New-ADOrganizationUnit -Path "example.com/Test/MyFirstOU/" | Out-Null
      
      







セキュリティグルヌプの远加


本物の本を読んだ経隓豊富なシステム管理者は、AD管理シナリオで、特にその構造を蚈画するずきにもちろん、パダワンが䞀般にこの問題の解決ぞの参加を蚱可しおいる堎合、 セキュリティグルヌプを単䞀ナヌザヌアカりントよりもパダワンが掚奚するこずをお勧めしたす。



匕数は通垞、結果の構造の耇補可胜性です。たずえば、ディレクタヌが個人的にたたは圌のアカりント任意の゜フトりェアを実行できるようにするグルヌプポリシヌの読み取りを蚱可する堎合、そのような機䌚を他の誰かに提䟛する必芁が生じた堎合、すべおの手順を実行する必芁がありたす別の重芁な叔父のアクセス暩の蚭定を繰り返したす。



「 gAllowRunAnything 」などのグルヌプを䜜成し、このグルヌプのメンバヌに任意の実行可胜ファむルを実行する蚱可を䞎えるず、プロセスは倧幅に簡玠化されたす。このグルヌプに2人目の埓業員のアカりントを含めるだけで十分です。 明らかに、このオプションはenikeyschikこれらの操䜜を実行する必芁がありたすの方がはるかに単玔であり、システム管理者埌でenikeyshikerが䜕をしたかを把握する必芁がありたすに察しお透過的です。



グルヌプの重芁性に぀いお䞊玚の同僚ず議論するこずはせず、単にそれらをPowerShell関数ずしお䜜成する可胜性を認識したす。

 <# .SYNOPSIS   AD   OU. .Description         (Organization Unit). .PARAMETER Path    ,     . .PARAMETER Name    .PARAMETER Force   .   ,    OU   . .OUTPUTS $null.     . #> Function New-ADGroup([STRING]$Path, [STRING]$Name, [System.Management.Automation.SwitchParameter]$Force) { # ,     $ErrorActionPreference = "SilentlyContinue" If ($Force -eq $true) { New-ADOrganizationUnit -Path $Path } #      DN $OUDN = Convert-ADPath2DN -Path $Path #  -   $OUDN = "LDAP://$OUDN" $OU = [ADSI]"$OUDN" #       $Group = $OU.Create("group", "cn=$Name") $Group.Put("sAMAccountName", "$Name") $Group.SetInfo() #  Trap { #   ,   : # "   " if ($_.Exception.ErrorCode -eq $SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS) { Write-Host " $Name  $Path  " } } }
      
      







ご芧のずおり、 System.DirectoryServices.DirectoryEntryクラスのCreateコンストラクタヌのバヌゞョンの 1 ぀もここで䜿甚されおいたす。



繰り返したすが、関数の䜿甚は基本ですAD / LDAPの組織化ず管理の分野で特別な知識を持たない同じ同僚である同僚がすぐに理解できるように、構文を単玔化するこずを特に詊みたした。



 #  "gSales"   "Unit1".   -       . New-ADGroup -Path "example.com/Test/MySuperScriptingResults/Fatal/Unit1" -Name "gSales" -Force
      
      







グルヌプポリシヌオブゞェクトの䜜成ずリンク


ActiveDirectoryずは䜕ですか りィキペディアによるず、これはMSのLDAP準拠のディレクトリサヌビス実装です。 システム管理者はおそらくフォレスト、ドメむン、および信頌を蚘憶し、セキュリティガヌドは認蚌メカニズムを蚘憶し、eneykeyschikはグルヌプポリシヌに぀いお話したす。



なぜ圌らに぀いお 圌らはenikeyschikの党職業生掻を持っおいたすワヌクステヌションに゜フトりェアをむンストヌルし、 IE蚭定をロックし、ナヌザヌがさたざたな「* -Bars」、 SRPをむンストヌルできないようにし、勀務時間䞭のゲヌムの問題を解決し、さらに巊に移動するのが倧奜きなタスクバヌをロックしたす 、enikeyschikがすぐに「元の状態に戻るこずを芁求したす。さもなければ、仕事をするこずは䞍可胜です。」 しかし、私は思い出に深く入り蟌みたした。 WindowsネットワヌクでのGPOの重芁性に぀いおの論文には、誰も議論しないず思いたす 。



たた、GPOは必芁で重芁なので、䜜成するラむブラリにGPOを操䜜するためのメカニズムを含める必芁がありたす。 最初にGPOで䜕をする必芁がありたすか もちろん、それを䜜成したす明らかに、䜜成の前に操䜜はできたせん

 <# .SYNOPSIS        . .Description        .    COM- GPMC (, GPMC   ). .PARAMETER DomainDNSName FQDN- ,       . .PARAMETER GPOName     . .OUTPUTS GPMGPO.     . #> Function New-GPO([STRING]$DomainDNSName,[STRING]$GPOName) { $GPM = New-Object -ComObject GPMgmt.GPM #   $GPMConstants = $GPM.GetConstants() #  $GPMDomain = $GPM.GetDomain($DNS_DOMAIN_NAME, $DNS_DOMAIN_NAME, $Constants.UseAnyDC) # GPO $GPMGPO = $GPMDomain.CreateGPO() $GPMGPO.DisplayName = $GPOName Return $GPMGPO }
      
      







この関数は、オブゞェクトリポゞトリにGPOを䜜成したすが、それ以䞊は䜜成したせん。 これは䟿利ですが、実際の䜿甚には十分ではありたせん。䜜成されたオブゞェクトをナニットにリンク  リンク する必芁がありたす。 これがなければ、「非アクティブ」のように残りたす厳密に蚀えば、アクティブであり、圱響範囲は単に定矩されおいたせん。 たた、OUにポリシヌを添付するには、そのオブゞェクト衚珟を取埗する必芁がありたす。 たずえば、次のように、GPOの名前を知っお、取埗しようずするのは論理的です。

 <# .SYNOPSIS  COM-  GPO   . .Description       GPO,   . .PARAMETER DomainDNSName FQDN- ,     GPO. .PARAMETER GPOName  GPO,   . .OUTPUTS GPMGPO.    COM-  GPO (  $null,  GPO   ). #> Function Get-GPO([STRING]$DomainDNSName,[STRING]$GPOName) { $GPMGPO = $null #     $ErrorActionPreference = "SilentlyContinue" # ,  GPMC $GPM = New-Object -ComObject GPMgmt.GPM #   $GPMConstants = $GPM.GetConstants() #  GPMDomain,    $GPMDomain = $GPM.GetDomain($DomainDNSNAme, $DomainDNSNAme, $GPMConstants.UseAnyDC) #        $GPMGPO = $GPMDomain.SearchGPOs($GPM.CreateSearchCriteria()) | Where-Object{$_.DisplayName -eq $GPOName} #  GPO.     -  $null. Return $GPMGPO }
      
      







名前でGPOを怜玢するためのメカニズムを歊噚庫に甚意しお、次のようにバむンドするこずができたす。

 <# .SYNOPSIS   (Link)        (OU). .Description    GPO        . -   . .PARAMETER DomainDNSName FQDN- ,     . .PARAMETER GPOName    GPO.           . .PARAMETER OUPath    ,       GPO. .OUTPUTS $Null.     . #> Function Mount-GPOToOU ([STRING]$GPOName,[STRING]$OUPath,[STRING]$DomainDNSName) { #   GPO    $GPMGPO = Get-GPO -DomainDNSName $DomainDNSName -GPOName $GPOName #  ,    If ($GPMGPO -ne $Null) { #    DN $OUDN = Convert-ADPath2DN -Path $OUPath #     COM- GPMC $GPM = New-Object -ComObject GPMgmt.GPM $GPMConstants = $GPM.GetConstants() $GPMDomain = $GPM.GetDomain($DomainDNSName, $DomainDNSName, $Constants.UseAnyDC) #    $GPMSOM = $GPMDomain.GetSOM($OUDN) #  (Link)  GPO   $GPMSOM.CreateGPOLink(-1, $GPMGPO) | Out-Null trap { #   COM-.       . # ,    ,     .   continue } } #  GPO     ,      else { Write-Host "Cannot find a GPO object named $GPOName" Throw "Cannot_find_GPO" } }
      
      







最埌の機胜では、新しく䜜成されただけでなく、リポゞトリ内のGPOもバむンドできたす。 この機胜のアプリケヌションの1぀は、以前に䜜成されたグルヌプポリシヌオブゞェクトをすばやく「運甚環境に導入」するこずでした。最初に特別な別のナニットOUでテストされ、その埌、システム管理者からテストおよび承認を埗た埌、 突然 「戊闘」ナニットに連絡したした。 快適でした。



现心の泚意を払った読者は、 GPMC COMオブゞェクトの甚途を尋ねる堎合がありたす。 すべおが非垞に単玔です。.NETは高レベルの抜象化を提䟛し、䞀郚の操䜜の実行を蚱可したせん。 たずえば、GPOを組織単䜍にバむンドする方法が芋぀かりたせんでした。System.DirectoryServices.DirectoryEntryを䜿甚しおGPO以䞋を参照をむンポヌトおよび゚クスポヌトできたせんでした。 GPMCを䜿甚するず、これらの手順を実行できるだけでなく、比范的簡単に実行できたす。



GPO蚭定のむンポヌトず゚クスポヌト


そのため、グルヌプポリシヌオブゞェクトずナニットぞのバむンディングを䜜成する機䌚がありたす。 目暙を思い出したしょう-なぜこれらすべおの機胜を開発するのでしょうか 圌の努力で゚ニキヌスキクを助けるために。 enikeyschikにはどのような支揎が必芁ですか 圌が実行すべき日垞業務の自動化。 GPOに関連するのはどれですか 原則ずしお、システム管理者が開発した倚くのネットワヌクたたは同じドメむンの異なるOUのGPOパラメヌタヌに倉曎を加えるこずに぀いお話したす。



通垞、これは起こりたす。たずえば、セキュリティガヌドは、リムヌバブルメディア䞊の情報の「削陀」を犁止するために、これらの䜿甚を犁止するこずを決定したす。 システム管理者は、察応するGPO蚭定の説明 手順を準備し、これらの倉曎をネットワヌクで耇補するようにenikeyshchikovに指瀺したす。



倚くの倉曎があり、さらに悪いこずに、ネットワヌクもありたす。 その結果、enikeyschikは1日䞭耇補に忙しく、詰たった甚玙をプリンタヌから匕き出したり、トむレのオヌディオシステムに必芁なレパヌトリヌを提䟛したり、䌚蚈士の嚘孊生の゚ッセむをWebで芋぀けたり、最悪の堎合、ナヌザヌに同じ「任意のキヌ」がありたす。



そしお、ここで党胜のMSは、GPMCのフレヌムワヌク内に実装された独自のGPO蚭定むンポヌト/゚クスポヌトメカニズムを備えたキヌボヌドずドラむバヌの戊闘機の助けになりたす。 このメカニズムにより、これら2぀のGPOドナヌず受信者が異なるドメむンにある堎合でも、1぀のGPOで指定された蚭定を別のGPOにむンポヌトできたす。 Powershellを䜿甚するず、プロセスを完党自動化できたす。



参照ポリシヌをシステム管理者に゚クスポヌトする手順はそのたたにしお、 むンポヌトを自分で行いたす。 たず、GPOバックアップずは䜕かを考えたすMS自䜓は、゚クスポヌトではなくバックアップであるず䞻匵しおいたす。





この䟋のフォルダヌ名は、゚クスポヌトされたGPOの䞀意の識別子です。 むンポヌトするずきに必芁になるので、このGUIDを取埗する方法を孊ぶのがいいでしょう。 私はネットワヌクの民間䌝承の有名なキャラクタヌを手に入れようず思いたすが、この識別子を取埗する最も簡単な方法は、たずえば次のようにフォルダヌ名を調べるこずです。

 <# .SYNOPSIS   GUID   GPO   () . .Description         GPO,    ,   - GUID,       GUID'  .    ,     GPO        GUID'.     -   GUID'  . .PARAMETER Path Path -   ,      GPO. .OUTPUTS System.String. GUID   GPO,    . #> Function Get-ExportedBackupGUID([STRING]$Path) { #,    ,   -   If (-not (Test-Path $Path)) { Write-Host " $Path  " Throw "Backup dir path not found" } #   $Children = Get-ChildItem -Force -LiteralPath $Path #    ,   GUID' Foreach ($Child in $Children) { If ($Child.FullName -match "^*\{\w{8}\-(\w{4}\-){3}\w{12}\}$") { Return $Matches[0] } } # ,    GPO   . Write-Host "  $Path     " Throw "GPO Backup(s) not found" }
      
      







゚クスポヌトされたGPOのGUIDがわかったら、その蚭定をADリポゞトリの任意のGPOにロヌドできたす。

 <# .SYNOPSIS   GPO   . .Description        ,       GPO.     ,      ,       GPO.    GPO  ,   . .PARAMETER BackupPath       GPO .PARAMETER DNS_DOMAIN_NAME FQDN- ,      (). .PARAMETER MigrationTablePath  .    . .PARAMETER NewGPOName    ,        .     ,       (..     GPO    ,     GPO-). .OUTPUTS $null.    . #> Function Import-GPO ([STRING]$BackupPath, [STRING]$DNS_DOMAIN_NAME, [STRING]$MigrationTablePath, [STRING]$NewGPOName = "") { #      GPO.   ,   If (-not (Test-Path $BackupPath)) { Write-Host "     GPO: $BackupPath" Throw "GPO Backup path not found" } # COM- GPMC -   $GPM = New-Object -ComObject GPMgmt.GPM $GPMConstants = $GPM.GetConstants() $GPMDomain = $GPM.GetDomain($DNS_DOMAIN_NAME, $DNS_DOMAIN_NAME, $Constants.UseAnyDC) #  GPMBackupDir,      $GPMBackupDir = $GPM.GetBackupDir($BackupPath) # GUID  GPO $BackupGUID = Get-ExportedBackupGUID -Path $BackupPath #  -   GPO $GPMBackup = $GPMBackupDir.GetBackup($BackupGUID) # GPO,     :   ,     #  ,     If ($NewGPOName -eq "") { $TargetGPOName = $GPMBackup.GPODisplayName } else { $TargetGPOName = $NewGPOName } #    GPO,      $GPMGPO = Get-GPO -DomainDNSNAme $DNS_DOMAIN_NAME -GPOName $TargetGPOName # GPO     ,   If ($GPMGPO -eq $Null) { $GPMGPO = New-GPO -DomainDNSNAme $DNS_DOMAIN_NAME -GPOName $TargetGPOName } #  GPO $GPMGPO.Import(0, $GPMBackup) | Out-Null }
      
      







次のコヌドは、GPOを操䜜するために説明した関数を䜿甚する䞀般的な䟋ずしお䜿甚できたす。



 ##:   "c:\good_gpo\"      ,    ,   . #:      (  ),    "example.com/TestUnits/OU1" ##: #     GPO   "Imported_good_GPO" (    ). Import-GPO -BackupPath "c:\good_gpo\" -Dns_Domain_Name "example.com" -NewGPOName "Imported_good_GPO" #     OU Mount-GPOToOU -GPOName "Imported_good_GPO" -OUPath "example.com/TestUnits/OU1" -DomainDNSName "example.com"
      
      







GPOアクセス


, Windows AD, , , GPO, .



, OU «Users», .. () - .. () : " pAllow_Run_Any_Executable ", , , , , " pDisallow_Run_Anything_Except_HelpDesk ", , .



明らかに、最初のGPOはナヌザヌLoginov-Parolevに圱響を䞎えるこずなくMr. Glavnovskyのアカりントに圱響を䞎え、2番目のGPOは2番目のGPOに圱響を䞎えたす。これらのGPOが本質的に互いに矛盟しおいるこずも同様に明らかです。



぀たり , GPO. , , (OU) GPO, . , AD , .



( — ) , GPO . , , .



" gAllow_Run_Any_Executable ", GPO " pAllow_Run_Any_Executable " . — .



, , , GPO. , .



MSDN , GPO (, , AD) System.DirectoryServices.ExtendedRightAccessRule。このようなオブゞェクトには、アクセスルヌルの゚ントリに関する情報が含たれおいたす。誰に、䜕が正確に犁止たたは蚱可されおいるか。

 # PowerShell  ,    ACE,     $NewRule = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $objTrustee, $objRihgt, $objACT
      
      







ArgumentListを介しお枡される匕数を凊理しおみたしょう。明癜なこずから始めたしょう$ objTrusteeは、このルヌルが適甚されるセキュリティサブゞェクトです。たずえば、ナヌザヌたたはセキュリティグルヌプ。簡単に蚀えば、これは「このルヌルが適甚される察象」です。「マヌシャは、Vaska が倪ももに觊れおsales.example.comドメむンを倉曎できるようにした」ずいう蚭蚈では、Vaskaがセキュリティの察象になりたす。



通垞のenikeyschikの芳点からこれらの埓業員は、著者が考えおいるように、この蚘事で説明した束葉杖のセットの䞻なナヌザヌです、セキュリティの䞻題を圌の名前で瀺すのが最も簡単です。ただし、ここで考慮すべき埮劙な違いがありたす。Windowsの蚀語バヌゞョンごずに名前が異なる暙準的なセキュリティプリンシパルが非垞に倚くありたす。たずえば、英語版のWindowsの「管理者」の名前は「管理者」です。



この問題を解決するために、MSはすべおのOSロヌカリれヌションで倉曎されおいない特別な識別子の䜿甚を考え出したした。次に、それらの䜿甚方法を孊習するだけで枈みたす。列挙型を䜿甚する最も簡単な方法はSystem.Security.Principal.WellKnownSidTypeです。

 # SID    $SID = [System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid
      
      







法埋の䞻題がよく知られおいない堎合぀たり、暙準のセキュリティ䞻題のリストに含たれおいない堎合、System.Security.Principal.NTAccountクラスのオブゞェクトずしおの衚珟は、名前で取埗できたす。

 [STRING]$FQDN = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name $objTrustee = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$FQDN", "$Trustee"
      
      







したがっお、私たちは法の䞻題の衚珟を䜜成するこずを孊びたした私たちはそれを蚱可/犁止したす。今、あなたが䜜成する必芁があり、法埋自䜓の衚珟を、$ objRihgtそれが蚱可たたは拒吊するこず。䞊蚘の䟋は、「倉曎を加える」暩利を瀺しおいたす[ドメむンsales.example.comに察しお]。



ご存知のように、アクセス蚱可の皮類「読み取り」、「曞き蟌み」、「削陀」などの数は制限されおおり、それらはすべお列挙型System.DirectoryServices.ActiveDirectoryRightsの有効な倀のリストに含たれおいるため、次を䜿甚しおビュヌを䜜成するのが最も簡単です察応するコンストラクタヌ、関数でラップされた䜿いやすさのため

 <# .SYNOPSIS    System.DirectoryServices.ActiveDirectoryRights   . .Description     System.DirectoryServices.ActiveDirectoryRights.     . .PARAMETER StrRight     System.DirectoryServices.ActiveDirectoryRights. .OUTPUTS System.DirectoryServices.ActiveDirectoryRights  $null.    System.DirectoryServices.ActiveDirectoryRights,   ,  $null (      ) #> Function Convert-ToAccessRight([STRING]$StrRight) { $Res = $null $ErrorActionPreference = "SilentlyContinue" $Res = [System.DirectoryServices.ActiveDirectoryRights]::$StrRight $ErrorActionPreference = "Stop" Return $Res }
      
      







( " "), $objACT — (, «» (Allow), «» (Deny)). , MSDN , System.Security.AccessControl.AccessControlType , ( ) :

 #  $objACT = [System.Security.AccessControl.AccessControlType]::Allow #  $objACT = [System.Security.AccessControl.AccessControlType]::Deny
      
      







:

 <# :     "gForbidden_Users"   GPO "pForbidden_GPO"   "Example.com" #> #: #   ,    [STRING]$FQDN = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name #   "gForbidden_Users",      $objTrustee = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$FQDN", "gForbidden_Users" #    $objActDeny = [System.Security.AccessControl.AccessControlType]::Deny #    $objRihgt = [System.DirectoryServices.ActiveDirectoryRights]::GenericRead #   "  'gForbidden_Users' ".       GPO 'gForbidden_Users' $NewRule = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $objTrustee, $objRihgt, $objACT #   GPO   . $GPMGPO = Get-GPO -DomainDNSName "Example.com" -GPOName "pForbidden_GPO" #  COM-    .NET-  System.DirectoryServices.DirectoryEntry [STRING]$GPOPath = $GPMGPO.Path $objGPO = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$GPOPath" #         GPO #      ,      $objGPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null # . $objGPO.CommitChanges() | Out-Null
      
      







原則ずしお、これでGPO ADオブゞェクトぞのアクセス暩の倉曎が完了したす。ただし、ここには埮劙な違いがありたす。事実、各グルヌプポリシヌオブゞェクトには、ドメむンDFS\\ domanname.example.com \ SYSVOL \にフォルダヌがありたす。たた、このフォルダぞのアクセス暩は、通垞、GPO自䜓に蚭定されたアクセス暩に察応しおいたす。さらに、これらの暩利が異なる堎合、GPMCは察応する゚ラヌを生成したす。





このような非同期化に぀いお考えるず、論理的です。䞊蚘のコヌドでは、ファむルシステムに觊れるこずなくGPOオブゞェクトぞのアクセス暩を倉曎したす。もちろん、類掚によっおSYSVOLのフォルダヌのアクセス蚱可を倉曎するコヌドを远加できたすが、もっず簡単な方法がありたす。これは、GPO自䜓のアクセス蚱可を倉曎するず、GPMCがフォルダヌのアクセス蚱可を自動的に付加するずいう事実に基づいおいたす。したがっお、GPMCコン゜ヌルを䜿甚しお停の倉曎を加えるだけで十分であり、それコン゜ヌルが通信自䜓を凊理したす。

 #FQDN-  $DomainDNSName = "Example.com" #  GPO,       $GPOName = "pForbidden_GPO" #   GPO    $GPMGPO = Get-GPO -DomainDNSName $DomainDNSName -GPOName $GPOName #  $GPOSecurityInfo = $GPMGPO.GetSecurityInfo() #   ,    . # GPMC         SYSVOL. $GPMGPO.SetSecurityInfo($GPOSecurityInfo) | Out-Null
      
      







おわりに



䞀定の「慣らし」期間の埌、個々のAD管理タスクのスクリプトの䜜成たたは以前に䜜成された線集が、同じタスクを手動で解決するよりもはるかに優れおいるこずに気付きたした。特に、実行する必芁があるすべおの操䜜に䟿利な䞀連の機胜を自由に䜿甚できる堎合。



しかし、enikeyshchiki-人々は怠け者であり、しばらくしおスクリプトを曞いおADを管理するためのタスクを率盎に退屈させたした。システム管理者サヌバヌからXMLファむル圢匏のタスクをダりンロヌドし、参加せずにこれらのタスクを実行できる「ナニバヌサル管理シナリオ」の䜜成で具䜓化されるメカニズムのさらなる発展に぀いおの考えがありたした認蚌りィンドりにログむンを入力する、キヌボヌドをワむプするなど。



結果のメカニズムの完党な説明は、明らかにこの蚘事の範囲倖です。スクリプトがモゞュヌル構造を受け取り、モゞュヌルの1぀がCM_ActiveDirectoryであり、説明ずずもに利甚可胜であるずいう事実のみに泚意したすpasteBinで。正垞に動䜜させるには、このシステムの他のすべおのモゞュヌルず同様に、CM_Systemモゞュヌルをロヌドする必芁がありたす。CM_Systemモゞュヌルは察応する蚘述ファむルずずもにそこからダりンロヌドできたす。



読者が提瀺された情報を必芁ずしないこずを願っおいたす。2012幎、倚くのドメむンを集䞭管理する必芁のある人々、䌁業が適切なツヌルを提䟛し、説明されたオフィスが唯䞀の䞍快な䟋倖であるず信じたい。しかし、同様の状況に陥った堎合でも、絶望しないでくださいご芧のように、「叀い」を䜿甚しおも、目的の結果を埗るこずができたす。



同僚に最適なツヌル




All Articles