Finding folders and files with same name using PowerShell - powershell

I need to extract the fileversion of certain DLL files of which I do not know the name. All I know is where the file that holds the fileversion is located and that its name is the same as the folder it is hiding beneath.
In truth it's something like this:
C:\inetpub\wwwroot\APPFolder\bin\files
(where the name of the Subfolder matches the name of the file in the bin folder)
After many tries (and a lot of failures), I've gone a bit back and forth, and I'm now leaning comfortably at this bit of code .... close, but no cigar:
Get-ChildItem -Path c:\temp\Documents -recurse -Filter *.dll | where-object{ (Get-ChildItem -Path c:\temp\Documents -recurse -Filter *.dll) -match $_.Directory.Name }
This code searches for all the files recursively under \temp\documents and then matches the files in the folders, which is nice ... but not quite what I wanted. Also the code above gives the folders where the files that match the folders they are in and not only the matched file.
So ... any suggestions? There are more than one DLL file in the bin folder mentioned above which is part of why I need to select the one with the same name as the APPFolder.

Here is a code sample which will give you the full file path to the files you're looking for.
dir . -Recurse -Filter *.dll | ? { -not $_.PSIsContainer } | ? { $_.FullName.ToLower().Contains( [IO.Path]::DirectorySeparatorChar + [IO.Path]::GetFileNameWithoutExtension( $_.Name.ToLower() ) + [IO.Path]::DirectorySeparatorChar ) } | Select -ExpandProperty FullName
Breaking it down, we have:
dir . -Recurse -Filter *.dll
This will search the current directory and its children recursively for all files that have a .dll file extension:
? { -not $_.PSIsContainer }
This will eliminate directories that end in .dll. Unlikely, but possible
? { $_.FullName.ToLower().Contains( [IO.Path]::DirectorySeparatorChar + [IO.Path]::GetFileNameWithoutExtension( $_.Name.ToLower() ) + [IO.Path]::DirectorySeparatorChar }
This will filter it down to the DLL files that have a file name the same as the name of a directory above it in the path.
Select -ExpandProperty FullName
This will give you the full file path.
You can then follow the answer to this question here to get the FileVersion.

Related

Powershell how to get the full path of a folder that is deep in the folder structure by knowing only the beginning of the path

Would please anyone tell how I can get the path of a specific folder with Powershell command that is about 10, 15 places down in folder structure.
E.g. In the following folder structure
C:\Folder1\Folder2\Folder3\...\....\....\....\....\.....\....\....\...\MyFolder
Here I have the starting folder path accessible i-e.
C:\Folder1\Folder2\Folder3\
but I don't know the missing ...\...\....\ folders.
I want to get the full path to the MyFolder. Any help doing that with Powershell?
Try this:
get-childitem -Path 'c:\Folder1' -Directory -Recurse | ? {$_.Basename -eq 'MyFolder'} | Select FullName
Or:
get-childitem -Path 'C:\folder1' -Directory -Recurse -Filter 'MyFolder' | Select FullName

How to find all folders which has folder named "Intro" AND filetype *.mp4

The closest I got was using powershell Get-ChildItem given multiple -Filters
Get-ChildItem -Include "Intro", "*.mp4" -Recurse
I think, -Include with multiple params work as OR operator. It gives folders with either "Intro" folder OR "*.mp4" files.
But I need AND condition. Folder must contain a folder named "Intro" and "*.mp4" files.
I need folders structured following -
E:.
└───test1.mp4
└───test2.mp4
└───test3.mp4
└───test4.mp4
└───test5.mp4
└───test6.mp4
└───Intro
Update 1
I am searching for folders which meet two condition.
It must have a subfolder named Intro AND
It must have *.mp4 files.
The answer would look something like the following I guess.
Get-ChildItem -Directory -Recurse {HasSubFolderNamedIntro && HasMP4Files}
Just wanted to add another Method (one-liner) to get the folder which contains mp4 files and a folder Intro (probs to #HenrikStanleyMortensen for most of it):
(Get-ChildItem -include "*.mp4" -Recurse -File).DirectoryName | Select-Object -Unique | Where-Object {(Get-ChildItem $_ -Recurse -Include 'Intro' -Directory)}
Do you need the command to only return the file objects or do you also want the folder objects?
If just the files I would do it like this:
Get-ChildItem -include "*.mp4" -Recurse -File | Where-Object {$_.Directory.Name -match 'Intro'}
So we use the include to find the mp4 files and reduce the amount of objects we pipe.
Then we pipe it to Where-Object and look for the property with the name of the folder and says we want it to contain the word "intro". If the folder needs to be called Intro exactly and not just contain it you can change the -match to -eq
Edit
To get the directories then we could do it like this:
(Get-ChildItem -include "*.mp4" -Recurse | Where-Object {$_.Directory.Name -match 'Intro'}).DirectoryName | Select-Object -Unique
Now we say that all the files that we found that matches our search, we want to see the full directory path of those files.
To only get one match per directory, so if we have 1 directory that matches with multiple mp4 files, and we don't want to see that same directory in our output one time per file, we can pipe the result into Select-Object -Uniqueto only see each directory once.
Edit 2
After clarification from OP.
To find a folder that contains both mp4 files and a subfolder called intro I don't think we can do that only from the Get-ChildItem command in any way I know of, so we can loop through each folder like this:
$Files = (Get-ChildItem -include "*.mp4" -Recurse -File).DirectoryName | Select-Object -Unique
foreach($File in $Files) {
Get-ChildItem -Path $File.DirectoryName -Recurse -Include 'Intro' -Directory
}
We Pipe to the Select-Object -Unique to make sure that folders with multiple mp4 files are not looped through more than once thus giving us an output with the same intro folder multiple times.

Move a files that have the same name but different extension. Powershell

I am a junior tech and have been tasked to write a short powershell script. The problem is that I have started to learn the PS 5 hours ago - once my boss told that I'm assigned to this task. I'm a bit worried it won't be completed for tomorrow so hope you guys can help me a bit. The task is:
I need to move the files to different folders depending on certain conditions, let me start from the he folder structure:
c:\LostFiles: This folder includes a long list of .mov, .jpg and .png files
c:\Media: This folder includes many subfolders withe media files and projects.
The job is to move files from c:\LostFiles to appropiate folders in c:\Media folder tree if
The name of the file from c:\LostFiles corresponds to a file name in one of the subfolders of the C:\media We must ignore the extension, for example:
C:\LostFiles has these files which we need to move (if possible) : imageFlower.png, videoMarch.mov, danceRock.bmp
C:\Media\Flowers\ has already this files: imageFlower.bmp, imageFlower.mov
imageFlower.png should be moved to this folder (C:\media\Flowers) because there is or there are files with exactly the same base name (extension must be ignored)
Only the files that have corresponding files (the same name) should be moved.
So far I have written this piece of code (I know it is not much but will be updating this code as I am working on it now (2145 GMT time). I know I missing some loops, hey yeah, I am missing a lot!
#This gets all the files from the folder
$orphans = gci -path C:\lostfiles\ -File | Select Basename
#This gets the list of files from all the folders
$Files = gci C:\media\ -Recurse -File | select Fullname
#So we can all the files and we check them 1 by 1
$orphans | ForEach-Object {
#variable that stores the name of the current file
$file = ($_.BaseName)
#path to copy the file, and then search for files with the same name but only take into the accont the base name
$path = $Files | where-object{$_ -eq $file}
#move the current file to the destination
move-item -path $_.fullname -destination $path -whatif
}
You could build a hashtable from the media files, then iterate through the lost files, looking to see if the lost file's name was in the hash. Something like:
# Create a hashtable with key = file basename and value = containing directory
$mediaFiles = #{}
Get-ChildItem -Recurse .\Media | ?{!$_.PsIsContainer} | Select-Object BaseName, DirectoryName |
ForEach-Object { $mediaFiles[$_.BaseName] = $_.DirectoryName }
# Look through lost files and if the lost file exists in the hash, then move it
Get-ChildItem -Recurse .\LostFiles | ?{!$_.PsIsContainer} |
ForEach-Object { if ($mediaFiles.ContainsKey($_.BaseName)) { Move-Item -whatif $_.FullName $mediaFiles[$_.BaseName] } }

How can Powershell copy an entire folder structure but exclude one folder and its contents

This seems like a simple operation but I can't figure out how to get Powershell to copy an entire folder structure from one location to another but exclude one folder (called 'connections') and its contents.
I've tried combining Copy-Item and Get-ChildItem like so
cpi (gci folder1 -Exclude connections) folder2 -recurse
but it seems the -recurse parameter overwrites the -exclude parameter and the connections folder and its contents are copied. Without -recurse the contents of the folders I do want copied are ignored.
I'm not sure why that isn't working, it seems to behave correctly on my machine.
You could always pipe to Copy-Item:
Get-ChildItem folder1 | where { !(($_ -is [System.IO.DirectoryInfo]) -and ($_.Name -eq "connections")) } | Copy-Item -Destination folder2 -Recurse
The advantage of this is that you can just get PowerShell to print out the output after:
Get-ChildItem folder1 | where { !(($_ -is [System.IO.DirectoryInfo]) -and ($_.Name -eq "connections")) }
That way you can check exactly what is getting copied (i.e. is the "connections" folder missing?)

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)