[Gelöst] PowerShell scripting

---rOOts---

Senior Member
Ich habe mir ein kleines PowerShellskript gebastelt, damit ich mit einem klick
den Firefox sowie den Profilordner sichern kann!
CSS:
$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

$Laufwerk = Read-Host "Geben Sie das Laufwerk für die Sicherung ein, z.B. E"
if(!$Laufwerk.EndsWith(":")){
    $Laufwerk += ":"
}
$Laufwerk = $Laufwerk.ToLower()
$LogPfad = "$Laufwerk\BackupFirefox\$datum"

# -------------------------------------------------------

# Überprüfen, ob das Verzeichnis vorhanden ist
if (Test-Path ($LogPfad)) {
    # Eine Meldung ausgeben und den Benutzer auffordern, das Verzeichnis zu löschen
    Write-Host "Das Verzeichnis $LogPfad existiert bereits."
    $delete = Read-Host "Möchten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich löschen? (J/N)"
    if ($delete -eq "J" -or $delete -eq "j") {
        Remove-Item -Path $LogPfad -Force -Recurse
        Write-Host "Das Verzeichnis wurde gelöscht."
    } else {
        Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
        Exit
    }
}
# -------------------------------------------------------

# Fortfahren mit dem Erstellen des Verzeichnisses und der Sicherung
if(!(Test-Path ($LogPfad)))
{
    New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles"-CompressionLevel Optimal -DestinationPath "$LogPfad\$profile.zip"
Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -CompressionLevel Optimal -DestinationPath "$LogPfad\$program.zip"

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt")))      
{
    $Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
       Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")
       Add-Content $Logfile "`n`n"  
}
Blöd, dass hier keine Zeilennummern angezeigt werden!

Das funktioniert so weit auch ganz gut,
aber ich würde es gerne später in eine EXE umwandeln wollen, nur gibt es da keine Rückmeldungen,
habe ich schon probiert!

Ab Zeile 3 wird das Laufwerk abgefragt, wo die Sicherungen hin sollen.
Diese Abfrage hätte ich gerne in einem Windowsauswahlfenster.

Ab Zeile 13 wird geprüft, ob das anzulegende Verzeichnis schon vorhanden ist
und wenn ja, muss dies bestätigt werden.
Auch das hätte ich gerne als Windowsfenster!

Nun habe ich dazu einen Codeschnipsel im Netz gefunden.
Code:
$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Möchten Sie das Verzeichnis
und alle darin enthaltenen Dateien wirklich löschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",2)

Nur, wie verknüpfe ich die Buttons "Ja" & "Nein" mit meinem Code?
 
Zuletzt bearbeitet:
Mit
Code:
if ($host.UI.RawUI.KeyAvailable) {
$taste = $host.UI.RawUI.ReadKey()
write-host "Tastendruck erkannt $taste"
}
sollte es irgendwie gehen, aber ....
ich bin zu blöd dazu!
 
Wie funktioniert das mit dem EXE erstellen? Vielleicht gibt's da noch einen
Parameter zu setzen?

hth
 
Moin,

Ab Zeile 3 wird das Laufwerk abgefragt, wo die Sicherungen hin sollen.
Diese Abfrage hätte ich gerne in einem Windowsauswahlfenster.
Dafür würde ich den Ordner-Auswahl Dialog von Windows Forms nutzen:
Code:
Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog]@{
  RootFolder  = "MyComputer"
  Description = "Backupverzeichnis auswählen:"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$Datum"

Nun habe ich dazu einen Codeschnipsel im Netz gefunden.
Code:
$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Möchten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich löschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",2)

Nur, wie verknüpfe ich die Buttons "Ja" & "Nein" mit meinem Code?
für eine "Ja/Nein"-Abfrage müsste hinten eigentlich eine 4 statt der 2 stehen. Siehe auch VBScript - Popup Method

Du reagierst darauf genauso, wie du es auch schon bei Read-Host oben getan hast.
Bei ja ist $Answer = 6, bei Nein ist $Answer = 7.
Also kannst du entwederif oder switch nutzen, um auf das Ergebnis zu regieren.

Code:
$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Möchten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich löschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

switch ($Answer) {
  6 {
    # Code bei Ja
  }
  7 {
    # Code bei Nein
  }
}

Gruß Thomas
 
Zuletzt bearbeitet:
Hey @TK87, vielen lieben Dank!
Ich habe ja vom Skripten so gar keine Ahnung, aber dank Dir und ChatGPT ist folgendes Skript daraus geworden,
und es funktioniert wie gewünscht!
Was nicht geht ist das Skript in eine Exe zu konvertieren, bzw, das geht schon, nur es funktioniert dann nicht mehr.

Das Skript:

Code:
$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog] @{
RootFolder  = "MyComputer"
Description = "Geben Sie das Laufwerk für die Sicherung ein, z.B. E"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$datum"

$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Möchten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich löschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

switch ($Answer) {
6 {
Remove-Item -Path $LogPfad -Force -Recurse
Write-Host "Das Verzeichnis wurde gelöscht."
}
7 {
Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
Exit
}
}

if(!(Test-Path ($LogPfad))) {
New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -DestinationPath "$LogPfad\$program.zip" -CompressionLevel Optimal

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt")))           
{
$Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")     
Add-Content $Logfile "`n`n"       
}

Also Danke noch ein Mal.

Nun geht es daran, ein Skript zu schreiben, welches
a. eine Auswahl der Sicherungen ermöglicht
und
b. vorher auch fragt, ob die Daten wirklich überschrieben werden sollen.

Mal schauen, was ich da so zusammen bekomme.
 
Habe noch etwas am Skript herumgebastelt!
Wenn der Firefox noch geöffnet ist, kommt eine Abfrage, ob er beendet werden soll.

Code:
$ProcessName = "Firefox"

if (Get-Process $ProcessName -ErrorAction SilentlyContinue) {
    $wshshell = New-Object -ComObject WScript.Shell
    $Frage = $wshshell.Popup("Soll $ProcessName beendet werden?", 0, "$ProcessName ist noch aktiv.", 4)

    if ($Frage -eq 6) {
        Get-Process $ProcessName | Stop-Process
    }
    else {
        Exit
    }
}
else {
    Write-Host "$ProcessName ist nicht aktiv."
}

$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog] @{
  RootFolder  = "MyComputer"
  Description = "Waehlen Sie das Laufwerk fuer die Sicherung aus:"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$datum"

$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Moechten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich loeschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

switch ($Answer) {
  6 {
    Remove-Item -Path $LogPfad -Force -Recurse
    Write-Host "Das Verzeichnis wurde gelöscht."
  }
  7 {
    Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
    Exit
  }
}

if(!(Test-Path ($LogPfad))) {
    New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -DestinationPath "$LogPfad\$program.zip" -CompressionLevel Optimal

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt")))           
{
    $Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
       Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")     
       Add-Content $Logfile "`n`n"       
}

 
So,
habe auch etwas Hilfe von ChatGPT für das RestoreSkript in Anspruch genommen!

Aber es ist ein gewaltiger Bug vorhanden!
Gleich zu Anfang sollte eigentlich festgelegt werden, dass das Skript sich mit den beiden ZIP-Files in einem X-belibigen Ordner befindet.
Da ist der Wurm drin, und ChatGPT stolpert da auch drüber.
Das will heißen, ich brauche unbedingt Menschliche Hilfe.
Hier der bisherige Code:
Code:
$scriptDir = Split-Path $MyInvocation.MyCommand.Path
$profileZip = Join-Path $scriptDir"Profilverzeichnis.zip"
$programZip = Join-Path $scriptDir"Programmverzeichnis.zip"
$profilePath = "$env:APPDATA\Mozilla\Firefox\Profiles"
$programPath = "$env:ProgramFiles\Mozilla Firefox"

if ((Test-Path $profilePath) -and (Test-Path $programPath)) {
    $answer1 = [System.Windows.Forms.MessageBox]::Show("Möchten Sie das Firefox-Profilverzeichnis überschreiben?", "Firefox-Profilverzeichnis vorhanden", [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Question)
    $answer2 = [System.Windows.Forms.MessageBox]::Show("Möchten Sie das Firefox-Programmverzeichnis überschreiben?", "Firefox-Programmverzeichnis vorhanden", [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Question)
    if ($answer1 -eq "Yes") {
        if (Test-Path $profileZip) {
            Expand-Archive -Path $profileZip -DestinationPath $profilePath -Force
            Write-Output "Firefox-Profilverzeichnis erfolgreich entpackt."
        } else {
            Write-Output "ZIP-Datei für Firefox-Profilverzeichnis nicht gefunden."
            Exit
        }
    }
    if ($answer2 -eq "Yes") {
        if (Test-Path $programZip) {
            Expand-Archive -Path $programZip -DestinationPath $programPath -Force
            Write-Output "Firefox-Programmverzeichnis erfolgreich entpackt."
        } else {
            Write-Output "ZIP-Datei für Firefox-Programmverzeichnis nicht gefunden."
            Exit
        }
    }
} else {
    if (-not (Test-Path $profilePath)) {
        Write-Output "Das Firefox-Profilverzeichnis ist nicht vorhanden."
    }
    if (-not (Test-Path $programPath)) {
        Write-Output "Das Firefox-Programmverzeichnis ist nicht vorhanden."
        Exit
    }
}
 
Was nicht geht ist das Skript in eine Exe zu konvertieren, bzw, das geht schon, nur es funktioniert dann nicht mehr.
Ich halte ehrlich gesagt nicht viel von solchen online-konvertern.

Nutze besser die Kommandozeilenversion, die man als Modul nachinstallieren kann - die hat bei mir bisher immer funktioniert.

Einmalig in Powershell:
Code:
Install-Modul PS2Exe -Scope CurrentUser -Force
fortan kannst du Skripts mit folgenden Befehl konvertieren:
Code:
ps2exe -inputFile "C:\Pfad\zum\Script.ps1" -noConsole -noOutput -outputFile "C:\Pfad\zur\Output.exe"
Um beste Ergebnisse zu erzielen, Powershell-Skripte immer in der Kodierung UTF8 mit BOM speichern.


Aber es ist ein gewaltiger Bug vorhanden!
Gleich zu Anfang sollte eigentlich festgelegt werden, dass das Skript sich mit den beiden ZIP-Files in einem X-belibigen Ordner befindet.
Da ist der Wurm drin, und ChatGPT stolpert da auch drüber.
Das will heißen, ich brauche unbedingt Menschliche Hilfe.
Hier der bisherige Code:
Code:
$profileZip = Join-Path $scriptDir"Profilverzeichnis.zip"
$programZip = Join-Path $scriptDir"Programmverzeichnis.zip"
Da fehlen bei den Join-Path-Befehlen schlicht Leerzeichen zwichen dem $scriptDir und dem Rest. Der Befehl erwartet 2 Argumente, wenn du alles aneinander schreibst, übergibst du aber nur eins.

Vollständig würde der Befehl eigentlich lauten:
Code:
Join-Path -Path $scriptDir -ChildPath "Profilverzeichnis.zip"
Man kan die Parameter selbst zwar auslassen, aber du übergibst quasi nur den Path-Parameter - und der Befehl fragt dann das nichtübergebene Argument für den ChildPath-Parameter ab.

Gruß Thomas
 
Vielen lieben Dank für Deine Unterstützung!
Habe die Korrektur mit dem Leerzeichen vorgenommen.
Jedoch startet das Skript immer noch nicht.
Die Konsole öffnet sich ganz kurz, um sich dann gleich wieder zu beenden.

Zum Testen habe ich das Skript dann mal etwas zusammen gestrichen.
Aber auch da, gleiches Verhalten.
Das Ding durch ChatGPT überprüfen lassen, ohne Befund.
Ich weiß jetzt an dieser Stelle nicht weiter.
Zum Erstellen des Skripts nutze ich Visual Studio Code.
Code:
$scriptDir = Split-Path $MyInvocation.MyCommand.Path
$profileZip = Join-Path -Path $scriptDir -ChildPath "Profilverzeichnis.zip"
$profilePath = "$env:APPDATA\Mozilla\Firefox\Profiles"

if (Test-Path $profilePath) {

$answer1 = [System.Windows.Forms.MessageBox]::Show("Möchten Sie das Firefox-Profilverzeichnis überschreiben?", "Firefox-Profilverzeichnis vorhanden", [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Question)
if ($answer1 -eq "Yes") {
if (Test-Path $profileZip) {
Expand-Archive -Path $profileZip -DestinationPath $profilePath -Force
Write-Output "Firefox-Profilverzeichnis erfolgreich entpackt."
} else {
Write-Output "ZIP-Datei für Firefox-Profilverzeichnis nicht gefunden."
Exit
}
}
} else {
if (-not (Test-Path $profilePath)) {
Write-Output "Das Firefox-Profilverzeichnis ist nicht vorhanden."
Exit
}
}
 
Da fehlt eine Abschließende geschweifte Klammer für den letzten else-Block.
EDIT: Mein Fehler. Die habe ich scheinbar beim kopieren nicht mitgenommen.

Zudem fehlt die Zeile Add-Type -A System.Windows.Forms, welche die .Net-Biblithoken ladet.

Du solltest dir im übrigen angewöhnen, mit Code-Einrückung zu arbeiten. Das macht das debuggen erheblich einfacher.
Code:
Add-Type -A System.Windows.Forms
$scriptDir = Split-Path $MyInvocation.MyCommand.Path
$profileZip = Join-Path -Path $scriptDir -ChildPath "Profilverzeichnis.zip"
$profilePath = "$env:APPDATA\Mozilla\Firefox\Profiles"

if (Test-Path $profilePath) {

  $answer1 = [System.Windows.Forms.MessageBox]::Show("Möchten Sie das Firefox-Profilverzeichnis überschreiben?", "Firefox-Profilverzeichnis vorhanden", [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Question)
  if ($answer1 -eq "Yes") {
    if (Test-Path $profileZip) {
      Expand-Archive -Path $profileZip -DestinationPath $profilePath -Force
      Write-Output "Firefox-Profilverzeichnis erfolgreich entpackt."
    } else {
      Write-Output "ZIP-Datei für Firefox-Profilverzeichnis nicht gefunden."
      Exit
    }
  }
} else {
  if (-not (Test-Path $profilePath)) {
    Write-Output "Das Firefox-Profilverzeichnis ist nicht vorhanden."
    Exit
  }
}
 
Zuletzt bearbeitet:
Wow, nun noch mal Danke.
Es funktioniert!!
Nun werde ich noch die Abfrage einbauen, ob FF geöffnet ist.

Für das Sicherungs-Skript hatte ich heute Morgen noch eine Idee,
habe aber im Netz, so auf die Schnelle nichts gefunden.
Eine Abfrage der Firefox.exe, welche Version sie ist,
um diese Info dann noch in die "Log"-Datei, die am Ende generiert wird, einzufügen.

Mit den Einrückungen, das habe ich ja, nur sobald ich speichere, ist das wieder weg.

Zu der PS2Exe, das Modul muss ich irgendwo downloaden?
https://github.com/MScholtes/PS2EXE
Grafische Oberfläche.
https://www.windowspro.de/tool/powershell-scripts-kompilieren-win-ps2exe
 
Code:
Install-Module PS2Exe -Scope CurrentUser -Force
Für das Sicherungs-Skript hatte ich heute Morgen noch eine Idee,
habe aber im Netz, so auf die Schnelle nichts gefunden.
Eine Abfrage der Firefox.exe, welche Version sie ist,
um diese Info dann noch in die "Log"-Datei, die am Ende generiert wird, einzufügen.
Code:
$FF_Version = gp 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'| ? DisplayName -like "*firefox*"|select -Expand DisplayVersion

Mit den Einrückungen, das habe ich ja, nur sobald ich speichere, ist das wieder weg.
Dann stimmt etwas bei deinen Einstellungen im Visual Studio Code nicht, denn das darf so nicht sein.

Zu der PS2Exe, das Modul muss ich irgendwo downloaden?
Nein. Du brauchst nur Powershell auf deinem Rechner zu öffnen und den Befehl, den ich oben gepostet habe auszuführen. Dadurch wird das Modul automatisch heruntergeladen und installiert.
EDIT: Ok, mein Fehler, da fehlt ein "e" im Befehl. Es muss natürlich heissen:
Code:
Install-Module PS2Exe -Scope CurrentUser -Force

Gruß Thomas
 
Man, Du bist ja schneller als die Polizei erlaubt. :)
Habe die PS2Exe nun installiert.
Danke.
Das mit der Versionsabfrage verstehe ich nicht!
Sorry, damit werde ich mich aber zu einem späteren Zeitpunkt nochmals beschäftigen.

Und zu den Einrückungen.
Da liegt ein Missverständnis vor, denke ich.
In Notepad++, aber auch in Visual Studio Code wird das richtig, also mit Einrückungen abgespeichert.
Nur so bald ich hier den Code per copy&paste einfüge, immer noch mit Einrückungen,
markiere und dann auf "Code" klicke, ist die Formatierung dahin.

Werde nun erst einmal meine bisherigen Ideen versuchen umzusetzen,
habe auch noch einen Bug entdeckt, und diesen beseitigen,
und danach beschäftige ich mich wieder mit der Versionsabfrage.
 
Und zu den Einrückungen.
Da liegt ein Missverständnis vor, denke ich.
In Notepad++, aber auch in Visual Studio Code wird das richtig, also mit Einrückungen abgespeichert.
Ah ok. Ich hatte das so verstanden, dass nach dem speichern im Visual Studio Code die Einrückungen weg sind.

Wo wir gerade schon bei Notepad++ sind: Du kannst unter "Ausführen > Externes Programm ausführen" folgende Zeile einfügen:
Code:
powershell -NoExit -ExecutionPolicy ByPass -Command "cd -Lit '$(CURRENT_DIRECTORY)';. '.\$(FILE_NAME)'"
und dann unten drunter auf den "speichern" Knopf drücken, dann Namen und falls gewünscht eine Tastenkombination vergeben und fortan kannst du Skripte auch bequem aus Notepad++ heraus ausführen.
Beachte, dass das Skript vor der Ausführung jedoch immer gespeichert sein muss.

Nur so bald ich hier den Code per copy&paste einfüge, immer noch mit Einrückungen,
markiere und dann auf "Code" klicke, ist die Formatierung dahin.
Erst auf code drücken, dann per Copy&Paste einfügen, so klappt es.

Das mit der Versionsabfrage verstehe ich nicht!
Sorry, damit werde ich mich aber zu einem späteren Zeitpunkt nochmals beschäftigen.
Ich lese lediglich die Firefox-Version aus der Registry aus und schreibe sie in die Variable $FF_Version. Diese kannst du dann nach belieben in deine Log-Datei speichern.

Gruß Thomas
 
Hey, echt klasse wie Du mir hilfst.
Danke, danke, danke.
Ich würde Dir ja ein Bierchen ausgeben, aber Aachen ist echt weit weg von Hanau.

Also das mit dem LOG und dem Einfügen eines Textes
"Die gesicherte Firefox-Version ist: $FF_Version"
habe dank Deines Hinweises begriffen und hinbekommen.

Habe heute, und nur zum Testen ein Backupt mit dem Skript gemacht,
und leider festgestellt, dass da etwas mit der Prüfung, ob es denn schon ein Backup gibt, nicht stimmt.

Warum werde ich gefragt, ob das Verzeichnis überschrieben werden kann,
wenn es dieses gar nicht gibt?
Und in der Konsole steht, dass das Verzeichnis nicht gefunden werden konnte.
Die Sicherungsfunktion klappt aber!
Es wird der Ordner angelegt und auch die zwei ZIP-Dateien sowie die Textdatei.

Und hier noch ein Test!
Das Einfügen des Codes.
Code:
$ProcessName = "Firefox"

if (Get-Process $ProcessName -ErrorAction SilentlyContinue) {
    $wshshell = New-Object -ComObject WScript.Shell
    $Frage = $wshshell.Popup("Soll $ProcessName beendet werden?", 0, "$ProcessName ist noch aktiv.", 4)

    if ($Frage -eq 6) {
        Get-Process $ProcessName | Stop-Process
    }
    else {
        Exit
    }
}
else {
    Write-Host "$ProcessName ist nicht aktiv."
}

$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog] @{
  RootFolder  = "MyComputer"
  Description = "Waehlen Sie das Laufwerk fuer die Sicherung aus:"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$datum"

$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Moechten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich loeschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

switch ($Answer) {
  6 {
    Remove-Item -Path $LogPfad -Force -Recurse
    Write-Host "Das Verzeichnis wurde gelöscht."
  }
  7 {
    Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
    Exit
  }
}

if(!(Test-Path ($LogPfad))) {
    New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -DestinationPath "$LogPfad\$program.zip" -CompressionLevel Optimal

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt"))) {
  $FF_Version = gp 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'| ? DisplayName -like "*firefox*"|select -Expand DisplayVersion
  $Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
    Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")
    Add-Content $Logfile ("Die gesicherte Firefox-Version ist: $FF_Version")     
    Add-Content $Logfile "`n`n"       
}
 
Keine Ahnung was genau ich da tue,
aber ich habe den Fehler beseitigen können!
Code:
$ProcessName = "Firefox"

if (Get-Process $ProcessName -ErrorAction SilentlyContinue) {
    $wshshell = New-Object -ComObject WScript.Shell
    $Frage = $wshshell.Popup("Soll $ProcessName beendet werden?", 0, "$ProcessName ist noch aktiv.", 4)

    if ($Frage -eq 6) {
      Get-Process $ProcessName | Stop-Process
    }
    else {
      Exit
    }
  }
else {
  Write-Host "$ProcessName ist nicht aktiv."
}

$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

  Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog] @{
  RootFolder  = "MyComputer"
  Description = "Waehlen Sie das Laufwerk fuer die Sicherung aus:"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$datum"

if (Test-Path ($LogPfad)) {
  $wshshell = new-object -comobject wscript.shell
  $Answer = $wshshell.popup("Moechten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich loeschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

  switch ($Answer) {
    6 {
      Remove-Item -Path $LogPfad -Force -Recurse
      Write-Host "Das Verzeichnis wurde gelöscht."
    }
    7 {
      Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
      Exit
    }
  }
}
if(!(Test-Path ($LogPfad))) {
    New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

  Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
  Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -DestinationPath "$LogPfad\$program.zip" -CompressionLevel Optimal

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt"))) {
  $FF_Version = gp 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'| ? DisplayName -like "*firefox*"|select -Expand DisplayVersion
  $Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
    Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")
    Add-Content $Logfile ("Die gesicherte Firefox-Version ist: $FF_Version")     
    Add-Content $Logfile "`n`n"       
}
 
Und weiter im Takt!
Habe in PowerShell die Funktion von 7z integrieren können.
Auch klappt das mit dem EXE erstellen.

Ich habe auch an das Ende des Skriptes den Code für ein Hinweisfenster anfügen können,
damit man weiß, dass der ganze Vorgang abgeschlossen ist.

So weit, so gut.

Wenn ich nun die systemeigene Packfunktion nutze, eine Exe erstelle, erscheint beim Packvorgang ein Fenster mit einer Fortschrittsanzeige.
Schön, und wie ich finde hilfreich.
Wenn ich aber die Packfunktion von 7z nutze, wird so eine Anzeige nicht generiert, das ist blöd!
Denn ich würde viel lieber 7z nutzen, einfach, weil der ganze Vorgang viel schneller geht und obendrein die Zip-files auch noch einen klitzekleines bisschen kompakter sind.
Auch kann ich da die Kompressionsrate einstellen.

Jedoch so sehr ich mich auch bemühe, und auch rege ChatGPT mit Fragen löchere, ich bekomme weder das Eine noch das Andere hin.

Ob Du Thomas, oder auch jeder andere, der sich mit PowerShell auskennt, mir da unter die Arme greifen könnte?
 
Und wie gesagt (geschrieben), wenn mit interner Funktion
Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
komprimiert wird, zeigt es im PoweShell-Fenster eine Fortschrittsanzeige an.
Wenn mit 7zip
compress-7zip -path "$env:appdata\Mozilla\Firefox\Profiles" -CompressionLevel Normal -ArchiveFileName "$LogPfad\$profile.zip" -Format Zip
dann nicht.
Und wenn das ganze Skript dann zur EXE konvertiert wurde, macht sich das insoweit bemerkbar,
das erste Möglichkeit, ein eigenes Fenster generiert, zweite jedoch nicht.

Hier mal das ganze Skript.
Code:
$ProcessName = "Firefox"

if (Get-Process $ProcessName -ErrorAction SilentlyContinue) {
    $wshshell = New-Object -ComObject WScript.Shell
    $Frage = $wshshell.Popup("Soll $ProcessName beendet werden?", 0, "$ProcessName ist noch aktiv.", 4)

    if ($Frage -eq 6) {
      Get-Process $ProcessName | Stop-Process
    }
    else {
      Exit
    }
  }
else {
  Write-Host "$ProcessName ist nicht aktiv."
}

$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "yyyy.MM.dd"

  Add-Type -A System.Windows.Forms

$SelectDir = [Windows.Forms.FolderBrowserDialog] @{
  RootFolder  = "MyComputer"
  Description = "Waehlen Sie das Laufwerk fuer die Sicherung aus:"
}
if ($SelectDir.ShowDialog() -ne "OK") {return}

$LogPfad = "$($SelectDir.SelectedPath)\BackupFirefox\$datum"

if (Test-Path ($LogPfad)) {
  $wshshell = new-object -comobject wscript.shell
  $Answer = $wshshell.popup("Moechten Sie das Verzeichnis und alle darin enthaltenen Dateien wirklich loeschen?",0,"Das Verzeichnis $LogPfad existiert bereits.",4)

  switch ($Answer) {
    6 {
      Remove-Item -Path $LogPfad -Force -Recurse
      Write-Host "Das Verzeichnis wurde gelöscht."
    }
    7 {
      Write-Host "Das Verzeichnis wird nicht gelöscht. Das Skript wird beendet."
      Exit
    }
  }
}
if(!(Test-Path ($LogPfad))) {
    New-Item -Path $LogPfad -ItemType Directory
}

$profile = "Profilverzeichnis"
$program = "Programmverzeichnis"

  Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
#  compress-7zip -path "$env:appdata\Mozilla\Firefox\Profiles" -CompressionLevel Normal -ArchiveFileName "$LogPfad\$profile.zip" -Format Zip 
  Compress-Archive -Path "$env:ProgramFiles\Mozilla Firefox" -DestinationPath "$LogPfad\$program.zip" -CompressionLevel Optimal
#  compress-7zip -path "$env:ProgramFiles\Mozilla Firefox" -CompressionLevel Normal -ArchiveFileName "$LogPfad\$program.zip" -Format Zip

if (!(Test-Path ("$LogPfad\Sicherung am $date.txt"))) {
  $FF_Version = gp 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'| ? DisplayName -like "*firefox*"|select -Expand DisplayVersion
  $Logfile = (New-Item -Path "$LogPfad\Sicherung am $date.txt"  -ItemType File -Force).FullName
    Add-Content $Logfile ("Letzte Sicherung von Firefox am $(get-date -Format "dddd, dd. MMMM yyyy, HH:mm:ss") Uhr`n")
    Add-Content $Logfile ("Die gesicherte Firefox-Version ist: $FF_Version")     
    Add-Content $Logfile "`n`n"       
}
$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Sicherung abgeschlossen",0,"Firesave",0)
 
Wenn mit 7zip
compress-7zip -path "$env:appdata\Mozilla\Firefox\Profiles" -CompressionLevel Normal -ArchiveFileName "$LogPfad\$profile.zip" -Format Zip
dann nicht.
Diese Funktion war mir unbekannt. Ich würde hier besser gleich mit der Syntax der 7z.exe arbeiten.
Code:
$7z = "C:\Pfad\zur\7z.exe"
Write-Host "Archiviere Dateien... "
&$7z a -mx9 -bso0 -bsp1 "C:\Pfad\zur\Output.7z" "C:\zu\archivierender\Pfad\*"
So hast du auch eine Fortschrittsanzeige. -mx gefolgt von einer Zahl von 0-9 steht für die Compression. 0 heisst keine Kompression, 9 heisst maximale Kompression. Standard ist 5.

Und wenn das ganze Skript dann zur EXE konvertiert wurde, macht sich das insoweit bemerkbar,
das erste Möglichkeit, ein eigenes Fenster generiert, zweite jedoch nicht.
Das ist natürlich wieder eine andere Geschichte. Es gäbe 2 Möglichkeiten, dies zu lösen...

Möglichkeit 1:
Du kannst beim konvertieren in EXE das -NoConsole weglassen. Dann öffnet sich beim Ausführen der EXE-Datei ein Konsolenfenster, in dem die normale 7z-Fortschrittsanzeige wie bei der Ausführung des obigen Befehls zu sehen ist.​
Möglichkeit 2:
Man könnte auch den Fortschritt des Outputs von 7z abfangen und in eine Fortschrittsanzeige gemäß der von Compress-Archive umwandeln. Dann würde auch hier beim Ausführen der EXE ein neues Fenster mit dem Fortschritt erzeugt. Allerdings wirkt sich das natürlich auch negativ auf die Performance aus.​
Code:
$7z = "C:\Pfad\zur\7z.exe"
&$7z a -mx9 -bso0 -bsp1 "C:\Pfad\zur\Output.7z" "C:\zu\archivierender\Pfad\*" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
  ForEach-Object { Write-Progress -Activity "Dateien werden archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}
Gruß Thomas​
 
Oben