$uptime .ps1 script assistance

This topic contains 6 replies, has 4 voices, and was last updated by Profile photo of Dan Potter Dan Potter 1 month, 1 week ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #51634
    Profile photo of Creed Cordonier
    Creed Cordonier
    Participant

    Hello!

    I am using PS to write a .ps1 to use as a logon script. The script should get the value of system uptime, then perform some simple logic based on that value. I am coming up short (beginner) and could use some help. I think my script is falling down as I suspect my $uptime variable may be storing a function, but not the value of the completed function. I am still trying to assign the Value to the variable. Here is my attempt at scripting this:

    function Get-SystemUptime {
        $operatingSystem = Get-WmiObject Win32_OperatingSystem
       "$((Get-Date) - ([Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)))" 
    }
    
    $uptime = Get-SystemUptime
    
    if (Get-SystemUptime -ge 14) {
       write-host "Reboot your computer"
       }

    To me, this has created a function which does work and returns '1.00:43:03:4281895', for my particular system.

    I then assigned it to $uptime variable.

    I am then trying to use logic that IF the value of my function -ge 14.00, do this thing.

    Right now the Get-SystemUptime function and $uptime variable return what I need, but I do not think my IF logic is getting the returned value.

    I will add that the ultimate goal is to use this .ps1 as a logon script in our environment that will run once when a user logs in. If the computer has not been reboot in more than 14 days, I will need to call something else in the script to display an annoying message, prompting the user to reboot.

    Any assistance is appreciated! Thank you!

    #51648
    Profile photo of Creed Cordonier
    Creed Cordonier
    Participant

    UPDATE:

    I got this working, here:

    function Get-SystemUptime {
        $operatingSystem = Get-WmiObject Win32_OperatingSystem
       "$((Get-Date) - ([Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)))" 
    }
    
    $uptime = Get-SystemUptime
    
    if ($uptime -ge "14.00:00:00:0000000") {
       write-host "Reboot your computer"
       }
    #51650
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Your function is returning a string. If the string was the hours, it would work, but seeing if 14 is equal 1.00:43:03:4281895 to won't ever work because it's returning a timespan as a string.

    PS C:\Users\Rob> $uptime.GetType()
    
    IsPublic IsSerial Name                                     BaseType                                                                                                                                         
    -------- -------- ----                                     --------                                                                                                                                         
    True     True     String                                   System.Object                                                                                                                                    
    

    So, if we modify you function to return a TimeSpan object, then we get properties such as days to perform a comparison against:

    function Get-SystemUptime {
        $operatingSystem = Get-WmiObject Win32_OperatingSystem
        New-TimeSpan -Start ([Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)) -End (Get-Date)
    }
    
    $uptime = Get-SystemUptime
    
    if ($uptime.Days -ge 14) {
       write-host "Reboot your computer"
    }
    

    You'll note if you look at $uptime now, it has properties that can be used to do comparisions:

    PS C:\Users\Rob> $uptime.GetType()
    
    IsPublic IsSerial Name                                     BaseType                                                                                                                                         
    -------- -------- ----                                     --------                                                                                                                                         
    True     True     TimeSpan                                 System.ValueType                                                                                                                                 
    
    
    
    PS C:\Users\Rob> $uptime
    
    
    Days              : 6
    Hours             : 19
    Minutes           : 56
    Seconds           : 46
    Milliseconds      : 457
    Ticks             : 5902064572319
    TotalDays         : 6.83109325499884
    TotalHours        : 163.946238119972
    TotalMinutes      : 9836.77428719833
    TotalSeconds      : 590206.4572319
    TotalMilliseconds : 590206457.2319
    
    #51652
    Profile photo of Christian Sandfeld
    Christian Sandfeld
    Participant

    Hi Creed,

    When comparing date/time in PowerShell, it is easiest to work with datetime objects.
    However as you may have found out yourself, the LastBootUpTime property of the returned WMI object does not return a datetime object, but a string object.

    Fortunately though the WMI object itself has the 'ConvertToDateTime' method, that can be used to convert the string to a proper datetime object.

    Changing your 'Get-SystemUptime' function to this:

    function Get-SystemUptime {
        $operatingSystem = Get-WmiObject Win32_OperatingSystem
        $operatingSystem.ConvertToDateTime($operatingSystem.LastBootUpTime)
    }
    

    Makes it return a proper datetime object, as can be seen here:

    PS > Get-SystemUptime
    
    22. august 2016 13:17:47
    
    
    
    PS > (Get-SystemUptime).GetType()
    
    IsPublic IsSerial Name                                     BaseType                                          
    -------- -------- ----                                     --------                                          
    True     True     DateTime                                 System.ValueType                                  
    
    
    
    PS > 
    

    Having changed your function you can compare the returned datetime object, to a datetime object where you subtract the desired number of days (14) as follows:

    if ( (Get-SystemUptime) -lt (Get-Date).AddDays(-14) ) {
        write-host "Reboot your computer"
    }
    
    #51654
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Powershell lets you cheat because it's converting the string to a timespan automatically for -ge comparison logic to work. Powershell is an object oriented language, so you want to really try to leverage an object like the TimeSpan example because you aren't assuming that Powershell is going to perform the correct type conversion.

    #51664
    Profile photo of Creed Cordonier
    Creed Cordonier
    Participant

    This is excellent help. Thank you so much, Rob and Christian.

    I went with Rob's suggestion as it gave the object properties to work with in a way that I understood.

    Now when I query $uptime.Days, I return '1', which is very easy to make a comparison to.

    Thank you!!

    #51687
    Profile photo of Dan Potter
    Dan Potter
    Participant

    bonus, if you use ciminstance it's already a datetime object.

    (Get-CimInstance Win32_OperatingSystem).lastbootuptime.gettype()

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.