Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
July 3, 2023

Writing Multi-Value Functions

I’ve devoted the last few articles to writing advanced functions. By now, you should know to ask yourself, “Who will be using my function and how?” Let’s continue working with the Get-ComputerUptime function.

Function Get-ComputerUptime {
    [cmdletbinding()]
    [alias('gcup', 'cup')]
    [OutputType('PSCustomObject')]

    Param(
        [Parameter(
            Position = 0,
            ValueFromPipelineByPropertyName,
            ValueFromPipeline,
            HelpMessage = 'Specify the name of a remote computer.'
        )]
        [Alias('CN', 'Name')]
        [ValidateNotNullOrEmpty()]
        [String]$ComputerName = $env:computername,

        [Parameter(HelpMessage = 'Format the last boot up time as universal time')]
        [Alias('UTC')]
        [switch]$ToUniversal
    )

    Begin {
        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN  ] Starting $($MyInvocation.MyCommand)"
        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN  ] Running under PowerShell v$($PSVersionTable.PSVersion)"
    } #Begin
    Process {
        Try {
            Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Querying $($ComputerName.ToUpper()) for last boot up time"
            $os = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $ComputerName -ErrorAction Stop

            Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Last boot up time is $($os.LastBootUpTime)"
            $up = New-TimeSpan -Start $os.LastBootUpTime -End (Get-Date)

            if ($ToUniversal) {
                Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Converting last boot up time as UTC"
                $last = ($os.LastBootUpTime).ToUniversalTime()
            }
            else {
                $last = $os.LastBootUpTime
            }

            [PSCustomObject]@{
                ComputerName = $os.CSName
                LastBoot     = $last
                Uptime       = $up
            }
        } #Try
        Catch {
            Throw $_
        } #Catch
    } #Process
    End {
        Write-Verbose "[$((Get-Date).TimeOfDay) END    ] Ending $($MyInvocation.MyCommand)"
    } #End
} #close function

The function works fine with a single computer. This version of the function lets the user pass a computer name as a parameter value or from the pipeline.

PS C:\> Get-ComputerUptime -ComputerName srv1 

ComputerName LastBoot              Uptime
------------ --------              ------
SRV1         6/26/2023 12:58:20 PM 00:09:53.8649244

PS C:\> "dom1" | Get-ComputerUptime 

ComputerName LastBoot             Uptime
------------ --------             ------
DOM1         6/25/2023 9:44:43 PM 15:24:03.1188809
Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
Powered by Buttondown, the easiest way to start and grow your newsletter.