如何查找(並移除)Active Directory 中的未鏈接 GPOS

隨著組織的發展,Active Directory (AD) 環境和群組原則 (GP) 基礎設施也會隨之擴大。群組原則物件 (GPOs) 可能很快變得難以管理,不知不覺間,你的環境中可能有數十個未連結的 GPOs。讓我們來改變這種情況。

在本教程中,你將學習如何使用群組原則管理控制台 (GPMC) 和 PowerShell 發現所有這些未連結的 GPOs。

讓我們開始吧!

先決條件

本文將是一個帶有實際示例的教程。如果你想跟著做,請確保你擁有:

  • 一個 Active Directory 域。本文將使用一個名為 HomeLab.Local 的域。
  • A Windows computer joined to the AD domain. This tutorial will use Windows 10.
  • Windows 電腦已經安裝了遠程服務器管理工具 (RSAT) 套件。

未連結的 GPOs 來自哪裡?

當您創建一個GPO並定義了所有要應用於客戶電腦的設置時,該GPO實際上並沒有做任何事情。要實際影響客戶電腦,GPO必須與AD組織單元(OU)

隨著時間的推移,越來越多的管理員創建GPO,忘記關聯它們,取消OU上的GPO,打算刪除它們但從未執行,無用的GPO可能會不斷增加。特別是在大型組織中,未關聯的GPO可能會增加到數百個,如果不進行適當維護的話。

在GPMC中查找未關聯的GPO

您可以通過兩種方式之一找到未關聯的GPO;通過GPMC或通過PowerShell。如果您只有一小部分未關聯的GPO,使用GPMC可能比創建PowerShell腳本更合適。

通過GPMC查找未關聯的GPO:

1. 通過在開始菜單中輸入“group policy management”來打開GPMC。當GPMC程序出現時,打開它。

2. 在GPMC中,進入Forest:<您的林名 —> Domains —> <您的域名>,右鍵點擊域名並點擊Search。這將彈出Search for Group Policy Objects對話框。

Search option in GPMC console

3. 點擊 搜尋項目 下拉選單並選擇 GPO 連結。此搜尋項目將搜尋與 OU 連結的 GPO。將 條件 下拉選單更改為 存在於,並將網域設定為您的網域。

在下面的截圖中,這些設定的組合將搜尋所有連結至至少一個 OU 的 GPO,網域為 homelab.local

完成後,點擊 新增 以添加條件。它將顯示在 所有搜尋條件 區域下。

Adding search item in “Search for Group Policy Objects” window

4. 現在,點擊 搜尋 按鈕以找到符合搜尋條件的所有 GPO。

using search option in “Search for Group Policy Objects” window

5. 如下面的截圖所示,搜尋結果中只顯示連結的 GPO。

Search results for linked GPOs

6. 要找到未連結的 GPO,現在需要手動將所有 GPO 與連結的 GPO 進行比較,如下面的截圖所示。在下面的截圖中,只有三個 GPO 是連結的。通過查看 群組策略物件 節點下的 GPO,您可以看到兩個 GPO 未顯示(UnlinkedGPO1 和 UnlinkedGPO2)。這意味著它們未連結。

這個任務將耗費大量時間,接下來您將看到如何通過 PowerShell 執行此任務。

Comparing search results with all the Group Policy Objects

當 GPO 被分配給像 OU 這樣的 AD 物件時,連結的 GPO 將具有連結,如下圖所示。如果您只有少數 GPO,您可以尋找具有連結的 GPO 和沒有連結的 GPO。沒有連結的 GPO 是未連結的 GPO。

Displaying linked GPO

使用 PowerShell 尋找未連結的 GPO

在 GPMC 中搜索 GPO 可能對於一些 GPO 有效,但如果您有數百或數千個 GPO 來管理數千個端點,您將會遇到困難。在這種情況下,是時候自動化這個過程並建立一個方便的 PowerShell 工具了。

假設您正在使用已安裝 RSAT 的本地域組加入的 Windows PC:

1. 打開 Windows PowerShell 控制台。

2. 導入 GroupPolicy 模組。GroupPolicy 模組隨 RSAT 一起提供,應已安裝在您的系統上。此模組包含在 PowerShell 中處理 GPO 所需的所有命令。

Import-Module GroupPolicy

3. 使用 所有 參數運行 Get-GPO PowerShell cmdlet。此 cmdlet 查詢 AD 並返回找到的所有 GPO。

Get-GPO -All
Get-Gpo cmdlet output

4. 現在,您可以查詢域中的所有 GPO,現在您必須找出哪些是未鏈接的。為此,運行 Get-GPOReport cmdlet。此 cmdlet 允許您提供一個名稱和一種輸出類型以返回。

Get-GPOReport -Name SomeGPO -ReportType XML

手動複製並粘貼上一步找到的其中一個 GPO 名稱,然後運行此命令。您將看到該 cmdlet 返回 GPO 具有的所有設置的 XML 報告。特別注意名為 LinksTo 的部分,如下所示。此部分包含代表其鏈接到的 OU 路徑的 SOMPath XML 節點。

Sample output containing LinksTo section

Get-GPOReport cmdlet 只能一次獲取一個 GPO 的報告。 這個 cmdlet 只包括來自域的搜索結果,而不包括來自 AD 站點。

5. 現在你知道如何使用 Get-GPO 找到所有 GPO 以及使用 Get-GPOReport 命令發現它們所連結到的內容,把它們結合起來,通過在控制台中複製並粘貼以下 PowerShell 命令。

以下命令查詢域中的所有 GPO (Get-GPO),然後為每個 GPO 生成一個 XML 報告 (Get-GPOReport),只允許報告中不包含 <LinksTo> 字符串的 GPO (Select-String) 返回。

Get-GPO -All | Where-Object {
     $_ | Get-GPOReport -ReportType XML | Select-String -NotMatch "<LinksTo>"
 }

在本教程的環境中,您可以在下面的示例中看到 UnlinkedGPO1UnlinkedGPO2 沒有與任何 OU 連結。

Listing out unlinked GPO in the domain

構建一個未連結 GPO 的 PowerShell 工具

現在,讓我們將您學到的一切都放在一起,並構建一個您在現實世界中可能使用的 PowerShell 腳本。

1. 打開您喜歡的代碼編輯器,並將以下 PowerShell 腳本複製/粘貼到其中。 將腳本保存為 Remove-UnlinkedGPO.ps1。 此腳本:

  • 創建一個帶有當前日期的文件夾,以存儲未連結的 GPO 報告。
  • 查找 AD 中所有未連結的 GPO。
  • 為每個未連結的 GPO 創建一個 HTML 報告並保存到磁盤。
  • 創建並附加到一個文本文件中所有未連結的 GPO 列表。
  • 使用 Remove-GPO 命令確認步驟刪除每個未連結的 GPO。

您也可以通过 GitHub 下载 Remove-UnlinkedGPO.ps1 脚本。

Import-Module GroupPolicy
 $Date = Get-Date -Format dd_MM_yyyy
 $BackupDir = "c:\GPOBackup\$Date"
## 创建一个目录来存储 GPO 报告
 if (-Not(Test-Path -Path $BackupDir))  {
   New-Item -ItemType Directory $BackupDir -Force
 }
# 获取所有以 XML 为 GPO 报告类型的 GPO,并查找 XML 报告中的 section 部分。
# 只考虑没有 section 部分的 GPO。
 Get-GPO -All | Where-Object { $_ | Get-GPOReport -ReportType XML | Select-String -NotMatch "<LinksTo>" } | ForEach-Object {
   # 备份 GPO、HTML 报告并将 GPO 详细信息保存到文本文件是可选的。
   Backup-GPO -Name $_.DisplayName -Path $BackupDir
    # 运行报告并将其保存为 HTML 报告到磁盘
   Get-GPOReport -Name $_.DisplayName -ReportType Html -Path "$BackupDir\$($_.DisplayName).html"
   # 在备份文件夹中创建并追加到名为 UnlinkedGPOs.txt 的文本文件中
   # 包含 Get-GPO 返回的每个 GPO 对象的内容
   $_ | Select-Object * | Out-File "$BackupDir\UnLinkedGPOs.txt" -Append
   # 移除 GPO,但在移除之前先提示
   $_.Displayname | Remove-GPO -Confirm
 }

2. 执行 Remove-UnlinkedGPO.ps1 脚本。

3. 如果发现未关联的 GPO,则脚本将提示您移除它。此提示来自于使用 Remove-GPO cmdlet 和 Confirm 开关。要确认移除单个 GPO,请点击 Yes;否则,请点击 Yes to All 以移除所有未关联的 GPO,无需进一步确认。

GPO deletion confirmation prompt

脚本完成后,如果找到至少一个未关联的 GPO,在 C:\GPOBackup\<date> 文件夹中,您应该会看到 GPO 内容作为 GUID 文件夹,以及 HTML 报告和 UnlinkedGPOs.txt 文件。

Displaying Backup Folder

4. 现在,用浏览器打开其中一个 GPO HTML 报告。您可以看到报告包含该 GPO 中定义的所有设置。在下面的示例中,UnlinkedGPO1 GPO 包含 PowerShell 执行策略的设置。

GPO HTML report

5. 最后,打开 UnlinkedGPOs.txt 文件。您将看到它包含与 Get-GPO cmdlet 接收到的相同输出。

UnlinkedGPOs.txt GPO listing

结论

您现在应该知道如何使用 GPMC 和 PowerShell 在您的 AD 环境中找到所有未关联的 GPO。

您更偏向哪种方式?您有没有想到改进 PowerShell 脚本的方法?

Source:
https://adamtheautomator.com/unlinked-gpo/