I'm a blind user and I keep having to go find what's breaking a few people's computers and it's getting annoying. They always click on "install this Active-X" or "download the free video player now" and I have to then dig through everything.
I whipped up a powershell script to search C:\ for files that have a write time of 5 minutes ago and less for testing purposes the Get-ChildItem part works. Now I just want to get a list of file paths to make my life easier but I am missing something.
Here's what I have so far:
cd c:\
$fileizer = Get-ChildItem -Path . -exclude *.txt,*.log -ErrorAction SilentlyContinue -Recurse| ? {$_.LastWriteTime -gt (Get-Date).AddMinutes(-5)}
echo $fileizer
Here are the results if I just do the Get-ChildItem part of it:
PS C:\Users\tryso> c:\bin\hours.ps1
Directory: C:\bin
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 8/1/2017 2:44 PM 169 hours.ps1
PS C:\>
Obviously I am going to narrow down the path to something more specific than just C:\ like to get into C:\Windows\Temp and C:\Users\ and the likes, I'm just wondering how to parse everything to just give me a list of files and their path.
I'd also like to point out that 5 minutes old is dumb, yes I know. I just did that to make it scream through my C:\ drive because you'd be amazed at how many files have a write time of .5 hours in C:\ LoL.
Ultimately I'd like to figure out how to find new files as opposed to recent write times if that's possible.
Sorry if my query is lame or a repeat, the only close examples I have found don't work for me for some reason and I'm pretty new at PS scripting - but it's getting pretty addicting and awesome LoL.
Thanks a million for any help!
Ryan
The Select-Object cmdlet can pull out the information you're looking for. Often you will want to know more than one piece of info on your results, so dot sourcing isn't going to be the most efficient.
Try something like this to see the full path, size and last modified timestamp:
Get-ChildItem -Path $path -exclude .txt,.log -ErrorAction SilentlyContinue -Recurse | Where-Object {$_.LastWriteTime -gt (Get-Date).AddMinutes(-5)} | Select-Object FullName, Length, LastWriteTime
Related
I'm looking at doing a recursive Get-ChildItem -r to get lastWriteTime, length and group for count by extension.
I get a bunch of errors, e.g., 'Get-ChildItem : Could not find item C:\Pics & Videos\Thumbs.db'.
I was thinking some folders or filenames had special characters in the name of the folder or file. I was able to encapsulate in quotes to correct some of the erroring files, but not all.
[System.IO.File]::Exists("C:\Pics & Videos\Thumbs.db") gave me a True, but
Get-ChildItem "C:\Pics & Videos\Thumbs.db" gave me the error.
I'm going to look at [System.IO.Fileinfo], but wonder if anyone can answer why I get these errors using Get-ChildItem aka ls?
Thanks
I may have found what I was looking for. With $Path a full path to the starting folder I want to recursively get file info from.
[IO.Directory]::EnumerateFileSystemEntries($path,"*.*","AllDirectories") |
ForEach { [System.IO.FileInfo]"$_" }
Other suggestions are welcome that might be faster. I'm looking at millions of files over 4500 folders. get-childitem only was able to get 60% of the files with 40% being errors without values. This is for one department and there are several.
Tested: get-childItem vs EnumerateFiles vs Explorer vs TreeSize
$path = "P:\Proxy Server Files\Dept1\sxs\"
First choice was slow. I get errors; so I added the error count as a guess.
$error.clear()
(get-ChildItem $path -r -ErrorAction SilentlyContinue).count
1333
$error.count
256
Second choice was much faster but gave less numbers.
$error.clear()
([IO.Directory]::EnumerateFileSystemEntries($path,"*.*","AllDirectories")).count
1229
$error.count
0
Trying to only look at files recursively again I get errors; so I added the error count as a guess.
$error.clear()
(get-ChildItem $path -r -file).count
558
$error.count
256
Looking at just files I get a much lower number that expected.
([IO.Directory]::EnumerateFileSystemEntries($path,"*.*","AllDirectories") | ForEach { [System.IO.FileInfo]"$_" }| Where Mode -NotMatch "d").count
108
Tried another method but same result.
([IO.Directory]::EnumerateFiles($path,"*.*","AllDirectories")| ForEach { [System.IO.FileInfo]"$_" }| Where Mode -NotMatch "d").count
108
From Windows Eplorer I see 37 files and 80 folders.
TreeSize.exe shows 1175 files on 775 folders.
I'm not sure what count to believe. Admin rights used to get all counts.
Any ideas why so many different results?
Thumbs.db is (typically) a hidden file. By default Get-ChildItem doesn't look for hidden files. Pass -Force (-Hidden shows only hidden items):
PS> get-childitem .\Thumbs.db
Get-ChildItem: Could not find item C:\[...]\Thumbs.db.
PS> get-childitem .\Thumbs.db -Force
Directory: C:\[...]
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a-h- 24/12/2016 11:17 13824 Thumbs.db
This was answered in question 9508375.
get-childitem -literalpath
This handles the problem with special characters in the name.
I am interested in a power shell script that will do a recursive search for files using a filename pattern.
I thought I would find it with Copyforbuild.bat, but I cannot find where I can download it or copy the source code.
Any help is appreciated.
I am not sure what copyforbuild.bat is, if that is from an application, but that is not a powershell script. If you are looking for a file recursively you can use Get-ChildItem (or GCI for short).
gci -Path C:\ -Recursive -Filter somefile.ext
That would search the whole C:\ drive for a file named "somefile.ext". If that doesn't solve what you are trying to do, could you be more specific as to what you are looking for?
If you need to match patterns then you probably want to use a Regular Expression (RegEx). I'm not sure how powershell will deal with "too long" folders (over 256 character path length), but in general you could do:
gci -Path C:\ -Recursive | ? {$_.Name -match "<RegEx Pattern>"}
For more information on RegEx see http://www.regular-expressions.info/powershell.html
gci -Path "C:\tasks" -recurse -Filter "rspc.doc*" -ErrorAction SilentlyContinue | Out-File c:\temp\rspc9.txt
This command when entered into PowerShell will look for a file with the pattern rspc.doc* that is in C:\Tasks and all folders underneath it. It redirects the output to a file.
If there is a folder with a long name or there is some other error, then it will continue to search, ignoring the error.
Background
There is a directory that is automatically populated with MSI files throughout the day. I plan on leveraging Task Scheduler to run the script shown below every 15 minutes. The script will search the directory and copy any new MSIs that have been created in the last 15 minutes to a network share.
Within this folder C:\ProgramData\flx\Output\<APP-NAME>\_<TIME_STAMP>\<APP-NAME>\ there are two other folders: Repackaged and MSI Package. The Repackaged folder does not need to be searched as it does not contain any MSIs. Also I have found that it needs to be excluded in some way to prevent this error:
Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
At line:14 char:32
+$listofFiles=(Get-ChildItem <<<< -Recurse -Path $outputPath -Include "*.msi" -Exclude "*.Context.msi" | where {$_.LastAccessTime -gt $time.AddMinutes($minutes)})
+ CategoryInfo : ReadError: C:\ProgramData\...xcellence\Leg 1:String) [Get-ChildItem], PathTooLongException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand
Limitations
I am stuck using Powershell v1.0
I have no control over the directory structure of the source location
Updated:
I don't know the app name or the what the time stamp will be. That is something else that is out of my control.
Current plans
I have read about using -Filter and I am aware of filters that are similar to functions but I wasn't able to come up with any ideas of how to use them. My only thought at the moment would be to do something like:
$searchList=Get-ChildItem "all instances of the MSI Package folder"
foreach($folder in $searchList){
$listofFiles=Get-ChildItem "search for *.msi"
foreach($file in $listofFiles){"Logic to copy MSI from source to destination"}
}
However...I thought that there might be a more efficient way of doing this.
Questions
How can I limit depth that Get-ChildItem searches?
How can I limit the Get-ChildItem search to C:\ProgramData\flx\Output\<APP-NAME>_<TIME_STAMP>\<APP-NAME>\MSI Package
How can I only search folders that have been accessed in the last 15 minutes? I don't want to waste time drilling down into folders when I know MSI has already been copied.
Any additional advice on how to make this script more efficient overall would also be greatly appreciated.
Script
My current script can be found here. I kept getting: "Your post appears to contain code that is not properly formatted as code" and gave up after the fourth time trying to reformat it.
You can try this
dir C:\ProgramData\flx\Output\*\*\*\*\* -filter *.msi
this search all .msi files at this level
C:\ProgramData\flx\Output\<APP-NAME>\_<TIME_STAMP>\<APP-NAME>\Repackaged or 'MSI Package' or whatever else present folder
without recursion, this avoid too deep folder that give you error.
Pipe the result to:
Where {$_.LastAccessTime -gt (Get-Date).AddMinutes(-15)} #be sure no action on file is taken before the dir command
or
Where {$_.LastWriteTime -gt (Get-Date).AddMinutes(-15)} #some file can be re-copied maybe
With help from C.B. this is my new search which eliminates the issues I was having.
Changed -Path to C:\ProgramData\flx\Output\*\*\*\* to help limit the depth that was searched.
Used -Filter instead of -Include and put the -Exclude logic into the where clause.
Get-ChildItem -Path C:\ProgramData\flx\Output\*\*\*\* -Filter "*.msi" | where {$_.Name -notlike "*.Context.msi" -and $_.LastAccessTime -gt (Get-Date).AddMinutes(-15)}
You can't limit the recursion depth of Get-ChildItem except to not use -Recurse i.e. Get-ChildItem is either depth = 0 or N.
Set up variables for app name and timestamp e.g.:
$appName = "foo"
$timestamp = Get-date -Format HHmmss
Get-ChildItem "C:\ProgramData\flx\Output\${appName}_$timestamp\$appName\MSI Package" -force -r
You can filter the results like so:
Get-ChildItem <path> -R | Where {$_.LastWriteTime -gt (Get-Date).AddMinutes(-15)}
this is the scenario.
p1
|_f1
|_f2
p2
|_f1
|_f2
Can anyone please help me with a powershell script that copies the files shown above from the TFS to a temporary folder ??? where f1,f2,and so on are the subfolders..
I have no experience with either, but in the interest of a least pointing you in the right direction, check out this site. http://coolthingoftheday.blogspot.com/2009/03/pstfs-powershell-and-tfs-better-than.html
There are a couple of commands that will give you at least part of what you want. You will still need to do some digging to figure out the time stamp stuff.
You may want to check the answer to my question on a very similar scenario.
You will find answer to
give me all files in this folder (or subfolder)
as well as
that where modified after x/y/zzzz
but I'm still not sure about the
dump those files to folder other than they would normally go to
update
Incorporating your approach
Get-TfsItemProperty $/MyFirstTFSProj -r -server xyzc011b |
Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
Copy-Item -Destination C:\SomeDir -Whatif
you normally can omit the Copy-Item -Path param because it will be provided by the pipeline.
I don't have a TFS at to test with Get-TfsItemProperty but you could try
Get-TfsItemProperty $/MyFirstTFSProj -r -server xyzc011b |
Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
Get-Member
do find out about where this $null value is coming from.
I assume you did already see this post. To maintain the folder structure on the destination you need to include the -Force switch on the Copy-Item to create missing target folders:
Get-TfsItemProperty $/MyFirstTFSProj -r -server xyzc011b |
Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
Copy-Item -Destination C:\SomeDir -Force -Whatif
I'm still not sure if you need to retrieve/export the files prior to copy them - you should check on the second answer from Richard Berg in the post mentiond above.
I'm trying to build a function that will show me all path's where a certain filename is located. The function would take one parameter, that being the file name.
The result would be either a list of all paths, or a message saying there's no such file on the system.
I'm new to Powershell, and I'm not getting the syntax just yet.
I've tried this:
Get-ChildItem -Path -Include notepad.exe
But that threw an error message. I'm currently trying:
$i="notepad.exe"
Foreach ($i in Get-ChildItem c:\ -Recurse){echo -Path}
Started that now, it's still running, don't know what'll happen, really.
EDIT: echo'd an enormous amount of lines that just say "-Path"...
Can anybody help with this problem? I'm running Powershell 1.0 by the way.
So, to explain what I wish to see when executing this command, here is an example of what I expect after looking for *.txt:
C:/foo.txt
C:/A/foobar.txt
C:/A1/foo.txt
And so on, listing the path to all .txt files on my harddrive. Only the paths, one per line, no extra info needed.
EDIT2:
I've done it. I'm gonna leave this question up for those who make look for this in the future.
The function I used was this(this specific example will hand you a list of all .zip files on your harddrive, edit where needed):
Get-ChildItem -Path c:\ -Include "*.zip" -Recurse -Force -Name > c:\listOfPaths.txt
This created a file called listOfPaths.txt on my C:\ folder and this contained a list of all occurences of any file ending with .zip in all subfolders of my harddrive.
The "c:\" bit isn't mentioned, but I don't mind.
EDIT3:
thanks capar for a more complete version.
Here is capar's code(or how I got it to work, since Get-Children doesn't work in 1.0)
Get-ChildItem -Path c:\ -Recurse *.txt | Select-Object -Property FullName
Since it's Friday night, I decided to play with Power Shell to see if I can help :)
This comes pretty close to what you are asking for I think:
Get-ChildItem -Path c:\ -Recurse *.txt | Select-Object -Property FullName
If it helps, this command will list the properties of any object that will be returned by Get-ChildItem:
Get-ChildItem | Get-Member
ls c:\ -r | ? {$_.name -eq "notepad.exe"}
Get-Children is not recognized in Powershell V3 either. It would be great if someone removed that bad example.
As a warning to anyone searching for files: C:\ on today's hard drives will take a long time to run. You are well advised to narrow your search as much as you can. Since your folder structure might include spaces or special characters, use the typewriter quote (") or apostrophe (') delimeters.
$mylistoffiles = Get-ChildItem -Path 'C:\Windows\Setup\Scripts' -Recurse *.cmd | Select-Object -Property FullName
$mylistoffiles