如何通过目录树递归以使用 Powershell 查找文件
How to recurse through a directory tree to find files with Powershell
现在,在你抛出 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.
}
}
}
递归函数怎么写?
我会这样写。有些是伪代码,因为我不精通 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"
}
基本递归。
现在,在你抛出 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.
}
}
}
递归函数怎么写?
我会这样写。有些是伪代码,因为我不精通 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"
}
基本递归。