Need powershell script for the below:
provided comma-separated filenames with parent folder like below:
$itemsToInclude = "stage\arsw.war,dev\deployfile"
I wish to search recursively for all comma-separated files mentioned in $itemsToInclude
under the $workspace="D:\ims" location
and include only the files where BOTH the filename and the parent folder-name matches into hello.zip
Thus D:\ims\work1\app1\src\stage\arsw.war
should be included in hello.zip while D:\ims\work1\app1\src\wow\arsw.war
should not because the parent folder should be stage
as mentioned in the $itemsToInclude
Thus expected result is that hello.zip should contain the following files.
D:\ims\work1\myapp2\src\dev\deployfile\file1.txt
D:\ims\work1\myapp2\src\dev\deployfile\file2.txt
D:\ims\work1\app1\src\stage\arsw.war
Tried the below powershell but it failed:
PS D:\ims> cd D:\ims
$workspace = “D:\ims”
$itemsToInclude = “stage\arsw.war,dev\deployfile”
$items = $itemsToInclude -split “,” | ForEach-Object { $_.Trim() }
$matchingFiles = @()
foreach ($item in $items) {
# Get the file name and the parent folder name from the item
Write-Host "Split-Path -Path $item -Leaf"
$fileName = Split-Path -Path $item -Leaf
Write-Host "Split-Path -Path $item -Parent"
$parentFolder = Split-Path -Path $item -Parent
Write-Host "$fileName and $parentFolder"
$files = Get-ChildItem -Path $workspace -Filter $fileName -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Directory.Name -eq $parentFolder }
# Add the matching files to the array using array subexpression operator
$matchingFiles = @($matchingFiles; $files)
Write-Host "FOUND $($files.FullName) and $($matchingFiles.FullName)"
if ($matchingFiles) {
Compress-Archive -Path $matchingFiles -DestinationPath hello.zip
}
else {
Write-Host “No matching files were found in $workspace” }
}
Output:
Split-Path -Path stage\arsw.war -Leaf
Split-Path -Path stage\arsw.war -Parent
arsw.war and stage
FOUND D:\ims\work1\app1\src\stage\arsw.war and D:\ims\work1\app1\src\stage\arsw.war
Compress-Archive : The path 'arsw.war' either does not exist or is not a valid file system path.
At line:33 char:1
+ Compress-Archive -Path $matchingFiles -DestinationPath hello.zip
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (arsw.war:String) [Compress-Archive], InvalidOperationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive
Split-Path -Path dev\deployfile -Leaf
Split-Path -Path dev\deployfile -Parent
deployfile and dev
FOUND and D:\ims\work1\app1\src\stage\arsw.war
Compress-Archive : The path 'arsw.war' either does not exist or is not a valid file system path.
At line:33 char:1
+ Compress-Archive -Path $matchingFiles -DestinationPath hello.zip
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (arsw.war:String) [Compress-Archive], InvalidOperationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive
There are a couple of issues with this attempt.
Files inside dev\deployfile
is not Found although it is present.
The files under dev\deployfile
are not added to hello.zip
Kindly assist.
A simplified way to do it is by creating a regex pattern to match on the item's .FullName
property. The following would only include those files in your Zip Archive, however, it's worth noting that the file's hierarchy is lost in the compressed file. They are placed in Zip's root.
$itemsToInclude = 'stage\arsw.war,dev\deployfile'
$pattern = $itemsToInclude.Split(',').ForEach({ [regex]::Escape($_) }) -join '|'
$workspace = 'D:\ims'
Get-ChildItem $workspace -Recurse -File |
Where-Object FullName -Match $pattern |
Compress-Archive -DestinationPath hello.zip
Also, worth considering, if hello.zip
already exists you would need to use the -Update
switch.