Powershell - Delete folders containing a file with a specific FileDescription? - powershell

I am using the below code to get the FileDescription of a file:
(dir C:\test.exe).VersionInfo | select-object FileDescription | fl
This is working fine, the next step is: I am looking to search for all files that end with a specific FileDescription, then delete the folders where these files reside. Is this possible? Thanks!

There was an error in my pipe. The file information was lost since we only pipe .VersionInfo
Get-ChildItem C:\test.exe | Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} | Remove-Item -WhatIf
It would make more sense if you were to use -Recurse to return more file and keep using Where-Object to filter just the ones you want. This should find the files and return their folder names. Since there could be more than one file in a folder that matches we could pipe the results in Select-Object -Unique to get the individual folders.
Get-ChildItem C:\MyFolder -Recurse | Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} | ForEach-Object{Split-Path $_.FullName -Parent} | Select-Object -Unique | ForEach-Object{Remove-Item $_ -WhatIf -Confirm:$false -Force -Recurse}
I leave the -WhatIf as a precaution. Remove if the code suits your needs.

Does this work?
Get-ChildItem C:\MyFolder -Recurse | `
Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} |`
%{$_.DirectoryName}|`
sort-object -unique| `
remove-item -recurse -whatif

Related

copying a file over to a destination then using the where-object -like command not working

I am trying to copy a file over to a destination but use the where-object {$_.name -like '*DEA 052020*'}
Here is my current script but it just ends up copying over the PDF RECON CENTER to the destination:
cd \\sageshare\share\
Where-Object {$_.Name -like '*DEA 052020*'}
$SourceDir = "\\Sageshare\share\Reconciliation\PDF Recon Center\$_"
copy-item -path $SourceDir -destination "\\Sageshare\share\Reconciliation\Account Rec. Sheets\Separate Accounts\DEA"
Still really new to working with powershell scripting so I am not sure how to place the $_.Name in the $SourceDir.
Before you perform your where clause, you need to pass something into it. It doesn't know what you're doing. You will need to list the contents of the share directory first, and then perform your where clause.
Get-ChildItem \\sageshare\share\ | Where-Object {$_.Name -like '*DEA 052020*'}
If you want to recursively search, then pass in the -recurse switch to your Get-ChildItem command, like so
Get-ChildItem \\sageshare\share\ -recurse
From there you can pipe your Copy-Item command into your destination, like so
Get-ChildItem \\sageshare\share\ | Where-Object {$_.Name -like '*DEA 052020*'} | Copy-Item -destination "\\Path\To\Destination"

Moving Current objects (For me Folders) to the parent of the directory their in using PowerShell

I am trying to search through folders on a share drive for subfolders with "*OutPuts" in the name. These folders should have folders in them but should not have files:
select fullname,#{N='SubDirectories';E={[boolean]($_ |
get-childitem -directory).count}},#{N='SubFiles';E={[boolean]($_ |
get-childitem -file).count}}
When these folders are found I want to move any folders from the output folder to the Project folder (Parent of its Parent). Example:
Starting Condition: C:\AllProjects\Projectfolder\outputs\SubProjectFolder
Wanted Outcome: C:\AllProjects\Projectfolder\SubProjectFolder
Here's the full Code:
code somewhat reformatted for readability ...
$folders=Get-ChildItem C:\AllProjects -recurse -Directory |
where {$_.name -like "*Outputs"} |
select fullname,
#{N='SubDirectories';E={[boolean]($_ |
get-childitem -directory).count}},
#{N='SubFiles';E={[boolean]($_ |
get-childitem -file).count}}
$folders
$folders |
where {$_.subdirectories -eq $true -and $_.subFile -eq $False} |
foreach {
get-childitem |
Move-Item $_ -destination $_.parent.parent}
When ever I run the code the following message comes up:
cmdlet Move-Item at command pipeline position 1
Supply values for the following parameters:
Path[0]:
I'm pretty new to PowerShell so if someone could help break this down for me and tell me what I'm supposed to put here that would be greatly appreciated. Thank you for your time.
UPDATE
*I've tried it with
-Path $_, -Path $_.PsPath, -Path $_.FullName.
I've even tried Get-Item. With the -Path though I now get a message that's a little different:
cmdlet ForEach-Object at command pipeline position 2 Supply values for the following parameters: Process[0]:

Return the second level directory names only

I would like to retrieve all (and only) second level directory names of my disk. For example, C:\folder1\folder2 and C:\folder1\folder3, I need to retrieve only folder2 and folder3.
I write this and the PS displays all the directory names:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer} | Select-Object Name
I found this help, and I modify the previous command in this way:
Get-ChildItem -Recurse | `Where-Object {($_.directory -match '^*\\\S*$')} ` | ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
but when I use it the PS doesn't display anything.
I can't understand why, someone can help me? Thank you!
Only files appear to have a .directory property, directories do not, so you will never get something which passes your (.directory matches a pattern) filter and also passes your (PSIsContainer) filter.
Except that your PSIsContainer filter doesn't work:
| ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
this doesn't make sense; you can only filter the pipeline using ? with cmdlet | ? {}, you cannot filter at the start of a loop scriptblock with no input and get anything useful. This is running where-object {} over and over in a loop, - and that has no output.
Using -Recurse will be very slow, as you go into every single directory all the way to the end, and make [fileinfo] objects for all the files as well.
Apart from Matt's wildcard answer, assuming PS v3 or above, you could list all the directories in the root, and then all the directories inside those, and stop there:
Get-ChildItem c:\ -Directory | Get-ChildItem -Directory | Select -ExpandProperty Name
or
gci c:\ -Dir | ForEach { (gci $_ -Dir).Name }
You should just be able to use some fun wildcards to get what you want here.
Get-ChildItem \*\*\ | Where-Object{$_.PSIsContainer}
Or if you have at least PowerShell 3.0 this would be faster
Get-ChildItem \*\*\ -Directory
Then if you wanted just the names tack on | Select-Object -ExpandProperty Name
Here with full path, network compatible:
(Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}
Want it stored in an array?
$subfolders = (Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}

Copy the newest file from folder and exclude files by part of the name via PowerShell

I try to copy the newest file from folder (.exe files) by using this type of command:
Get-ChildItem "K:\" -File -include "*.exe" | Where-Object { $_. $_.LastWriteTime like "I don't know which parameter I should type here} Copy-Item -Path $files -Destination "C:\"
I don't want to use complex script with variables and etc. (for now)
Here is folder structure which I have:
Release_OSInstaller_2015_CL287638x64_NoDB.exe
Release_OSInstaller_2015_CL287638x64.exe
Release_OSInstaller_2015_CL287337x64_NoDB.exe
Release_OSInstaller_2015_CL287337x64.exe
And so on. Basically every day a new build is deployed in folder where from I copied the file to my machine (remote).
I need to create a script which will copy the newest build but I want to exclude all files with "NoDB.exe" parameter.
Not sure if it is the fastest way (probably not). But if you are not crawling through huge filesystems
Copy-Item -Path (Get-ChildItem "K:\" -File -include "*.exe" |
Where Name -NotMatch '.*NoDB\.exe$' | Sort-Object -Descending
LastWriteTime | Select-Object -First 1) -Destination "C:\"
should do the trick. (My first answers seems to have been wrong ;) )
And I totally missed the excluding condition so now Martin Brandl Addition is included ^^
In addition to the answer from whatever, you could add a Where condition and skip the NoDBfiles:
Get-ChildItem "K:\" -Filter '*.exe' |
Where Name -NotMatch '.*NoDB\.exe$' |
sort LastWriteTime -Descending |
select -first 1 |
Copy-Item -Destination 'C:\'

Outputing Remove-Item to a log file

Scanning a directory for a specific set of files and sorting them by date. Keeping 7 of the LATEST copies of the file regardless of date, and removing the oldest if over 7. I am having a hard time producing a log file showing the deletes since Remove-Item has no output.
Below is a copy of my code:
$path = "C:\- Deploy to Production -\Previous Deploys\*_*_BOAWeb.rar" #BOA
$files = Get-ChildItem -Path $path -Recurse | Where-Object {-not $_.PsIsContainer}
$keep = 7
if ($files.Count -gt $keep) {
$files | Sort-Object CreationTime |
Select-Object -First ($files.Count - $keep) |
Remove-Item -Force
}
First off you are over complicating things. Add -Descending to your Sort command, and then change your Select to -Skip $keep. It's simpler that way. Then you have options for outputting your deleted files.
Remove-Item -Force -Verbose 4>&1 | Add-Content C:\Path\To\DeletedFiles.log
or (keeping with your current code above)
Select-Object -First ($files.Count - $keep) |Tee-Object -filepath C:\Path\To\DeletedFiles.log -append
The first will output the verbose output of Delete-Item and append it to whatever log file you specify the path for (use Set-Content if you want to replace the log instead). The second option will append the [FileInfo] objects onto a log that you specify.
Edit: As pointed out by Ansgar Wiechers, I had forgotten to to combine my verbose and stdout streams, so 4>&1 was added to the above code to correct that issue.