Hilfestellung PowerShell Script
Hi zusammen,
ich würde gerne folgendes erreichen. Über ein PowerShell Script möchte ich GPOs in Massen im- und exportieren können, sowie nicht verlinkte GPOs löschen. Mit meinem PowerShell Script kann ich sowohl Exportieren als auch Löschen, aber das Importieren klappt einfach nicht.
Ich habe einen Stammordner der den Namen der GPO trägt, wonach auch eine importierte GPO dann benannt werden soll.
In diesem Stammordner gibt es einen Unterordner, der vermutlich nach der ID der GPO benannt ist, da der einen kryptischen Namen hat. Innerhalb des Unterordner befindet sich dann die Backup.xml. Diese Backup.xml ist der Grund warum ich nicht importieren kann, da das Script diese Datei nicht findet. Ich habe vieles probiert und auch rekursiv als Parameter mit angegeben, damit er auch die Unterordner durchsucht, aber es funktioniert einfach nicht.
So bin ich nun auf euer Schwarmwissen angewiesen. Anbei mein Script, vielleicht findet sich ja jemand, der den Fehler findet oder mir zumindestens eine Hilfestellung geben kann.
Quacksalber
ich würde gerne folgendes erreichen. Über ein PowerShell Script möchte ich GPOs in Massen im- und exportieren können, sowie nicht verlinkte GPOs löschen. Mit meinem PowerShell Script kann ich sowohl Exportieren als auch Löschen, aber das Importieren klappt einfach nicht.
Ich habe einen Stammordner der den Namen der GPO trägt, wonach auch eine importierte GPO dann benannt werden soll.
In diesem Stammordner gibt es einen Unterordner, der vermutlich nach der ID der GPO benannt ist, da der einen kryptischen Namen hat. Innerhalb des Unterordner befindet sich dann die Backup.xml. Diese Backup.xml ist der Grund warum ich nicht importieren kann, da das Script diese Datei nicht findet. Ich habe vieles probiert und auch rekursiv als Parameter mit angegeben, damit er auch die Unterordner durchsucht, aber es funktioniert einfach nicht.
So bin ich nun auf euer Schwarmwissen angewiesen. Anbei mein Script, vielleicht findet sich ja jemand, der den Fehler findet oder mir zumindestens eine Hilfestellung geben kann.
Quacksalber
# PowerShell-Skript zum Exportieren und Importieren aller GPOs mit Logdatei, unter Auslassung bestimmter GPOs
# Prüfen, ob das Skript mit Administratorrechten ausgeführt wird
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "Bitte starten Sie das Skript mit Administratorrechten." -ForegroundColor Red
Exit
}
# Importieren des Group Policy PowerShell-Moduls
Import-Module GroupPolicy
# Festlegen der Pfade für Export, Import und Logdatei
$ExportPath = "C:\test\Scripte\GPO-Import\Exportierte GPOs"
$ImportPath = "C:\test\Scripte\GPO-Import\Importierende GPOs"
$LogPath = "C:\test\Scripte\GPO-Import\Logs"
# Erstellen des Log-Dateinamens mit Zeitstempel
$timestampForFile = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$LogFileName = "GPO-Log_$timestampForFile.txt"
$LogFilePath = Join-Path -Path $LogPath -ChildPath $LogFileName
# GPOs, die nicht exportiert werden sollen
$ExcludeGPOs = @("Default Domain Policy", "Default Domain Controllers Policy")
# Funktion zum Schreiben in die Logdatei
function Write-Log {
param (
[string]$Message
)
# Überprüfen und Erstellen des Log-Verzeichnisses, falls es nicht existiert
if (-not (Test-Path -Path $LogPath -PathType Container)) {
New-Item -ItemType Directory -Path $LogPath
}
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $LogFilePath -Value "[$timestamp] $Message"
}
# Funktion zum Exportieren aller GPOs
function Export-AllGPOs {
Get-GPO -All | Where-Object { $ExcludeGPOs -notcontains $_.DisplayName } | ForEach-Object {
$GPOName = $_.DisplayName
$GPOId = $_.Id
$FullPath = $ExportPath + "\" + $GPOName
if (-not (Test-Path -Path $FullPath)) {
New-Item -ItemType Directory -Path $FullPath
}
try {
Backup-GPO -Guid $GPOId -Path $FullPath
Write-Log "GPO wurde erfolgreich exportiert: $GPOName -> $FullPath"
} catch {
$errorMessage = "Fehler beim Exportieren der GPO '$GPOName': $_"
Write-Log $errorMessage
Write-Host $errorMessage -ForegroundColor Red
}
}
}
function Import-AllGPOs {
Get-ChildItem -Path $ImportPath -Directory | ForEach-Object {
$GPOName = $_.Name
$FullPath = $_.FullName
# Finden der BackupId im Importordner
$BackupId = (Get-ChildItem -Path $FullPath -Filter "Backup.xml").FullName
if ($BackupId) {
$BackupId = [xml](Get-Content $BackupId)
$BackupId = $BackupId.BackupGpo.BackupId
} else {
Write-Log "Fehler: Keine Backup.xml für GPO '$GPOName' in '$FullPath' gefunden."
return
}
if (Test-Path -Path $FullPath) {
try {
$NewGPO = New-GPO -Name $GPOName
Restore-GPO -BackupId $BackupId -TargetName $NewGPO.DisplayName -Path $FullPath -CreateIfNeeded
Write-Log "GPO wurde erfolgreich importiert: $GPOName"
} catch {
Write-Log "Fehler beim Importieren der GPO '$GPOName': $_"
}
} else {
Write-Log "Fehler: Der Importpfad $FullPath konnte nicht gefunden werden."
}
}
}
# Funktion zum Löschen nicht verknüpfter GPOs
function Remove-UnlinkedGPOs {
$GPOs = Get-GPO -All
foreach ($GPO in $GPOs) {
$GPOReport = Get-GPOReport -Guid $GPO.Id -ReportType Xml
$GPOReportXml = [xml]$GPOReport
# Überprüfen, ob die GPO Verknüpfungen hat
$links = $GPOReportXml.GPO.LinksTo
if ($null -eq $links) {
try {
Remove-GPO -Guid $GPO.Id -Confirm:$false
Write-Log "Nicht verknüpfte GPO wurde gelöscht: $($GPO.DisplayName)"
} catch {
Write-Log "Fehler beim Löschen der nicht verknüpften GPO: $($GPO.DisplayName) - $_"
}
}
}
}
# Benutzerauswahl für Export oder Import
$auswahl = Read-Host "Wählen Sie eine Option: (E)xportieren aller GPOs, (I)mportieren aller GPOs oder (L)öschen aller nicht verknüpften GPOs"
switch ($auswahl.ToUpper()) {
"E" {
Export-AllGPOs
}
"I" {
Import-AllGPOs
}
"L" {
Remove-UnlinkedGPOs
}
default {
Write-Host "Ungültige Auswahl. Bitte wähle 'E' für Export, 'I' für Import oder 'L' für Löschen"
}
}
Write-Host "Vorgang abgeschlossen. Überprüfen Sie die Logdatei unter $LogFilePath für Details."
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 7688751462
Url: https://administrator.de/contentid/7688751462
Ausgedruckt am: 28.11.2024 um 07:11 Uhr
10 Kommentare
Neuester Kommentar
$backupId = (Get-Item -Path "$FullPath\*\Backup.xml").FullName
Hier kennt ja keiner deine Ordner-Struktur im Import-Ordner wenn da eine Ebene tiefer keine Backup.xml liegt dann liegt da auch keine in deinem uns geschilderten Verzeichnis oder du hast keine Zugriffsrechte auf den Ordner.
Klappt hier problemlos guckst du.
https://tio.run/##TYvLCoMwEEX38xVDKKiFJPS567bL/oOPUYMTG0xCC@K3py266N1c7u ...
Klappt hier problemlos guckst du.
https://tio.run/##TYvLCoMwEEX38xVDKKiFJPS567bL/oOPUYMTG0xCC@K3py266N1c7u ...
Nein, wenn es eckige ( [ ] ) im Pfad gäbe dann eher so aber nicht.
https://tio.run/##TYxLCoMwGIT3OUUIBbUQFbVVF90UkmXv4ONXg4kVk9CCePbUUhed1c ...
https://tio.run/##TYxLCoMwGIT3OUUIBbUQFbVVF90UkmXv4ONXg4kVk9CCePbUUhed1c ...
"Der Parametersatz kann mit den angegebenen benannten Parametern nicht aufgelöst werden."
RTFM ! Restore-GPO-TargetName gibbet ned
-CreateIfNeeded gibbet ned
Du meinst wohl Import-GPO und das New-GPO ist dann überflüssig wenn CreateIfNeeded benutzt wird.
function Import-AllGPOs {
foreach($gpo in Get-ChildItem -Path $ImportPath -Directory){
$BackupId = (Get-Item "$($gpo.Fullname)\{*}" | select -First 1).Name
if (!$BackupId){
Write-Log "Fehler: Kein Backup in '$($gpo.Fullname)' gefunden."
continue
}
try {
Import-GPO -BackupId $BackupId -Path $gpo.Fullname -TargetName $gpo.Name -CreateIfNeeded -ErrorAction Stop
Write-Log "GPO wurde erfolgreich importiert: $($gpo.Name)"
} catch {
Write-Log "Fehler beim Importieren der GPO '$($gpo.Name)': $($_.Exception.Message)"
}
}
}
Wenn ich deine Importfunktion nutze, steht im Log nur "[2024-02-21 17:51:58] Fehler: Kein Backup in 'C:\test\Scripte\GPO-Import\Importierende GPOs\TEST-GPO' gefunden."
Nö klappt hier völlig problemlos in meinem Test, hast du wohl ein Fehler beim Kopieren gemacht ...Mit meiner neuen Importfunkion
function Export-AllGPOs {
function Export-AllGPOs {
Je nee is klar 😂
Machen wir dem Trauerspiel mal ein Ende
function Export-GPOs {
param(
[parameter(mandatory=$true)][string]$path,
[parameter(mandatory=$false)][string[]]$exclude
)
if (!(Test-Path $path)){New-Item -Type Dir -Path $path | out-null}
foreach($gpo in Get-GPO -All | ? DisplayName -notin $exclude){
$savepath = join-path $path $gpo.DisplayName
if (!(Test-Path $savepath)){New-Item -Type Dir -Path $savepath | out-null}
Backup-GPO -Guid $gpo.Id -Path $savepath
}
}
function Import-GPOs {
param(
[parameter(mandatory=$true)][ValidateScript({Test-Path -LiteralPath $_ -PathType Container})][string]$path,
[parameter(mandatory=$false)][string[]]$exclude
)
foreach($gpofolder in Get-ChildItem -Path $path -Directory -Exclude $exclude){
$backupid = (Get-Item "$($gpofolder.Fullname)\{*}").Name
if(!$backupid){
write-error "Folder '$($gpofolder.Name)' does not contain a GPO!" -Category ObjectNotFound
continue
}
Import-GPO -BackupId $backupid -Path $gpofolder.Fullname -TargetName $gpofolder.Name -CreateIfNeeded
}
}
Export-GPOs -Path "$home\Desktop\GPO-Backup" -exclude "Default Domain Controllers Policy","Default Domain Policy"
Import-GPOs -Path "$home\Desktop\GPO-Backup" -exclude "Default Domain Controllers Policy","Default Domain Policy"
me => out 🖖