Powershell archive multiple directories in single zip archive - powershell

UPD1 - I reworked my question to make it less vague
I'm new in Powershell and need someone advise.
I have a directories, which I need to zip, for example:
in C:\inetpub\wwwroot\STAGETEST\
App_Config
Resources
bin
There are another bunch of directories in C:\inetpub\wwwroot\STAGETEST\ and I need to zip only App_Config, Resources, bin - with all subdirectories and files, keeping structure.
For this I have a script:
$SOURCEDIR = "C:\inetpub\wwwroot\STAGETEST\"
$SOURCEFOLDERS = "App_Config", "Resources", "bin"
Get-ChildItem -Path $SOURCEDIR -Include "$SOURCEFOLDERS" -Directory
$SOURCE = Get-ChildItem -Path $SOURCEDIR -Directory
Add-Type -assembly "system.io.compression.filesystem"
Foreach ($s in $SOURCE)
{
$DESTINATIONDIR = Join-path -path $SOURCEDIR -ChildPath "$($s.name).zip"
#Check if archive already exists and delete it
If(Test-path $DESTINATIONDIR) {Remove-item $DESTINATIONDIR}
[io.compression.zipfile]::CreateFromDirectory($s.fullname, $DESTINATIONDIR)
Unfortunately, I cannot understand, how to implement proper Get-ChildItem -include to get all necessary multiple directories?
Perhaps, is there any other approach?

according to Get-ChildItem help:
Include -
Specifies, as a string array, an item or items that this cmdlet includes in the operation. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as *.txt. Wildcards are permitted.
The Include parameter is effective only when the command includes the Recurse parameter or the path leads to the contents of a
directory, such as C:\Windows*, where the wildcard character specifies the contents of the C:\Windows directory.
so, You need an array and -Recurse parameter
$SOURCEFOLDERS = #("App_Config", "Resources", "bin")
$SOURCE = Get-ChildItem -Path $SOURCEDIR -Include $SOURCEFOLDERS -Directory -Recurse

Related

Powershell - Get-ChildItems -recurse not working

i am new to powershell and struggling a bit.
$SOURCE="\\server\folder\sub1\sub2\sub3\sub4"
$TYPE='*.csv'
$SUB="*subx*
Get-ChildItem -recurse -path $SOURCE -include $TYPE -filter $SUB
In my head this is to search a network path folder for folders below "sub4" that are all named "subx" if that makes sense.
Then want to return a list of files that are XX*.csv (csv's that start with XX) that are present in the subfolders that exist in sub folders below these "subx" folders.
so the paths may end up being
"\\server\folder\sub1\sub2\sub3\sub4\xxxxx\yyyyy\subx\zzzzzzz\XX*.csv"
"\\server\folder\sub1\sub2\sub3\sub4\aaaaa\bbbbb\subx\ccccccc\XX*.csv"
But it doesnt work, it only returns 1 file with subx in the name ending in .csv
I can run this and it returns the list of folders/files called "subx" but it doesnt recurse through the subfolders below subx
$SOURCE="\\server\folder\sub1\sub2\sub3\sub4"
$SUB="*subx*
Get-ChildItem -recurse -path $SOURCE -filter $SUB
I can run this and it returns all files called XX*.csv in the sub folders below the $SOURCE path
$SOURCE="\\server\folder\sub1\sub2\sub3\sub4"
$TYPE='*.csv'
Get-ChildItem -recurse -path $SOURCE -include $TYPE
any tips would be appreciated!!!
Split the operation into 2 steps:
Discover the subx folders under sub4
Discover the *.csv files under each of those
Note: In the following example I'm deliberate avoiding -Include because it's terribly slow in combination with -Recurse.
Get-ChildItem -Path $SOURCE -Directory -Recurse -Filter subx |Get-ChildItem -File -Recurse -Filter *.csv

Powershell copy file/folder based on keyword

I want to copy folder which match with the keyword. however i want powershell read the keyword from starting point. i added my script below
if any folder name contain test at the start, script will copy the folder. but it's coping all folder even if "Test" keyword is available in the middle name. like if there is two folder
"This.is.a.Test.Folder"
"Test.this.is.a.Folder"
I want powershell copy only "Test.this.is.a.Folder"
any help please
$dest = "D:\2";
$include= #("*Test*")
Get-ChildItem $source -recurse -Force -Verbose -include $include | copy-Item -Destination {Join-Path $dest $_.FullName.Substring($source.length)}```
Your wildcard is meant to capture anything that contains the word Test in this case.
If you want to specifically start with the word Test followed by anything: Test*
Contrary, anything that ends with the word Test would be: *Test
$include = #( "Test*" )
Get-ChildItem $source -Include $include -Recurse -Force -Verbose |
Copy-Item -Destination {
Join-Path $dest -ChildPath $_.FullName.Substring($source.length)
}
Note, that you can use -File to filter only files and -Directory to filter only folders.

Powershell script to copy folder structure and specific file types

I have the following script to copy the folder structure (including empty folders) and specific file types into another directory. However, the issue is that the script copies all files instead of just the .dat and .py files even though I'm using the -Include switch. How to fix this so that it only copies the desired file types
$sourceDir = "C:\User\001"
$targetDir = "C:\User\002"
Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Include '*.dat', '*.py' -Container
As #Lee_Dailey pointed out, it's probably best to use robocopy for this:
robocopy $sourceDir $targetDir *.dat *.py /e
Yes, this is tricky. You should look up the documentation for the -Include parameter
The Include parameter is effective only when the command includes the contents of an item, such as C:\Windows*, where the wildcard character specifies the contents of the C:\Windows directory.
You could make it work like this:
Copy-Item $sourceDir\* -Destination $targetDir -Recurse -Include '*.dat', '*.py'
-Container is true by default, so you can safely omit it.
Note that you can always use the -WhatIf switch to check if you command will actually do what you want.
You could make it work like this:
i use -Filter
Specifies a filter to qualify the Path parameter. The FileSystem
provider is the only installed PowerShell provider that supports the
use of filters. You can find the syntax for the FileSystem filter
language in about_Wildcards. Filters are more efficient than other
parameters, because the provider applies them when the cmdlet gets the
objects rather than having PowerShell filter the objects after they're
retrieved.
#('*.dat', '*.py') | %{Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter $_ -Force}
or
Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter '*.dat' -Force
Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter '*.py' -Force
it should work but
The Include parameter is effective only when the command includes the
contents of an item, such as C:\Windows*, where the wildcard character
specifies the contents of the C:\Windows directory.
Copy-Item -Destination $targetDir -Recurse -Include '*.dat', '*.py'
may find it easier to include files that can be excluded
Copy-Item -Destination $targetDir -Recurse -Exclude'*.da1', '*.xxx

Copying Folders with Wildcards

I am trying to copy a whole bunch of files using Powershell, from one directory to another on my computer.
I used Get-ChildItem C:\Users\Tom\Google Drive\My Files\*\Assessment 1\* to identify that this was the path that I wanted to copy too, and I know about Copy-Item, but I want to maintain parts of the path name when copied.
Example:
If I copy from C:\Users\Tom\Google Drive\My Files\Cool Stuff\Assessment 1\*
I want the files to go to a folder that is created called C:\Users\Tom\Archive\Cool Stuff\Assessment 1
Whereas if I copy from C:\Users\Tom\Google Drive\My Files\New Stuff\Assessment 1\*
I want the files to go to a folder that is created called C:\Users\Tom\Archive\New Stuff\Assessment 1
You could use the Get-ChildItem cmdlet to recursively find all Assessment 1 folders within your base directory and then remove the base path using -replace to finally copy the items using the Copy-Item cmdlet:
$baseDir = 'C:\Users\Tom\Google Drive\My Files\'
$destination = 'C:\Users\Tom\Archive\'
Get-ChildItem $baseDir -directory -Filter 'Assessment 1' -Recurse | ForEach-Object {
$newPath = Join-Path $destination ($_.FullName -replace [regex]::Escape($baseDir))
Copy-Item $_.FullName $newPath -Force -Recurse
}

How do I exclude a folder in compress-archive

Can I somehow exclude a folder when I compress an archive like this?
$compress = Compress-Archive $DestinationPath $DestinationPath\ARCHIVE\archiv-$DateTime.zip -CompressionLevel Fastest
Now it always saves the whole folder structure of $destinationpath to the archive, but since the archive is in the same folder, it always gets zipped into a new archive, making the archive double in size every time I run the command.
Get all the files you want to compress, excluding the files and folders you don't want compressed and then pass that to the cmdlet
# target path
$path = "C:\temp"
# construct archive path
$DateTime = (Get-Date -Format "yyyyMMddHHmmss")
$destination = Join-Path $path "ARCHIVE\archive-$DateTime.zip"
# exclusion rules. Can use wild cards (*)
$exclude = #("_*.config","ARCHIVE","*.zip")
# get files to compress using exclusion filer
$files = Get-ChildItem -Path $path -Exclude $exclude
# compress
Compress-Archive -Path $files -DestinationPath $destination -CompressionLevel Fastest
you can use -update option of Compress-Archive. Select your subdirs with Get-ChildItem and Where
like it:
$YourDirToCompress="c:\temp"
$ZipFileResult="C:\temp10\result.zip"
$DirToExclude=#("test", "test1", "test2")
Get-ChildItem $YourDirToCompress -Directory |
where { $_.Name -notin $DirToExclude} |
Compress-Archive -DestinationPath $ZipFileResult -Update
I know this question is rather old, but wanted to post my solution here. This solution has worked for me and I hope it may help someone else having the same issue.
I took the ideas from the previous answers and developed them a bit.
So generally speaking what you need to do is to create two lists, one for the files in the root directory and another one for directories (excluding the directory you'd want to omit). Then you need to concatenate these two lists together and put them into -Path parameter of Compress-Archive cmdlet.
Voila! It will create a .zip archive with all files and directories we need, preserving the directory structure.
$files = Get-ChildItem -Path /RootDir -File
$directories = Get-ChildItem -Path /RootDir -Recurse -Directory -Exclude DirToExclude
Compress-Archive -Path $($files + $directories) -DestinationPath Archive.zip