Say I have a list of file names like this:
some-file.ts
my-project-service.ts
other.ts
something-my-project.ts
I need to change the file names that have my-project in them to have just that part renamed to $appname$.
So my-project-service.ts would become $appname$-service.ts
And I need to do this recursively from a root directory.
I seem to be to be hopeless at PowerShell so I thought I would ask here to see if anyone can help me out.
Use the Get-ChildItem cmdlet with the -recurse switch to get all items recursivly from a root directory. Filter all items containing my-project using the Where-Object cmdlet and finally rename them using the Rename-Item cmdlet:
Get-ChildItem "D:\tmp" -Recurse |
Where {$_.Name -Match 'my-project'} |
Rename-Item -NewName {$_.name -replace 'my-project','$appname$' }
Related
I have mulitple sub-folders in the main folder which has number of files in each of them. I want to keep the contents of certain folders intact and delete the contents in the rest of them.
I tested the code, but it deletes the files in all the sub-folders 7 days before.
$Path="C:\Shreyas1"
$NumberOfDays="-7"
$CurrentDate=Get-Date
$DeleteDays=$CurrentDate.AddDays($NumberOfDays)
## Heading
##$excludes="Specs"
Get-ChildItem $Path -Exclude $excludes -Recurse |
Where-Object{($_.LastWriteTime -lt $DeleteDays )} |
Remove-Item
You should try using the same "Where" statement after your Get-ChildItem cmdlet to filter out specific file names. Try something like this:
Get-ChildItem $Path -Recurse | Where-Object {$_.Name -notlike "*$excludes*" -and $_.LastWriteTime -lt $DeleteDays}
Run that first to make sure you get what you want, then you can pipe to Remove-item -Confirm:$false like you have done in your OP. Edit: The -Confirm:$false switch means that it won't prompt you to confirm whether or not you want to delete the file, it will just delete. That is why you want to run Get-ChildItem first.
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.
I am trying to select files that have identical names except for the extenstion...
IE:
idiotCode.dll, idiotCode.pdb, idiotCode.xml, StupidFool.dll, StupidFool.pdb, StupidFool.xml
et cetera.
take a gander at my where-Object call in the below script line...
gci -path $FromPath | ? {$_.Name -match "idiotCode|StupidFool|YourAnIdiot|TheSuckIstHeMatterWhichU" -and $_.Name -like "*.dll"} | foreach{write-host("Do I have the files here? : "+ $_.Fullname + " -destination" + $ToPath) }
Can I use the like parameter to do that? Is there another way to do that? Maybe something in my get-childItem method call which I could pipe into my Where-Object call?
There is a lot that you can do with just the Get-ChildItem Cmdlet. If you look at the help Get-ChildItem, you can do a lot of the filtering there. Specifically using the filters -Filter, -Include and -Exclude
For ex:
Get-ChildItem -Path $FromPath -Include "idiotCode.*","StupidFool.*","YourAnIdiot.*","TheSuckIstHeMatterWhichU.*" -Filter "*.dll"
Ok, I'm a little confused as to the whole concept here because you say you want to select multiple files of the same name but different extensions. Then you pull a directory listing of PathA, filter out everything except files in a kind of "approved names list", and only allow .DLL files to show, and then reference PathB for reasons unknown.
I'm guessing here, but I think you want to query .DLL files from PathA, and then check for matching files from PathB.
$Reference = (GCI $FromPath -Filter "*.DLL").basename
GCI $ToPath|?{$_.BaseName -Match $Reference}|FT -Group BaseName
For a simple example, let's say I have a folder, Root, with three folders in it; Folder1, Folder2, and Folder3. Each of these folders (including Root) has a bunch of files in them, including .pdb files. I want to use the PowerShell Get-ChildItem cmdlet to return all of the files in all of the folders (including Root), except for the .pdb files in Folder2. If I use:
Get-ChildItem -Path C:\Root -Recurse -Exclude *.pdb
Then I get back all of the non-.pdb files in all of the directories, which is close to what I want. So I assumed that the following would achieve what I want:
Get-ChildItem -Path C:\Root -Recurse -Exclude \*\\Folder2\\*.pdb
But this does not exclude any of the pdb files in Folder2 (or any other folders). I have tried several variants for the -Exclude filter, such as Folder2\\\*.pdb, but I cannot get it to work. In fact, even using \*\\\*.pdb does not seem to do anything; no .pdb files get excluded from any folders.
So it seems that the wildcards cannot be used for directories, only filenames, but I assume I am just doing something wrong. I found this article explaining the wildcard and range operators, but unfortunately it does not discuss using them with directory names; only file names.
I haven't seen the exclude parameter working with directories either.
You could try piping into Where-Object. That is,
Get-ChildItem -Recurse *.pdb | Where-Object {$_.FullName -notMatch "folder2"}
OhadH's answer is almost there.
You can use
Get-ChildItem -Recurse | Where-Object {$_.FullName -notmatch "folder2" -or $_.Name -notlike "*.pdb" }
or
Get-ChildItem -Recurse | ? {$_.FullName -notlike "*folder2*" -or $_.Name -notlike "*.pdb" }
It depends on where your folder2 is located. But I think you got the idea.
I hate to say it, but PowerShell is not any convenient as Bash or other shells.
gci "C:\Root" -Recurse | Where-Object {$_.FullName -notlike "*Folder2\*.pdb*"} | Export-CSV "C:\Root\Export.csv" -NoType
Tried, tested & one liner :-). This works as I have copied your folder & file structure to replicate. Sorry about it being a few years late, however.
Feel free to tweak the code to your needs, obviously.
Use asterisk and recursion parameter:
Get-ChildItem -Path "C:\Users\*\AppData\Roaming\Microsoft\"
-Filter "*config*" -Recurse | Select -ExpandProperty FullName
This should be work for you:
Get-ChildItem -Path C:\Root -Exclude "*\Folder2\*.pdb" -Recurse
I have 2 tasks that I'd like to use PowerShell for:
1 - I also need to rename all the index.asp to Default.aspx
2 - I have a directory C:\WWW where I need to rename all the .asp files to .aspx, recursively.
I have tried the Rename-Item command but always get errors.
Cannot create a file when that file already exists
How can I rename files in PowerShell?
Use the Get-ChildItem cmdlet to get all index.asp files. Pipe the result to the Rename-Item cmdlet and give the files the new name.
Get-ChildItem c:\www -Filter Index.asp -Recurse | Where-Object {$_.Extension -eq '.asp' } | Rename-Item -NewName Default.aspx
, that will get you index.aspx files as well so pipe the result to the `Where-Object' cmdlet and filter based on the file extension
Do the same for asp files, notice that now you will get .aspx files as well so pipe the result to the `Where-Object' cmdlet and filter based on the file extension. in the new name, take just the base name of each file (without extension) and append it '.aspx'
Get-ChildItem c:\www -Filter *.asp -Recurse | Where-Object {$_.Extension -eq '.asp' } | Rename-Item -NewName {$_.BaseName + '.aspx'}