I want the sorted list of date using powershell - powershell

I am getting list of dates and storing it into an array like
$arraylist={2022-03-24T12:05:05Z 2022-03-29T12:04:10Z 2022-03-23T12:54:07Z 2022-03-26T13:15:36Z 2022-03-22T10:06:11Z 2022-03-23T09:54:08Z}
by using a command $arrayList +=$listdate. Now I want the sorted list of date alone like
$sortedlist={2022-03-29 2022-03-26 2022-03-24 2022-03-23 2022-03-23 2022-03-22}
Not with timing. I am doing these things in PowerShell. The details of date which I am getting is in string format not in date-time format. can anyone help me out with this?
I initially split the date with $arrayList.Split('T') and stored the date alone in another array. But it is not sorted form. I tried to sort it but I am not getting desired sorted list.
Is there any other way to get desired sorted list of date?

If you are getting your dates in a single string (as per the example of data you have provided) it would be possible to split the string into an array and then convert the array of strings into datetime objects:
$DateString = "2022-03-24T12:05:05Z 2022-03-29T12:04:10Z 2022-03-23T12:54:07Z 2022-03-26T13:15:36Z 2022-03-22T10:06:11Z 2022-03-23T09:54:08Z"
$array = $DateString -split " "
$FormattedDates = Foreach ($item in $array){
[DateTime]::ParseExact($Item, "yyyy-MM-ddTHH:mm:ssK", $null)
}
$FormattedDates | Sort | ForEach-Object {$_.ToString("yyyy-MM-dd")}

Related

Powershell CSV modification

CSV source exemple:
"Requested Quantity","Unit of Measure","Requested Date","Forecast Timing Qualifier","Rating"
"4.00 ","EA","26.09.2022","W","DOA1"
"12.00 ","EA","27.09.2022","W","DOA1"
I need to remove the last 3 Characters to Requested Quantity and
I need to convert the Requested Date format to Month.Day.Year for each line.
Input : "4.00 ","EA","26.09.2022","W","DOA1"
Output : "4","EA","09/26/2022","W","DOA1"
I got the Requested quantity ok but I need some help with converting the date portion.
Thanks
For the Requested Quantity column you can use the -replace operator to remove the dot and everything after. For the date column, use [Datetime]::ParseExact() to parse the existing format, then convert back to a string with the desired format:
Import-Csv path\to\source.csv |ForEach-Object {
# Cut the trailing decimals off the quantity
$_.'Requested Quantity' = $_.'Requested Quantity' -replace '\..*$'
# Parse and re-format date column
$_.'Requested Date' = [datetime]::ParseExact($_.'Requested Date', 'dd.MM.yyyy', $null).ToString('MM/dd/yyyy')
# output the modified object for export
$_
} |Export-Csv path\to\output.csv -NoTypeInformation

How to convert powershell UTC datetime object to EST

I have date time strings coming in, formatted like the following:
2017-08-03T12:30:00.000Z
I need to be able to convert these to EST. Every function I have tried throws one error or another, typically being:
"String was not recognized as a valid DateTime."
I have tried variations of the below:
$time = '2017-08-03T12:30:00.000Z'
[datetime]$datetime = $time
$culture = [Globalization.CultureInfo]::InvariantCulture
[DateTime]::ParseExact($datetime, 'MM-dd-yyyy HH:mm:ss', $culture)
I think it has something to do with how the Date Time string I am referencing has the **T** and then the UTC time, but can't figure out what to do about it. Maybe I should parse out the time, convert it and then reattach to the first part of the string, the date, and combine them together for the final output? Seems like way too much work and a solution which would cause potential errors in the future.
You should be able to convert a Zulu time string to a DateTime value simply by casting it. However, the resulting value will be in local time, so you should convert it back to UTC for further calculations:
$timestamp = '2017-08-03T12:30:00.000Z'
$datetime = ([DateTime]$timestamp).ToUniversalTime()
Then you can use the TimeZoneInfo class to convert the UTC timestamp to the desired timezone:
[TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($datetime, 'Eastern Standard Time')
Use [TimeZoneInfo]::GetSystemTimeZones() | Select-Object Id, DisplayName to get a list of the recognized timezones.
Try using the static ConvertTimeBySystemTimeZoneId() method of the [System.TimeZoneInfo] class:
$time = '2017-08-03T12:30:00.000Z'
$result = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date -Date $time), 'Eastern Standard Time')
The returned $result is a [DateTime].
BTW, if you ever need to convert it back, here's how:
Get-Date -Date $result -Format FileDateTimeUniversal
Hope this helps.

Can't convert value from datatable to datetime

Using powershell 5.1
I have a function called that returns a string representing a date like this
"4/22/2019 12:00:00 AM"
function Get-LastLogTime() {
$lastRunDate = Get-SQLData "." "AdHoc" "SELECT TOP 1 o.LogTime FROM dbo.FAQlog o WHERE o.RecordsSent = 1 ORDER BY o.LogTime DESC"
return $lastRunDate
}
Where LogTime is the usual Datetime SQL type and Get-SQLData is another function that returns a datatable.
If I just check the return value, I get something like this
LogTime
-------
4/22/2019 12:00:00 AM
Ok, great, but I need to compare this date to the current date. So, I do something like this but i get an error on the line trying to convert $testDate to datetime.
# test
$testDate = Get-LastLogTime
([DateTime]$testDate) -lt (Get-Date)
If I just do a simple comparison at the command line, it works, eg.
([DateTime]"4/22/2019 12:00:00 AM" ) -lt (Get-Date)
It works with
([DateTime]"4/22/2019 12:00:00 AM" )
Because you are casting DateTime on a String.
Return value of Get-LastLogTime is not a string probably and casting it to a Datetime does not work.
get-LastLogTime | get-member will show you the methods you have available on the returned data type such as, for instance, ToString, and that can be used to perform the comparison.

How to Display Modified Time and Modified By Fields Correctly with Powershell

I have a script that outputs to CSV all items/files from all Lists and Libraries. In addition, it displays the current and previous versions of an item/file. This also displays which user modified the file for each version and also displays the date/time the file was modified for every version:
function Get-DocInventory([string]$siteUrl) {
$web = Get-SPWeb "http://contoso.com/sites/Depts3/HBG"
foreach ($list in $web.Lists) {
foreach ($item in $list.Items) {
foreach($version in $item.Versions){
$data = #{
"Version" = $version.VersionLabel
"List Name" = $list.Title
"Created By" = $item["Author"]
"Created Date" = ($item["Created"] -as [datetime]).DateTime
"Modified By" = $version["Editor"]
"Modified Date" = ($version["Modified"] -as [datetime]).DateTime
"Item Name" = $item.Name
}
New-Object PSObject -Property $data | Select "List Name", "Item Name", "Version", "Created By", "Created Date", "Modified By", "Modified Date"
}
}
$web.Dispose();
}
}
Get-DocInventory | Export-Csv -NoTypeInformation -Path C:\GenerateReport.csv
Below is a sample of what the script outputs:
And below is an excel example of what I see when I go to the Version History of the Lions.pdf file:
I have 2 problems:
The column Modified By is displaying email and domain username which is not required.
My script displays the column Modified Date as 5 hours ahead. The script output for Version 1 of Lions.pdf displays time as 11:23 AM. But when I go to Version History of Lions.pdf it says that Version 1 was modified at 6:23 AM. The time discrepancy is the same across the board as 5 hours ahead which is incorrect.
I can't seem to figure out what I am doing wrong here. Can someone please assist in the issue I am having? My main concern is the time and I would greatly appreciate any assistance.
User Fields
Normally in server side code, accessing a user field value using array notation (eg myItem["Author"]) would return an object that you would cast to an appropriate type (Microsoft.SharePoint.SPFieldUserValue). Powershell, however, automatically casts these values to strings, which is why you're getting undesirable values.
Fortunately, there's a way around it! First, get the field itself as an object, then pass the field value into the field's GetFieldValue() method.
$userField = $item.Fields.GetField("Author");
$authorObject = $userField.GetFieldValue($item["Author"]);
You'll then have an object with properties you can access to retrieve the desired values, such as LookupValue for the user's display name on the site.
$authorName = $authorObject.LookupValue;
Date Fields
Date fields are little easier, because Powershell will actually hand them over to you as DateTime objects.
To format a DateTime object, you can just call .ToString() and pass in a parameter indicating the desired format.
$data = #{
...
"Modified Date" = $item["Modified"].ToString("MM/dd/yyyy h:mm tt");
...
}
Time Discrepancy
This is most likely attributable to your local timezone. The times displayed on a SharePoint site via the browser are determined by your PC's timezone settings. The times actually saved to SharePoint's underlying database are determined by the server's timezone settings.
To reconcile them, you can use the DateTime object's .ToUniversalTime() method to get a corresponding DateTime object in UTC time (and optionally offset it as desired until it aligns with the local timezone and daylight savings adjustments).
Edit: I'm guessing you're in US Eastern time (UTC-5) and it's giving you results in UTC time (Universal Coordinated Time, which is 5 hours ahead of you except during daylight saving time). You should be able to offset the hours manually to account for this.
$localOffset = -5;
$modified = $version["Modified"] -as [datetime];
if($modified.IsDaylightSavingTime()){$localOffset += 1;}
$modifiedLocal = $modified.addHours(-$localOffset);

Powershell variable interrogation of date & time difference

Morning All,
I have a variable as follows: $machines = $user2,$name,$serial,$purchased
sample data stored in $machines is:
User1,
Laptop1,
xyz1234,
01/01/2010
I am wanting to create a new variable called $tobereplaced containing all of the records in $machines with a date greater than 4 years old from todays date.
the fuzzy logic code for this im expecting to be someting like $tobereplaced = $machines.$purchased | where {$_$purchased = -getdate > 4 years} etc etc but i cant quite figure it out.
Assistance would be greatly appreciated.
Thanks
$fourYearsAgo = (Get-Date).AddYears(-4)
$tobereplaced = $machines | Where-Object { (Get-Date $_[-1]) -le $fourYearsAgo }
Convert the date as DateTime and compare it against a date four years ago. Like so,
# Assuming $m[3] contains the timestamp, parse it as a DateTime and compare
# against a date four years ago.
if([DateTime]::Parse($m[3]) -le [DateTime]::Now.AddYear(-4)) {
$tobereplaced += $m
}
Depending on your locale, you might need to tell [DateTime]::Parse() how to parse the date. Is 01/12/2010 1st of December, 2010 or 12th January, 2010?