【问题标题】:Write PowerShell console text to a file将 PowerShell 控制台文本写入文件
【发布时间】:2018-12-03 15:50:43
【问题描述】:

我有一个 PowerShell 脚本,它连接到数据库并循环访问一些数据。

脚本完成或引发错误后,我需要将控制台中显示的任何文本附加到日志文件中。

使用Write-Output 无法实现这一点,因为我不想保存特定值,我只需要将整个控制台文本附加到文件中。

谢谢。

编辑:

事实上,我正在寻找的最终结果是一个带有时间戳的日志文件,这是我的代码:

$server = "USER\SQLEXPRESS"
$database = "database_test"
$tablequery = "SELECT name from sys.tables"

#Delcare Connection Variables
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString

$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandText = $tablequery
$command.Connection = $connection

#Load up the Tables in a dataset
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $command
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$connection.Close()

$DriveName = (get-location).Drive.Name
$extractDir = md -Force "$($DriveName):\csv\files"

# Loop through all tables and export a CSV of the Table Data
foreach ($Row in $DataSet.Tables[0].Rows)
{
    $connection.open();
    #Specify the output location of your dump file
    $command.CommandText = "SELECT * FROM [$($Row[0])]"
    $command.Connection = $connection

    (Get-Culture).NumberFormat.NumberDecimalSeparator = '.'
    (Get-Culture).DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'

    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
    $SqlAdapter.SelectCommand = $command
    $DataSet = New-Object System.Data.DataSet
    $SqlAdapter.Fill($DataSet)
    $connection.Close()

    $extractFile = "$($extractDir)\$($Row[0]).csv"
    $DataSet.Tables[0]  | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
}

我需要在日志文件中使用时间戳打印导出到 csv ($extractFile) 的每个文件名,然后如果发生错误,我也需要使用时间戳打印,依此类推,直到脚本完成。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您可以使用 Start-Transcripttry/catch/finally 或编写自己的代码(将控制台输出存储到变量,并附加文本文件需要时附上内容)。注意-Append 参数和Start-Transcript

    没有代码,很难知道推荐哪一个。

    展开

    现在您已经添加了一些代码,请查看有关每种方法的一些附加信息。我不熟悉通过 PowerShell 进行的 SQL,因此不确定您将得到什么样的输出/错误(关于错误,特别是是否存在终止或非终止)

    成绩单

    Start-Transcript 应该在开头,Stop-Transcript 在结尾。这将记录控制台上通常显示的任何内容。在已记录成绩单时运行 Start-Transcript 会导致严重错误。

    Start-Transcript -Path "c\temp\mylogfile.txt"
    
    $server = "USER\SQLEXPRESS"
    $database = "database_test"
    $tablequery = "SELECT name from sys.tables"
    ...
    
    ...
        $extractFile = "$($extractDir)\$($Row[0]).csv"
        $DataSet.Tables[0]  | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
    }
    
    Stop-Transcript
    

    终止错误

    酌情添加try/catch/finally。你可以偷懒把它加到整个代码上,或者做正确的事并包装可能导致terminating errors的部分。

    ...
    foreach ($Row in $DataSet.Tables[0].Rows)
    {
        try{
            $connection.open();
            #Specify the output location of your dump file
            ...
    
            ...
            ...
            $extractFile = "$($extractDir)\$($Row[0]).csv"
            $DataSet.Tables[0]  | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
        }catch{
            # what to do if there is a terminating error
        }finally{
            # what to do whether there is an error or not
    
            if(Test-Path "$($extractDir)\$($Row[0]).csv"){
                # simple check: if a file was created, no error... right?
                "$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $($Error[0])" | Out-File "c:\temp\mylogfile.txt" -Append
            }else{
                "$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $extractFile" | Out-File "c:\temp\mylogfile.txt" -Append
            }
        }
    }
    ...
    

    无终止错误

    只需添加一行即可导出错误。确保在每个循环中清除自动变量 $Error

    ...
    foreach ($Row in $DataSet.Tables[0].Rows)
    {
        $Error.Clear()
        $connection.open();
        #Specify the output location of your dump file
        ...
    
        ...
        ...
        $extractFile = "$($extractDir)\$($Row[0]).csv"
        $DataSet.Tables[0]  | Export-Csv $extractFile -NoTypeInformation -Encoding UTF8
    
        # if there are no errors, write filename. Otherwise write errors
        if([string]::IsNullOrEmpty($Error){
            "$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $extractFile" | Out-File "c:\temp\mylogfile.txt" -Append
        }else{
            "$(Get-Date -f 'yyyy-MM-dd hh:mm:ss') $Error" | Out-File "c:\temp\mylogfile.txt" -Append
        }
    }
    ...
    

    【讨论】:

    • 我更新了我的问题,以便您了解我真正想做的事情。
    【解决方案2】:

    您可以使用Start-Transcript 进行调试:

    Start-Transcript -path "C:\temp\myTranscript.txt"
    

    在脚本开头添加,并将所有控制台输出写入C:\temp\myTranscript.txt

    【讨论】:

    • 它没有用,如果你想看一下,我已经更新了我的问题。
    • 你把Start-Transcript放在哪里了?
    • 脚本结束
    • 应该在脚本的最开始
    • 上面说,他File参数无效