converting datetime from wmiobject to datetime - powershell

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

Related

Pulling EventLogs using powershell from a certain time period

I am trying to run a powershell script that will pull application event logs from between 2 certain times. I have the following code:
$Begin = Get-Date -Date '2/04/2022 14:36:00'
$End = Get-Date -Date '2/04/2022 14:40:00'
Get-EventLog –LogName Application -After $Begin -Before $End
I keep receiving the following error.
Get-Date : Cannot bind parameter because parameter 'Date' is specified more
than once. To provide multiple values to parameters that can accept multiple
values, use the array syntax. For example, "-parameter value1,value2,value3".
Does anyone know what I am doing wrong?
Get-Eventlog itself is depreciated.
You can use Get-Winevent like js2010 is suggesting.
-filterhashtable is (I believe) the only way to specify a time period.
$EventLogFilter = #{
Logname = 'System'
StartTime = [datetime]::Today.AddHours(-$Hours)
EndTime = [datetime]::Today
}
This would give you everything that happened in the last number of $hours you specify.
This is a list of key-value pairs.
An example with get-winevent's filterhashtable. Any string that can be converted to a datetime would work. Searching every log would require a foreach-object loop.
get-winevent -filterhashtable #{logname = 'application'; starttime = '12:45 pm';
endtime = '12:50 pm' }
ProviderName: gupdate
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2/7/2022 12:45:19 PM 0

Comparing TICKS time in 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

Powershell last bootup time of computer showing two different outputs

$OSInfo = get-wmiobject -class win32_operatingsystem -computername c83323
($OSInfo `
| Format-List `
#{Name="OS Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}} `
| Out-String).Trim() #Output OS Name, Boot Time, and Install Date
output --> OS Boot Time : 12/6/2016 4:09:20 PM
$osinfo = get-wmiobject -class win32_operatingsystem -computername c83323
$osinfo.ConvertToDateTime($osinfo.LastBootUpTime)
output --> Tuesday, December 06, 2016 4:09:20 PM
Why is it when I run the first set, I get time in one way, but when I run it the 2nd way, I get it in a completely different format?
This is because you are using Format-List and/or Out-String in the first case. When using these, PowerShell formats the DateTime object's output, just as if you wrote this:
"$(Get-Date)"
The output of your second instance will be in DateTime type. This format depends on the datetime format you have Choosen on your system.
I modified your code to get the type:
$osinfo = get-wmiobject -class win32_operatingsystem; ($osinfo.ConvertToDateTime($osinfo.LastBootUpTime)).GetType()
But in your first instance, you use something called a calculated property (check this link) , which basically let you "Format" and display attributes in the way you prefer. In your case, thru the expression you have provided your date and time had converted into an array and hence it lost its format.
Get type:
($OSInfo | Format-List #{Name="OS Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}}).GetType()
The above type would be an array.
EDIT:
Below snippet should do the trick!
#("Computer1","Computer2") | foreach {
$OSInfo = get-wmiobject -class win32_operatingsystem -computername $_;
"Boot time for Computer: $_ = " + $OSInfo.ConvertToDateTime($OSInfo.LastBootUpTime);
} | Out-File "C:\thefolderYouPrefer\boottime.txt"

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.

PowerShell and CSV

I'm working on script which collects information about computer (os version, software installed etc.) and I would like to get output in CSV file to be able to import in SQL later.
Currently, I have something like this:
$os = Get-WmiObject Win32_OperatingSystem
$soft = Get-WmiObject Win32_Product
$customerid = $env:UserName
$osversion = $os.Caption
$osplatform = $os.OSArchitecture
$ossp = $os.servicepackmajorversion
$timestamp = Get-Date -Format "dd.MM.yyyy HH:mm"
$timestamp,$customerid, $osversion, $osplatform, $ossp, $soft.Name, $soft.Version | Out-File C:\test.csv
I would prefer output file something like this:
http://s9.postimg.org/5zmwoda4f/image.png
but at the moment I'm gettting all information this way:
http://s12.postimg.org/9gsrvdfz1/image.png
How can I achieve output like in the first image?
Thank you for any help!
What you are seeing is how the pipe is dealing with arrays. To get the output you desire we need to make some other changes since you didn't make any effort to add titles and what not. This output deviates slightly from what you desire since it is easier to have the software title on its own line.
$os = Get-WmiObject Win32_OperatingSystem
$soft = Get-WmiObject Win32_Product
$customerid = $env:UserName
$osversion = $os.Caption
$osplatform = $os.OSArchitecture
$ossp = $os.servicepackmajorversion
$timestamp = Get-Date -Format "dd.MM.yyyy HH:mm"
$softwareDetails = ($soft | ForEach-Object{",$($_.Name),,,,,$($_.Version)"})
"Time:,$timestamp",
"UserName:,$customerid",
"OS Version,$osversion",
"Architecture,$osplatform",
"Service Pack,$ossp",
"Software Versions",
$softwareDetails | Out-File C:\test.csv
Since we are using arrays for output each entry will be on it's own line. I would have suggested using Export-CSV but your desired output does not match a traditional csv file.