A more elegant GPO Export Script

My previous post Export All GPOs in a domain to XML or HTML gets hit quite frequently, and today I had need to use the script so I took a bit more time to refine it.

Now instead of having to run two separate scripts, it has been consolidated to one, and the following features have been added:

  1. Pop up explorer to select export location
  2. exports a csv list of all of the GPOs
  3. sanitizes GPO names that contain forward or back slashes and replaces these characters with hyphens
  4. puts a subfolder for HTML and a subfolder for XML in the export location specified
  5. Utilizes transcript to a text log in the export location
  6. zips both folders, log, and csv into an archive for easy upload/download
  7. has a confirmation button that the script completed with the export location on script completion.

In the end, the selected export folder will contain the following:

  1. A folder called “HTML” with an individual HTML export of each group policy in the domain
  2. A folder called “XML” with an individual XML export of each group policy in the domain
  3. A text file that includes the transcript of the powershell session
  4. A csv that includes a list of all the GPOs found
  5. A zip file of all of the above

##prompt user to select a folder for exports
$Shell = New-Object -ComObject "WScript.Shell"
$Button = $Shell.Popup("Please select a folder to store exported reports.", 0, "Completed", 0)
Add-Type -AssemblyName System.Windows.Forms
$browser = New-Object System.Windows.Forms.FolderBrowserDialog
$null = $browser.ShowDialog()
$rootpath = $browser.SelectedPath

##define export paths for all outputs
$gpolist = Join-Path -path $rootpath -ChildPath "GPO-list.csv"
$logfile = Join-Path -path $rootpath -ChildPath "GPO-Export-Log.txt"
$HTMLfolderpath = join-path $rootpath HTML
$XMLfolderpath = join-path $rootpath XML

##start logging
Start-transcript -path $logfile

##check for folders, create if they don't exist
if(!(Test-path -PathType Container $htmlfolderpath))
{
    write-host "creating HTML Export Directory" -ForegroundColor DarkGreen -BackgroundColor Black
    start-sleep -seconds 2
    New-item -ItemType Directory -path $HTMLfolderpath
}

if(!(Test-path -PathType Container $XMLfolderpath))
{
    write-host "creating XML Export Directory" -ForegroundColor DarkGreen -BackgroundColor Black
    start-sleep -seconds 2
    New-item -ItemType Directory -path $XMLfolderpath
}

#get list of GPOS and exports as CSV
write-host "Getting List of GPOs"
start-sleep -seconds 2
$AllGpos = get-gpo -all
$AllGpos | Export-Csv $gpolist

##iterate through GPOS to export reports
ForEach($g in $AllGpos)
{
    $filename = $g.DisplayName
    ##replaces backslashes and forward slashes with hyphens
    $filename = $filename -replace '\\', '-'
    $filename = $filename -replace '/', '-'
    write-host "exporting reports for GPO $filename" -ForegroundColor DarkGreen -BackgroundColor Black
    $HTMLfullpath = join-path -path $HTMLfolderpath -childpath $filename
    $HTMLGpo = Get-GPOReport -reporttype html -guid $g.Id -path $HTMLfullpath
    $XMLfullpath = join-path -path $XMLfolderpath -childpath  $filename
    $XMLGpo = Get-GPOReport -reporttype xml -guid $g.Id -path $XMLfullpath

}

##add HTML extensions to exported HTML files
Write-host "adding extension to HTML files" -ForegroundColor DarkGreen -BackgroundColor Black
get-childitem -path $HTMLfolderpath | Rename-Item -NewName { $PSItem.Name + ".html" }

##add XML extensions to exported XML files
Write-host "adding extension to XML files" -ForegroundColor DarkGreen -BackgroundColor Black
get-childitem -path $XMLfolderpath | Rename-Item -NewName { $PSItem.Name + ".xml" }

##stop logging
Stop-transcript

##zip all results into export folder
Write-host "zipping results" -ForegroundColor DarkGreen -BackgroundColor Black
$zipfile = $rootpath + "\allGPOs.zip"
compress-archive -path $rootpath -DestinationPath $zipfile

##prompt user that export is completed
Write-host "Completed Export" -ForegroundColor DarkGreen -BackgroundColor Black
$Shell = New-Object -ComObject "WScript.Shell"
$Button = $Shell.Popup("Export Completed to $rootpath. Click OK to Exit.", 0, "Completed", 0)




Export All GPOs in a domain to XML or HTML

EDIT 8/28/2024: I have updated this script and it is available at A more elegant GPO Export Script

Not a lot of exposition on this one.

I have a client that has 100+ Group Policy Objects that I wanted to export. Now in the time I was developing a way to automatically do this, I probably could have right clicked each and exported, but that’s no fun and I can use this script in the future.

General Script Notes

  1. Change $folderpath variable to an existing folder path, this script will not create the folder structure, but if you want to add that, feel free
  2. the last line will go through this entire folder and rename with a new file extension, xml or html, depending on which script you are running. Please use a clean and empty folder for this. If there is anything else in the folder, it will get the filetype changed!

Powershell script to export all GPOs to XML

$folderpath = "C:\path\to\existing\folder\"
$AllGpos = get-gpo -all
ForEach($g in $AllGpos)
{
    $filename = $g.DisplayName
    $fullpath = join-path -path $folderpath -ChildPath $filename
    $Gpo = Get-GPOReport -reporttype xml -guid $g.Id -path $fullpath

}

get-childitem -path $folderpath | Rename-Item -NewName { $PSItem.Name + ".xml" }

Powershell script to export all GPOs to HTML

$folderpath = "C:\path\to\existing\folder\"
$AllGpos = get-gpo -all
ForEach($g in $AllGpos)
{
    $filename = $g.DisplayName
    $fullpath = join-path -path $folderpath -ChildPath $filename
    $Gpo = Get-GPOReport -reporttype html -guid $g.Id -path $fullpath

}

get-childitem -path $folderpath | Rename-Item -NewName { $PSItem.Name + ".html" }

That’s all for today!