If you’ve ever looked at sysjobhistory, you know that the way SQL Server stores datetimes and durations in this table are not very friendly. Well, that’s not quite true. They are human-readable if they are small, but if you’ve got a job that runs for hours (days?), it becomes more and more difficult.
For example, a job which started at 9:05AM today (5/9/2011) would have a run_time of 905 and a run_date of 20110905. Both of those are recognizable, but since they are integers, it’s complicated to get them into a datetime variable in PowerShell in order to manipulate them. I have seen several posts on how to create a UDF (user-defined function) to convert these values to a datetime, and that’s usually a good solution. Unfortunately, it’s not always possible (politically) to create a UDF on a SQL instance. For example, if you are simply monitoring a box to make sure that backups are run, and don’t have much control over the box besides that function, you might not be allowed to create the necessary UDFs. Similarly, a SQL solution involving a select statement that kneads the data into the value you want is not a great solution because it’s not reusable, except in the cut-paste sense.
For that reason, I have written 4 different functions to assist with managing job data.
function convertfrom-SqlAgentDuration{
param($sql_duration)
return New-TimeSpan -seconds ($sql_duration % 100) -minutes (($sql_duration / 100) % 100) -hours ($sql_duration /10000)
}
function convertfrom-SQLAgentDateTime{
param($sql_startdate,$sql_starttime)
return (get-date -year ($sql_startdate/10000) -month ($sql_startdate/100 % 100) -day ($sql_startdate %100) -hour ($sql_starttime/10000 % 100) -minute ($sql_starttime/100 % 100) -sec ($sql_starttime % 100))
}
function convertto-SQLAgentDuration{
param([System.TimeSpan]$duration)
return $duration.seconds+100*$duration.minutes+10000*($duration.hours+24*$duration.days)
}
function convertto-SQLAgentDateTime{
param([datetime]$date)
return (new-object PSObject -property @{date=[int](get-date $date -uformat "%Y%m%d");time=[int](get-date $date -uformat "%H%M%S")})
}
Obviously, these are not high-performance functions, but given the volume of data you would be getting out of the SQL Agent, that shouldn’t pose any kind of problem. Here are some example usages:
PS>get-date
Monday, May 09, 2011 9:01:58 PM
_________________________________________________________________________________
PS>convertto-sqlagentdatetime (get-date) | ft -auto
date time
---- ----
20110509 210648
_________________________________________________________________________________
PS>convertfrom-sqlagentdatetime 20110509 210648
Monday, May 09, 2011 9:06:48 PM
_________________________________________________________________________________
PS>convertfrom-SqlAgentDuration 12345
Days : 0
Hours : 1
Minutes : 23
Seconds : 45
Milliseconds : 0
Ticks : 50250000000
TotalDays : 0.0581597222222222
TotalHours : 1.39583333333333
TotalMinutes : 83.75
TotalSeconds : 5025
TotalMilliseconds : 5025000
I hope these functions are useful to you. Let me know what you think.