Returning custom objects in PowerShell, simplified

I’ve stumbled upon this simplified technique to return custom objects in my PowerShell functions.

My first take on it was this, but I’ve simplified it. In this simplified variation, you just create and return the object in the same hash. For example:

[PsCustomObject]@{
    ComputerName = $ComputerSystem.DNSHostName;
    Domain = $ComputerSystem.Domain;
    ProcessCount = $ProcessCount;
    }

This is a hash, as you probably have seen before, but the [PsCustomObject] is what makes it a custom object.

And in context of a function:

# Example Function
function Get-SystemInfo {

    # Prepare the info
    $OS = Get-CimInstance -ClassName Win32_OperatingSystem # for FreePhysicalMemory, Caption, PSComputerName, SystemDrive
    $LoadPercentage = (Get-CimInstance -ClassName Win32_Processor).LoadPercentage
    $ProcessCount = (Get-Process).Count
    $SystemDrive = Get-CimInstance -ClassName Win32_LogicalDisk -filter "Name = '$($OS.SystemDrive)'" 
    $ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem

    # Return the properties in a custom object
    [PsCustomObject]@{
        ComputerName = $ComputerSystem.DNSHostName;
        Domain = $ComputerSystem.Domain;
        FreePhysicalMemory = "{0:n0}" -f ($OS.FreePhysicalMemory /1KB) + " MB";
        OS = $OS.Caption;
        LastBootUpTime = $OS.LastBootUpTime;
        LoadPercentage = $LoadPercentage;
        ProcessCount = $ProcessCount;
        SysVolFree = "{0:n1}" -f ($SystemDrive.FreeSpace /1GB) + " GB"
        }
     
    }

# Example Usage

# Using the results, put them into an object "$Result"
$Result = Get-SystemInfo

# Access the values inside the object
$Result.LastBootUpTime

Get-Subnet, a PowerShell advanced function

I wrote a PowerShell advanced function “Get-Subnet” to return a subnet mask for a given bit or bit range.

The cmdlet, with embedded help, including examples:

<#
.Synopsis
   Returns a subnet mask for a given bit or bit range.
.DESCRIPTION
   For a given number of bits, or range of bits, returns the equivilant subnet mask(s) and number of available hosts in that subnet.
   Returns NetworkBits, SubnetMask, NumberOfHosts for each bit.
   NetworkBits is provided for completeness, in the case of multiple objects returned. 
   SubnetMask string is useful for situations where you know network bits and want to set a subnet mask on a network card. 
   NumberOfHosts is useful for understanding implications of using a selected number of bits.
.EXAMPLE
   PS C:\>Get-Subnet

Returns:
>   NetworkBits SubnetMask      NumberOfHosts
>   ----------- ----------      -------------
>             8 255.0.0.0            16777214
>             9 255.128.0.0           8388606
>            10 255.192.0.0           4194302
>            11 255.224.0.0           2097150
>            12 255.240.0.0           1048574
>            13 255.248.0.0            524286
>            14 255.252.0.0            262142
>            15 255.254.0.0            131070
>            16 255.255.0.0             65534
>            17 255.255.128.0           32766
>            18 255.255.192.0           16382
>            19 255.255.224.0            8190
>            20 255.255.240.0            4094
>            21 255.255.248.0            2046
>            22 255.255.252.0            1022
>            23 255.255.254.0             510
>            24 255.255.255.0             254
>            25 255.255.255.128           126
>            26 255.255.255.192            62
>            27 255.255.255.224            30
>            28 255.255.255.240            14
>            29 255.255.255.248             6
>            30 255.255.255.252             2

   With no parameters, the command lists subnet masks for bit range 8 to 30.
.EXAMPLE
   PS C:\>Get-Subnet -MinBits 20 -MaxBits 24

Returns:
>   NetworkBits SubnetMask    NumberOfHosts
>   ----------- ----------    -------------
>            20 255.255.240.0          4094
>            21 255.255.248.0          2046
>            22 255.255.252.0          1022
>            23 255.255.254.0           510
>            24 255.255.255.0           254
   
   Return a specific range of subnet masks.
.EXAMPLE
   PS C:\>$a = (Get-Subnet -Bits 20).SubnetMask
   PS C:\>Write-Host "20 bit Subnet mask is $a"

   Returns:
>  20 bit Subnet mask is 255.255.240.0

   Store a specific subnet mask to a variable.
#>

function Get-Subnet

{
              [CmdletBinding(DefaultParameterSetName='Parameter Set 1')]
              Param
              (
                [Parameter(ParameterSetName='Parameter Set 1')]
                $Bits,
          
                [Parameter(ParameterSetName='Parameter Set 2')]
                $MinBits,

                [Parameter(ParameterSetName='Parameter Set 2')]
                $MaxBits

              )
    if ($Bits -ne $null) {
        $MinBits = $Bits
        $MaxBits = $Bits
        }
        else {
            if ($MinBits -eq $null) {
                $MinBits = 8
                }
            if ($MaxBits -eq $null) {
                $MaxBits = 30
                }
            }

    foreach ($i in ($MinBits..$MaxBits)) 
    {
        $binary = ([string]"1" * $i).PadRight(32,"0")

        $InvertedBinary = ([string]"0" * $i).PadRight(32,"1")

        $NumberOfHosts = [convert]::ToInt32($InvertedBinary,2) -1 

        $Oct1 = [string][convert]::ToInt32($binary.Substring(0,8),2)
        $Oct2 = [string][convert]::ToInt32($binary.Substring(8,8),2)
        $Oct3 = [string][convert]::ToInt32($binary.Substring(16,8),2)
        $Oct4 = [string][convert]::ToInt32($binary.Substring(24,8),2)

        $SubnetMask = $Oct1 + "." + $Oct2 + "." + $Oct3 + "." + $Oct4

        [PsCustomObject]@{
            "NetworkBits" = $i; 
            "SubnetMask" = $SubnetMask; 
            "NumberOfHosts" = $NumberOfHosts
            }
        } 

}