Powershell文件清单中的包含和ID以及父ID

时间:2019-03-30 12:21:18

标签: powershell

我有一个Powershell脚本来执行和共享文件共享。我想知道如何在csv文件的每一行中添加ID,并在csv中的行中添加父ID。

我是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文件的每一行中添加ID,并在csv中的行中添加父ID。

2 个答案:

答案 0 :(得分:0)

这应该做您想要的:

#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,因为如果按目录树中的位置对内容进行排序,则最容易分配有序ID。

$CurrentID从1开始,因为循环中的第一项不是根父项。循环将在每次循环迭代结束时将此变量加1($CurrentID++),以便下一个文件/目录将具有一个新的数字。由于此代码将$CurrentID创建为Int32类型,因此如果您拥有超过20亿个文件/目录,则会遇到问题。您将必须将其初始化为64位类型($CurrentID = [long]1)。但是,我相信哈希表中只能有Int32数量的键,因此,如果您有数十亿个文件,则需要采用不同的策略。

$IDs是一个有序哈希表,可跟踪所有文件和目录的ID。哈希表中的每个键都是循环中当前项目的路径。该值是ID分配。这意味着您可以使用语法$IDs.path访问ID。初始化之后,我添加了ID为0的第一个条目,它代表根父级。

在循环内部,我创建了ID属性,该属性仅存储$CurrentID的当前值。我创建了“ ParentID”,它在$IDs哈希表中查找父目录,并返回该键的ID值。

我更新了$CSVColumnOrder,将IDParentID作为列。

如果以不同的方式进行初始排序,则ID方案可能会略有不同。您不必增加1。您可能需要一个要求,即目录的ID小于文件的ID,并且需要更多的代码(尽管我没有看到此要求)。

答案 1 :(得分:0)

尝试类似这样的东西:

$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