2017-08-07 48 views
2

查找文件現在,你扔出去找-ChildItem -Recurse的超級簡單的答案之前,這是我唯一的問題:如何通過目錄樹遞歸使用PowerShell

我遠程連接使用PowerShell到Azure ,抓取站點(槽)列表,然後遍歷站點並使用Kudu API查找目錄結構中的所有圖像。由於Kudu沒有遞歸的概念,我必須構建自己的遞歸函數來抓取根目錄中的所有圖像,然後遍歷所有兒童和孩子的孩子等,以便在這些目錄中找到圖像文件。

這裏是我連接到Azure和抓根目錄代碼:

function Get-AzureRmWebAppPublishingCredentials($resourceGroupName, $webAppName, $slotName = $null){ 
    if ([string]::IsNullOrWhiteSpace($slotName)){ 
     $resourceType = "Microsoft.Web/sites/config" 
     $resourceName = "$webAppName/publishingcredentials" 
    } 
    else{ 
     $resourceType = "Microsoft.Web/sites/slots/config" 
     $resourceName = "$webAppName/$slotName/publishingcredentials" 
    } 
    $publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force 
     return $publishingCredentials 
} 


function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName, $slotName = $null){ 
    $publishingCredentials = Get-AzureRmWebAppPublishingCredentials $resourceGroupName $webAppName $slotName 
    return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword)))) 
} 

function Fill-MimeTypes(){ 
    return @("image/gif", "image/x-icon", "image/jpeg", "image/png", "image/tiff", "image/bmp") 
} 

$MimeTypes = Fill-MimeTypes 
[System.Collections.ArrayList]$Directories = @() 


#Login to Azure Account 
Login-AzureRmAccount 

#Get the Azure subscription 
Select-AzureRmSubscription -SubscriptionName [Subscription Name] 

#Get the resource group name 
$resourceGroupName = [Resource Group Name] 

#Get the WebApp name 
$Resources = Find-AzureRmResource -ResourceType Microsoft.Web/sites -ResourceGroupNameContains $resourceGroupName 

ForEach($Resource in $Resources) 
{ 
    #Get the WebAppName 
    $WebAppName = $Resource.Name 

    #Now, get the publishing creds 
    $publishingCredentialsHeader = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $WebAppName $null 
    $ApiUrl = "https://$WebAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/" 

    #Now get the list of files in the wwwroot directory 
    $InitialList = Invoke-RestMethod -Uri $ApiUrl -Headers @{Authorization=$publishingCredentialsHeader} -Method GET -ContentType "application/json" 

    ForEach($Item in $InitialList) 
    { 
     If($MimeTypes -Contains $Item.mime)  
     { 
      #Add image file data to a collection 
     } 

     If ($Item.mime -eq "inode/directory") 
     { 
      #So, here is where I need to recurse... 
      #The mime type of inode/directory means it's a directory ;) 
      #I now need to call the Api again with the Url and get the contents of the current directory and rinse and repeat until done 
      #But I cannot forget about the other directories in the root directory and their children. 
     } 
    } 
} 

如何我寫的遞歸函數?

+1

Up one ..對如何在沒有Get-ChildItem的情況下執行此操作感興趣。一個自定義函數可以有額外的參數,在正確的情況下非常有用 – cet51

+1

你已經演示瞭如何編寫和調用函數,並且你已經寫了評論,你需要做什麼 - 「##添加圖像文件數據到一個集合*「 - 我想你知道如何做這個位? 「*#我現在需要再次調用Api與Url *」 - 這一點?所以你的問題真的「解釋遞歸給我?」有各種語言的遞歸目錄遍歷示例 - https://stackoverflow.com/q/24783862/478656或https://rosettacode.org/wiki/Walk_a_directory/遞歸 - 哪種方法可以執行遞歸漫遊模式或另一個 – TessellatingHeckler

+1

,這個模式或多或少是你在你的評論中寫的,例如函數遞歸 - 步行{將文件添加到集合;對於每個目錄:Recursive-Walk $ directory}; 「*我不能忘記根目錄中的其他目錄*」 - 你不能忘記它們,它們被保存在運行代碼的結構中,就像'1..10 | foreach {process-number $ _}'在函數調用時不會忘記數字 – TessellatingHeckler

回答

2

我會寫它如下。有些是僞代碼,因爲我不是PS的語法或關鍵字精通:

function Collect-Files($apiUrl, $creds, $currentDir) 
{ 
    $list = Invoke-RestMethod -Uri $apiUrl/$currentDir/ -Headers @{Authorization=$creds} -Method GET -ContentType "application/json" 

    If($MATCHLIST -eq $null) 
    { 
     $MATCHLIST = @() #initialize array 
    } 


    ForEach($Item in $list) 
    { 
     If($MimeTypes -Contains $Item.mime)  
     { 
      #Add image file data to a collection 
      $MATCHLIST += $Item #add to array 
     } 

     If ($Item.mime -eq "inode/directory") 
     { 
      $nextDir = $Item.name 
      $MATCHLIST = Collect-Files $apiUrl $creds $currentDir/$nextDir 
     } 
    } 

    return ($MATCHLIST) 
} 

然後,如下以前的代碼調用該函數:

#Get the WebApp name 
$Resources = Find-AzureRmResource -ResourceType Microsoft.Web/sites -ResourceGroupNameContains "Nav-Inventory" 

ForEach($Resource in $Resources) 
{ 
    #Get the WebAppName 
    $WebAppName = $Resource.Name 

    #Now, get the publishing creds 
    $publishingCredentialsHeader = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $WebAppName $null 
    $ApiUrl = "https://$WebAppName.scm.azurewebsites.net/api/vfs/site/" 

    #Now get the list of files in the wwwroot directory 
    $InitialList = Invoke-RestMethod -Uri $ApiUrl -Headers @{Authorization=$publishingCredentialsHeader} -Method GET -ContentType "application/json" 

    $MATCHES += Collect-Files $ApiUrl $publishingCredentialsHeader "wwwroot" 
} 

基本遞歸。

+0

我將代碼更新爲後代和將來讀者的實際工作代碼。 – crackedcornjimmy