Вычислить хэш файла длиннее 256 символов?

Я использую скрипт 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 можно автоматизировать задачи резервного копирования и восстановления данных.


2
578
1

Ответ:

Решено

В Windows PowerShell вы можете добавить \\?\ к полному пути и прочитать файл:

Get-FileHash -Path "\\?\$($matches.FullName)"