how to convert function to work recursively - powershell

I have this awesome powershell script that will remove special characters from filenames:
Function Rename-Files($path)
{
Get-ChildItem -path $path |
Foreach-Object {
$newName = $_.name -replace '[^A-Za-z0-9-_ ]', ''
if (-not ($_.name -eq $newname)){
Rename-Item -Path $_.fullname -newname ($newName)
}
}
} #end function
Rename-Files -path "C:\somepath"
i would like to know whether it is possible to get this working not just on the top directory but recursively through the entire directory structure?

Just add the -Recurse Get-ChildItem parameter. e.g.
Get-ChildItem -Recurse -path $path

Related

Adding _ at the end of every file name of 3 type of extension in a folder

How could I modify name of every file by adding _ before the filename extension in a Get-ChildItem -Include without calling 3 times a Foreach.
My script works, but I would like to simplify it by using -Include and not -Filter.
function renommer_fichier {
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.jpg
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.jpg', '_.jpg' }
}
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.mp3
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.mp3', '_.mp3' }
}
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.mpeg
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.mpeg', '_.mpeg' }
}
}
Unfortunately, the -Include parameter - which supports specifying multiple patterns - doesn't work as one would intuitively expect:
Use Get-Item instead of Get-ChildItem and append \* to the input path to make -Include work as intended.
See this answer for background information.
Use the .BaseName and .Extension properties in the delay-bind script block you're passing to Rename-Item to facilitate inserting _ before the filename extension.
Get-Item -Path C:\mestp\mesFichiers\* -Include *.jpg, *mp3, *.mpeg |
Rename-Item -WhatIf -NewName { $_.BaseName + '_' + $_.Extension }
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

remove file's end and the begigng using powershell

i have a folder contains pdf files starting with paracel_ and end with _manifest
for example :
paracel_123_manifest
i use this command to remove the "manifest" from the file but i dont konw how to remove the "paracel" from the satart of the file
$dir = "C:\temp"
$phrase = "_manifest"
$length=$phrase.Length
Get-ChildItem $dir -Recurse| Where-Object { $.Name -like "$phrase" } | Rename-Item -NewName { $.name.substring(0,$.BaseName.length-$length)+$.Extension}# -WhatIf -verbose
thanks in advance!!
hope someone can assist
A
$dir = "C:\temp"
$phrase = "_manifest"
Get-ChildItem $dir -Filter "paracel_*$phrase*.pdf" -Recurse | ForEach-Object {
Rename-Item $_.FullName -NewName ($_.Name.Replace("_manifest","")).Replace("paracel_","") -WhatIf -verbose
}
You were on the right path. I just changed the filter and put parsed the items in a foreach loop.

How to include folders in Powershell -include string

I am doing some batch file name updates and am having trouble including folders. I have it currently set to target only specific file types, but I also want to include folders. Since folders don't have an extension I am unsure how to specify folders in the "-include" string. Any help would be greatly appreciated.
Here is what I am currently working with, but it ignores folders when I would like them included.
Get-ChildItem k:/toolbox/powershell -Include *.gif, *.jpg, *.png, *.xls,
*.xlsx, *.ppt, *.pptx, *.doc, *.docx, *.pdf -recurse | where {$_.name -match
"_"} | foreach {
$New=$_.name.Replace("_","-")
Rename-Item -path $_.Fullname -newname $New -passthru
}
(Get-Item '~\Desktop\*') | foreach { $FolderName = $_.name.Replace("_","-"); Rename-Item -path $_.fullname -newname $FolderName -passthru }
I would just add 2nd statement:
Get-ChildItem "k:/toolbox/powershell" -Recurse |where mode -eq d----- | where {$_.name -match "_"} | foreach {$New=$_.name.Replace("_","-")
Rename-Item -path $_.Fullname -newname $New -passthru }
If you run Get-ChildItem "k:/toolbox/powershell" you will receive a list of items where the "Mode" is "d-----" for directories, hence you can use that filter criteria for directories

I want to remove recursively square brackets from file names

I have a lot of files in a directory containing square brackets for example:
Filename 1 [12454365].txt
I tried the following script but it's giving me the an error.
get-childitem -recurse | foreach { move-item -literalpath $_.name ($_.name -replace '\[.*\]', '')}
Error message
move-item : A device attached to the system is not functioning.
Only want to remove square brackets not everything in between!
If you specify -Recurse, you will need to specify the file with FullName because it will be targeted other than the current directory.
(Get-ChildItem -File -Recurse) | foreach {
$dest = Join-Path $_.DirectoryName ($_.Name -replace "[\[\]]")
Move-Item -LiteralPath $_.FullName $dest
}
Also, it is better to use Rename-Item for file renaming.
(Get-ChildItem -File -Recurse) | Rename-Item -NewName { $_.Name -replace "[\[\]]" }
I believe the issue is that you are replacing the brackets and everything in between.
Get-ChildItem * -Filter "*`[*`]*" | Rename-Item -NewName { $_.name -replace '\[','' -replace '\]','' }

Recursively removing/renaming files using powershell

I have to go through many levels of child folders and remove special characters that are invalid in SharePoint, mainly '#&'
I have scoured the internet trying different commands; rename-item/move-item, variations of the two, all to no avail. The closest i've gotten is using:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'}
but i keep getting this error: Rename-item: Source and destination path must be different.
Could someone point me in the right direction?
Regards
That error only happens when you attempt to rename a directory to the same NewName as the current name, you can safely ignore it.
Add -ErrorAction SilentlyContinue to silently suppress the error message:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'} -ErrorAction SilentlyContinue
You need to filter out the files that you're not planning to rename:
Get-ChildItem -Recurse |
Where-Object { $_.Name -match '[!##&]' } |
Rename-Item -NewName {$_.Name -replace '[!##&]','_'}
something like this may work
dir -Recurse -File | ? basename -Match '[!##&]' | % {
# if the file.txt already exists, rename it to file-1.txt and so on
$num = 1
$base = $_.basename -replace'[!##&]', '_'
$ext = $_.extension
$destdir = Split-Path $_.FullName
$newname = Join-Path $destdir "$base$ext"
while (Test-Path $newname) {
$newname = Join-Path $destdir "$base-$num$ext"
$num++
}
ren $_.fullname $newname
}