Return only directory from Get-ChildItem - powershell

The following query searched for locations of a file in PowerShell. Is there any way to just return the directory instead of the directory attributes and filename?
Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse

(Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse).DirectoryName

I'm assuming you only want the names of the directories that contain matched files here:
Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse | % { split-path $_.fullname } | sort -uniq

Related

Get ChildItem from only files of specific folders

I try to export files of specific named Folders:
Get-ChildItem -Path 'C:\Test' -Name -Recurse -File > C:\Test\Test.txt
I get a list like:
content.csv
Test.txt
Folder 1\INTERESTED_FOLDER\a - Kopie.txt
Folder 1\INTERESTED_FOLDER\a.txt
Folder 1\Neuer Ordner\ttt.txt
Folder 1\Neuer Ordner - Kopie\ttt.txt
Folder 2\INTERESTED_FOLDER\b - Kopie.txt
Folder 2\INTERESTED_FOLDER\b.txt
Folder 2\Neuer Ordner\ttt.txt
Folder 2\Neuer Ordner - Kopie\ttt.txt
But what i want is:
Folder 1\INTERESTED_FOLDER\a - Kopie.txt
Folder 1\INTERESTED_FOLDER\a.txt
Folder 2\INTERESTED_FOLDER\b - Kopie.txt
Folder 2\INTERESTED_FOLDER\b.txt
I tried with -Filter "INTERESTED" etc. but then i only get
C:\Test\Folder 1\INTERESTED_FOLDER
C:\Test\Folder 2\INTERESTED_FOLDER
What i do wrong?
If I read your question correctly, you want the FullNames of the files (so their names including the path).
If that is the case, remove the -Name switch and filter on the DirectoryName property like:
(Get-ChildItem -Path 'C:\Test' -Recurse -File |
Where-Object { $_.DirectoryName -match 'INTERESTED_FOLDER' }).FullName | # also matches 'MY_INTERESTED_FOLDER_123'
Set-Content -Path 'C:\Test\Test.txt'
Alternatives for the Where-Object clause:
# also matches 'MY_INTERESTED_FOLDER_123'
Where-Object { $_.DirectoryName -like '*INTERESTED_FOLDER*' }
or if you are looking for a precise match on the complete folder name
# does NOT match 'MY_INTERESTED_FOLDER_123'
Where-Object { $_.DirectoryName -split '[/\\]' -contains 'INTERESTED_FOLDER' }
You can perform a wildcard search using the -Filter parameter:
Get-ChildItem -Path 'C:\Test' -Name -Recurse -File -Filter *INTERESTED_FOLDER* > C:\Test\Test.txt
If for example, you were interested in finding the files in INTERESTED_FOLDER but also only the files that are .txt you could do:
-Filter *INTERESTED_FOLDER*.txt
Using the -Name parameter affects your capabilities because you are returning strings instead of FileInfoObjects. You may then use Where-Object to capture everything.
Get-ChildItem -Path 'C:\Test' -Name -Recurse -File |
Where {$_ -match '\\INTERESTED_FOLDER\\'} |
Set-Content c:\test\test.txt
Note that the matching above assumes INTERESTED_FOLDER is not a direct descendent of your path. If that is a possibility, then your match expression needs to be updated to \\?INTERESTED_FOLDER\\.

How to loop through all subfolders in a directory, and remove files with a specific filename

I am trying to write a script in Powershell to remove some files automatically with a certain file name.
My idea is to get all the folders in the directory, then loop through the subdirectory, and remove all items with the file name, but it doesn't seem to be working as expected.
Here is my script
$folders = Get-ChildItem -path "C:\Website-Backup" -Recurse | Where-Object {$_.PsIsContainer} |Group-Object {$_.FullName.Split('_')[0] }
$subfolders = Get-ChildItem -path $folders -Recurse | Where-Object {$_.PsIsContainer} | Group-Object {$_.FullName.Split('_')[0] }
ForEach($subfolder in $subfolders)
{
Remove-Item * -Include *100x*
}
Any idea why the script doesn't seem to be doing anything?
I think you can simplify your code if I understand correctly to:
Get-ChildItem "C:\Website-Backup" -Recurse -include "*100x*" -file | remove-item
The Group-Object command is likely what's confusing things here - Remove-Item is expecting a path - you're not referencing the subfolder variable in your loop as well, so this is the same as just running the Remove-Item command as many times as there are items in the array.
You can try this instead;
Get-ChildItem -Path "C:\Website-Backup" -Recurse | Where-Object -FilterScript { $_.name -like 'MyFile.txt' } | Remove-Item
This will pipe the returned child items into Where-Object, filter it to the specified file name, then pass that to Remove-Item as a file path.
You can also skip the Where-Object, but you lose a bit of control this way;
Get-ChildItem -Path 'C:\WebSiteBackup\*MyFile.txt' -Recurse | Remove-Item

Powershell folder archiving

I have a powershell script that simply uses the Get-ChildItem command to search through a directory for a folder matching a keyword. When found I need it to zip it and leave it right in that same directory.
Here's what I've tried by piping the command into both 7zip and the native compress:
set-alias zip "$env:ProgramFiles\7-Zip\7z.exe"
Get-ChildItem $path "keyword" -Recurse -Directory | zip a
AND
Get-ChildItem $path"keyword" -Recurse -Directory | compress-archive
Both times it always asks for a source and destination which is hard to define since I'm having it search through a drive with many sub-folders. I though using the pipe would imply the source as well.
Any ideas? Thanks!
EDIT:
I suppose I could set the Get-ChildItem to a variable and use that as the "source" and have the destination be a generic location for them all but I'd have to name them differently, no?
Give this a try:
$path = "INSERT SOURCE ROOT"
foreach ($directory in Get-ChildItem $path -Recurse -Directory -Filter "keyword"| Select-Object FullName | foreach { $_.FullName}) {
$destination = Split-Path -Path $directory -Parent
Compress-Archive -Path $directory -DestinationPath $destination
}
This is looking inside the path for anything matching the "keyword", going up 1 level, and then zipping the found file.
With temp and temp2 directories under C:\ this is working for me (note that the directories must have content):
Get-ChildItem "C:\" "temp*" -directory | compress-archive -DestinationPath "C:\tempzip.zip"
It zips all directories found to C:\tempzip.zip.
I believe what you actually want is:
$dirs = Get-ChildItem "C:\" "temp*" -directory
foreach ($dir in $dirs){
compress-archive $dir.fullname -DestinationPath "$($dir.fullname).zip"
}
Note that I omitted -recurse for my testing.
You can do this:
get-childitem -path "The Source Path" -recurse | where {$_.Name -match "Keyword"} | foreach {
$parent = Split-Path -Path $_ -Parent
Compress-Archive -Path $_ -DestinationPath $parent
}

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

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.