Powershell - calculate elapsed time between CreateTime and LastWriteTime - powershell

I have a script that outputs some file properties to a CSV file. Two of those are CreationTime and LastWriteTime. I'd like to include the elapsed time between those values.
I know how to calculate the elapsed time. I'm unsure how to append it to the properties returned by the Select-Object command.
Get-ChildItem -File -Recurse |
Select-Object -Property FullName,Name,CreationTime,LastWriteTime |
Export-Csv -Path .\elapsed.csv -NoTypeInformation
Desired output would be:
FullName, Name, CreationTime, LastWriteTime, ElapsedTime (calculated value in h:mm:ss)
C:\Temp\File1.txt, File1.txt, 5/23/2020 7:30, 5/23/2020 7:45, 0:15:00

This can be done with Select-Object's calculated property feature. Add an expression as a hash table to the property list. One specifies a name for the calculated property and an expression for the calculation. Since CreationTime and LastWriteTime already are DateTime objects, subtraction is supported by base types. Like so,
gci | Select-Object -Property FullName,Name,CreationTime,LastWriteTime,` # split line with extra `
#{Name ='Elapsed'; Expression = {$_.LastWriteTime-$_.CreationTime}}

Related

how to parse a value to variable using powershell from data in table format

I have command $Var1=Get-ChildItem -Attributes !Directory Statement_*.pdf | Sort-Object -Descending -Property LastWriteTime | select -First 1|Select-Object "Name" which gives me output in below format
Name
----
Statement_2022MTH05_750571314.pdf
I only want to store Statement_2022MTH05_750571314.pdf file name in a variable, so that when I fire command Write-Output $Var1 then it should print Statement_2022MTH05_750571314.pdf only. Thanks in advance.
You can use -ExpandProperty Name which will Specifies a property to select, and indicates that an attempt should be made to expand that property. So,
Select-Object -First 1 | Select-Object "Name"
can be replaced with
Select-Object -First 1 -ExpandProperty Name

PowerShell: how to append text files in Order?

$inputpath = 1.txt, 2.txt ....
Command:
Get-ChildItem -Path $inputpath\* -Include *.txt | Sort-Object -Property Name | Get-Content | ForEach-Object { Add-Content -Path d:\MergedFile.txt -Value "$_" }
The Result is a mixed file with duplicated content and in a random order. How can I append multiple files to a new file while considering the order of the source files?
When you sort on a file's Name property, you're sorting string values, and the result will be sorted alphabetically - which means 10 goes before 9 for example.
If you want to sort by the numerical value represented by the string name, you'll have to explicitly tell Sort-Object to treat the input values as such:
Get-ChildItem ... | Sort-Object -Property {$_.Name -replace '\D' -as [int]} |...
In the property expression {$_.Name -replace '\D' -as [int]} we take the Name property value (like before), remove any non-digit characters, and finally convert the resulting string to an integer.

Extract Path from FullName property into results

I have this script:
Get-ChildItem -Path R:\MyFolder\archive -Recurse |
>> Sort-Object -Property LastAccessTime |
>> Select-object -Property Name, FullName
Rather than FullName I'd like the Path without the files name so I tried to adapt as follows:
Get-ChildItem -Path R:\MyFolder\archive -Recurse |
>> Sort-Object -Property LastAccessTime |
>> Select-object -Property Name, [System.IO.Path]::GetDirectoryName(fullname)
I'm obviously very new to PS - is it clear what I am attempting, and failing, to do?
Generally, Get-ChildItem cmdlet returns objects of different type:
System.IO.FileInfo
System.IO.DirectoryInfo
Unfortunately, on the latter you do not find property called DirectoryName. You can use Get-ChildItem -File (the -File parameter eliminates such objects), or use calculated property as follows:
$rootPath = 'R:\MyFolder\archive'
Get-ChildItem -Path $rootPath -Recurse |
Sort-Object -Property LastAccessTime |
Select-Object -Property Name,
#{ Name = 'DirectoryName';
Expression = { $_.FullName | Split-Path }}
For explanation, read in Select-Object => Parameters:
-Property
Specifies the properties to select. These properties are added as
NoteProperty members to the output objects. Wildcards are permitted.
The value of the Property parameter can be a new calculated
property. To create a calculated property, use a hash table.
Valid keys are:
Name (or Label):
Expression or
How about :
Get-ChildItem -Path 'R:\MyFolder\archive' -Recurse | Sort-Object -Property LastAccessTime | Select-object -Property Name, DirectoryName
?

Get Subtypes of VersionInfo

I would like to get few file attributes from Powershell command Get-Item or Get-ItemProperty
Get-Item -Path c:\windows\system32\gdi32.dll | Select Name, Length, VersionInfo.ProductVersion, VersionInfo.FileVersion, CreationTime, LastAccessTime, LastWriteTime
Get-ItemProperty -Path c:\windows\system32\gdi32.dll -Name Name, Length, VersionInfo.ProductVersion, CreationTime, LastAccessTime, LastWriteTime
Both of the commands does not give me VersionInfo.ProductVersion
When you pass VersionInfo.ProductVersion as a parameter argument to a function, PowerShell interprets it as the string "VersionInfo.ProductVersion", and starts looking for a property with that exact name. But a FileInfo object doesn't have such a property, which is why it doesn't work.
You'll need a calculated property in order to grab the the property values of VersionInfo:
Get-Item ... |Select Name,Length,#{Name='ProductVersion';Expression={$_.VersionInfo.ProductVersion}},#{Name='FileVersion';Expression={$_.VersionInfo.FileVersion}},CreationTime,LastAccessTime,LastWriteTime
You can also prepare all the property names as an array ahead of time:
$ItemProperties = #(
'Name'
'Length'
#{Name = 'ProductVersion'; Expression = {$_.VersionInfo.ProductVersion}}
#{Name = 'FileVersion'; Expression = {$_.VersionInfo.FileVersion}}
'CreationTime'
'LastAccessTime'
'LastWriteTime'
)
Get-Item ... |Select $ItemProperties

Replace some text in an objects property?

I have a requirement to request some information that comes in the form of an object. I need to replace some test in one of the properties and then write the list of objects to CSV.
When I do
Get-Process | select * | %{ $_Path.Replace("chrome", "ie") }
I have two problems
If $_.Path is null, it gives me an error that you cannot call a method on a null-valued expression
The output is a single string representing the text that was replaced (just the Path property). I need the original object and all of it's properties kept, but with the updated path value.
So of course when I try to do
Get-Process | select * | %{ $_Path.Replace("chrome", "ie") } | Export-Csv -Path "out.csv"
What I get is a single property Length because the output of the above is a string with only the Length property.
Get-Process | select * | %{ $_.Path = $_.Path.Replace("chrome", "ie"); $_ } | Export-Csv -Path "out.csv" -NoTypeInformation
$_.Path instead of $_Path
Assign the replaced text back to the path property
and output the object after doing the assignment
Help Links (if available):
Get-Process (in module Microsoft.PowerShell.Management)
select is an alias for Select-Object (in module Microsoft.PowerShell.Utility)
% is an alias for ForEach-Object
Export-Csv (in module Microsoft.PowerShell.Utility)
try this
Get-Process | select *, #{N="Path";E={$_.Path.Replace("chrome", "ie") }} -ExcludeProperty Path | export-csv -Path "c:\temp\out.csv" -NoTypeInformation