Powershell get-childitem exclude directory several levels deep - powershell

I have a folder containing changed files to deploy to another server. I am building a list of files below the root, recursively, and I want to skip an entire folder. This is not working:
gci -path \\myfolder -recurse -exclude "*\excludeme\*" | where{! $_PSIsContainer}
It is going ahead and listing all the files in excludeme as well. Even this didn't work:
gci -path \\myfolder -recurse -exclude "\\myfolder\excludeme\*" | where etc.
I should note that "excludeme" is a folder that contains a number of software project folders, i.e. a whole mess of subfolders in itself. Help!

You should be able to use -Exclude if you simple enter the name of the folder:
GCI \\MyFolder -Recurse -Exclude "ExcludeMe"
With that said, if it doesn't work for you (and it wouldn't surprise me, because the File System Provider is horrible at filtering IMHO), you can always filter after you get the results, it will just be a little slower:
GCI \\MyFolder -Recurse | Where{$_.FullName -NotMatch "\\ExcludeMe(\\|$)"}

Related

PowerShell Script finding File using extension and excluding a folder

I am using the below code:
Get-ChildItem -Path N:\USERS -Filter DANTOM.DTM -Recurse -ErrorAction SilentlyContinue -Force
I need it to either find the file "DANTOM.DTM" or the extension ".DTM". I need to exclude the folder N:\USERS\EDI because it is a 1.7TB folder that would never have this file in it. So in doing so would really speed up the process.
I would like the end result to either spit into a .txt file saying which folders inside of N:\USERS has the file or just have it display as a list in powershell.
Thank you,
Assuming that the files of interest do not reside directly in N:\USERS (only in subdirs.), try the following (PSv3+ syntax); send to a file by appending > dirs.txt, for instance.
Get-ChildItem N:\USERS -Directory | ? Name -ne 'EDI' |
Get-ChildItem -Recurse -Filter *.DTM |
ForEach-Object { $_.DirectoryName }
Note: While it is tempting to try a simpler approach with -Exclude EDI, it unfortunately doesn't seem to be effective in excluding the entire subtree of the EDI subfolder.

How do I prevent Get-ChildItem from traversing a particular directory?

Let me start by saying that I've looked at Unable to exclude directory using Get-ChildItem -Exclude parameter in Powershell and How can I exclude multiple folders using Get-ChildItem -exclude?. Neither of these has an answer that solves my problem.
I need to search a directory recursively for files with a certain extension. For simplicity, let's just say I need to find *.txt. Normally, this command would suffice:
Get-ChildItem -Path 'C:\mysearchdir\' -Filter '*.txt' -Recurse
But I have a major problem. There's a node_modules directory buried somewhere inside C:\mysearchdir\, and NPM creates extremely deep nested directories. (The detail of it being an NPM managed directory is only important because this means the depth is beyond my control.) This results in the following error:
Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
I believe this error bubbles up from the limitations in the .NET IO libraries.
I can't search in the other directories around it very easily. It's not at the top of the directory; it's deeper in, say at C:\mysearchdir\dir1\dir2\dir3\node_modules, and there are directories I need to search at all those levels. So just searching the other directories around it is going to be cumbersome and not very maintainable as more files and directories are added.
I've tried to -Exclude parameter without any success. That isn't surprising since I just read that -Exclude is only applied after the results are fetched. I can't find any real info on using -Filter (as is noted in this answer).
Is there any way I can get Get-ChildItem to work, or am I stuck writing my own recursive traversal?
Oh, man, I feel dumb. I was facing the same problem as you. I was working with #DarkLite1's answer, trying to parse it, when I got to the "-EA SilentlyContinue" part.
FACEPALM!
That's all you need!
This worked for me, try it out:
Get-ChildItem -Path 'C:\mysearchdir\' -Filter '*.txt' -Recurse -ErrorAction SilentlyContinue
Note: This will not exclude node_modules from a search, just hide any errors generated by traversing the long paths. If you need to exclude it entirely, you're going to need a more complicated solution.
Maybe you could try something like this:
$Source = 'S:\Prod'
$Exclude = #('S:\Prod\Dir 1', 'S:\Prod\Dir 2')
Get-ChildItem -LiteralPath $Source -Directory -Recurse -PipelineVariable Dir -EV e -EA SilentlyContinue |
Where {($Exclude | Where {($Dir.FullName -eq "$_") -or ($Dir.FullName -like "$_\*")}).count -eq 0}

How to use the Copy-Item cmdlet correctly to copy piped files

I am building a small script which should copy all .zip files to a special folder called F:\tempzip.
I tried it with Copy-Item cmdlet, but I didn't manage to do it. The script should copy all files from this folder (recursively) which are ".zip".
This is the part of the script I am talking about:
get-childitem F:\Work\xxx\xxx\xxx -recurse `
| where {$_.extension -eq ".zip"} `
| copy-item F:\tempzip
What do I have to add?
It's a lot simpler than that. Copy-Item has its own -Recurse switch. All you have to do is:
Copy-Item F:\Work\xxx\xxx\xxx\*.zip F:\tempzip -Recurse
When piping items to copy-item you need to tell it that "F:\tempzip" is the destination path.
| Copy-Item -Destination F:\tempzip
You can also cutout piping to the where operator by using Get-ChildItem's parameter -filter.
Get-Childitem "C:\imscript" -recurse -filter "*.zip" | Copy-Item -Destination "F:\tempzip"
Edit: Removal of unnecessary foreach loop and updated explanation.
For whatever reason, the Copy-Item recursion didn't accomplish what I wanted, as mentioned here, and how it is documented to work. If you have a bunch of *.zip or *.jpg files in arbitrarily deep subfolder hierarchies, and you want to copy them to a single place (one flat folder, elsewhere), I had better luck with a piped command involving Get-ChildItem. Say you are currently in the folder containing the root of your search:
Get-ChildItem -Recurse -Include *.zip | Copy-Item -Destination C:\Someplace\Else
That command will copy all the files and not duplicate the folder hierarchies.

Copy files from directory structure but exclude a named folder

I am looking to copy files from a directory structure over to a new folder. I am not looking to preserve the file structure, just get the files. The file structure is such that there can be nested folders, but anything in a folder named 'old' I do not want moved over.
I made a couple attempts at it, but my powershell knowledge is very limited.
Example being where the current file structure exists:
Get-ChildItem -Path "C:\Example\*" -include "*.txt -Recurse |% {Copy-Item $_.fullname "C:\Destination\"}
This gives me all the files all I want, including all the files I don't want. I do not want to include any files that are in the 'old' folder. To note: there are multiple 'old' folders. I tried -exclude, but it looks like it only pertains to the file name, and I am not sure how to -exclude on a path name, while still copying the files.
Any help?
How about this:
C:\Example*" -include "*.txt -Recurse |
?{$_.fullname -notmatch '\\old\\'}|
% {Copy-Item $_.fullname "C:\Destination\"}
Exclude everything that has '\old\' anywhere in it's path.
If we sneak a little where-object into the pipeline I think you'll get what you seek. Each object that has a property named Directory (System.IO.FileInfo) with a property named Name with a value of old will not be passed to Copy-Item.
Get-ChildItem -Path "C:\Example*" -include *.txt -Recurse | ? {-not ($_.Directory.Name -eq "old")} | % {Copy-Item $_.fullname "C:\Destination\"}
(Untested)

How can this way exclusion of files be achieved in PowerShell?

I have a PowerShell script on a production server to show me the list of database backup files that are older than 30 days.
I need to see only the files that have the extension of ".bak". However, in my script there is no matching syntax or regular expression, so I am also getting to see a list of files which have an extension like "filename.foo.bak". These files may be text files or other configuration files on the server for which backups have been taken automatically by the program that uses these files.
How do I enable a match filter so that I see only "*.bak" and not other files as mentioned above?
As mentioned by mjolinor, I have used this script to do the exclusion.
gci $paths -recurse -filter *.bak -exclude *.*.bak | ?{!$_.psiscontainer}
However, I have learnt that I need to exclude some system folders such as C:\Windows.
How can this be accomplished as well?
Try this:
gci *.bak -exclude *.*.bak
I tried to reply to your comment, but the code doesn't show up right. -exclude takes a string[] argument, so:
gci -recurse -filter *.bak -exclude *.*.bak,windows |? {!$_.psiscontainer}