Get only leaf nodes from Get-ChildItem - powershell

I would like to filter out only leaf nodes (folders) from Get-ChildItem, those ones that do not contain any other folders in them.
Here is my current query:
Get-ChildItem -Recurse -Directory -Exclude "*SubStr*"

He was on the right path, but just forgot the -Directory on the second Get-ChildItem command.
Get-ChildItem -Recurse -Directory -Exclude "*SubStr*" | Where-Object { -not (Get-ChildItem $_.FullName -Directory) }
Note: If you want to find hidden folders you will have to use -Force on both Get-ChildItem commands in the line below.

You would need another filter to establish whether or not the folder has anything inside it:
Get-ChildItem -Recurse -Directory -Exclude "*SubStr*" | Where-Object { -not (Get-ChildItem $_.FullName) }

Get-ChildItem -Recurse -Directory -Exclude "*SubStr*" |?{$_.psiscontainer}

Related

Get-ChildItem recursively but exclude files in the parent folder

I need to get a list of files in all subdirectories of $PSScriptRoot but exclude any files in the parent folder of $PSScriptRoot.
$Files = Get-ChildItem -LiteralPath $PSScriptRoot -Recurse | Where-Object {!$_.PSIsContainer}
You could list the parent folders first, then recurse each directory for files:
$Files = Get-ChildItem -LiteralPath $PSScriptRoot -Directory | Get-ChildItem -File -Recurse
You can add a Where-Object clause to filter out all files that are directly inside the $PSScriptRoot:
$Files = Get-ChildItem -LiteralPath $PSScriptRoot -Recurse -File | Where-Object { $_.DirectoryName -ne $PSScriptRoot}
you can use switch -File instead of Where-Object {!$_.PSIsContainer} as of PowerShell version 3.0
You just need to call Get-ChildItem again as a pipe
$Files = Get-ChildItem -LiteralPath $PSScriptRoot -Recurse | Where-Object {!$_.PSIsContainer} | Get-ChildItem

I need to find a Folder on the Network Share

How can I find Folders called BlueMountain when this folder could be nested anywhere in my Users home folder
\\Server\Users\<personsname>\
Ultimately I want to delete the folder but just to be on the safe side. The BlueMountain folder must have one of these subfolder
Certs
Config
Macros
Scripts
Spool
Traces
Transfer
This is what I have so far
Get-ChildItem -Path \\Server\Users -Recurse -Directory -Filter $_.FOLDERNAME | ForEach-Object {
If $_.FullName --eq "BlueMountain" {
}
}
You can use -recurse to look for the last thing in your path recursively. So this:
Get-ChildItem \\server\Users\BlueMountain -recurse
Will look in all subfolders of "\server\Users" for anything named "BlueMountain". Then you just need to make sure it has one of your folders.
$SubFolders = 'Certs','Config','Macros','Scripts','Spool','Traces','Transfer'
Get-ChildItem \\server\Users\BlueMountain -recurse | Where{Get-ChildItem "$($_.FullName)\*" -Include $SubFolders}
That should list only the BlueMountain folders found recursively in \server\Users which contain one of the specified subfolders. Then you can just pipe that to Remove-Item -force and call it a day. Or if you want to track things pipe it to tee-object and then to remove-item.
try this :
$SubFolders = 'Certs','Config','Macros','Scripts','Spool','Traces','Transfer'
$wordtosearch="BlueMountain"
$SearchPattern= ($SubFolders | %{ "$wordtosearch\\$_" }) -join "|"
get-childitem "\\Server\Users" -directory -Recurse |
where FullName -match $SearchPattern |
Split-Path -path {$_.FullName} -Parent |
remove-item -Recurse -ErrorAction SilentlyContinue

exclude multiple folder using gci

I have 2 subfolders 'PS Logs', 'Executables' in the root directory "C:\Temp\". How to exclude them using gci. I am doing the crude way where I exclude all the underlying files in these sub-folder.
Get-ChildItem -Path "C:\Temp\" -recurse -exclude *.*
Try this
Get-ChildItem C:\temp -Recurse | Where-Object {!($_.FullName -match 'PS Logs') -and !($_.FullName -match 'Executables')} | Select-Object -ExpandProperty Fullname
You are almost there :)
Get-ChildItem C:\Temp -Recurse -Exclude "PS Logs", "Executables"

How to rename files using HttpUtility.UrlEncode method in PowerShell?

I have a bunch of html files that I need to rename with url encoding before I upload them to the server. I've tried:
Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html | Rename-Item -NewName { $_.Name.replace("*.html",[Web.Httputility]::UrlEncode("*.html")) }
But that doesn't apply the encoding, can this be even done somehow?
Here's a basic way to do it, based on this answer:
(Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -File) |
foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
Originally I had written it without the () around the Get-ChildItem, but found it was still reading directory information while the rename had already renamed the first item. Then the rename reencoded the first item a second time, thus making it a bit munged up.
Here's a cleaner version that handles the files first and then folders:
$files = Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -File
$folders = Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -Directory
$files | foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
$folders | foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
Based on your answers i did this to make it work
(Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html) |
foreach { ren $_.fullName ([uri]::EscapeDataString($_.Name))} | Out-Null
Get-ChildItem -Path c:\temp\ -Recurse | ?{ $_.PSIsContainer } |
foreach { ren $_.fullName ([uri]::EscapeDataString($_.Name))}
First I had to do only files and then folders, because when top folder gets renamed, then the path to files inside it doesn't exist any more.

Deleting all folders/files except for one folder and all root-files

I've had some months away from Powershell so excuse me if this is obvious..
I have a directory containing hundreds of filed and folders, and I would like to delete everything EXCEPT for all files in the root directory and one of the subfolders.
I will be creating a scheduled task to do this once a week.
This is what I have so far:
get-childitem -recurse | ?{ $_.psiscontainer } | remove-item
but it is quite obvious that I am only deleting folders..
Do you want to keep the contents of the one subfolder or just the subfolder itself? For the former do this:
Get-ChildItem 'C:\foo' -Exclude 'subfoldername' |
Where-Object { $_.PSIsContainer } |
Remove-Item -Recurse -Force
For the latter delete the contents of the subfolder in a second step:
Get-ChildItem 'C:\foo' -Exclude 'subfoldername' |
Where-Object { $_.PSIsContainer } |
Remove-Item -Recurse -Force
Get-ChildItem 'C:\foo\subfoldername' | Remove-Item -Recurse -Force
With PowerShell v3 and newer you can replace the Where-Object filter by adding a parameter -Directory to Get-ChildItem:
Get-ChildItem 'C:\foo' -Exclude 'subfoldername' -Directory |
Remove-Item -Recurse -Force
Try this
get-childitem -exclude SubFolderName -recurse | ?{ $_.psiscontainer } | remove-item
This command will do what you are looking for. From what I have read, the Remove-Item is buggy.
Get-ChildItem -Path D:\Temp -Recurse | Remove-Item -Exclude W3SVC5 -Recurse -force