Я использую скрипт Boe Prox для печати списка всех файлов и папок в каталоге. Мне нужен сценарий Prox (в отличие от других команд печати каталога Windows), потому что он использует robocopy для печати путей к файлам длиннее 260 символов.
Моя проблема в том, что я также хочу, чтобы хэш файла печатался вместе с именем файла. Я модифицировал скрипт для получения хэшей (см. ниже), и он обычно работает, за исключением случаев, когда путь к файлу длиннее 260 символов. Длинные пути к файлам получают пробел в хэш-столбце конечного вывода.
Исследования, которые я провел:
Попытки исправить проблему:
Hash = $matches.Hash
(это возвращает все пробелы вместо файловых хэшей)If ($_.Trim() -match "^(?<Children>\d+)\s+") {
(это приводит к коду ошибки WARNING: Cannot bind argument to parameter 'Path' because it is null.
)Я очень надеюсь, что это может произойти: комментарии в исходном сценарии Бо включают строку: «Версия 1.1 - добавлена возможность вычислять хэши файлов».
Вот мой (частично рабочий скрипт):
Function Get-FolderItem {
[cmdletbinding(DefaultParameterSetName='Filter')]
Param (
[parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('FullName')]
[string[]]$Path = $PWD,
[parameter(ParameterSetName='Filter')]
[string[]]$Filter = '*.*',
[parameter(ParameterSetName='Exclude')]
[string[]]$ExcludeFile,
[parameter()]
[int]$MaxAge,
[parameter()]
[int]$MinAge
)
Begin {
$params = New-Object System.Collections.Arraylist
$params.AddRange(@("/L","/E","/NJH","/BYTES","/FP","/NC","/XJ","/R:0","/W:0","T:W"))
If ($PSBoundParameters['MaxAge']) {
$params.Add("/MaxAge:$MaxAge") | Out-Null
}
If ($PSBoundParameters['MinAge']) {
$params.Add("/MinAge:$MinAge") | Out-Null
}
}
Process {
ForEach ($item in $Path) {
Try {
$item = (Resolve-Path -LiteralPath $item -ErrorAction Stop).ProviderPath
If (-Not (Test-Path -LiteralPath $item -Type Container -ErrorAction Stop)) {
Write-Warning ("{0} is not a directory and will be skipped" -f $item)
Return
}
If ($PSBoundParameters['ExcludeFile']) {
$Script = "robocopy `"$item`" NULL $Filter $params /XF $($ExcludeFile -join ',')"
} Else {
$Script = "robocopy `"$item`" NULL $Filter $params"
}
Write-Verbose ("Scanning {0}" -f $item)
Invoke-Expression $Script | ForEach {
Try {
If ($_.Trim() -match "^(?<Children>\d+)\s+(?<FullName>.*)") {
$object = New-Object PSObject -Property @{
FullName = $matches.FullName
Extension = $matches.fullname -replace '.*\.(.*)','$1'
FullPathLength = [int] $matches.FullName.Length
Length = [int64]$matches.Size
FileHash = (Get-FileHash -Path $matches.FullName).Hash
Created = (Get-Item $matches.FullName).creationtime
LastWriteTime = (Get-Item $matches.FullName).LastWriteTime
}
$object.pstypenames.insert(0,'System.IO.RobocopyDirectoryInfo')
Write-Output $object
} Else {
Write-Verbose ("Not matched: {0}" -f $_)
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
}
}
Get-FolderItem "C:\TestingFileFolders"
🤔 А знаете ли вы, что...
С PowerShell можно автоматизировать задачи резервного копирования и восстановления данных.
В Windows PowerShell вы можете добавить \\?\ к полному пути и прочитать файл:
Get-FileHash -Path "\\?\$($matches.FullName)"