Column Directory empty? - powershell

I thought that applying this answer about replacing a path would work for:
$folder = 'C:\test'
$List = Get-ChildItem $folder -Recurse | Sort-Object -Property LastWriteTime
$List | Format-Table name, LastWriteTime, #{Label="Directory"; Expression={$_.Directory.Replace($folder, "")}}
Instead I get nothing in Directory column whereas I should get
\subfolder\
since the files are in
c:\test\subfolder
Name LastWriteTime Directory
---- ------------- ---------
test.1.png 7/21/2018 10:20:44 PM
test.2.png 7/21/2018 10:21:16 PM
test.3.png 7/21/2018 10:21:43 PM
subfolder 9/10/2018 6:53:28 PM

The Directory member of Get-ChildItem is a System.IO.DirectoryInfo. It has a member, Name, that can be used.
PS H:\clan\2018-09-05> (Get-ChildItem).Directory | Get-Member
TypeName: System.IO.DirectoryInfo
Try using:
Get-ChildItem | ForEach-Object { $_.Directory.Name }

Related

Append same string to all variables in column of CSV in powershell

I would like help on how to add string -Config to each name in column Name.
CSV file contains:
FullName Name LastWriteTime
\\remotecomputer\ Henry 4/30/2020 3:44:57 PM
\\remotecompter\ Magy 12/7/2020 9:04:28 PM
The desired output:
FullName Name LastWriteTime
\\remotecomputer\ Henry-Config 4/30/2020 3:44:57 PM
\\remotecompter\ Magy-Config 12/7/2020 9:04:28 PM
My current code:
$InvoiceList = Import-CSV -Path C:\$source-PREP.csv | foreach($list in $InvoiceList){
$Name=$($list.name)
Get-ChildItem -Path 'C:\Names' -Filter *.txt | where {$_.Name -like '*' }|Copy-Item -Destination 'c:\newfolder' -Force }
Since your file has only a few known columns, you could use Select-Object and append -Config to the values in the Name column using a calculated property:
$data = Import-CSV -Path "C:\$source-PREP.csv" |
Select-Object FullName, #{Name = 'Name'; Expression = {'{0}-Config' -f $_.Name}}, LastWriteTime
$data | Export-Csv -Path "C:\$source-PREP.csv" -NoTypeInformation -Force
Result
FullName Name LastWriteTime
-------- ---- -------------
\\remotecomputer\ Henry-Config 4/30/2020 3:44:57
\\remotecompter\ Magy-Config 12/7/2020 9:04:28
You just need to iterate of each line in the CSV and update the name property. Once done export back out to CSV
$csvfile = 'some\path\to\file.csv'
$csvdata = Import-Csv $csvfile
$csvdata | ForEach-Object {$_.name = $_.name + '-Config'}
$csvdata | Export-Csv $csvfile -NoTypeInformation

How to compare 2 directories and list only the files which are different?

I have the following code that compares 2 directories and outputs an indicator to indicate the difference between the directory files.
$Folder1 = "source_folder_path"
$Folder2 = "dest_folder_path"
function Get-Directories ($path)
{
$PathLength = $path.length
Get-ChildItem $path -Recurse | % {
Add-Member -InputObject $_ -MemberType NoteProperty -Name RelativePath -Value $_.FullName.substring($PathLength+1)
$_
}
}
Compare-Object (Get-Directories $Folder1) (Get-Directories $Folder2) -Property RelativePath | Sort RelativePath, Name -desc
This gives me an output like this:
The side indicator <= means the file or folder exists only in the source. i.e., missing in the destination.
The side indicator => means the file or folder exists only in the destination. i.e., missing in the source.
However, i only want to list the files that are different (i.e. dont exist in the directory), and only different by Name. Currently, the code above compares the file with the extension, and if the extension is different, e.g. image1.jpg vs image1.png, it will mark them as different. however, i dont want that and instead i would like it to ignore the extension.
i.e.
image1.png vs image1.jpg = no difference, dont list it
image1.png in folder 1 but not in folder 2 = list it
# Resolve the input folders to full paths first.
$Folder1 = Convert-Path $Folder1
$Folder2 = Convert-Path $Folder2
Compare-Object (Get-ChildItem -File -Recurse $Folder1) `
(Get-ChildItem -File -Recurse $Folder2) `
-Property {
# Determine the relative path and then compare
# the directory path + the file *base* name.
$relativePath = $_.FullName.Substring(
($Folder1.Length, $Folder2.Length)[$_.FullName.StartsWith($Folder2, 'InvariantCultureIgnoreCase')]
)
[IO.Path]::GetDirectoryName($relativePath) + '/' +
[IO.Path]::GetFileNameWithoutExtension($relativePath)
} -PassThru |
Select-Object Name, Directory
The above doesn't just list the name (which could be ambiguous), but also the directory in which a given unique file was found.
If I understand this correctly, compare two folders using the basename property:
Directory: C:\Users\admin\foo\dir1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 11/24/2020 4:54 PM 4 image1.png
-a--- 11/24/2020 4:55 PM 4 image2.png
Directory: C:\Users\admin\foo\dir2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 11/24/2020 4:54 PM 4 image1.jpg
compare-object (dir dir1) (dir dir2) -property basename
basename SideIndicator
-------- -------------
image2 <=

Search for specific folder name in filtered path

I need to search for a specific folder name from filtered path.
For example:
I have some folders like on disk m:
M:\
├───2.46.567
│ └───A
├───3.09.356
│ └───A
├───4.05.123
│ └───A
└───4.05.124
└───B
I want to search folder A only from 4.05.xxx dir. And also i want to check is this folder is last one contains folder A.
I try something like the following command:
Get-ChildItem -Path m:\* -recurse -filter '*4.05*' | sort -descending LastWriteTime
Can I do this in PowerShell?
Get-ChildItem allows wildcards on several levels in a path not just the last - no recurse needed.
Get-ChildItem 'M:\4.05.*\A' -Directory | Sort-Object -Descending LastWriteTime
In the above tree this returns just one entry:
Directory: M:\4.05.123
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2019-08-30 12:10 A
An alternative with the same result based on above tree:
Get-ChildItem -Path 'M:\4.05.*' -Filter A -Recurse -Directory | Sort-Object -Descending LastWriteTime
PowerShell Version 2 variant
Get-ChildItem 'M:\4.05.*\A' | Where-Object {$_.PSIsContainer} |
Sort-Object -Desc LastWriteTime | Select-Object -First 1 | Set-Location
Try this:
param(
$SourceDir = "M:\"
)
$a = gci $SourceDir | foreach { $i = gci $sourcedir\$_ -Name ; if($i.equals("A")) {"$_"} }
for($h=0;$h -le $a.Length-1; $h++ ) {
if($a[$h] -like "4.05.*") {
$a[$h]
if( $a[$h].equals($a[$a.length-1])) {
"It is the last one."
}}}
This will return all folders that contain a folder "A" and have "4.05." as part of its name. It will also return whether or not it is the last folder in the array, therefore also the last folder that contains "A".
You can also use Resolve-Path.
(Resolve-Path "M:\4.05.*\A").ProviderPath
This returns the string (not the folder object!) of the paths you're after.

PowerShell CSV Compare files with dynamic file names [duplicate]

We produce files with date in the name.
(* below is the wildcard for the date)
I want to grab the last file and the folder that contains the file also has a date(month only) in its title.
I am using PowerShell and I am scheduling it to run each day. Here is the script so far:
$LastFile = *_DailyFile
$compareDate = (Get-Date).AddDays(-1)
$LastFileCaptured = Get-ChildItem -Recurse | Where-Object {$LastFile.LastWriteTime
-ge $compareDate}
If you want the latest file in the directory and you are using only the LastWriteTime to determine the latest file, you can do something like below:
gci path | sort LastWriteTime | select -last 1
On the other hand, if you want to only rely on the names that have the dates in them, you should be able to something similar
gci path | select -last 1
Also, if there are directories in the directory, you might want to add a ?{-not $_.PsIsContainer}
Yes I think this would be quicker.
Get-ChildItem $folder | Sort-Object -Descending -Property LastWriteTime -Top 1
Try:
$latest = (Get-ChildItem -Attributes !Directory | Sort-Object -Descending -Property LastWriteTime | select -First 1)
$latest_filename = $latest.Name
Explanation:
PS C:\Temp> Get-ChildItem -Attributes !Directory *.txt | Sort-Object -Descending -Property LastWriteTime | select -First 1
Directory: C:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/7/2021 5:51 PM 1802 Prison_Mike_autobiography.txt
Get-ChildItem -Attributes !Directory *.txt or Get-ChildItem or gci : Gets list of files ONLY in current directory. We can give a file extension filter too as needed like *.txt. Reference: gci, Get-ChildItem
Sort-Object -Descending -Property LastWriteTime : Sort files by LastWriteTime (modified time) in descending order. Reference
select -First 1 : Gets the first/top record. Reference Select-Object / select
Getting file metadata
PS C:\Temp> $latest.Name
Prison_Mike_autobiography.txt
PS C:\Temp> $latest.DirectoryName
C:\Temp
PS C:\Temp> $latest.FullName
C:\Temp\Prison_Mike_autobiography.txt
PS C:\Temp> $latest.CreationTime
Friday, May 7, 2021 5:51:19 PM
PS C:\Temp> $latest.Mode
-a----
#manojlds's answer is probably the best for the scenario where you are only interested in files within a root directory:
\path
\file1
\file2
\file3
However, if the files you are interested are part of a tree of files and directories, such as:
\path
\file1
\file2
\dir1
\file3
\dir2
\file4
To find, recursively, the list of the 10 most recently modified files in Windows, you can run:
PS > $Path = pwd # your root directory
PS > $ChildItems = Get-ChildItem $Path -Recurse -File
PS > $ChildItems | Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName, LastWriteTime
You could try to sort descending "sort LastWriteTime -Descending" and then "select -first 1." Not sure which one is faster

Powershell Get-ChildItem most recent file in directory

We produce files with date in the name.
(* below is the wildcard for the date)
I want to grab the last file and the folder that contains the file also has a date(month only) in its title.
I am using PowerShell and I am scheduling it to run each day. Here is the script so far:
$LastFile = *_DailyFile
$compareDate = (Get-Date).AddDays(-1)
$LastFileCaptured = Get-ChildItem -Recurse | Where-Object {$LastFile.LastWriteTime
-ge $compareDate}
If you want the latest file in the directory and you are using only the LastWriteTime to determine the latest file, you can do something like below:
gci path | sort LastWriteTime | select -last 1
On the other hand, if you want to only rely on the names that have the dates in them, you should be able to something similar
gci path | select -last 1
Also, if there are directories in the directory, you might want to add a ?{-not $_.PsIsContainer}
Yes I think this would be quicker.
Get-ChildItem $folder | Sort-Object -Descending -Property LastWriteTime -Top 1
Try:
$latest = (Get-ChildItem -Attributes !Directory | Sort-Object -Descending -Property LastWriteTime | select -First 1)
$latest_filename = $latest.Name
Explanation:
PS C:\Temp> Get-ChildItem -Attributes !Directory *.txt | Sort-Object -Descending -Property LastWriteTime | select -First 1
Directory: C:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/7/2021 5:51 PM 1802 Prison_Mike_autobiography.txt
Get-ChildItem -Attributes !Directory *.txt or Get-ChildItem or gci : Gets list of files ONLY in current directory. We can give a file extension filter too as needed like *.txt. Reference: gci, Get-ChildItem
Sort-Object -Descending -Property LastWriteTime : Sort files by LastWriteTime (modified time) in descending order. Reference
select -First 1 : Gets the first/top record. Reference Select-Object / select
Getting file metadata
PS C:\Temp> $latest.Name
Prison_Mike_autobiography.txt
PS C:\Temp> $latest.DirectoryName
C:\Temp
PS C:\Temp> $latest.FullName
C:\Temp\Prison_Mike_autobiography.txt
PS C:\Temp> $latest.CreationTime
Friday, May 7, 2021 5:51:19 PM
PS C:\Temp> $latest.Mode
-a----
#manojlds's answer is probably the best for the scenario where you are only interested in files within a root directory:
\path
\file1
\file2
\file3
However, if the files you are interested are part of a tree of files and directories, such as:
\path
\file1
\file2
\dir1
\file3
\dir2
\file4
To find, recursively, the list of the 10 most recently modified files in Windows, you can run:
PS > $Path = pwd # your root directory
PS > $ChildItems = Get-ChildItem $Path -Recurse -File
PS > $ChildItems | Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName, LastWriteTime
You could try to sort descending "sort LastWriteTime -Descending" and then "select -first 1." Not sure which one is faster