适用于AWS的PowerShell:仅列出"文件夹"来自S3 bucket?

时间:2016-04-22 19:39:58

标签: powershell amazon-web-services amazon-s3 aws-powershell

有没有简单的方法可以使用PowerShell来获取"文件夹列表"来自S3存储桶,没有列出每个对象,只编写不同路径的编译列表?我工作的桶中有成千上万个单独的物体,这需要很长时间。

这可能是一个非常愚蠢的问题,如果是这样的话,我很抱歉,但我无法在Google或SO上找到任何答案。我尝试添加通配符到-KeyPrefix和Get-S3Object的-Key参数无效。这是唯一可能能够完成我之后所做的cmdlet。

毫无意义的背景故事:我只想确保将文件传输到正确的现有文件夹。我是签约的第三方,因此我没有控制台登录权限,而且我不是维护AWS账户的人。

我知道使用Java和C#以及其他人可以做到这一点,但是我在PS中完成了这个相当简单的项目并且希望能够坚持下去。

提前致谢。

3 个答案:

答案 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