有没有简单的方法可以使用PowerShell来获取"文件夹列表"来自S3存储桶,没有列出每个对象,只编写不同路径的编译列表?我工作的桶中有成千上万个单独的物体,这需要很长时间。
这可能是一个非常愚蠢的问题,如果是这样的话,我很抱歉,但我无法在Google或SO上找到任何答案。我尝试添加通配符到-KeyPrefix和Get-S3Object的-Key参数无效。这是唯一可能能够完成我之后所做的cmdlet。
毫无意义的背景故事:我只想确保将文件传输到正确的现有文件夹。我是签约的第三方,因此我没有控制台登录权限,而且我不是维护AWS账户的人。
我知道使用Java和C#以及其他人可以做到这一点,但是我在PS中完成了这个相当简单的项目并且希望能够坚持下去。
提前致谢。
答案 0 :(得分:3)
您可以使用AWS Tools For PowerShell列出存储桶中的对象(通过Get-S3Object),并从响应对象中提取公共前缀。
下面是一个递归检索子目录的小型库:
function Get-Subdirectories
{
param
(
[string] $BucketName,
[string] $KeyPrefix,
[bool] $Recurse
)
@(get-s3object -BucketName $BucketName -KeyPrefix $KeyPrefix -Delimiter '/') | Out-Null
if($AWSHistory.LastCommand.Responses.Last.CommonPrefixes.Count -eq 0)
{
return
}
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes
if($Recurse)
{
$AWSHistory.LastCommand.Responses.Last.CommonPrefixes | % { Get-Subdirectories -BucketName $BucketName -KeyPrefix $_ -Recurse $Recurse }
}
}
function Get-S3Directories
{
param
(
[string] $BucketName,
[bool] $Recurse = $false
)
Get-Subdirectories -BucketName $BucketName -KeyPrefix '/' -Recurse $Recurse
}
此递归函数依赖于在每次迭代时更新KeyPrefix以检查传递给它的每个KeyPrefix中的子目录。通过将分隔符设置为'/'
,在敲击分隔符的第一次出现之前匹配KeyPrefix字符串的键将在$ AWSHistory的最后一个响应中滚动到CommonPrefixes集合中。
仅检索S3存储桶中的顶级目录:
PS C:/> Get-S3Directories -BucketName 'myBucket'
检索S3存储桶中的所有目录:
PS C:/> Get-S3Directories -BucketName 'myBucket' -Recurse $true
这将返回一个字符串集合,其中每个字符串都是一个公共前缀。
示例输出:
myprefix/
myprefix/txt/
myprefix/img/
myotherprefix/
...
答案 1 :(得分:0)
$objects = Get-S3Object -BucketName $bucketname -ProfileName $profilename -Region $region
$paths=@()
foreach($object in $objects)
{
$path = split-path $object.Key -Parent
$paths += $path
}
$paths = $paths | select -Unique
write-host "`nNumber of folders "$paths.count""
Write-host "$([string]::join("`n",$paths)) "
答案 2 :(得分:0)
此版本的Powershell在一个S3 Bucket中迭代超过1000个键(aws仅限制了1000个用于API get-S3object的键,因此我们需要一个while循环来获取超过1000个键,即文件夹) 输出生成到csv之后,记得在Excel中对重复项进行排序以删除重复项(PS,任何人都可以帮助对重复项进行排序,因为我认为我的脚本与重复项不兼容)
#Main-Code
$keysPerPage = 1000 #Set max key of AWS limit of 1000
$bucketN = 'testBucket' #Bucketname
$nextMarker = $null
$output =@()
$Start = "S3 Bucket Name : $bucketN"
$End = "- End of Folder List -"
Do
{
#Iterate 1000 records per do-while loop, this is to overcome the limitation of only 1000 keys retrieval per get-s3object calls by AWS
$batch = get-s3object -BucketName $bucketN -Maxkey $keysPerPage -Marker $nextMarker
$batch2 = $batch.key | % {$_.Split('/')[0]} | Sort -Unique
$output += $batch2
$batch2
$nextMarker= $AWSHistory.LastServiceResponse.NextMarker
} while ($nextMarker)
#Output to specific folder in a directory
$Start | Out-file C:\Output-Result.csv -Append
$output | Out-file C:\Output-Result.csv -Append
$End | Out-file C:\Output-Result.csv -Append