How to recurse through a directory tree to find files with Powershell

crackedcornjimmy

Now, before you throw out the super simple answer of Get-ChildItem -Recurse, here is my unique issue:

I am connecting remotely to Azure with Powershell, grabbing the site (slot) list, then looping over the sites and finding all images in the directory structure, using Kudu API. Since Kudu has no notion of recursion, I have to build my own recursive function to grab all images from the root directory, then recurse through all children and chidren's children, etc, to also find the image files in those directories.

Here is my code for connecting to Azure and grabbing the root directory:

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.
        }
    }
}

How can I write the recursive function?

tpsands

I would write it as follows. Some is psuedo-code as I am not versed in PS syntax or keywords:

    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)
} 

Then, your previous code would call this function as follows:

    #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"
}

Basic recursion.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

recurse through powershell object

Efficiently recurse through directory of files while minimizing memory usage in Python

How to recursively traverse a directory tree and find only files?

Powershell script to search through a directory of excel files to find a string only searching through 1 file

How to find a file which contains characters and extension in recurse mode in Powershell?

How to search through a directory and find corresponding video and xml files and rename?

How to Find All .tex Files in Directories in Recurse Grep?

Go through very large directory tree with find

Loop through files in a directory using PowerShell

Find number of files in each directory in a tree of directories

Recurse through CSV input files with logparser

Looping through a directory to find matching files

Find directory, if match then don't recurse

How to loop through all the files in a directory and print all the file names, like the command tree

How to skip mounted files when walking through a directory tree with readdir_r

How to delete files and then directory in Powershell?

Send tree from a directory via SMTP through powershell

How do I copy files recursively through a directory tree while appending parent folder names to the new files? Batch or VBScript

How to traverse a really big directory tree with Powershell?

How can I find all UTF-16 encoded text files in a directory tree with a Unix command?

How do I find files by their extension in a specific directory and go through them with Power Shell?

PowerShell: Iterate Through Directory List, Copy Files with Duplicate Handling

How to loop through directory and move like files?

How to go through files in directory in ascending order

How to loop through directory files using IF THEN and variables?

Powershell -Recurse Parameter; How to exclude specific subdirectory

find and recurse

Find all the json files which are invalid in directory tree structure

Powershell Copy-Item -recurse does not pick up new directory