How can this way exclusion of files be achieved in PowerShell? - 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}

Related

Powershell Script to find a specific file type in specific subfolders of a directory

I have a directory with several subfolders in it. I specifically want to search for the directory for a set of subfolders that begin with the combination "SS". Once it finds those specific subfolders, I want to run a batch file on those folders and also delete files of specific file type.
I've got the search for the specific subfolders to work using gci and -Recurse using the following code:
$BaseDir = "P:\Directory1\"
$FolderName = "SS"
Get-ChildItem $BaseDir -Recurse | Where-Object {$_.PSIsContainer -and $_.Name.StartsWith($FolderName)}
This finds the correct subfolders, but I'm lost on how after I've gotten these results to run the batch file on them and delete the files with the specific file type. I've tried using foreach and ForEach-Object, but it's not giving any results. I've searched and can't seem to find a solution for this.
You could also use -Include, but it's picky about the path handed to it.
get-childitem( join-path $directory "*") -Include *.txt,*.pdf
The -Include option needs the path to have that trailing * wildcard on it, and WILL NOT work without it.
join-path is also the OS-safe way to create a path without using a directory delimiter that might not work if you're running the code on a non-Windows host.

Remove-Item with Recurse and Exclude multiple subdirectories

I am trying to create a script to delete all files and directories within a folder, except for specified folders and their content.
Example tree:
test/
- images/
- folder_to_keep/
- misc/
- blah/
- some_other_folder/
- another_to_keep/
- snafu/
I've searched for this specific question with little luck. I've tried:
Remove-Item .\test\* -Exclude (".\test\images\folder_to_keep", ".\test\some_other_folder\another_to_keep") -Recurse
but that still deletes everything.
FYI, I am trying to run this script in a build job on an Atlassian Bamboo server if that helps anyone. See: https://confluence.atlassian.com/bamboo0515/script-894237366.html. If there is a better way using their options (Shell, Windows PowerShell, /bin/sh or cmd.exe) that would be great too.
Edit: robocopy might be an option also. The basic problem is that I need to mirror the source and the destination paths, but there are folders in the destination that must remain unchanged (they get filled from another process).
-Exclude applies only to leaf elements, not the full path. For example, a filter -Exclude 'foo' would remove a folder named "foo" from the result list, but not its files or child folders.
Combine the parent paths you want excluded in a regular expression and use a regexp (non-)match.
$excludes = "$($pwd.Path)\test\images\folder_to_keep",
"$($pwd.Path)\test\some_other_folder\another_to_keep"
$re = ($excludes | ForEach-Object {[regex]::Escape($_)}) -join '|'
Get-ChildItem -Recurse -Force | Where-Object {
$_.FullName -notmatch "^$re"
} | Remove-Item -Force

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}

Powershell get-childitem exclude directory several levels deep

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(\\|$)"}