Включение идентификатора and и родительского идентификатора в каталог файлов Powershell

#powershell

#powershell

Вопрос:

У меня есть скрипт powershell, который выполняет инвентаризацию файлового ресурса. Я хочу знать, как добавить идентификатор к каждой строке в csv-файле, а также родительский идентификатор к строке в csv.

Я новичок в Powershell, но разобрался, как заставить скрипт инвентаризации работать. Вот код.

 #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'
#, '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  #| where {$_.PSIsContainer} #Uncomment for folders only


$HashOutput = ForEach ($file in $SourcePathFileOutput) {
    Write-Output (New-Object -TypeName PSCustomObject -Property @{
        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
}


$HashOutput | Export-Csv -NoTypeInformation -Path $DestinationCSVPath
  

Я хочу знать, как добавить идентификатор к каждой строке в csv-файле, а также родительский идентификатор к строке в csv.

Комментарии:

1. Я совсем не уверен, что вы имеете в виду под ID … Не могли бы вы подробнее остановиться на этом и, возможно, привести пример желаемого результата?

2. Присвоение уникального идентификатора каждому результату, а также последующее вычисление родительского элемента. Например C:files, Идентификатор 1, родительский идентификатор 0, C:FilesFolder Идентификатор 2, родительский идентификатор 1 и т.д. По ходу работы генерирует свой список вместе со всеми другими вычислениями.

Ответ №1:

попробуйте что-то вроде этого:

 $ID=1
$SourcePath="c:temp"

$SourcePathFileOutput=@()

#for have the parent dir
$SourcePathFileOutput  = Get-Item $SourcePath | %{
$ParentPath=if ($_.PSIsContainer){$_.parent.FullName}else{$_.DirectoryName}

Add-Member -InputObject $_ -MemberType NoteProperty -Name "ID" -Value ($ID  )
Add-Member -InputObject $_ -MemberType NoteProperty -Name "PARENTPATH" -Value $ParentPath
$_
}

#for have all directory and file
$SourcePathFileOutput  = Get-ChildItem $SourcePath -Recurse | %{
$ParentPath=if ($_.PSIsContainer){$_.parent.FullName}else{$_.DirectoryName}

Add-Member -InputObject $_ -MemberType NoteProperty -Name "ID" -Value ($ID  )
Add-Member -InputObject $_ -MemberType NoteProperty -Name "PARENTPATH" -Value $ParentPath
$_
}

#List dir for optimise 
$DirOutput=$SourcePathFileOutput | where {$_.psiscontainer}

#for output result (add all properties you want)
$list=foreach ($Current in $SourcePathFileOutput)
{
$Result=[pscustomobject]@{
    Path = $Current.FullName
    PARENTPATH=$Current.PARENTPATH
    ISDIR=$Current.psiscontainer
    ID=$Current.ID
    PARENTID=($DirOutput | where {$_.FullName -eq $Current.PARENTPATH}).ID
}

#Initialise parent root
if ($Result.PARENTID -eq $null) {$Result.PARENTID=0}

#send result on output
$Result
} 

$list | Out-GridView
  

Ответ №2:

Это должно сделать то, что вы хотите:

 #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. Возможно, у вас есть требование, чтобы идентификаторы каталогов были меньше, чем у файлов, и для этого потребуется больше кода (хотя я не видел этого требования).

Комментарии:

1. Спасибо @AdminOfThings. Я получаю эту ошибку, есть идеи? — Инвентаризация общего доступа к файлам.ps1:20 char: 40 $IDs.add($file. полное имя, $currentId) ~ Отсутствует оператор ‘=’ после ключа в хэш-литерале. В C:UsersUserfileshare inventory.ps1:20 char: 40 $IDs.add($file. полное имя, $currentId) ~ Хэш-литерал был неполным. CategoryInfo: ParserError: (:) [], ParentContainsErrorRecordException FullyQualifiedErrorId : MissingEqualsInHashLiteral

2. @CameronStewart Я обновил код, чтобы устранить эту проблему.