Это должно делать то, что вы хотите:
#Set-ExecutionPolicy Unrestricted
$SourcePath = "G:\My Drive"
$DestinationCSVPath = "e:\G Drive Inventory 20180611.csv" #Destination for Temp CSV File
$CSVColumnOrder = 'Path', 'IsDIR', 'Directory', 'FileCount', 'Parent', 'Name', 'CreationTime', 'LastAccessTime', 'LastWriteTime', 'Extension', 'BaseName', 'B','ID','ParentID'
#, 'Root', 'IsReadOnly', 'Attributes', 'Owner', 'AccessToString', 'Group' #, #'MD5', #'SHA1' #Order in which columns in CSV Output are ordered
#FOLDERS ONLY
#$SourcePathFileOutput = Get-ChildItem $SourcePath -Recurse | where {$_.PSIsContainer}
#FILES AND FOLDERS
$SourcePathFileOutput = Get-ChildItem $SourcePath -Recurse | Sort-Object Fullname #| where {$_.PSIsContainer} #Uncomment for folders only
$CurrentID = 1
$IDs = [ordered]@{}
$IDs.add(($SourcePathFileOutput[0].fullname | split-path),0)
$HashOutput = ForEach ($file in $SourcePathFileOutput) {
$IDs.add($file.fullname,$CurrentID)
Write-Output (New-Object -TypeName PSCustomObject -Property @{
ID = $CurrentID
ParentID = $IDs.$($file.fullname | split-path)
Path = $file.FullName
IsDIR = $file.PSIsContainer
Directory = $File.DirectoryName
FileCount = (GCI $File.FullName -Recurse).Count
Parent = $file.Parent
Name = $File.Name
CreationTime = $File.CreationTime
LastAccessTime = $File.LastAccessTime
LastWriteTime = $File.LastWriteTime
Extension = $File.Extension
BaseName = $File.BaseName
B = $File.Length
#Root = $file.Root
#IsReadOnly = $file.IsReadOnly
#Attributes = $file.Attributes
#Owner = $acl.owner
#AccessToString = $acl.accesstostring
#Group = $acl.group
#MD5 = Get-FileHash $file.FullName -Algorithm MD5 | Select-Object -ExpandProperty Hash
#SHA1 = Get-FileHash $file.FullName -Algorithm SHA1 | Select-Object -ExpandProperty Hash
}) | Select-Object $CSVColumnOrder
$CurrentID++
}
$HashOutput | Export-Csv -NoTypeInformation -Path $DestinationCSVPath
Объяснение:
Я передал $SourcePathFileOutput
на Sort-Object
, потому что проще всего назначить заказанныйИдентификатор, если вещи отсортированы по их расположению в дереве каталогов.
$CurrentID
начинается с 1, поскольку первый элемент в цикле не является корневым родителем.Ваш цикл будет увеличивать эту переменную на 1 ($CurrentID++
) в конце каждой итерации цикла, так что следующий файл / каталог получит новый номер.Поскольку этот код создает $CurrentID
как тип Int32
, у вас будут проблемы, если у вас более 2 миллиардов файлов / каталогов.Вам придется инициализировать его как 64-битный тип ($CurrentID = [long]1
).Тем не менее, я считаю, что в хеш-таблице может быть только число ключей Int32, поэтому нужно использовать другую стратегию, если у вас есть миллиарды файлов.
$IDs
- это упорядоченная хеш-таблица, которая отслеживает идентификаторыдля всех файлов и каталогов.Каждый ключ в хэш-таблице - это путь к текущему элементу в цикле.Значением является присвоение идентификатора.Это означает, что вы можете получить доступ к идентификатору, используя синтаксис $IDs.path
.После инициализации я добавил первую запись с идентификатором 0, которая представляет корневого родителя.
Внутри цикла я создал свойство ID
, которое просто хранит текущее значение $CurrentID
.Я создал 'ParentID', который ищет родительский каталог внутри хеш-таблицы $IDs
и возвращает значение идентификатора этого ключа.
Я обновил $CSVColumnOrder
, чтобы ID
и ParentID
были столбцами.
Вы могли бы немного отличать схему идентификатора, если бы вы делали начальную сортировку иначе.Вам не нужно увеличивать на 1. У вас может быть требование, чтобы каталоги имели меньшие идентификаторы, чем файлы, и для этого потребуется больше кода (хотя я не видел этого требования).