Setup default date format like yyyy-mm-dd in Powershell? - powershell

A simple & short question:
How can I setup a default date format in powershell like yyyy-mm-dd ? so any date output will be like this format?
or How to setup a date format globally in one script ?
Is there a way to output date only without time? when I output LastWriteTime, Default is
13-03-2014 14:51
I only need 13-03-2014 but 14:51.

A date in PowerShell is a DateTime object. If you want a date string in a particular format, you can use the built-in string formatting.
PS C:\> $date = Get-Date
PS C:\> $date.ToString("yyyy-MM-dd")
2014-04-02
You can also use the string format (-f) operator:
PS C:\> "{0:yyyy-MM-dd}" -f $date
2014-04-02
The LastWriteTime property of a file is a DateTime object also, and you can use string formatting to output a string representation of the date any way you want.
You want to do this:
Get-ChildItem -Recurse \\path\ -filter *.pdf | Select-Object LastWriteTime,Directory
You can use a calculated property:
Get-ChildItem C:\Users\Administrator\Documents -filter *.pdf -Recurse |
Select-Object Directory, Name, #{Name="LastWriteTime";
Expression={$_.LastWriteTime.ToString("yyyy-MM-dd HH:mm")}}
Run
help Select-Object -Full
and read about calculated properties for more information.

i've used this, it works for me, just copy it at the beginning of your script
$currentThread = [System.Threading.Thread]::CurrentThread
$culture = [CultureInfo]::InvariantCulture.Clone()
$culture.DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'
$currentThread.CurrentCulture = $culture
$currentThread.CurrentUICulture = $culture
in case you'll find problem in loading assembly for CultureInfo (i had this issue on Windows 2008 Server), change line 2 in this way
$currentThread = [System.Threading.Thread]::CurrentThread
$culture = $CurrentThread.CurrentCulture.Clone()
$culture.DateTimeFormat.ShortDatePattern = 'dd-MM-yyyy'
$currentThread.CurrentCulture = $culture
$currentThread.CurrentUICulture = $culture

for always usage you can add in your .\Documents\WindowsPowerShell\profile.ps1
$culture = (Get-Culture).Clone()
$culture.DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'
Set-Culture $culture

Related

Powershell - Formatting column as date

I am importing a CSV which has 5 "columns". One of them is a date and time. The 3rd party software that is reading this column, then does not sort the date well.
IE: (4/8/2022 1:24:08 PM) will sort above (4/13/2022 8:51:52 AM)
Even though 4/13 is after 4/8 it will not sort it properly. I would like to add a leading zero in front of the month and date with powershell. I did do some searching but nothing seems to make sense to me, I am not a HUGE programmer.
Thanks for any help!
This is what I am currently doing. I am using unique to remove duplicate rows (this is needed for what I am doing).
$FinalSessions = Import-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv" | Sort-Object * -Unique
$FinalSessions | Export-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv" -NoTypeInformation
$FinalSessions
You can use Get-Date to actually get a datetime object and then reformat it.
It would look something like this:
$FinalSessions = Import-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv"| Sort-Object * -Unique
$FinalSessions | % { $_.DateColumn = Get-Date $_.DateColumn -Format "MM/dd/yyyy hh:mm:ss tt" }
$FinalSessions | Export-Csv -Path
"C:\Windows\AdminArsenal\UserSessions.csv" -NoTypeInformation
$FinalSessions
Just replace "DateColumn" with the name of your column
Assuming that the column that contains the date-time string is named Date (adjust as needed):
Import-Csv -Path C:\Windows\AdminArsenal\UserSessions.csv |
ForEach-Object { $_.Date = ([datetime] $_.Date).ToString('s') } |
Sort-Object * -Unique -OutVariable finalSessions |
Export-Csv -Path C:\Windows\AdminArsenal\UserSessions.csv -NoTypeInformation
$finalSessions
Note that the s format specifier (in ISO 8601 format) is used to reformat the date-time strings, as that results in a string whose lexical sorting reliably indicates chronological order, across year boundaries; e.g. 2022-05-05T17:52:47

Powershell copy files with creation date equals given date

I'm trying to copy files with creation date equals to given date with no luck
args passed is current date 2/12/2020 and created a few files today but it copy nothing
what am I missing?
CODE
function findLogs ($searchDate)
{
Get-ChildItem c:\logs | Where-Object{ $_.CreationTime -eq $searchDate -and $_.Name -like "logs*" } | ForEach-Object {
$fileName = $_.Name
Copy-Item "c:\$fileName" -Destination c:\backup
}
}
you need truncate time
function findLogs ($searchDate)
{
Get-ChildItem c:\logs | Where-Object{ ([DateTime]::Parse($_.CreationTime.ToString("yyyy-MM-dd") -eq $searchDate -and $_.Name -like "logs*" } | ForEach-Object {
$fileName = $_.Name
Copy-Item "c:\$fileName" -Destination c:\backup
}
}
When working with PowerShell, there are two things to remember.
PowerShell is object-oriented.
PowerShell uses pipelines.
To the extent you can stick to these rules, you will have more options and your work will be easier.
You've done a good job with the pipeline.
Here are some tools to investigate the object side of things.
What objects are being compared?
Here I'll use the date format for my locale. I see you're using day-month-year.
You can use Get-Member to investigate objects in PowerShell.
> "12/2/2020" | Get-Member
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object Clone(), System.Objec…
CompareTo Method int CompareTo(System.Object value),…
Contains Method bool Contains(string value), bool C…
...
Here we see that our date string is a System.String.
I'd like to know what type of object CreationTime is.
> Get-ChildItem -File | Select-Object -First 1 | ForEach-Object CreationTime | Get-Member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method datetime Add(timespan value)
AddDays Method datetime AddDays(double value)
AddHours Method datetime AddHours(double value)
...
Here we see that CreationTime is a System.DateTime.
Let's get our values to be the same type.
If you want to do shell-style string comparisons, there is nothing stopping you. But then you would be missing all the richness of PowerShell objects.
In principle, we're comparing two dates. So, let's convert our string input to a DateTime object.
> [DateTime] "12/2/2020"
Wednesday, December 2, 2020 12:00:00 AM
Notice that when we type cast a date string like "12/2/2020" to a DateTime object, a time is automatically filled in for the Hour, Minute, and Second properties. By default, midnight is used.
Solving the problem with the date comparison.
Let's look at one of the DateTime objects from my earlier query.
> Get-ChildItem -File | Select-Object -First 1 | ForEach-Object CreationTime
Saturday, September 26, 2020 10:57:33 AM
In my particular case, my file shows the date Saturday, September 26, 2020 10:57:33 AM.
DateTime objects always include the time. In our case, we don't care about the time. So, one way to solve our problem is to set the time portion of our objects to the same value. Then, when we compare two objects, only the date portion can affect the outcome.
Let's look at the properties and methods of DateTime to see if there is anything that can help us.
The first property on the list is Date. That seems like it might be interesting. Let's look at that.
The description of Date is:
Gets the date component of this instance.
A new object with the same date as this instance, and the time value set to 12:00:00 midnight (00:00:00).
This sounds like it might be useful.
Remember, when we type cast our string date, we got a DateTime object with the time portion set to midnight.
Here, we're taking a date and returning the same date with the time set to midnight.
Now we have a method of setting both our string input and file creation times to the same value. So, when we compare those DateTime objects, we'll just be comparing the date portions. This will solve our problem.
Let's demonstrate the necessary code.
> [DateTime] "12/2/2020"
Wednesday, December 2, 2020 12:00:00 AM
> Get-ChildItem -File | Select-Object -First 1 | ForEach-Object { $_.CreationTime.Date }
Saturday, September 26, 2020 12:00:00 AM
Final Answer
So, let's use [DateTime] type casting and the Date property to fix our function.
Here, I've also added parameters with default values. We can call findLogs in the same way as before. But we also have the option of changing the way the function works without having to rewrite it.
I've also used the FullName property to simplify the file copy.
function findLogs ([string] $searchDate, [string] $source = "c:\logs", [string] $destination = "c:\backup", [string] $nameLike = "logs*" )
{
Get-ChildItem -Path $source -File |
Where-Object { ($_.CreationTime.Date -eq (([DateTime] $searchDate).Date)) -and ($_.Name -like $nameLike) } |
ForEach-Object { Copy-Item -Path $_.FullName -Destination $destination }
}
In my environment, I was able to copy one of my bookmarklets to a backup folder:
$a = "C:\Users\Michael\Desktop\Bookmarklets"
$b = "C:\Users\Michael\Desktop\Backup"
findLogs -searchDate "12/3/2020" -source $a -destination $b -nameLike "Mark*"

Powershell Datetime Filter Is Not Using Correct ShortDate Pattern

I am trying to filter LastWriteTime on the Get-ChildItem function, however when I try to filter using a british date, it fails because it's not in the American format.
When I run (Get-Culture).DateTimeFormat.ShortDatePattern I receive dd/MM/yyy which is the correct format.
However when I execute the powershell filter statement :-
GCI 'C:\ | ?{$_.LastWriteTime -ge '21/01/2018'}
I receive the following :-
Cannot convert value "21/01/2018" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
However if I alter the date to 01/21/2018 I receive the correct results.
I have attempted to use $_.LastWriteTime.ToString('dd-MM-yyyy') -ge '01[![enter image description here][1]][1]/01/2018' which doen't work correctly as it returns dates from 2017.
Convert your date string to a date object first:
$date = get-date '21/01/2018'
gci C:\ | ? {$_.LastWriteTime -ge $date }

Format a column of dates in CSV

I'm attempting to format some dates in the first column of a CSV. I would prefer to user something like powershell as I plan to automate this task. Does anyone have any advice on the best way to change the format of the date from something like MM/DD/YYY to YYYY-MM-DD? I've tried something like this:
$date = date -f ('yyyyMMdd')
$HMDA = Import-Csv "C:\HMDA\$date.YieldTableFixed.csv"
ForEach-Object {
$HMDA.Date = [datetime]::ParseExact($HMDA.Date).ToString('YYYY-MM-DD')
} |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
Unfortunately, that didn't seem to do anything but give me a parse error and I can't seem to figure out why that is. Is there a way I can say something like:
ForEach-Object{
$HMDA.A2:$HMDA.A63 = HMDA.$AC.Date.Format('YYYY-MM-DD')
}
Ok, there's some basic errors here, but that's just a matter of not knowing better I think. Now this is hard to answer accurately because you did not give us an example of the incoming date field, so if it has some strange formatting this may throw errors as PowerShell fails to recognize that a string is in fact a date.
First off, if you pipe to a ForEach loop you reference the current object with $_. Such as:
Import-Csv "C:\HMDA\$date.YieldTableFixed.csv" | ForEach-Object {
$_.Date = get-date $_.Date -f 'yyyy-MM-dd'
} | Export-Csv -NoTypeInformation C:\HMDA\test.csv
What would probably be simpler, as I recently learned from somebody else here on SO, would be to use Select, create the updated property on the fly, and then exclude the original property, effectively replacing it with the new one. Something like this:
Import-Csv "C:\HMDA\$date.YieldTableFixed.csv" |
Select *,#{label = 'Date';expression={get-date $_.Date -f 'yyyy-MM-dd'}} -ExcludeProperty Date |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
ParseExact() expects 3 parameters: the date string, a format string, and a format provider (which may be $null). Also, your output format string is incorrect (the year and day format specifiers need to be lowercase), and ForEach-Object reads from a pipeline.
Change this:
$HMDA = Import-Csv "C:\HMDA\$date.YieldTableFixed.csv"
ForEach-Object {
$HMDA.Date = [datetime]::ParseExact($HMDA.Date).ToString('YYYY-MM-DD')
} |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
into this:
Import-Csv 'C:\HMDA\$date.YieldTableFixed.csv' | ForEach-Object {
$_.Date = [DateTime]::ParseExact($_.Date, '*M\/dd\/yyyy', $null).ToString('yyyy-MM-dd')
$_
} | Export-Csv -NoTypeInformation 'C:\HMDA\test.csv'

LastAccessTime and get-date Comparison

I am parsing through a directory with multiple sub-directories and want to compare the LastAccessed time with the get-date time to see if the file has been accessed since yesterday, and based on that I will either delete the file or leave it alone. I have tried piping the get-date results out to a text file and pull it back as a string, I have tried wildcard I have even gone as far as using the -like as opposed to -eq in order to get the comparison to work, but it is not properly comparing the data. Any help would be greatly appreciated.
Here is my current code:
$servers="servera","serverb"
$date3=get-date -Format d
foreach($a in $servers){
$CTXGPDir="\C$\ProgramData\Citrix\GroupPolicy"
$CTXGPDirFP="\\"+"$a"+"$CTXGPDir"
$CTXGPUserDirstoRM=Get-ChildItem "$CTXGPDirFP"|where-Object{$_.Name -notlike "*.gpf"}
foreach($i in $CTXGPUserDirstoRM){
$datestring="$date3"+" *"
$CTXUserGPPath="\C$\ProgramData\Citrix\GroupPolicy\$i"
$CTXUserGPFP="\\"+"$a"+"$CTXUserGPPath"
$file=get-item $CTXUserGPFP
$isFileInactive=$file|select-object -expandproperty LastAccessTime
write-host $file
write-host $isFileInactive
write-host $datestring
if($isFileInactive -like "$datestring *"){write-host "$CTXUserGPFP on $a has lastwritetime of $isFileInactive and should NOT BE deleted"}
if($isFileInactive -notlike "$datestring *"){write-host "$CTXUserGPFP on $a has lastwritetime of $isFileInactive and SHOULD BE deleted"}
}
Your date comparison is deeply flawed.
get-date -format d returns a String representing the current date based on your regional settings.
get-childitem <file> | select -expandproperty lastaccesstime returns a DateTime object, which gets formatted as a "long" date/time using your regional settings.
To compare these two dates effectively, you need to convert the latter to the same format.
$isFileInactive=($file|select-object -expandproperty LastAccessTime).ToShortDateString()
$isFileInactive is now a String formatted the same as you get with get-date -format d and you can make a proper comparison.
if($isFileInactive -eq $datestring){write-host "$CTXUserGPFP on $a has lastwritetime of $isFileInactive and should NOT BE deleted"}
If you have to deal with timezones, you may want to amend it to add .ToLocalTime() before ToShortDateString();