Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Powershell在目录树中递归查找文件_Powershell_Azure_Recursion_Kudu - Fatal编程技术网

如何使用Powershell在目录树中递归查找文件

如何使用Powershell在目录树中递归查找文件,powershell,azure,recursion,kudu,Powershell,Azure,Recursion,Kudu,现在,在您抛出Get ChildItem-Recurse这个超级简单的答案之前,我有一个独特的问题: 我正在使用Powershell远程连接Azure,获取站点(插槽)列表,然后在站点上循环,并使用Kudu API查找目录结构中的所有映像。由于Kudu没有递归的概念,我必须构建自己的递归函数,从根目录中获取所有图像,然后通过所有子目录和子目录的子目录等进行递归,以便在这些目录中找到图像文件 以下是我连接Azure并获取根目录的代码: function Get-AzureRmWebAppPubli

现在,在您抛出Get ChildItem-Recurse这个超级简单的答案之前,我有一个独特的问题:

我正在使用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.
        }
    }
}

如何编写递归函数?

我将按如下方式编写它。有些是psuedo代码,因为我不熟悉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"
}

基本递归

上一个。。对如何在不获取ChildItem的情况下执行此操作感兴趣。自定义函数可以有额外的参数,这在正确的情况下非常有用。您已经演示了如何编写和调用函数,并且您已经在注释中编写了所需操作-“#将图像文件数据添加到集合”-我想您知道怎么做吗?“#我现在需要用Url再次调用Api”-这一点呢?那么你的问题真的是“向我解释递归吗?”有很多不同语言的递归目录遍历示例-或者-它们以一种或另一种方式执行递归遍历模式,该模式或多或少是你在评论中写的,例如函数递归遍历{将文件添加到集合;对于每个目录:Recursive Walk$directory};“我不能忘记根目录中的其他目录”-您不能忘记它们,它们以与
1..10 | foreach{process number$}相同的方式保存在运行代码的结构中
当它转到函数callI时,不要忘记数字。我将您的代码更新为实际工作代码,以供后代和未来读者使用。