【问题标题】:How can I change my code to output to the console and to an output log in Powershell?如何更改我的代码以输出到控制台和 Powershell 中的输出日志?
【发布时间】:2020-12-22 20:35:12
【问题描述】:

这是我在 Powershell 中编写的第一件事(我更喜欢 VBA 人),如果您发现它有很多问题,请原谅。我真的只是在即兴发挥,所以非常感谢任何帮助。

我为我的工作制作了这个,基本上是抓取主要的子文件夹并吐出它们的大小、文件数和文件夹数。它工作得很好,输出日志按照我想要的方式出现。我希望它在控制台和输出日志中更新,因为我们经常检查大文件夹,所以它可能需要一些时间,所以我想让人们看到它在每个文件夹中更新。但是,我想不通。

我看到也许Tee-Object 可以/应该使用,但我不太清楚如何将它与我想要输出的所有行合并。我想输出的每一行都带有echo 命令。 Write-Host 似乎只有在我禁用日志时才有效。

这是我的代码:

While ($true){
    $startDirectory = Read-Host "Enter path/directory"
    if (Test-Path -Path $startDirectory) { break }
    Write-Host "Wrong path. Please try again" -ForegroundColor Red
}
Write-Host ""
Write-Host "Getting information..." -ForegroundColor Green
Write-Host "This can take a while if the selected directory is large and/or contains a lot of files. An output log will be created at the end."
Write-Host ""
 
$directoryItems = Get-ChildItem $startDirectory | Where-Object {$_.PSIsContainer -eq $true} | Sort-Object
$ParentFileSize = 0
$TotalFiles = 0
$TotalFolders = 0
$SubFileCount = 0
$SubFolderCount = 0
$SubFileSize = 0
$TotalSize = 0
$Tab = [char]9 

$(
echo "Output file generated to: $env:USERPROFILE\Desktop\Output.txt" " "
echo "List of Folders in '$startDirectory'" " "
echo "Size (GB): $Tab Files: $Tab Folders: $Tab Folder Name:" " "

$ParentFileCount = (Get-ChildItem $startDirectory -File).Count
$ParentFolderCount = (Get-ChildItem $startDirectory -Directory).Count
$ParentFileSize = Get-ChildItem $startDirectory -File | Measure-Object -property Length -sum | Select-Object Sum
$ParentFileSize = "{0:N2}" -f ($ParentFileSize.sum / 1GB)
foreach ($i in $directoryItems)
{
    $subFolderItems = Get-ChildItem $i.FullName -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
    $FolderSize = "{0:N2}" -f ($subFolderItems.sum / 1GB)
    $FileCount = Get-ChildItem $i.FullName -Recurse -File | Measure-Object | %{$_.Count}
    $FolderCount = Get-ChildItem $i.FullName -Recurse -Directory | Measure-Object | %{$_.Count}

    echo "$FolderSize $Tab $Tab $FileCount $Tab $Tab $FolderCount $Tab $Tab $i"
    $SubFileCount = $SubFileCount + $FileCount
    $SubFolderCount = $SubFolderCount + $FolderCount
    $SubFileSize = $SubFileSize + $FolderSize
}

$TotalFolders = $SubFolderCount + $ParentFolderCount
$TotalFiles = $SubFileCount + $ParentFileCount
$TotalSize = $SubFileSize +  $ParentFileSize
$TotalSize = "{0:N2}" -f ($TotalSize)
$SubFileSize = "{0:N2}" -f ($SubFileSize)

echo " " " " "Total in '$startdirectory':" " "
echo "Size: $TotalSize GB ($SubFileSize GB in sub-folders)" "Files: $TotalFiles ($SubFileCount in sub-folders)" "Folders: $TotalFolders ($SubFolderCount in sub-folders)"

) *>&1 > $env:USERPROFILE\Desktop\Output.txt

Invoke-Item $env:USERPROFILE\Desktop\Output.txt

【问题讨论】:

  • Write-Host 不写入控制台的原因是因为在 Windows PowerShell v5+ 中它使用信息流。这意味着*>&1write-host 重定向到成功流,该成功流将重定向到您的文件。如果您只想捕获成功和错误,那么 2>&1 将在控制台显示 write-host 输出时这样做。

标签: powershell


【解决方案1】:

Tee-Object 是正确的方法。它允许您同时写入文件并将输入转发到管道中,最终在控制台中结束。

将您要提供给Tee-Object 的输出的代码移动到函数或脚本块中。

使用脚本块的示例:

& {
    Write-Output 'foo'
    Sleep 2
    Write-Output 'bar'
} *>&1 | Tee-Object log.txt

使用函数的示例:

Function FooBar {
    Write-Output 'foo'
    Sleep 2
    Write-Output 'bar'
}

FooBar *>&1 | Tee-Object log.txt

我的示例中的 Sleep 只是为了证明在脚本块或函数仍在运行时显示输出。

如果您将脚本块更改为$( some code ),您只会在代码完成后立即收到输出。

【讨论】:

  • 您好,感谢您的评论。我想我已经想通了,现在可以开始工作了。
【解决方案2】:
"some text" | Tee-Object -Variable consoleOutput | Out-File "d:\logFileName.log"
Write-Host $consoleOutput

【讨论】:

  • 您好,感谢您的回复,但我不确定您是否完全理解我的要求?这对我不起作用,并且我的原始代码中缺少很多东西。主要是,用户需要输入要搜索的目录(它应该测试它是否存在,如果没有让用户重试),那么它应该只列出该目录中的第一个子文件夹,而不是这些子中的每个子文件夹-folders(到大小的小数点后 2 位),然后日志应该输出到桌面。我喜欢你使用的模板方式,但它现在对我不起作用。
  • 再一次,我的代码面临的唯一问题是我希望它在脚本运行以及输出到日志文件时在控制台中显示文件夹列表。目前它只是记录并没有在控制台中显示任何内容。
  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多