Это первая вещь, которую я написал в 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
"some text" | Tee-Object -Variable consoleOutput | Out-File "d:\logFileName.log"
Write-Host $consoleOutput
Привет, я ценю ответ, но я не уверен, что вы полностью поняли, о чем я спрашиваю? Это не работает для меня, и в моем исходном коде не хватает многих вещей. В основном, пользователю необходимо ввести каталог для поиска (который должен проверить, существует ли он, и если нет, чтобы пользователь повторил попытку), тогда он должен отображать только первые подпапки в этом каталоге, а не все подпапки в этих подпапках. -папки (до 2-х знаков после запятой в Размере), после чего лог должен выводиться на рабочий стол. Мне нравится, как вы используете шаблон, но на данный момент он просто не работает для меня.
Опять же, на самом деле моя единственная проблема, с которой я сталкиваюсь в своем коде, заключается в том, что я хочу, чтобы он отображал список папок в консоли во время запуска сценария, а также вывод в файл журнала. На данный момент он просто регистрируется и ничего не показывает в консоли.
Хотя этот код может дать ответ на вопрос, предоставление дополнительного контекста относительно того, как и/или почему он решает проблему, улучшит долгосрочную ценность ответа.
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 )
, вы получите вывод только сразу, когда код завершится.
Привет, спасибо за ваш комментарий. Думаю, я все понял и теперь работаю.
Причина, по которой
Write-Host
не пишет в консоль, заключается в том, что в Windows PowerShell v5+ он использует информационный поток. Это означает, что*>&1
перенаправляетwrite-host
на поток успеха, который перенаправляется на ваш файл. Если вы хотите фиксировать только успехи и ошибки, то, например,2>&1
будет делать это, показываяwrite-host
вывод на консоли.