Powershell - Get-ChildItem wildcard - powershell

Get-ChildItem filename*.log.* fetches filename*.log as well. How can I get only the log files ending with dot extension filename*.log.* so I can delete them? I want to use Remove-Item but decided to check using get-childItem.
Here is the files.
Server1234.log
Server1234.log.1
Server1234.log.2
Server1234.log.3
Server1234.log.4
Get-ChildItem filename*.log.* shows all of the above. I don't want Server1234.log in the output.

Your filter should work. I have created 3 files:
New-Item 'Server1234.log' -ItemType File
New-Item 'Server1234.log.1' -ItemType File
New-Item 'Server1234.log.2' -ItemType File
And here is the output of Get-ChildItem Server1234*.log.*
PS D:\> Get-ChildItem Server1234*.log.*
Directory: D:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 13/05/2020 10:51 0 Server1234.log.1
-a---- 13/05/2020 10:51 0 Server1234.log.2
Note: The filter parameter of the Get-ChildItem cmdlet doesn't use regex! If you want to use regex you can do this within the Where-Object cmdlet:
Get-ChildItem | Where-Object { $_.Name -match 'Server123.*log\.+' }

You might use the filter
Get-ChildItem filename*.log.?*
The question mark states that at least one character has to be there...

Related

Powershell Get-childitem script not saves output on Windows 10 machines or when pushed remotely

I have written a simple script that should collect all local documents from folders on C: drive (*.pdf, *.jpg, *.xls, *.doc) and save them to the "computername" text file under the C:\TEMP folder.
I have been able to launch this locally on Windows 11 machine without issues! When I tried to do the same thing on Windows 10 machine text file was empty!
I have narrow this down to the user account interaction, as it seems on Windows 10 machines. If this script is launched from PowerShell running as current user on Windows 10 it seems the script generates output. If it is Run as Administrator (locally or via remote push as admin) I got empty file. I would appreciate any guidance.
code:
$FindDate=(Get-Date).adddays(-180)
[System.IO.Directory]::CreateDirectory('C:\TEMP')
{Get-ChildItem -Path C:\ -Directory} |
Where-Object Name -NotIn #('Windows','Program Files','$Recycle.Bin','Windows.old') |
% { Get-ChildItem -Include *.doc,*.docx,*.pdf,*.jpg,*jpeg,*.xls,*.xlsx -File -
Recurse} -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -ge $FindDate } |
Select LastWriteTime,Name,Directory |
Out-File C:\TEMP\$env:Computername.txt
there are some issues with the current code:
e.g. you do:
{Get-ChildItem -Path C:\ -Directory}
this defines a expression and will not execute:
PS C:\Users\vcxy> {Get-ChildItem -Path C:\ -Directory}
Get-ChildItem -Path C:\ -Directory
PS C:\Users\vcxy>
you want probably:
PS C:\Users\vcxy> Get-ChildItem -Path C:\ -Directory
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 8/15/2022 2:46 PM AMD
d----- 6/5/2021 2:10 PM PerfLogs
d----- 4/19/2022 6:56 PM plc_debug
d-r--- 9/22/2022 6:26 PM Program Files
d-r--- 6/12/2022 5:02 PM Program Files (x86)
d----- 9/27/2022 6:43 PM TEMP
d----- 9/27/2022 5:06 PM tmp
d-r--- 10/6/2021 12:44 PM Users
d----- 4/8/2020 2:18 PM VM
d----- 9/22/2022 10:46 PM Windows
I'll updated your version as needed:
$FindDate=(Get-Date).adddays(-180)
#This works but you could also do new-item C:\temp -ItemType Directory
[System.IO.Directory]::CreateDirectory('C:\TEMP')
$folders = Get-ChildItem -Path C:\ -Directory | Where-Object {$_.Name -Notmatch 'Windows|Program Files|$Recycle\.Bin|Windows\.old'}
$files = #(
$folders | % {
Get-ChildItem -Path $_.fullname -Include *.doc,*.docx,*.pdf,*.jpg,*jpeg,*.xls,*.xlsx -File -Recurse -ErrorAction:SilentlyContinue | Where-Object {$_.LastWriteTime -ge $FindDate}
}
)
#You should use export-csv, its better for later processing of the data
If ($files){
$files | Select LastWriteTime,Name,Directory | export-csv C:\TEMP\$env:Computername.txt
}
It will only create the output file if files are found, no files no output file or in regards to the original version, no files no content in the output file.

Find all files with the exact extension in Powershell

I'm trying to get all the files that end with ".asp" but I also get the files that ends in ".aspx" or ".asp..." when I do :
Get-ChildItem C:\test -Filter *.asp -Recurse | % {$_.FullName}
For the example, let's say I have a directory with test1.asp, test2.aspx and test3.asp, if I execute my script, the output will be:
C:\test\test1.asp
C:\test\test2.aspx
C:\test\test3.asp
but I only wanted it to get me "test1.asp and test3.asp".
For information, I use Powershell 2.1.
Can someone tell me how to fix that?
Try to check one more the last 3 symbols
Get-ChildItem 'C:\test' -Filter '*.asp' -Recurse |
Where {$_.Name.substring($_.Name.length -3, 3) -Match 'asp'} | % {$_.FullName}
Caveat: PowerShell behavior seems to have changed!
Windows PowerShell 5.1.19041.2364:
PS C:\Users\OA> Get-ChildItem -File -Path "C:\Test" -Filter "*.txt"
Verzeichnis: C:\Test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 05.02.2023 09:59 0 TestFile.txt
-a---- 05.02.2023 09:59 0 TestFile.txtLirumLarumLöffelstiel
PowerShell Core 7.3.2:
PS C:\Users\OA> Get-ChildItem -File -Path "C:\Test" -Filter "*.txt"
Directory: C:\Test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 05.02.2023 09:59 0 TestFile.txt
Both commands were performed on Microsoft Windows Pro 10.0.19045.2546 (22H2).
Behavior on legacy operating systems: PS version 2.0 on Windows XP (using wildcard path instead of -File parameter) and PS version 5.14409.1018 on Windows 7: both have the former behavior.

Powershell Copy-Item not keeping folder structure

I have the below script to copy data from a local folder to a remote folder created with the current date. However the files are copying but the folder structure is not.
$Date = (Get-Date).ToString("MMddyyyy"),$_.Extension
$Source = "E:\Folder1\\*"
$Dest = "\\Server\Share\Folder2"
$Username = "Username"
$Password = ConvertTo-SecureString "Password" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential($Username, $Password)
Remove-PSDrive -Name T
Start-Sleep -s 1
New-PSDrive -Name T -PSProvider FileSystem -Root $Dest -Credential $mycreds -Persist
if (!(Test-Path "T:\$Date"))
{
md -Path "T:\$Date"
}
Get-ChildItem -Path $Source -Recurse | % { Copy-Item -Path $_ -Destination "T:\$Date" -Container -Force -Verbose }
Could anyone advise where I am going wrong here?
Thank you.
Nice script, I think we can get this sorted in no time!
Why this happened
The reason this is failing is in this step right here:
Get-ChildItem -Path $Source -Recurse
The -Recurse switch is causing you pain. To illustrate why this is, I created a simple folder structure.
When you run Get-ChildItem -Path $Source -Recurse alone, you'll get a recursive listing of all files in the $Source path, like so:
PS C:\temp\stack> Get-ChildItem -Recurse
Directory: C:\temp\stack
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 8/4/2017 10:50 AM Source
Directory: C:\temp\stack\Source
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 8/4/2017 10:57 AM 1
d----- 8/4/2017 10:57 AM 2
d----- 8/4/2017 10:57 AM 3
d----- 8/4/2017 10:57 AM 4
Directory: C:\temp\stack\Source\1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 8/4/2017 10:57 AM 20 Archive.rar
-a---- 8/4/2017 10:56 AM 0 File01.bmp
Well, in the next step of your script, you pipe that output over to Copy-Item for every single file.
You're basically expressly telling PowerShell 'take this folder and all of it's subfolders and everything, and dump them all in this one folder, ignoring the folder structure'
How to fix
What you really want to do is simply move the -Recurse parameter over to Copy-Item, and you're done :)
Get-ChildItem -Path $Source |
Copy-Item -Destination "T:\$Date" -Container -Recurse -Force -Verbose
Hope that helps, have a nice 🎃day!
This question is a few years old, but in case someone arrives here like I did...
In another post, a user suggested using robocopy. It worked great for me:
robocopy "source/folder" "target/folder" "*.file_extension" /s
This command copies from the source folder the files that match the given filter, replicating the folder structure in the destination folder.
In this case, it would be used like:
robocopy "E:\Folder1\" "\\Server\Share\Folder2" "*" /s

Powershell Remove-Item leaving Folders Behind

So I want to clean up some of my users profiles on a nightly basis using the following "script"
Get-ChildItem 'F:\View\Profiles\' -Recurse -Force |
Where-Object {$_.Directory -match 'F:\\View\\Profiles\\((\w*).V2)\\AppData\\Roaming\\Trillian\\users\\((\w*%\w*%\w*))\\logs\\(_CLOUD|ASTRA)'} |
Remove-Item -Recurse -Force
This deletes all the log files but leaves behind the folder structure. Because of that I tried the following query.
Get-ChildItem 'C:\TestProfileClean' -Recurse -Force |
Where-Object {(($_.Name -eq "logs" -and $_.Directory) -and $_.DirectoryName -match 'C:\\TestProfileClean\\(\w*.V2)\\AppData\\Roaming\\Trillian\\Users\\((\w*)%40(\w*)%2Ecom)' )} |
Remove-Item -Recurse -Force
This ensures that the folder deleted is named "logs" it is a directory and the directory name is in this format.
C:\\TestProfileClean\\(\w*.V2)\\AppData\\Roaming\\Trillian\\Users\\((\w*)%40(\w*)%2Ecom)
The problem is when I run the second command it does not delete any files, if I cut off $_.DirectoryName then I get the following output.
Directory: C:\TestProfileClean\username.V2\AppData\Roaming\Trillian\users\username%40compcorp%2Ecom
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 12/14/2016 9:56 AM logs
Which will delete what I want but isn't specific enough for me to be comfortable running it.
What am doing wrong that is preventing folders from being deleted but the script will delete all non folder items.
You are missing the wildcard to go through all of them under the folder . I just modified your code :
Get-ChildItem 'F:\View\Profiles\*' -Recurse -Force |
Where-Object {$_.Directory -match 'F:\\View\\Profiles\\((\w*).V2)\\AppData\\Roaming\\Trillian\\users\\((\w*%\w*%\w*))\\logs\\(_CLOUD|ASTRA)'} |
Remove-Item -Recurse -Force
Note: I am not checking the Regex. I am only tweaking the get-childitem part.
Apart from this , I have 2 other suggestion for you. If you really want to delete the user profiles nightly basis, then you can use the small utility tools
1) made of batch
2) made of powershell.
Below are the links for your reference.
Delprof - Batch
Delprof - Powershell
Hope this helps...!!!

Difference between -include and -filter in get-childitem

Can someone please explain the difference between -Include and -Filter options in the Get-ChildItem command .
Below are the two pieces of code that I am trying to execute . They both serve to find out the text files in a particular directory:
PS C:\Users\352997> get-childitem -path Desktop\Extras -filter *.txt
Directory: C:\Users\352997\Desktop\Extras
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 12/22/2014 4:05 PM 140 Expense_report.txt
-a--- 1/14/2015 4:41 PM 211 Extras.txt
-a--- 2/10/2015 2:46 PM 259 Learn Dutch.txt
PS C:\Users\352997> get-childitem -path Desktop\Extras -include *.txt
--The above command produces no result ----
Filter parameter is implemented by provider. It is efficient because applies when retrieving the objects.
Get-PSprovider commandlet shows providers that implement 'filter' parameter. For example, there are only two providers on my
system:ActiveDirectory and FileSystem
Include parameter is implemented by Powershell. It only works in conjunction with Recurse parameter (as MSDN describes here).
It's interesting that:
get-childitem -path Desktop\Extras\ -include *.txt
returns nothing
get-childitem -path Desktop\Extras\* -include *.txt
returns list of *.txt files
Maybe these are just nuances of the implementation.
Also see this excellent blog post: http://tfl09.blogspot.com/2012/02/get-childitem-and-theinclude-and-filter.html
-filter should be faster than -include. -filter can match the short version of filenames in powershell 5.1.