[Gelöst] PowerShell scripting

Absolut klasse!
Ich habe diesen Code verwendet!
Code:
$7z = ".\7z.exe"
&$7z a -mx5 -bso0 -bsp1 "$LogPfad\$profile.zip" "$env:appdata\Mozilla\Firefox\Profiles" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
  ForEach-Object { Write-Progress -Activity "Profilverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}
&$7z a -mx5 -bso0 -bsp1 "$LogPfad\$program.zip" "$env:ProgramFiles\Mozilla Firefox" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
  ForEach-Object { Write-Progress -Activity "Programmverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}

Und ihn einmal als PowerShell-Skript ausgeführt und ein zweites Mal als EXE. Klasse!
Und von wegen Performanceverlust, das ganze geht schneller als mit
Code:
Compress-Archive -Path "$env:appdata\Mozilla\Firefox\Profiles" -DestinationPath "$LogPfad\$profile.zip" -CompressionLevel Optimal
und auch schneller als mit
Code:
compress-7zip -path "$env:appdata\Mozilla\Firefox\Profiles" -CompressionLevel Normal -ArchiveFileName "$LogPfad\$profile.zip" -Format Zip

Eine letzte Sache aber hätte ich da noch!
Ich will ja nicht immer auch das Programmverzeichnis mit sichern,
also muss da eine Abfrage rein.
Code:
if (? (?)) {
  $wshshell = new-object -comobject wscript.shell
  $Answer = $wshshell.popup("Moechten Sie das Programmverzeichnis auch sichern?",0,"Firefox4backup",4)

  switch ($Answer) {
    # 6 entspricht "Ja"
    6 {
      Remove-Item -Path $LogPfad -Force -Recurse
      Write-Host "Das Programmverzeichnis wurde auch gesichert."
    }
    # 7 entspricht "Nein"
    7 {
      Write-Host "Das Programmverzeichnis wurde nicht gesichert."
      !!Hier muss die Sprunganweisung zu "if (!(Test-Path ("$LogPfad\Sicherung am $date.txt"))) { "hin !!!
    }
  }
}
Natürlich muss das dann zwischen die zwei Packbefehle.

Hier der aktuelle Stand:
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 entspricht "Ja"
    6 {
      Remove-Item -Path $LogPfad -Force -Recurse
      Write-Host "Das Verzeichnis wurde gelöscht."
    }
    # 7 entspricht "Nein"
    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"

$7z = ".\7z.exe"
&$7z a -mx5 -bso0 -bsp1 "$LogPfad\$profile.zip" "$env:appdata\Mozilla\Firefox\Profiles" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
  ForEach-Object { Write-Progress -Activity "Profilverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}
&$7z a -mx5 -bso0 -bsp1 "$LogPfad\$program.zip" "$env:ProgramFiles\Mozilla Firefox" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
  ForEach-Object { Write-Progress -Activity "Programmverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}

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)
 
Code:
!!Hier muss die Sprunganweisung zu "if (!(Test-Path ("$LogPfad\Sicherung am $date.txt"))) { "hin !!!
Sprunganweisungen gibts bei Powershell nicht. Entweder du packst den Code in den Codeblock, oder du definierst eine Funktion und rufst diese innderhalb des Codeblocks auf.

Ich will ja nicht immer auch das Programmverzeichnis mit sichern,
also muss da eine Abfrage rein.
Für meinen Geschmack sind das dann im Fall der Fälle einfach zu viele Abfragen hintereinander.

Vielleicht wäre es sinniger, gleich alles in eine Oberfläche zu packen? Mal als schnellschuss:
Code:
Add-Type -A System.Windows.Forms

#region Grundeinstellungen
  $7z    = "C:\Program Files\7-zip\7z.exe"
  $Reg   = "HKCU:\Software\FF_Backup"
  $Fonts = @(
    [Drawing.Font]::New("Microsoft Sans Serif",12)
    [Drawing.Font]::New("Microsoft Sans Serif",12,[Drawing.FontStyle]"Bold")
  )
  [Windows.Forms.Application]::EnableVisualStyles()
#endregion

#region Fensterelemente
  $Form  = [Windows.Forms.Form]@{Text="Backup Firefox"; AutoSize=$true; StartPosition='CenterScreen'; Size="100,100"; Padding='10,10,10,10'; KeyPreview=$true}
  $Table = [Windows.Forms.TableLayoutPanel]@{Dock='Fill'; AutoSize=$true}
  $Flow  = [Windows.Forms.FlowLayoutPanel]@{Anchor='Top'; AutoSize=$true; AutoSizeMode='GrowAndShrink'}
 
  $Open  = [Windows.Forms.Button]@{Size="100,40"; Text="Speicherort"; Font=$Fonts[0]; Anchor='Left'}
 
  $Textbox  = @(
    [Windows.Forms.TextBox]@{Font=$Fonts[0]; Margin='10,10,0,10'; Size="150,30"; Dock='Fill'}
    [Windows.Forms.TextBox]@{Font=$Fonts[1]; Margin='0,10,10,10'; Dock='Fill'; Text=" \Backup\$(Get-Date -Format 'yyyy.MM.dd')";  Enabled=$false}
  )
  $Checkbox = @(
    [Windows.Forms.Checkbox]@{Text="Programmverzeichnis sichern";      AutoSize=$true; Font=$Fonts[0];Margin='10,10,0,10'}
    [Windows.Forms.Checkbox]@{Text="vorhandenen Ordner überschreiben"; AutoSize=$true; Font=$Fonts[0];Margin='10,0,10,10'; Visible=$false}
  )
 
  $HS = [Hashtable]::Synchronized(@{
    Kill      = [Windows.Forms.Button]@{Size="160,40"; Text="Firefox beenden"; Font=$Fonts[1]; Margin='10,10,10,10'; ForeColor='Black' }
    Run       = [Windows.Forms.Button]@{Size="120,40"; Text="Ausführen";       Font=$Fonts[1]; Margin='10,10,10,10'; Enabled=$false}
    SavePath  = $false
    overwrite = $true
  })
#endregion

#region Fensteranordnung
  $Flow.Controls.Add($HS.Kill)
  $Flow.Controls.Add($HS.Run)
  [void]$Table.ColumnStyles.Add([Windows.Forms.ColumnStyle]::New('AutoSize'))
  [void]$Table.ColumnStyles.Add([Windows.Forms.ColumnStyle]::New('Percent',10))
  [void]$Table.ColumnStyles.Add([Windows.Forms.ColumnStyle]::New('Absolute',190))
  $Table.Controls.Add($Open,0,0)
  $Table.Controls.Add($Textbox[0],1,0)
  $Table.Controls.Add($Textbox[1],2,0)
  $Table.Controls.Add($Checkbox[0],0,3)
  $Table.Controls.Add($Checkbox[1],0,4)
  $Table.Controls.Add($Flow,0,5)
  $Table.SetColumnSpan($Checkbox[0],3)
  $Table.SetColumnSpan($Checkbox[1],3)
  $Table.SetColumnSpan($Flow,3)
 
  $Form.Controls.Add($Table)
#endregion

#region Runspace
  # Firefox-Status überwachen
  $RS = [powershell]::Create().AddScript({
    while ($true) {
      if (Get-Process "Firefox" -EA si) {
        $HS.Kill.Visible = $true
        $HS.Run.Visible  = $false
      } else {
        $HS.Kill.Visible = $false
        $HS.Run.Visible  = $true
        $HS.Run.Enabled  = $HS.SavePath -and $HS.overwrite
      }
    }
  })
  $RS.Runspace.SessionStateProxy.SetVariable('HS',$HS)
#endregion

#region Events
  $Form.Add_Load({
    $HS.handle = $RS.BeginInvoke()
    if (Test-Path $Reg) {
      $Textbox[0].Text = Get-ItemPropertyValue $Reg "(default)" -EA Si
    }
    [void]$this.ActivateControl($Checkbox[0])
  })
  $Form.Add_Closed({[void]$RS.Stop()})
  $Form.Add_KeyDown({
    switch ($_.KeyCode) {
      'Return' {$HS.Run.PerformClick()}
      'Escape' {$this.Hide()}
    }
  })
 
  $HS.Kill.Add_Click({
    Get-Process "Firefox"|kill
    $HS.Kill.Visible = $false
    $HS.Run.Visible  = $true
  })
  $HS.Run.Add_Click({
    $this.TopLevelControl.Hide()
    $HS.Action = $true
    [void](ni -force $reg -value $Textbox[0].Text.Replace('"',''))
  })
 
  $Textbox.Add_TextChanged({
    if ($this.Text -and (Test-Path $this.Text.Replace('"',''))) {
      $HS.SavePath = $true
      if (Test-Path (Join-Path $this.Text.Replace('"','') "Backup\$(get-date -Format "yyyy.MM.dd")")) {
        $Checkbox[1].Visible = $true
        $HS.overwrite = $false
      } else {
        $Checkbox[1].Visible = $false
        $HS.overwrite = $true
        $this.TopLevelControl.Size="100,100"
      }
    }
    else {$HS.SavePath = $false}
  })

  $Open.Add_Click({
    $Browse = [Windows.Forms.FolderBrowserDialog]@{
      RootFolder   = "MyComputer"
      SelectedPath = if ($HS.SavePath) {$Textbox.Text.Replace('"','')}
    }
    if ($Browse.ShowDialog() -eq 'ok') {$Textbox[0].Text = $Browse.SelectedPath}
  })
 
  $Checkbox[1].Add_CheckStateChanged({$HS.overwrite = $this.Checked})
#endregion

#region Ausführung
  [void]$Form.ShowDialog()
#endregion

if ($HS.Action) {
  $LogPfad = Join-Path $Textbox[0].Text.Replace('"','') $Textbox[1].Text.SubString(1)
  if (Test-Path "$LogPfad\Profilverzeichnis.zip") {rm -force "$LogPfad\Profilverzeichnis.zip"}
  &$7z a -mx5 -bso0 -bsp1 "$LogPfad\Profilverzeichnis.zip" "$env:appdata\Mozilla\Firefox\Profiles" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
    ForEach-Object { Write-Progress -Activity "Profilverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}
  if ($Checkbox[0].Checked) {
    if (Test-Path "$LogPfad\Programmverzeichnis.zip") {rm -force "$LogPfad\Programmverzeichnis.zip"}
    &$7z a -mx5 -bso0 -bsp1 "$LogPfad\Programmverzeichnis.zip" "$env:ProgramFiles\Mozilla Firefox" | out-string -stream | Select-String -Pattern "\d+(?=%)" -AllMatches |
      ForEach-Object { Write-Progress -Activity "Programmverzeichnis wird archiviert... " -PercentComplete ([int]$_.Matches.Value) -Status " "}
  }
}

Gruß Thomas
 
Zuletzt bearbeitet:
Wow.
Du bist Profi.

Habe zwei Kleinigkeiten geändert!
Code:
  $7z    = "$env:ProgramFiles\7-Zip\7z.exe"
und
Es war zweimal "Backup" als Ordner angegeben, geändert zu "BackupFirefox".

Ich habe das Skript dann mit
Code:
ps2exe -inputFile ".\Test.ps1" -noConsole -noOutput -outputFile ".\Test.exe"
konvertiert.
Funktioniert auch so weit, nur ...
der Prozess "Test" beendet sich nicht.

Das passiert bei dem alten Skript nicht! (Also bei der konvertierten EXE)
Da beendet sich der Prozess.
 
Vielleicht wäre es sinniger, gleich alles in eine Oberfläche zu packen? Mal als schnellschuss:
Code:
Add-Type -A System.Windows.Forms
...
}

Gruß Thomas
Funktioniert auch so weit, nur ...
der Prozess "Test" beendet sich nicht.

Das passiert bei dem alten Skript nicht! (Also bei der konvertierten EXE)
Da beendet sich der Prozess.
So doof scheine ich gar nicht zu sein.

Ich habe zum Einen noch den Code für die Textdatei angehängt
und
nach mehrmaligen lesen des, Deines Codes, bin ich darauf gekommen einfach
Code:
  Get-Process "Test"|kill
ganz ans Ende zu schreiben.

Ich danke Dir.
Auch wenn ich noch eine Idee hätte, lasse ich es jetzt gut sein.
Es ist ja nun mehr nicht mehr "mein" Programm und die Idee stammt ja ursprünglich auch nicht von mir.
Ich war/bin inspiriert von Firesave von Caschy.

Mal schauen, ob ich aus diesem Code auch irgendwie eine Restore-Geschichte hinbekomme.
 
Ich habe zum Einen noch den Code für die Textdatei angehängt
und
nach mehrmaligen lesen des, Deines Codes, bin ich darauf gekommen einfach
Code:
  Get-Process "Test"|kill
ganz ans Ende zu schreiben.
Nicht gut. Wenn du das Programm umbenennst geht das schief.

Ich werde bei Gelegenheit noch mal gucken wo das Problem liegt. Habe aber heute leider keine Zeit mehr dafür.

Gruß Thomas
 
OK,
habe mir noch einmal Dein Skript, ohne Veränderungen, zur Brust genommen und gleich am Anfang bin ich dann über diese Zeile gestolpert.
Code:
$Reg   = "HKCU:\Software\FF_Backup"
Also bin ich davon aus gegangen, dass das Skript "FF_Backup.ps1" heißen muss.
Gesagt, getan.
Dann das Skript in eine EXE konvertiert.
Läuft, nur, der Prozess "FF_Backup" wird auch nach Abschluss nicht beendet.
Mir scheint, als hätte ich gar keine Ahnung, was wohl auch stimmen dürfte.
Schade, dachte ich doch, ich würde zumindest dieses Skript so einigermaßen verstehen.
 
Schreibst du das Skript als Übung für dich?
Für den Zweck funktioniert MozBackup glaub ich immer noch ganz gut, wenn auch etwas in die Jahre gekommen.
 
Nicht gut. Wenn du das Programm umbenennst geht das schief.
...
Ich glaube, ich hab's!

1. Der Name der Datei, sei es das Skript oder auch die EXE, muss lauten "Backup Firefox.*"!
Tja, dann funktioniert es auch mit ä, ö & ü!
Dennoch wurde der Prozess nicht beendet.
Aber ich hatte dennoch wohl den richtigen Riecher!
2. Ans Ende Get-Process "Test"|kill geschrieben und es funktioniert!
Egal, ob das "Programm" vor getaner "Arbeit" geschlossen wird, oder ob es komplett durchläuft,
der Prozess verschwindet im Taskmanager.

Bitte um Bestätigung.

Wenn ich richtig liege, dann hätte ich ja doch das Skript verstanden, werde ich für mich noch ein, zwei Dinge anpassen,
und dann versuchen aus dem mir nun vorliegenden Code ein Skript zum wieder Herstellen zu basteln.
 
Moin,

bin leider heute erst dazu gekommen.
habe mir noch einmal Dein Skript, ohne Veränderungen, zur Brust genommen und gleich am Anfang bin ich dann über diese Zeile gestolpert.
Code:
$Reg   = "HKCU:\Software\FF_Backup"
Also bin ich davon aus gegangen, dass das Skript "FF_Backup.ps1" heißen muss.
Nein. Das ist lediglich ein Registrypfad, in dem ich den zuletzt verwendeten Pfad speichere.
Wenn du das Programm einmal ausgeführt hast und beim nächsten mal erneut startest, musst du das Backupverzeichnis so nicht immer neu öffnen.

1. Der Name der Datei, sei es das Skript oder auch die EXE, muss lauten "Backup Firefox.*"!
Nein. Der Prozess heisst immer wie die EXE-Datei, ganz egal wie die nun benannt ist.

Der Fehler lag im Runspace. Ich hatte diesen zwar gestoppt, jedoch nicht gänzlich geschlossen.

Ergänze unter der Zeile [void]$Form.ShowDialog() noch die Zeile:
Code:
  $RS.Dispose()
dann geht es.

Gruß Thomas
 
Vielen, vielen Dank für all Deine Tipps und letztendlich für Dein Skript.
Es funktioniert bestens und damit es auch so etwas wie ein LOG erstellt,
habe ich
Code:
$date = Get-Date -Format "yyyy.MM.dd - HH.mm.ss"
$datum = Get-Date -Format "dd.MM.yyyy"

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 vom $datum.txt"  -ItemType File -Force).FullName
    Add-Content $Logfile ("Diese Sicherung ist vom $(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("Vorgang beendet",0,"Firefox4backup",0)
angehängt.

Nun geht es an das Skript zum wieder herstellen.
Mal schauen, wie weit ich komme.
 
Habe z.Z. viel um die Ohren und wenn ich dann doch etwas Zeit finde, mich mit dem Thema zu befassen,
muss ich mich jedes Mal neu einarbeiten, weil ich ja nicht programmieren kann.
So verliere ich den Faden und ehrlich gesagt auch meine Motivation weiter zu machen.
Ich glaube, an dieser Stelle ist dann Ende, aus der Traum für einen Ersatz für Firesave von Caschy.
Zwar habe ich auch den Quellcode, aber die Skriptsprache von AutoIt ist ja noch komplizierter als jene von PowerShell.

Ich möchte mich noch einmal ganz, ganz herzlich bei Dir, TK87, für Deine Unterstützung bedanken.

Eine bitte noch an alle, die den Quellcode von Thomas verwenden, verweist bitte hier her auf diesen Thread in diesem Board.
Ist ja nicht zu viel verlangt.
Danke.
 
Oben