Comparing TICKS time in Powershell - powershell

I'm trying to compare two TICKS times, and i need the comparisons to be a little less precise and consider DateTime objects equal even if they were a few milliseconds apart (half minute tops) by removing any excess milliseconds and ticks from their DateTime objects (following jacubs guide).
problem is that my first ticks value ($date1) is generate from a performance counter, and i cannot convert him back to Date time again (Get-Date -Date ($date1)), getting the following error message:
Get-Date : Cannot bind parameter 'Date'. Cannot convert value
"636763462457113590" to type "System.DateTime". Error: "String was
not recognized as a valid dateTime"
This is my script:
$date1 = (Get-Counter -Counter '\TimeCheck\TIME').CounterSamples[0] | Select-Object -ExpandProperty RawValue
Get-Date $date1
Get-Date -Date ($date1) -Millisecond 0 | Select -ExpandProperty Ticks
$date2 = Get-Date
$date2.Ticks
Get-Date -Date ($date2) -Millisecond 0 | Select -ExpandProperty Ticks
$date1 -eq $date2
The only method this command works for me is if i wrote the TICKS time itself:
PS C:> Get-Date -Date 636763462457113590
Sunday, October 28, 2018 5:57:25 PM
What i'm doing wrong? even using out-string isn't working.

looks like $date1 in "Get-Date -Date ($date1)" is not numeric (based on error)
try Get-Date -Date ([int64]$date1) or [datetime][int64]$date1

this will convert from a tick count to a datetime object ...
$Ticks = 636763462457113590
$TimeFromTicks = [datetime]$Ticks
$TimeFromTicks
output = 2018 October 28, Sunday 5:57:25 PM

Related

Get-Date formatting/culture

How do I specify what part of my input string is the date and month?
If the input is 01/10/2017, this can be read as 1st Oct 2017 and 10th Jan 2017. Both are correct.
I want to be explicit that 01 is date and 10 is month, so that irrespective of locale and time format I can get a consistent result.
Sample code:
get-date -Date '01/10/2017'
The output is:
Tuesday, January 10, 2017 12:00:00 AM
The desired output is:
Sunday, October 01, 2017 12:00:00 AM
I have a solution for you. It requires that the culture as one of the arguments.
([datetime]::ParseExact($date,"dd/MM/yyyy",[Globalization.CultureInfo]::CreateSpecificCulture('en-GB')))
A culture does not have to be specified. However, the argument for it does, otherwise you will get an error:
Cannot find an overload for "ParseExact" and the argument count: "2".
[cultureinfo]::InvariantCulture or $null can be used as the third argument:
$date = "01/10/2017"
[datetime]::ParseExact($date, "dd/MM/yyyy", [cultureinfo]::InvariantCulture)
[datetime]::ParseExact($date, "dd/MM/yyyy", $null)
Output in all three cases
01 October 2017 00:00:00
Try this:
Get-Date(Get-Date -Date $date -Format 'dd/MM/yyyy')
You can enforce the culture for single commands (or command blocks). This should help avoiding that date chaos.
PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-US" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US"; get-date -Date '01/10/2017'
Tuesday, January 10, 2017 12:00:00 AM
PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-GB" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-GB"; get-date -Date '01/10/2017'
01 October 2017 00:00:00

Finding last snapmirror update date

I'm writing a script to check what is the last time a snapmirror relationship has been updated using PowerChell over cluster mode netapps.
I found that using snapmirror show on the CLI I could see "last transfer end timestamp" and there is also a property with the same name using PowerShell using:
get-ncsnapmirror | select lasttransferendtimestamp
Problem is at the CLI it shows a nice date (08/23 22:05:51) and using PowerShell all I get is a number (1471979101). Does anyone know how I could translate this number to a DateTime format? (.ToDateTime() didn't work)
It shows the total seconds from the beginning of UNIX time. So you could do:
$date = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 00 -Minute 00 -Second 00
$date.AddSeconds($integer)
EDIT : After Ansgar Wiechers's comment.
$date = (Get-Date '1970-01-01').AddSeconds($integer)
Where $integer is the number you get. The result that I get is:
PS C:\> $date = (Get-Date '1970-01-01').AddSeconds(1471979101)
PS C:\> $date.GetDateTimeFormats('s')
2016-08-23T19:05:01

PowerShell v2.0 - Converting to DateTime

I have some date variables, with which to perform queries against files in a specific directory. I can GCI each file no problem, as shown in the example below:
File1.xml 14/07/2016 17:09
File2.xml 15/07/2016 09:32
So I am searching for all files between a specific age range and my criteria is:
Older than:
$Today4am = Get-Date -Hour 4 -Minute 0 -Second 0
But later than
$Yesterday4am = $Today4am.AddDays(-1)
The variables output
$Today4am = 15 July 2016 04:00:00
$Yesterday4am = 14 July 2016 04:00:00
So the variable pipes out the date in a different format to the file themselves, so I need to ensure both formats are the same in order to do the comparison. Here is the original script:
$Filter = gci c:\temp\*.xml |
Where {$_.LastWriteTime -gt $Yesterday4am -and {$_.LastWriteTime-lt $Today4am}}
Bad argument to operator '-gt': Could not compare "14/07/2016 17:09:52" to "14/07/2016 0
4:00". Error: "Cannot convert value "14/07/2016 04:00" to type "System.DateTime". Error:
"String was not recognized as a valid DateTime."".
So I try to convert the variables to add -Format "dd/MM/yyyy HH:mm" and this outputs the correct format. But converting $Yesterday4am = $Today4am.AddDays(-1) -Format "dd/MM/yyyy HH:mm" produces the error:
Cannot convert value "15/07/2016 04:00" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
How can I get both date formats to agree?
Try using Get-date again to convert $Yesterday4am to DateTime:
| Where {$_.LastWriteTime -gt (Get-Date $Yesterday4am) -and {$_.LastWriteTime-lt $Today4am}}
And if you're worried about performance you can do the Get-Date conversion outside of the Where operator:
$Yesterday4am = Get-Date $Yesterday4am
$Filter = gci c:\temp\*.xml `
| Where {$_.LastWriteTime -gt $Yesterday4am -and {$_.LastWriteTime-lt $Today4am}}
I believe this was just an issue with your comparisons. If you run my script below you will see that they are both types "DateTime". If you format them they become strings which will not easily compare. When I ran my Where-Object command below I had no errors. Note: I am using PowerShell version 5.
PS> Write-Host "PowerShell Version: $($PSVersionTable.PSVersion.ToString())"
PowerShell Version: 5.0.10586.122
PS> $Today4am = Get-Date -Hour 4 -Minute 0 -Second 0
PS> Write-Host "`$Today4am is type `"$($Today4am.GetType().FullName)`""
$Today4am is type "System.DateTime"
PS> $Yesterday4am = $Today4am.AddDays(-1)
PS> Write-Host "`$Yesterday4am is type `"$($Yesterday4am.GetType().FullName)`""
$Yesterday4am is type "System.DateTime"
PS> $Filter = Get-ChildItem c:\temp\* | Where-Object -FilterScript { ( $_.LastWriteTime -gt $Yesterday4am ) -and ( $_.LastWriteTime-lt $Today4am ) }
PS> $Filter
Directory: C:\temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/14/2016 1:13 PM 0 asdfasd

converting datetime from wmiobject to datetime

Trying to get the difference in days between to dates: Today's date. and a date/time from a wmiobject (this was taken from a post from the PendingReboot script from Hey, Scripting! blog):
$Lastreboottime = Get-WmiObject win32_operatingsystem -ComputerName $Computer |
select csname, #{LABEL='LastBootUpTime';EXPRESSION=$_.ConverttoDateTime($_.lastbootuptime)}}
$Today = Get-Date -Format d
$DiffDays = $Today - $Lastreboottime
The result of $Today is
09/06/2016
and $Lastreboottime is
05/05/2016 11:13:21
So I want to get rid of the time but not sure how to do this.
Secondly, I get this error if I were to run the script, though I guess this may go away if I am able to extract the date only in $Lastreboot
Cannot convert the "#{csname=JDWTAWEB1; LastBootUpTime=05/05/2016 11:13:21}" value of type "Selected.System.Management.ManagementObject" to type "System.DateTime".
Any ideas?
Remove -Format d and compare the Date-properties of the DateTime-objects to get the days-diff only.
Your $Lastreboottime-variable references an object with both computername csname and the LastBootUpTime, so you need to access the LastBootUpTime
Try:
$Lastreboottime = Get-WmiObject win32_operatingsystem |
select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
$Today = Get-Date
$DiffDays = $Today.Date - $Lastreboottime.LastBootUpTime.Date
$DiffDays.TotalDays
13
I think that the WMIObject conversion might need to get to a Datetime object by way of a properly formatted string. I did this (minus the -Computername $Computer part) and it seemed to work.
[string]$BootTimeString=(Get-WmiObject win32_operatingsystem -ComputerName $Computer).lastbootuptime -replace '\..*',''
$BootTimeDT=[datetime]::ParseExact($BootTimeString,'yyyyMMddHHmmss',$null)
$DiffDays = (NEW-TIMESPAN –Start $BootTimeDT –End (Get-Date)).Days
Remove -Format d from Get-Date. You need DateTime object, not a string.
$Lastreboottime is an object with 2 properties: csname and lastbootuptime. You have to use lastbootuptime property.
Example:
$Today = Get-Date
$DiffDays = $Today - $Lastreboottime.lastbootuptime

In Get-WinEvent, which kind of interval of EndTime?

I used Get-WinEvent in Powershell to get eventlog in a time interval. To avoid data loss or repeat, I need to know the interval type of StartTime and EndTime.
In the following example in MSDN:
PS C:\> # Use the Where-Object cmdlet
PS C:\>$yesterday = (Get-Date) - (New-TimeSpan -Day 1)
PS C:\>Get-WinEvent -LogName "Windows PowerShell" | Where-Object {$_.TimeCreated -ge $yesterday}
# Uses FilterHashTable
PS C:\>$yesterday = (Get-Date) - (New-TimeSpan -Day 1)
PS C:\>Get-WinEvent -FilterHashTable #{LogName='Windows PowerShell'; Level=3; StartTime=$yesterday}
It seems that StartTime means ">=".
But I did not find any info about EndTime. what's it represent? "<" or "<="?
EndTime means <=. Just ran a test on my PC. When I set EndTime=(get-date -Date "03.08.2015 14:07:27") I get events on that precise time. Also the timestamps in the event log don't contain milliseconds, therefore filtering is done by 1 second precision.