PowerShell Tile to display server and lastboottime

i have a simple PowerShell Script that I am executing in a PowerShell Grid tile that returns a host name and its last boot time. The example data returns what you would see in Powershell as the name and the Date\Time. the Dashboard however renders the date\time as the number. Need some assistance on adjusting the format of the column as i am assuming that is where it is being converted back to a number. Additionally, not sure if I understand the Scoping. I want it to return all of the servers in the Group identified. using All Windows Server Computer Group in this case. Moving forward I will have to scope it tighter to a subset based on pre-existing SCOM Groups.

Script:
Get-WmiObject Win32_OperatingSystem | Select csname, LastBootUpTime

Hey Mike

What is the format of the time returned? Is it UTC or Unix? You just have to pass it as a custom property. Depending on which time format it is, one of the following should probably work:

@{
    Name = "timestamp";
    Expression = { [DateTime]::Parse($_.timestamp) }
}

OR

@{
        Name = "timestamp";
        Expression = {(Get-Date 01.01.1970) + ([System.TimeSpan]::fromseconds([int]$_.starttime))}
}

For more examples you can refer to the Github repository and see how some of those dashboards are scripted.

Hope this helps.

i am getting this output: 20210812162420.500000-300 While readable not human digestable :slight_smile:

So I did find this in the examples:
{{timeago(value)}}
this changes 20210812162420.500000-300 to August 12th 2021, 12:00:00 am

Can someone point me to more documentation on the use or datetime formatting of timeago? For this particular representation, I would rather have some form of month, day, hour, seconds displayed from that time

Hi Mike,

Check out these links for more resources on the TimeAgo function:

But, I get the impression that you want total control of the formatting of the DateTime value?

If you do, then you need to format the value as a String in your script.

Here is an example script that shoots out the LastBootUpTime value in three different ways.

Get-WmiObject Win32_OperatingSystem | 
Select csname, LastBootUpTime, 
@{LABEL = 'LastBootUpTime2'; EXPRESSION = { $_.ConverttoDateTime($_.lastbootuptime) } }, 
@{LABEL = 'LastBootUpTime3'; EXPRESSION = { ('{0:yyyy}/{0:MM}/{0:dd} {00:hh}:{00:mm}:{00:ss} {0:tt}' -f $_.ConverttoDateTime($_.lastbootuptime)).ToString()}}

If you want the long-winded explanation, that begins here.

On a SquaredUp Dashboard, the first value will appear as:

20210831140614.094750-240

When you apply the TimeAgo function in the Grid Column, it will then appear as:

August 31st 2021, 12:00:00 am

Take note that the time value is 12:00:00 am. I have found that when working with WMI, the DateTime value is returned in a weird format. In order to get the time portion of the value, you need to reformat the value like this:

$_.ConverttoDateTime($_.lastbootuptime)

This will output:

1630418774094.75

And when you apply the TimeAgo function, you will get:

August 31st 2021, 10:06:14 am

But if you want to format the value in a specific way, I don’t think the TimeAgo function will do that. But if you format the value as a String before it’s sent to SquaredUp, you can format it in any way that you want. Here’s an example:

('{0:yyyy}/{0:MM}/{0:dd} {00:hh}:{00:mm}:{00:ss} {0:tt}' -f $_.ConverttoDateTime($_.lastbootuptime)).ToString()

This will output:

2021/08/31 10:06:14 PM

Be warned, I didn’t account for any time zone drama. So, if your value is off by a couple of hours, you will need to adjust for the timezone in whatever way makes sense for you.

Hopefully, that helps.

1 Like

Thank you. That does it. But it is not acting on my scope of All Windows Server computer Group, i am only getting output for the current machine I am running SquaredUP on…what am I missing there?

Hi Mike,

For the PowerShell tile, when you select a Scope for the tile, all you’re doing is passing in a pre-filled variable called

$scope

into your script.

At that point, it’s up to you to loop through each item in the object. Something like this:

foreach ($item in $scope) {
    $item.DisplayName
}

Then for each iteration, you would need to save off the values.

But if I am to understand you correctly, you are wanting to run that WMI query against every server that is returned via the $scope parameter? Why do you want to do that when you have SCOM? Just create a collection rule for the value and be done with it.

In other words, when you start querying other servers there will be a delay while that other server processes your request. That means the dashboard won’t show anything until everything comes back.

On the other hand, I can envision doing this for other things, so the concept is a good idea. But I worry that will be disappointed with the results (in this case, at least).

Let me know your thoughts.

Thank you, this helps. As for why, because I was blinded by PowerShell :slight_smile: I will do the rule, as that makes way more sense. Then I just need to be able to make the simple tile to pull it in. Thanks Shawn

one follow-up on the scope and powershell that I just thought of… how does this handle agents in other domains, would I have to make separate groups based on domain and have different run as accounts to execute said PowerShell scripts against those scopes? Something to know for future endeavors and thank you so much for your time. i will tell you after having this for five years, the management finally see the value, so now I really get to spend more time in it. Exciting times.

Hello again!

The short answer about other domains is that it depends. :wink:

In all seriousness, it depends on what you’re doing and where you’re doing it.

For discussion purposes, if you have one Management Group monitoring two domains, then there is probably a “Trust” between the two domains. In that case, just user credentials that both domains “trust” and things should be fairly seamless.

But, if you are using Gateways (and need to use credentials), things can get more difficult. At that point, you will need to beef up your script so that it uses the correct credentials for the proper domain.

If you’re monitoring with certificates, then it gets even crazier.

In my experience, I always try to write my script so that they run as local system. That way, it doesn’t matter what domain the agent is in; as long as the Monitor or Rule can run, the script will run. But as soon as you need to pass credentials, things can, and will, get messy.

I’m not sure that really answered your question, but the answer is never short when it comes to multiple domains.

Just wanted to follow up on what I have been able to do.
We are already collecting System Uptime via Performance counter collection. System \ System Uptime.
It is in Seconds.
I am trying to figure out the {{}} format I can apply, where it comes out as nn Days, nn Hours, nn Seconds

Hey Mike

TL:DR
{{timeago(Date.now() - (value * 1000))}}

Just to walk you through it… you’re starting with {{value}} which you mentioned is the number of seconds that your system has been up. Step 1 is to get the current time.

{{Date.now()}}

The default for this object is miliseconds so to take away your {{value}} which is in seconds, we multiply {{value}} by 1000 as {{value * 1000}} then subtract it from {{Date.now()}}

{{Date.now() - (value * 1000)}}

Then to make it render in the format you want, we wrap the whole thing in {{timeago}}

{{timeago(Date.now() - (value * 1000))}}

You can apply some true/false switches to {{timeago}} to further customise the string format. Check this article.

So with your help I’ve been able to display the Date of the last reboot in the Matrix tile, customized to only show the one column.


My goal is to get that Date to Display as NN Days, NN Hours, etc. I don’t want anyone to have to do the math.

What I am finding is that the Tile does not format in a useful way, nor is it sortable by the output. So I have created a Performance (simple Threshold) monitor and I am now trying to get it to display in a useful way. Where the Tile output shows only when That Monitor exists for the Scoped Machine, but that is another topic.

I also suppose I could do a PowerShell Discovery and collect the date, but where to put it I am still working out.

thank you for all your help

1 Like