Add computer status to final output

How can I add the computer status like offline or error to this report. I have it check for errors and it displays while running but on the final output it omits the computers that failed. I would like for it to include all the computers and give the status.

 

ComputerName LastBoot Uptime


Server1 9/14/2018 9:01:11 AM 270 Days 5 Hours 4 Minutes
Server2 12/11/2018 4:12:24 PM 181 Days 21 Hours 52 Minutes
Server3 4/29/2019 2:27:15 PM 42 Days 23 Hours 37 Minutes

 

Function Get-Uptime {
    [CmdletBinding()]
    Param (
        [Parameter(ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]

        [string[]]$ComputerName, 
        [Switch]$ErrorLog,
        [string]$Logfile = 'c:\it\errorlog.txt',
        [Switch]$OU

    )

    if ($ou.IsPresent) {

        $oulist = Get-ADOrganizationalUnit -filter * | select DistinguishedName | Out-GridView -PassThru | Select-Object -ExpandProperty DistinguishedName
        $computers = Get-ADComputer -filter * -Properties * -SearchBase $oulist | select name -ExpandProperty name

        Foreach ($Computer in $computers) {
            Try {
                $OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop -ErrorVariable CurrentError
                $Uptime = (Get-Date) - $OS.ConvertToDateTime($OS.LastBootUpTime)

                $Properties = @{ComputerName = $Computer
                    LastBoot                 = $OS.ConvertToDateTime($OS.LastBootUpTime)
                    Uptime                   = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
                }

                $Obj = New-Object -TypeName PSObject -Property $Properties | Select ComputerName, LastBoot, UpTime

                write-host "Added $Computer to report"


                [Array]$objs += $Obj #Add it


            } 
            catch {

                Write-Warning "An error occured on $Computer"
                $
                if ($ErrorLog) {
                    Get-Date | Out-File $LogFile -Append
                    $Computer | Out-File $LogFile -Append
                    $CurrentError | out-file $LogFile -Append
                }

            } 
        }

        $Objs |Sort-Object LastBoot #Add it
    }

    else {

        Try {
            $OS = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -ErrorAction Stop -ErrorVariable CurrentError
            $Uptime = (Get-Date) - $OS.ConvertToDateTime($OS.LastBootUpTime)

            $Properties = @{ComputerName = $ComputerName
                LastBoot                 = $OS.ConvertToDateTime($OS.LastBootUpTime)
                Uptime                   = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
            }

            $Obj2 = New-Object -TypeName PSObject -Property $Properties | Select ComputerName, LastBoot, UpTime

            $obj2

        }

        catch {

            Write-Warning "Computer $ComputerName had the following error $CurrentError"


        }

    }

}

First off, you’ve got a loose ‘$’ on line 43 that probably isn’t helping.

You don’t have anything in the catch blocks that adds data to your ‘$objs’ array. When you say “it displays while running” I assume you mean that you see the Write-Warning message as per line 42. If you want entries in the array for the computers that don’t respond, you’ll need to create an object in the catch block using the same method as lines 26-31, substituting some default values like "Uptime = ‘Unknown’ " and then add the object to the array as on line 36.

My suggestions.

If I understood you script properly, the only reason you have if/else statement is just because you expect multiple computers if $OU is present. You can optimize the script in below order.

Check if $OU is present, if present get the computers and add/update it to $ComputerName.
Then have a foreach and put a try/catch statement inside it and try to get the an instance win32_operating system class foreach computer and use calculated properties to customize the properties, if errors, in catch create a hashtable with same keys, but value as ‘offline/not reachable’.

example,

#Create calculated properties
$LastBoot        = @{E= {$_.ConvertToDateTime($_.LastBootUpTime)};L='LastBoot'}
$SystemUptime    = @{E= {$UpTime=(Get-Date) - $_.ConvertToDateTime($_.LastBootUpTime);([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")};L='Uptime'}
$CurrentComputer = @{E= {$_.PSComputerName};L='Computer'}


Foreach($Computer in $ComputerName) {
    Try {
        Get-Wmiobject -Class win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop | Select-Object -Property @{E= {$_.ConvertToDateTime($_.LastBootUpTime)};L='LastBoot'},$SystemUptime,$CurrentComputer
    }
    Catch {
        $HashTable = @{
                          LastBoot = 'Offline'
                          Uptime   = 'Offline'
                          computer = $Computer
                      }
        New-Object -TypeName PSObject -Property $HashTable
    }
}