chkdsk
Goto Top

Powershell Start-Transcript zeigt kein Logging

Guten Morgen Zusammen,

folgende Ausgangssituation: Ich habe ein Skript welches alte Word Dokumente im .doc Format nach .docx umwandelt. In der GUI gebe ich den Quellpfad und den Zielpfad an. Das Skript konvertiert die Dateien im Quellpfad und verschiebt sie anschließend in den Zielpfad. Das funktioniert soweit auch.

Start-Transcript -path "c:\temp\Logfiles\convert_log.txt" -NoClobber  

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.IO

# Create a form
$form = New-Object System.Windows.Forms.Form
$form.Text = ".doc to .docx converter"  
$form.Size = New-Object System.Drawing.Size(380, 700)
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
#$Form.Icon            = 

# Create labels
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Point(10, 20)
$label1.Size = New-Object System.Drawing.Size(280, 20)
$label1.Text = "Quellordner:"  

$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10, 80)
$label2.Size = New-Object System.Drawing.Size(280, 20)
$label2.Text = "Zielordner:"  

# Create textboxes to display the selected folder paths
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10, 50)
$textBox1.Size = New-Object System.Drawing.Size(200, 20)
$textBox1.ReadOnly = $true

$textBox2 = New-Object System.Windows.Forms.TextBox
$textBox2.Location = New-Object System.Drawing.Point(10, 110)
$textBox2.Size = New-Object System.Drawing.Size(200, 20)
$textBox2.ReadOnly = $true

# Create button 1 to open the folder picker dialog for folder 1
$button1 = New-Object System.Windows.Forms.Button
$button1.Location = New-Object System.Drawing.Point(220, 50)
$button1.Size = New-Object System.Drawing.Size(60, 20)
$button1.Text = "Suche"  
$button1.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $result = $folderBrowser.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $selectedFolder = $folderBrowser.SelectedPath
        $textBox1.Text = $selectedFolder
    }
})

# Create button 2 to open the folder picker dialog for folder 2
$button2 = New-Object System.Windows.Forms.Button
$button2.Location = New-Object System.Drawing.Point(220, 110)
$button2.Size = New-Object System.Drawing.Size(60, 20)
$button2.Text = "Suche"  
$button2.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $result = $folderBrowser.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $selectedFolder = $folderBrowser.SelectedPath
        $textBox2.Text = $selectedFolder
    }
})

# Create button 1 to clear the selected folder path for folder 1
$clearButton1 = New-Object System.Windows.Forms.Button
$clearButton1.Location = New-Object System.Drawing.Point(300, 50)
$clearButton1.Size = New-Object System.Drawing.Size(60, 20)
$clearButton1.Text = "Löschen"  
$clearButton1.Add_Click({
    $textBox1.Text = ""  
})

# Create button 2 to clear the selected folder path for folder 2
$clearButton2 = New-Object System.Windows.Forms.Button
$clearButton2.Location = New-Object System.Drawing.Point(300, 110)
$clearButton2.Size = New-Object System.Drawing.Size(60, 20)
$clearButton2.Text = "Löschen"  
$clearButton2.Add_Click({
    $textBox2.Text = ""  
})

# Create the TextBox control
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Multiline = $true
$textbox.ScrollBars = "Vertical"  
$textbox.Location = New-Object System.Drawing.Point(10, 250)
$textbox.Size = New-Object System.Drawing.Size(350, 400)

# Function to append output to the textbox
function AppendToTextBox($text) {
    $textbox.AppendText("$text`r`n")  
    $textbox.ScrollToCaret()
}

# Create a button to convert .doc files and move them to the new folder
$copyButton = New-Object System.Windows.Forms.Button
$copyButton.Location = New-Object System.Drawing.Point(10, 180)
$copyButton.Size = New-Object System.Drawing.Size(350, 30)
$copyButton.Text = "++ Konvertieren ++"  
$copyButton.Add_Click({

    # Redirect output to the textbox
    $oldOut = [Console]::Out
    $outWriter = New-Object System.IO.StringWriter
    [Console]::SetOut($outWriter)
    function Write-Host($text) {
        AppendToTextBox $text
    }

    $sourcePath = $textBox1.text
    $destinationPath = $textBox2.text
    $fileFormat = "*.docx"  

    [ref]$SaveFormat = "microsoft.office.interop.word.WdSaveFormat" -as [type]  
    $1word = New-Object -ComObject Word.Application
    $1word.Visible = $False

    $Path = Get-ChildItem $sourcePath -Recurse -Force | where{$_.Extension -eq ".doc"}   
    if($Path){
        forEach($EV in $Path) {
            Write-Host "Converting: $($EV.FullName)" -ForegroundColor Green  
            [ref]$name = Join-Path -Path $EV.DirectoryName -ChildPath $($EV.BaseName + ".docx")  
            $opendoc = $1word.documents.open($EV.FullName)
            $opendoc.saveas([ref]$name.Value, [ref]$saveFormat::wdFormatDocument)
            $opendoc.saveas([ref]$name.Value, [ref]$SaveFormat::wdFormatDocument)
            $opendoc.close()
            $EV = $null
        }
    }

    $files = Get-ChildItem -Path $sourcePath -Filter $fileFormat -Recurse | Where-Object { $_.Name -notlike "~$*" }  

    foreach ($file in $files) {
        $destinationFile = $file.FullName.Replace($sourcePath, $destinationPath)
        $destinationDirectory = Split-Path -Path $destinationFile -Parent

        if (!(Test-Path -Path $destinationDirectory)) {
            New-Item -ItemType Directory -Path $destinationDirectory | Out-Null
        }

        Move-Item -Path $file.FullName -Destination $destinationFile
        Remove-Item -Path "$sourcePath\*~*.docx" -Force  
    }

    $sourceFiles = Get-ChildItem -Path $sourcePath -File -Recurse

    foreach ($sourceFile in $sourceFiles) {
        $baseName = $sourceFile.BaseName

        $destinationFile = Get-ChildItem -Path $destinationPath -File -Recurse | Where-Object { $_.BaseName -eq $baseName }

        if ($destinationFile) {
            $sourceMeta = Get-Item -Path $sourceFile.FullName

            $destinationFile.CreationTime = $sourceMeta.CreationTime
            $destinationFile.LastWriteTime = $sourceMeta.LastWriteTime
        }
    }

    # Restore output
    [Console]::SetOut($oldOut)
    $outWriter.Close()

    # Display the output in the textbox
    $output = $outWriter.ToString()
    AppendToTextBox $output

    $1word.Quit()
    $1word = $null
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

    Write-Host "Abgeschlossen!" -ForegroundColor Green  
})

Stop-Transcript

# Add controls to the form
$form.Controls.Add($label1)
$form.Controls.Add($textBox1)
$form.Controls.Add($button1)
$form.Controls.Add($clearButton1)
$form.Controls.Add($label2)
$form.Controls.Add($textBox2)
$form.Controls.Add($button2)
$form.Controls.Add($clearButton2)
$form.Controls.Add($copyButton)
$form.Controls.Add($textbox)

# Show the form
$form.ShowDialog() | Out-Null

Das Problem ist jetzt folgendes. Um zu überprüfen ob alle Dateien ordnungsgemäß konvertiert und verschoben wurden, wollte ich ein Logging einbauen um zu sehen welche Dateien entweder nicht konvertiert oder nicht verschoben wurden und was der Grund dafür ist. Die erstellte Datei ist jetzt prinzipiell nicht leer. Der typische Header der Transscript Datei ist vorhanden, ich sehe auch den Start und das Ende des Skripts aber eben nicht die Zwischenschritte des ausgeführten Skripts. Vielleicht kann mir hier jermand beim Logging helfen.

Beste Grüße

Content-ID: 7811932261

Url: https://administrator.de/contentid/7811932261

Printed on: November 6, 2024 at 17:11 o'clock

Kraemer
Kraemer Jul 11, 2023 at 06:38:23 (UTC)
Goto Top
Moin,

und das wundert dich warum?

Was machst du denn hier?
$oldOut = [Console]::Out
$outWriter = New-Object System.IO.StringWriter
[Console]::SetOut($outWriter)
nox309
nox309 Jul 11, 2023 at 06:49:53 (UTC)
Goto Top
Moin,

Wenn ich mich nicht täusche dann logt das Transkript nur den Inhalt der Konsole hier lässt du dir aber nichts ausgeben.
Den Grund dafür hat dir Kraemer ja schon genannt, zumindest wenn ich dein Skript richtig lese.

Ich habe mir mal eine "Log Funktion" gebaut die dir ggf. die Infos liefert die du haben willst wenn du sie entsprechend fütterst. Diese schreibt nicht nur eine Logdatei sondern wenn man will auch ein Konsolen Output.
myPosh_write-log
chkdsk
chkdsk Jul 11, 2023 at 06:58:44 (UTC)
Goto Top
Zitat von @Kraemer:

Moin,

und das wundert dich warum?

Was machst du denn hier?
$oldOut = [Console]::Out
$outWriter = New-Object System.IO.StringWriter
[Console]::SetOut($outWriter)

Ich habe die Zeilen jetzt mal entfernt, damit die Ausgabe auch in der Konsole angezeigt wird. Die Logdatei ist aber immer noch "leer".
nox309
nox309 Jul 11, 2023 at 07:08:14 (UTC)
Goto Top
Ich habe die Zeilen jetzt mal entfernt, damit die Ausgabe auch in der Konsole angezeigt wird. Die Logdatei ist aber immer noch "leer".

bekommst du denn eine Ausgabe in der Konsole was er macht?
Ich würde das Stop-Transcript noch an den Schluss setzten so das beim Schließen der GUI erst das Transcript beendet wird.
Kraemer
Kraemer Jul 11, 2023 at 08:16:37 (UTC)
Goto Top
Zitat von @chkdsk:

Ich habe die Zeilen jetzt mal entfernt, damit die Ausgabe auch in der Konsole angezeigt wird. Die Logdatei ist aber immer noch "leer".

Ich weiß nicht, was du erwartest. Hier leitest du ins Nirvana um
New-Item -ItemType Directory -Path $destinationDirectory | Out-Null

Remove-Item
Move-Item
hat keinen Output

und Word gibt nichts an die Konsole zurück...
chkdsk
chkdsk Jul 11, 2023 at 08:41:42 (UTC)
Goto Top
Zitat von @Kraemer:

Zitat von @chkdsk:

Ich habe die Zeilen jetzt mal entfernt, damit die Ausgabe auch in der Konsole angezeigt wird. Die Logdatei ist aber immer noch "leer".

Ich weiß nicht, was du erwartest. Hier leitest du ins Nirvana um
New-Item -ItemType Directory -Path $destinationDirectory | Out-Null

Remove-Item
Move-Item
hat keinen Output

und Word gibt nichts an die Konsole zurück...

Das ist natürlich richtig. Prinzipiell geht es mir auch eher um die Konvertierung.
Kraemer
Kraemer Jul 11, 2023 at 09:11:58 (UTC)
Goto Top
Zitat von @chkdsk:

Das ist natürlich richtig. Prinzipiell geht es mir auch eher um die Konvertierung.

weißt du eigentlich, was dein Skript macht?
chkdsk
chkdsk Jul 11, 2023 at 12:00:01 (UTC)
Goto Top
Zitat von @Kraemer:

Zitat von @chkdsk:

Das ist natürlich richtig. Prinzipiell geht es mir auch eher um die Konvertierung.

weißt du eigentlich, was dein Skript macht?

Selbstverständlich. Was soll die Frage? Hab es jetzt wie folgt gelöst.
<#############################################################################################################################################################################################################
running powershell visible#>
$window = Add-Type -memberDefinition @"  
[DllImport("user32.dll")]  
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru  
$window::ShowWindow((Get-Process –id $pid).MainWindowHandle, 5)

$scriptPath = $MyInvocation.MyCommand.Path
$logFilePath = Join-Path -Path (Split-Path -Path $scriptPath -Parent) -ChildPath "convert_log.txt"  

# Function to append output to the textbox and log file
function AppendToTextBox($text) {
    $textbox.AppendText("$text`r`n")  
    $textbox.ScrollToCaret()
    Write-Output $text | Out-File -FilePath $logFilePath -Append
}

function AppendErrorToTextBox($errorMessage) {
    $textbox.AppendText("ERROR: $errorMessage`r`n")  
    $textbox.ScrollToCaret()
    Write-Output "ERROR: $errorMessage" | Out-File -FilePath $logFilePath -Append  
}

$standardErrorWriter = [System.IO.StreamWriter]::new($logFilePath, $true)
$standardErrorWriter.AutoFlush = $true
[System.Console]::SetError($standardErrorWriter)

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.IO

# Create a form
$form = New-Object System.Windows.Forms.Form
$form.Text = ".doc to .docx converter"  
$form.Size = New-Object System.Drawing.Size(380, 700)
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
#$Form.Icon            = 

# Create labels
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Point(10, 20)
$label1.Size = New-Object System.Drawing.Size(280, 20)
$label1.Text = "Quellordner:"  

$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10, 80)
$label2.Size = New-Object System.Drawing.Size(280, 20)
$label2.Text = "Zielordner:"  

# Create textboxes to display the selected folder paths
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10, 50)
$textBox1.Size = New-Object System.Drawing.Size(200, 20)
$textBox1.ReadOnly = $true

$textBox2 = New-Object System.Windows.Forms.TextBox
$textBox2.Location = New-Object System.Drawing.Point(10, 110)
$textBox2.Size = New-Object System.Drawing.Size(200, 20)
$textBox2.ReadOnly = $true

# Create button 1 to open the folder picker dialog for folder 1
$button1 = New-Object System.Windows.Forms.Button
$button1.Location = New-Object System.Drawing.Point(220, 50)
$button1.Size = New-Object System.Drawing.Size(60, 20)
$button1.Text = "Suche"  
$button1.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $result = $folderBrowser.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $selectedFolder = $folderBrowser.SelectedPath
        $textBox1.Text = $selectedFolder
    }
})

# Create button 2 to open the folder picker dialog for folder 2
$button2 = New-Object System.Windows.Forms.Button
$button2.Location = New-Object System.Drawing.Point(220, 110)
$button2.Size = New-Object System.Drawing.Size(60, 20)
$button2.Text = "Suche"  
$button2.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $result = $folderBrowser.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $selectedFolder = $folderBrowser.SelectedPath
        $textBox2.Text = $selectedFolder
    }
})

# Create button 1 to clear the selected folder path for folder 1
$clearButton1 = New-Object System.Windows.Forms.Button
$clearButton1.Location = New-Object System.Drawing.Point(300, 50)
$clearButton1.Size = New-Object System.Drawing.Size(60, 20)
$clearButton1.Text = "Löschen"  
$clearButton1.Add_Click({
    $textBox1.Text = ""  
})

# Create button 2 to clear the selected folder path for folder 2
$clearButton2 = New-Object System.Windows.Forms.Button
$clearButton2.Location = New-Object System.Drawing.Point(300, 110)
$clearButton2.Size = New-Object System.Drawing.Size(60, 20)
$clearButton2.Text = "Löschen"  
$clearButton2.Add_Click({
    $textBox2.Text = ""  
})

# Create the TextBox control
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Multiline = $true
$textbox.ScrollBars = "Vertical"  
$textbox.Location = New-Object System.Drawing.Point(10, 250)
$textbox.Size = New-Object System.Drawing.Size(350, 400)

# Create a button to convert .doc files and move them to the new folder
$copyButton = New-Object System.Windows.Forms.Button
$copyButton.Location = New-Object System.Drawing.Point(10, 180)
$copyButton.Size = New-Object System.Drawing.Size(350, 30)
$copyButton.Text = "++ Konvertieren ++"  
$copyButton.Add_Click({

    function Write-Host($text) {
        AppendToTextBox $text
    }

    function Write-Error($errorMessage, $fileName) {
        $formattedErrorMessage = "ERROR: File $fileName - $errorMessage"  
        AppendErrorToTextBox $formattedErrorMessage
        Write-Output $formattedErrorMessage | Out-File -FilePath $logFilePath -Append
    }

    $sourcePath = $textBox1.text
    $destinationPath = $textBox2.text
    $fileFormat = "*.docx"  

    [ref]$SaveFormat = "microsoft.office.interop.word.WdSaveFormat" -as [type]  
    $word = New-Object -ComObject Word.Application
    $word.Visible = $True

    $Path = Get-ChildItem $sourcePath -Recurse -Force | where{$_.Extension -eq ".doc" }  

    if($Path){
        forEach($EV in $Path) {
            try {
                Write-Host "Converting: $($EV.FullName)" -ForegroundColor Green  
                [ref]$name = Join-Path -Path $EV.DirectoryName -ChildPath $($EV.BaseName + ".docx")  
                $opendoc = $word.documents.open($EV.FullName)
                $opendoc.saveas([ref]$name.Value, [ref]$saveFormat::wdFormatDocument)
                $opendoc.saveas([ref]$name.Value, [ref]$SaveFormat::wdFormatDocument)
                $opendoc.close()
                $EV = $null
            }
            catch {
                $errorMessage = $_.Exception.Message
                $fileName = [System.IO.Path]::GetFileNameWithoutExtension($EV.FullName)
                Write-Error $errorMessage $fileName
            }
        }
    }

    $files = Get-ChildItem -Path $sourcePath -Filter $fileFormat -Recurse | Where-Object { $_.Name -notlike "~$*" }  

    foreach ($file in $files) {
        try {
            $destinationFile = $file.FullName.Replace($sourcePath, $destinationPath)
            $destinationDirectory = Split-Path -Path $destinationFile -Parent

            if (!(Test-Path -Path $destinationDirectory)) {
                New-Item -ItemType Directory -Path $destinationDirectory | Out-Null
            }

            $destinationFilePath = Join-Path -Path $destinationPath -ChildPath $file.Name
            if (Test-Path -Path $destinationFilePath) {
                Write-Host "Overwriting existing file: $destinationFilePath" -ForegroundColor Yellow  
                Remove-Item -Path $destinationFilePath -Force
            }

            Move-Item -Path $file.FullName -Destination $destinationFile -ErrorAction Stop
            Remove-Item -Path "$sourcePath\*~*.docx" -Force  
        }
        catch {
            $errorMessage = $_.Exception.Message
            $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file.FullName)
            Write-Error $errorMessage $fileName
        }
    }

    $sourceFiles = Get-ChildItem -Path $sourcePath -File -Recurse

    foreach ($sourceFile in $sourceFiles) {
        try {
            $baseName = $sourceFile.BaseName

            $destinationFile = Get-ChildItem -Path $destinationPath -File -Recurse | Where-Object { $_.BaseName -eq $baseName }

            if ($destinationFile) {
                $sourceMeta = Get-Item -Path $sourceFile.FullName

                $destinationFile.CreationTime = $sourceMeta.CreationTime
                $destinationFile.LastWriteTime = $sourceMeta.LastWriteTime
            }
        }
        catch {
            $errorMessage = $_.Exception.Message
            $fileName = [System.IO.Path]::GetFileNameWithoutExtension($sourceFile.FullName)
            Write-Error $errorMessage $fileName
        }
    }

    $word.Quit()
    $word = $null
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

    Write-Host "Abgeschlossen!" -ForegroundColor Green  
})

# Stop capturing output to the log file and close it
$standardErrorWriter.Flush()
$standardErrorWriter.Close()

Stop-Transcript

# Add controls to the form
$form.Controls.Add($label1)
$form.Controls.Add($textBox1)
$form.Controls.Add($button1)
$form.Controls.Add($clearButton1)
$form.Controls.Add($label2)
$form.Controls.Add($textBox2)
$form.Controls.Add($button2)
$form.Controls.Add($clearButton2)
$form.Controls.Add($copyButton)
$form.Controls.Add($textbox)

# Show the form
$form.ShowDialog() | Out-Null