Get List of files Using Powershell - Modified between two dates - powershell

I'm using following command to get all the files which were modified before 20 hours and after 20 days past..
Get-ChildItem -Path '\\server\c$\Program Files (x86)\folder' -recurse -Filter *.* -include *.* |? {$_.LastWriteTime -lt (Get-Date).Addhours(-20) }|? {$_.LastWriteTime -gt (Get-Date).AddDays(-20)} | Select Fullname ,LASTWRITETIME | Sort-Object -Property LASTWRITETIME -Descending
It does gives me correct result.
But I'm getting Fullname as:
\\server\c$\Program Files (x86...
How can I get the fullname? Fullname is pretty long.. more than 260 character.
I've tried
Select -Expand Fullname
It works fine but i can't use it with LastWriteTime
Select -Expand Fullname, LastwriteTime
above command gives me error.

You can format output using Format-Table cmdlet like this:
$table_properties = #{Expression={$_.Fullname};Label="Full Name";width=195},
#{Expression={$_.LastWriteTime};Label="Last Write Time";width=35}
Get-ChildItem -Path '\\server\c$\Program Files (x86)\folder' -recurse -Filter *.* -include *.* |
? {$_.LastWriteTime -lt (Get-Date).Addhours(-20) }|
? {$_.LastWriteTime -gt (Get-Date).AddDays(-20)} |
Sort-Object -Property LASTWRITETIME -Descending |
Format-Table $table_properties
Instead of Select Fullname,LASTWRITETIME create custom object $table_properties with formatting parameters and pass it to Format-Table.
If your string is wider than PowerShell host display width than pipe output to Out-String -Width 500, where 500 is enough characters to display all fields.
See Creating custom tables article on TechNet.

Related

I need my Get-ChildItem string search command print file names along with their Date Modified values, sorted

I spent quite some time searching for the solution of my problem, but found nothing. I have one single folder with mostly .html files, and I frequently need to search to find the files that contain certain strings. I need the search result to be displayed with just the file name (as the file will only be in that one folder) and file's last write time. The list needs to be sorted by the last write time. This code works perfectly for finding the correct files
Get-ChildItem -Filter *.html -Recurse | Select-String -pattern "keyWord string" | group path | select name
The problem with it is that it displays the entire path of the file (which is not needed), it does not show the last write time, and it is not sorted by the last write time.
I also have this code
Get-ChildItem -Attributes !Directory *.html | Sort-Object -Descending -Property LastWriteTime | Select-Object Name, LastWriteTime
That code prints everything exactly as I want to see it, but it prints all the file names from the folder instead of printing only the files that I need to find with a specific string in them.
Since you are only using Select-String to determine if the text exists in any of the files move it inside a Where-Object filter and use the -Quiet parameter so that it returns true or false. Then sort and select the properties you want.
Get-ChildItem -Filter *.html |
Where-Object { $_ | Select-String -Pattern 'keyWord string' -Quiet } |
Sort-Object LastWriteTime |
Select-Object Name, LastWriteTime
For multiple patterns one way you can do it is like this
Get-ChildItem -Filter *.html |
Where-Object {
($_ | Select-String -Pattern 'keyWord string' -Quiet) -and
($_ | Select-String -Pattern 'keyWord string #2' -Quiet)
} |
Sort-Object LastWriteTime |
Select-Object Name, LastWriteTime
And another way using Select-String with multiple patterns which may be a bit faster
$patterns = 'keyword 1', 'keyword 2', 'keyword 3'
Get-ChildItem -Filter *.html |
Where-Object {
($_ | Select-String -Pattern $patterns | Select-Object -Unique Pattern ).Count -eq $patterns.Count
} |
Sort-Object LastWriteTime |
Select-Object Name, LastWriteTime
If you don't care about it being a bit redundant, you can Get-ChildItem the results after your searching:
Get-ChildItem -Filter *.html -Attributes !Directory -Recurse | Select-String -Pattern "keyWord string" | group path | foreach {Get-ChildItem $_.Name } | Sort-Object -Descending LastWriteTime | Select Name,LastWriteTime
After you Select-String you get the attributes of that object instead of the original, so we're taking the results of that object and passing it back into the Get-ChildItem command to retrieve those attributes instead.

Is it possible to use comments in Powershell multiple line commands?

Debugging and testing multiline commands in Powershell ISE has been bugging me for years. I like having multiple line commands because they are easy to read, but they make things harder to debug. As an example, I'm using the following command to get folders older than $days (which by the way works).
$dirs = Get-ChildItem $targetDir -Directory -exclude *.ps1 `
| Where CreationTime -gt (Get-Date).AddDays(-1 * $days) `
| Sort-Object -Property LastWriteTime
I'd like to change AddDays to AddMinutes to test different result sets but I want to leave the original line in so I can easily switch back and forth. Below I copied the line I want to keep and commented it out, and on the new line changed AddDays to AddMinutes Adding a # breaks the multiline feature. Is there an easy way around this I don't have to cut my copied line and move it "out" of the command? Or is there a way to split/unsplit a command into and out of multiple lines?
$dirs = Get-ChildItem $targetDir -Directory -exclude *.ps1 `
# | Where CreationTime -gt (Get-Date).AddDays(-1 * $days) `
| Where CreationTime -gt (Get-Date).AddMinutes(-1 * $days) `
| Sort-Object -Property LastWriteTime
(above does not work due to commented out line)
Use the multiline comment syntax instead of #.
<# comment #>
This should allow you to comment text within a multi-line command.
However, this works only if you are using Powershell 2.0
As powershell expects a continuation after a | or a ,
as the last char in a line you don't need the backtick and
you could format differently, then the single line comment in a longer pipe still works:
$dirs = Get-ChildItem $targetDir -Directory -exclude *.ps1 |
# Where CreationTime -gt (Get-Date).AddDays(-1 * $days) |
Where CreationTime -gt (Get-Date).AddMinutes(-1 * $minutes) |
Sort-Object -Property LastWriteTime
your problem is the [icky, nasty] backticks. [grin] powershell knows there is more coming after a pipe ... so there is no need to add a backtick if you put the pipe at the end of the segment that is being piped. like this ...
$dirs = Get-ChildItem $targetDir -Directory -exclude *.ps1 |
# Where CreationTime -gt (Get-Date).AddDays(-1 * $days) |
Where CreationTime -gt (Get-Date).AddMinutes(-1 * $days) |
Sort-Object -Property LastWriteTime
Try this, which can be included as a multiline comment example
$dirs = Get-ChildItem $targetDir -Directory -exclude *.ps1 `
<# | Where CreationTime -gt (Get-Date).AddDays(-1 * $days) #> ` | Where CreationTime -gt (Get-Date).AddMinutes(-1 * $days) `
| Sort-Object -Property LastWriteTime

How to get the directory location for file recently modified

Suppose we have two directories C:\username\test1 & C:\username\test2. Both directories contain same file script.ps1. Now with powershell script I want to search the file script.ps1 in both directories & want the complete file location of file which is latest modified/created.
I was using below command but it did not give the desired output
Get-ChildItem -Path "C:\username" script.ps1 -Recurse | Where-object {!$_.psIsContainer -eq $true} | ForEach-Object -Process {$_.FullName} | select -last 1
For a given directory you can use
Get-ChildItem C:\dir1\dir2 -Recurse -ErrorAction SilentlyContinue | Where {!$_.PsIsContainer}|select Name,DirctoryName, LastWriteTime |Sort LastWriteTime -descending | select -first 1   Name DirctoryName LastWriteTime
And if you want it to run for multiple directories, you will have to run a loop on each directory:
Get-ChildItem C:\dir\* | Where {$_.PsIsContainer} | foreach-object { Get-ChildItem $_ -Recurse -ErrorAction Sile   ntlyContinue | Where {!$_.PsIsContainer} | Select Name,DirectoryName, LastWriteTime, Mode | Sort LastWriteTime -descend   ing | select -first 1}
It will list files which are last modified for each directories.
Edit: Search for a file
You can use following command to search for a file recursively if it is there in multiple directories:
Get-ChildItem -Path C:\Myfolder -Filter file.whatever -Recurse -ErrorAction SilentlyContinue -Force
This will list all versions of the file found, from newest to oldest:
Get-ChildItem -Path "C:\UserName" `
-File `
-Recurse `
-Include "Script.ps1" |
Sort-Object LastWriteTime -Descending |
Format-Table LastWriteTime, FullName -AutoSize
If you only want the most recent one, then replace the Format-Table line with:
Select-Object -First 1

Powershell get second folder in filepath

I am new to powershell, I am trying to get the second folder in a filepath, after searching folders for a specific function. The issue seems to be when using split-item, i have differing levels of folder depths.
Get-ChildItem -Path d:\domains -Recurse *.php | Select-Object -Property FullName
So for example I am outputting:
D:\domains\domain.com\httpdocs\wordpress\wp-content\themes\twentytwelve\single.php
D:\domains\domain.com\httpdocs\wordpress\wp-content\themes\twentytwelve\tag.php
D:\domains\domain.com\httpdocs\wordpress\wp-includes\canonical.php
D:\domains\domain2.com\httpdocs\wordpress\wp-content\themes\twentytwelve\inc\custom-header.php
D:\domains\domain2.com\httpdocs\wordpress\wp-content\themes\twentytwelve\page-templates\front-page.php
D:\domains\domain2.com\httpdocs\wordpress\wp-content\themes\twentytwelve\page-templates\full-width.php
D:\domains\domain2.com\httpdocs\wordpress\wp-includes\canonical.php
I just want to search for the name of the second folder (i.e. domain.com/domain2.com) and just output the unique entries.
Many Thanks
Use Select-Object -First 1 -Skip 1 to grab the second item in a pipeline:
Get-ChildItem -Directory -Path d:\domains |Select -First 1 -Skip 1 |Get-ChildItem -Recurse *.php |Select-Object -ExpandProperty FullName
The -Directory switch for Get-ChildItem on the file system provider and the -First and -Skip parameters for Select-Object were introduced in PowerShell 3.0.
If you're using PowerShell v2, you could do the following:
Get-ChildItem -Path #(Get-ChildItem -Path D:\domains |Where-Object {$_.PSIsContainer})[1].FullName -Recurse *.php |Select-Object -ExpandProperty FullName

Powershell, trying to output only the path and lastwritetime on directories

I am trying to write a script that will output any directory that has not changed in over 90 days. I want the script to only show the entire path name and lastwritetime. The script that I wrote only shows the path name but not the lastwritetime. Below is the script.
Get-ChildItem | Where {$_.mode -match "d"} | Get-Acl |
Format-Table #{Label="Path";Expression={Convert-Path $_.Path}},lastwritetime
When I run this script, I get the following output:
Path lastwritetime
---- ----------
C:\69a0b021087f270e1f5c
C:\7ae3c67c5753d5a4599b1a
C:\cf
C:\compaq
C:\CPQSYSTEM
C:\Documents and Settings
C:\downloads
I discovered that the get-acl command does not have lastwritetime as a member. So how can I get the needed output for only the path and lastwritetime?
You don't need to use Get-Acl and for perf use $_.PSIsContainer instead of using a regex match on the Mode property. Try this instead:
Get-ChildItem -Recurse -Force |
? {$_.PSIsContainer -and ($_.LastWriteTime -lt (get-date).AddDays(-90))} |
Format-Table FullName,LastWriteTime -auto
You may also want to use -Force to list hidden/system dirs. To output this data to a file, you have several options:
Get-ChildItem -Recurse -Force |
? {$_.PSIsContainer -and ($_.LastWriteTime -lt (get-date).AddDays(-90))} |
Select LastWriteTime,FullName | Export-Csv foo.txt
If you are not interested in CSV format try this:
Get-ChildItem -Recurse -Force |
? {$_.PSIsContainer -and ($_.LastWriteTime -lt (get-date).AddDays(-90))} |
Foreach { "{0,23} {1}" -f $_.LastWriteTime,$_.FullName} > foo.txt
Also try using Get-Member to see what properties are on files & dirs e.g.:
Get-ChildItem $Home | Get-Member
And to see all values do this:
Get-ChildItem $Home | Format-List * -force