如何用PowerShell递归移动Azure Data Lake Store Gen1中未知文件名的文件?
Let's walk through what's off with your current script and get you moving those files correctly.
The Problem with Your Current Code
Your script tries to pipe items directly to Move-AzDataLakeStoreItem, but using $File in the destination path is incorrect. $File is an OutVariable collection of all matching items, and when you concatenate it into the path, PowerShell just converts the entire object to a messy string (which is why you see the partial target path in the -WhatIf output). Additionally, you need to handle each file individually instead of trying to move all at once.
Solution 1: Move Files from the Root Source Folder (No Subfolders)
This script targets only files in your specified source folder (not subfolders) that were modified in the last 7 days, and moves them to the target directory while preserving their original filenames:
# Define your ADLS account and paths for easier maintenance $adlsAccount = "my_acc" $sourceRoot = "/Training/TestCopy/Source/" $targetRoot = "/Training/TestCopy/Target/" # First, make sure the target directory exists (create if not) if (-not (Test-AzDataLakeStoreItem -Account $adlsAccount -Path $targetRoot)) { New-AzDataLakeStoreItem -Account $adlsAccount -Path $targetRoot -ItemType Directory -Force } # Get 7-day-old files, filter out folders, and move each one Get-AzDataLakeStoreChildItem -Account $adlsAccount -Path $sourceRoot | Where-Object { $_.Type -eq "File" -and $_.LastWriteTime -ge (Get-Date).AddDays(-7) } | ForEach-Object { # Build the full target path for each file $targetFilePath = Join-Path -Path $targetRoot -ChildPath $_.Name # Preview the move first with -WhatIf; remove it when you're ready to execute Move-AzDataLakeStoreItem -Account $adlsAccount -Path $_.FullPath -Destination $targetFilePath -WhatIf }
Key Details Here:
$_.FullPath: Grabs the complete path of each source file, whichMove-AzDataLakeStoreItemneeds to locate the file.Join-Path: Safely constructs the target path by combining the target folder with the original filename, avoiding messy string concatenation errors.- Target Directory Check: Ensures your target folder exists before trying to move files (ADLS won't auto-create it for you in all cases).
Solution 2: Recursively Move Files from Subfolders
Since the AZ module's Get-AzDataLakeStoreChildItem doesn't support -Recursive, we'll build a simple recursive function to dig into all subfolders and collect files. This also preserves the original folder structure if you want:
# Recursive function to get all files in a path and its subfolders function Get-ADLSRecursiveFiles { param( [string]$AccountName, [string]$CurrentPath ) $items = Get-AzDataLakeStoreChildItem -Account $AccountName -Path $CurrentPath foreach ($item in $items) { if ($item.Type -eq "File") { $item # Return the file object } elseif ($item.Type -eq "Directory") { # Recurse into the subfolder Get-ADLSRecursiveFiles -AccountName $AccountName -CurrentPath $item.FullPath } } } # Set your ADLS details $adlsAccount = "my_acc" $sourceRoot = "/Training/TestCopy/Source/" $targetRoot = "/Training/TestCopy/Target/" # Ensure target directory exists if (-not (Test-AzDataLakeStoreItem -Account $adlsAccount -Path $targetRoot)) { New-AzDataLakeStoreItem -Account $adlsAccount -Path $targetRoot -ItemType Directory -Force } # Get all 7-day-old files (including subfolders) and move them Get-ADLSRecursiveFiles -AccountName $adlsAccount -CurrentPath $sourceRoot | Where-Object { $_.LastWriteTime -ge (Get-Date).AddDays(-7) } | ForEach-Object { # Preserve the original subfolder structure in the target $relativePath = $_.FullPath.Substring($sourceRoot.Length) $targetFilePath = Join-Path -Path $targetRoot -ChildPath $relativePath # Create any missing subfolders in the target $targetFolder = Split-Path -Path $targetFilePath -Parent if (-not (Test-AzDataLakeStoreItem -Account $adlsAccount -Path $targetFolder)) { New-AzDataLakeStoreItem -Account $adlsAccount -Path $targetFolder -ItemType Directory -Force } # Preview the move; remove -WhatIf to execute Move-AzDataLakeStoreItem -Account $adlsAccount -Path $_.FullPath -Destination $targetFilePath -WhatIf }
Important Notes:
- Always test with
-WhatIffirst to verify the target paths are correct before making actual changes. - Ensure your Azure AD account has Write permissions on both the source and target paths in ADLS Gen1.
- If you don't need to preserve subfolder structure, just replace the
$relativePathlogic with$_.Name(like in Solution 1).
内容的提问来源于stack exchange,提问作者Bacon4life

