我有一个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。
答案 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
,将ID
和ParentID
作为列。
如果以不同的方式进行初始排序,则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