I create a PowerShell command that have to remove on my diskstation all files inside folders which contains the word "rendery". Everything would be fine, if the command deleted the files in the folder containing the word "rendery", because the script currently deletes the folder (along with the files that are inside) that contains the word "rendery".
Get-ChildItem C:\Test -Recurse | Where-Object {$_.PSIsContainer -eq $true -and $_.Name -match "rendery"} | Remove-Item -Recurse -Force
Insert another Get-ChildItem call after Where-Object to resolve only the child items of the target folders:
Get-ChildItem C:\Test -Recurse | Where-Object {$_.PSIsContainer -and $_.Name -match "rendery"} | Get-ChildItem | Remove-Item -Recurse -Force
Note that $_.PSIsContainer is already a boolean value, so you can shorten $_.PSIsContainer -eq $true to just $_.PSIsContainer
Related
I have a PS script which deletes the folders and files from a particular path older than 15 days.
I want to exclude "_tasks" folder and its contents from getting deleted but the scripts deletes the files and folders inside it even when I have provided -Exclude property to exclude _tasks folder and its contents.
Below is the script I am using.
How can I exclude the _tasks folder and its sub-folders and files from getting deleted?
Get-ChildItem –Path "F:\Suraj\Garbage" -Recurse -Exclude "__tasks" |
Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} |
Remove-Item -Force -Recurse
Below images shows that the files on the left side were deleted inside the _tasks folders. I don't want them to be deleted. Any suggestion for same would be helpful.
this piece of code selects all files except folder _task and its subfolders..
Get-ChildItem -Path 'F:\Suraj\Garbage' -Recurse |
Select-Object LastWriteTime -ExpandProperty FullName |
Where-Object { ($_ -notlike 'F:\Suraj\Garbage\_tasks*') -and ($_.LastWriteTime -lt (Get-Date).AddDays(-15))} |
Remove-Item -Force -Recurse
or better like Theo's suggest:
Get-ChildItem -Path 'F:\Suraj\Garbage' -Recurse |
Where-Object { ($_.FullName -notlike 'F:\Suraj\Garbage\_tasks*') -and ($_.LastWriteTime -lt (Get-Date).AddDays(-15))} |
Remove-Item -Force -Recurse
I want to get all files in subfolders, of the same root folder, that all contain the same string ("foo") in the name of the subfolder(s). Below gives me no error, and no output. I don't know what I'm missing.
Get-ChildItem $rootfolder | where {$_.Attributes -eq 'Directory' -and $_.BaseName -contains 'foo'}) | echo $file
Ultimately, I would like to not just echo their names, but move each file to a target folder.
Thank you.
Here is a solution that includes moving the child files of each folder to a new target folder:
$RootFolder = '.'
$TargetFolder = '.\Test'
Get-ChildItem $RootFolder | Where-Object {$_.PSIsContainer -and $_.BaseName -match 'foo'} |
ForEach-Object { Get-ChildItem $_.FullName |
ForEach-Object { Move-Item $_.FullName $TargetFolder -WhatIf } }
Remove -WhatIf when you are happy it's doing what it should be.
You might need to modify the Get-ChildItem $_.FullName part if you (for example) want to exclude sub-directories of the folders, or if you want to include child items in all subfolders of those paths, but not the folders themselves.
replace
Get-ChildItem $rootfolder | where {$_.Attributes -match 'Directory' -and $_.basename -Match 'foo'}) | echo $file
with
Get-ChildItem $rootfolder | where {($_.Attributes -eq 'Directory') -and ($_.basename -like '*foo*')} | Move-Item $targetPath
your request:
that all contain the same string ("foo")
you have to use the -like comparison operator. Also for exact match I would use -eq (case sensitive version is -ceq) instead of -match since its used for matching substrings and patterns.
workflow:
Gets all the files in directory, sending it through pipe to Where-Object cmdlet where you are filtering based on properties Attributes and Basename. When the filtering is done, its being sent to cmdlet Move-Item.
Adapt the first two vars to your environment.
$rootfolder = 'C:\Test'
$target = 'X:\path\to\whereever'
Get-ChildItem $rootfolder -Filter '*foo*' |
Where {$_.PSiscontainer} |
ForEach-Object {
"Processing folder: {0} " -f $_
Move $_\* -Destination $target
}
I am trying to write a silent script that deletes files older than 14 days and removes empty folders. The part that deletes files work fine, but the part that deletes folders is popping up a confirmation window no matter what I do to suppress it. Here's my code:
$date=(get-date).AddDays(-14)
$ConfirmPreference="None"
$DebugPreference="SilentlyContinue"
$ErrorActionPreference="SilentlyContinue"
$ProgressPreference="SilentlyContinue"
$VerbosePreference="SilentlyContinue"
$WarningPreference="SilentlyContinue"
$OutputEncoding=[console]::OutputEncoding
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {!$_.PSIsContainer -and $_.LastAccessTime -lt $date} | Remove-Item -Force
#The line below is the one that triggers the confirmation
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {$_.PSIsContainer -and #(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force | Where-Object {!$_.PSIsContainer}).Length -eq 0} | Remove-Item -Force
}
Most of the answers I have found say to add -Recurse to my final Remove-Item command, but that would be the opposite of what I want. If the folder is empty, I want it removed. If it is not empty, I do not want it removed. I'm not sure why non-empty folders are even being caught in the first place.
UPDATE
After much frustration, I discovered that the second line was processing items in reverse order, thus requiring confirmation. It was also not properly identifying empty folders, which also triggered confirmation. I ended up using the following function.
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {!$_.PSIsContainer} | Where-Object {$_.LastAccessTime -lt $date} | Remove-Item -Force
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {$_.PSIsContainer} | Where-Object {#(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force).Length -eq 0} | Remove-Item -Force
}
I put it here because while it is a solution (it erases files and folders to my satisfaction), it is not an answer to my posted question.
Remove -Force from first Get-ChildItem and add -Recurse and -Confirm:$false.
This will work:
Get-ChildItem -Path $strPath -Recurse |
Where-Object {$_.PSIsContainer -and
#(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force |
Where-Object {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -Force -Recurse -Confirm:$false
If you are using v3 or higher powershell client you can use the -directory and -file switches for Get-ChildItem and use this:
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force -File | Where-Object {$_.LastAccessTime -lt $date} | Remove-Item -Force
Get-ChildItem -Path $strPath -Recurse -Force -Directory | Where-Object {(gci $_.FullName -File -Recurse -Force).count -eq 0} | Remove-Item -Force -Recurse
}
Yes, I added -Recurse to the folder removal because with my testing no folders with any files in them were being passed to that point, and if it is a folder with nothing but empty folders in it then they all need to go anyway right?
I have one big folder and I want to select 3 folders out of that and ALL items which are in these folders. I fail because I select everything with the name of the folder, so my script just copies the 3 empty folders.
that's what I have :
$folder = get-childitem "C:\bigfolder\" | where-Object {$_.name -eq "1" -or $_.name -eq "2" -or $_.name -eq "3"} | % {Copy-Item -Path $_.FullName -Destination C:\_archive\}
right now it just copies folder 1,2,3 to my folder C:\_archive
I first tried to add -recursive but that doesn't change anything. I probably have to use something else than name...
Put the -Recurse in the Copy-Item scriptblock i.e:
% {Copy-Item -Path $_.FullName -Destination C:_archive\ -Recurse}
I´m totally new to Powershell and wanted to write a script that deletes all non-mp3 files in a directory.
My solution:
get-childitem -Recurse |
Where-Object {!($_.PSIsContainer)} |
Where {$_.Extension -ne ".mp3"} |
remove-item
What can be improved in this statement or could be written in another way.
Are there any problems with this statement?
Thank you.
I would use just one Where-Object command:
Get-childitem -Recurse |
Where-Object {!$_.PSIsContainer -AND $_.Extension -ne '.mp3'} |
Remove-Item -whatIf
If you're certain that no directories have 'mp3' extension :
Get-childitem -Recurse | Where-Object {$_.Extension -ne '.mp3'} |
Remove-Item -whatIf
Remove -whatIf to delete the files.