Find directories two levels down that do not contain certain file - powershell

I have done some Windows batch scripting, but I have never worked with PowerShell, so I am looking for some startup help.
I would like to
parse a directory tree
find all the directories two levels down that do not contain folder.jpg
write the list of these directories to a text file
So far I have found this link which addresses part of the question. I have also found that Get-ChildItem \*\*\* should get me to the directories two levels down.
I would appreciate it if someone could help me put this together.
Thanks a lot

You need a combination of Get-Child, Foreach-Object, Test-Path, Join-Path and Write-Object:
Get-ChildItem *\*\* -Directory | ForEach-Object {if(!(Test-Path(Join-Path -Path $_ -ChildPath "folder.jpg"))) {Write-Output $_}}
This will write all the DirectoryInfo object where the file doesn't exist to the pipeline. You can then opt to write them to a file.

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.

Powershell: How to copy files from one Directory to another

I am looking to copy a series of files from one directory to another. Essentially the files are a series of zip folders that are simply changed versions of programs. The files will be named something like: test_1_092.zip in the source directory and test_1_091.zip in the target directory. I don't want the script to look at the numeric portion of the folder, simply the name.
Please forgive my lack of knowledge as this is my first foray into powershell scripting. Any thoughts or need more info?
Something to start with
(Get-ChildItem -Filter "*.zip").Name | where {$_ -like 'test_1_*'} | Move-Item -Destination .\1 -Force -WhatIf
Please confirm the output from –whatif , then remove it to perform the action.
For the relation between the new and old name, please provide some more information.

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}

backing up certain files in a folder using powershell

I have a couple of questions. I have certain binaries in a folder...
F:\program files\application\Client\
I only want to copy the latest dll's that have a certain phrase in there names. Lets say "MVCsite". I know you can use Get-ChildItem -Filter with the filter parameters, to get just child items with a .dll extension, but is there a way to look for specific files with specific keywords, or am I going to have to literally copy a list of files out of the directory and move it to a back up folder? Is there a quick and dirty command to do that? As you can tell, I am new to powershell, but I am learning fast.
gci -path $path -filter "*.dll" | where {$_.Name -match "Keyword1|Keyword2|etc"}
Simply use wildcards in your -Path parameter:
Copy-Item F:\program files\application\Client\*MVCsite*.dll X:\DestinationDir
That will copy all files in F:\program files\application\Client\ whose names contain the string "MVCsite" and have the extension ".dll". Is that what you wanted to accomplish? If not, please clarify.

Comparing directories and making changes according to last modified time in PowerShell

Am trying to learn powershell in order to write this script but I have been unable to learn fast enough. I need a script in powershell to do the following:
Compare two directories, copy over any missing files or subdirectories.
During the compare, also copy the most recent file(by last modified time) to the reference object.
This script should essentially lead to two duplicate directories on different servers, both with the most up to date last modified files and sub dirs.
Here is a little of what I have come up with. All it does now is compares the two dirs and determines what is missing from each. It is pretty basic and no where near where it needs to be. Pointers would be greatly appreciated if they would help me along the way. Thanks.
$test1 = Get-ChildItem -Recurse -path C:\test1
$test2 = Get-ChildItem -Recurse -path C:\test2
Compare-Object -ReferenceObject $test -DifferenceObject $test2
For your requirements I would just use a straight robocopy. You can call it from Powershell with the ampersand (call) operator:
& robocopy "C:\test1" "C:\test2" /e /dcopy:T
Here is a link with some examples: robocopy