Chapters/converting-a-function-to-a-class/TMMachineInfo/TMMachineInfo.psm1

#Requires -version 5.0

class ToolmakingMachineInfo {

    # Properties
    [string]$ComputerName
    [string]$OSVersion
    [string]$SPVersion
    [string]$OSBuild
    [string]$Manufacturer
    [string]$Model
    [string]$Procs
    [string]$Cores
    [string]$RAM
    [string]$SysDriveFreeSpace
    [string]$Arch
    hidden [string]$Protocol

    # Constructors
    ToolmakingMachineInfo([string]$ComputerName, [string]$Protocol) {
        $this.ComputerName = $ComputerName
        $this.Protocol = $Protocol
        $this.Refresh()
    }

    Refresh() {
        if ($this.protocol -eq 'Dcom') {
            $option = New-CimSessionOption -Protocol Dcom
        } else {
            $option = New-CimSessionOption -Protocol Wsman
        }
 
        Try {
            $params = @{'ComputerName'=$this.Computername
                        'SessionOption'=$option
                        'ErrorAction'='Stop'}
            $session = New-CimSession @params
  
            $os_params = @{'ClassName'='Win32_OperatingSystem'
                           'CimSession'=$session}
            $os = Get-CimInstance @os_params

            $cs_params = @{'ClassName'='Win32_ComputerSystem'
                           'CimSession'=$session}
            $cs = Get-CimInstance @cs_params

            $sysdrive = $os.SystemDrive
            $drive_params = @{'ClassName'='Win32_LogicalDisk'
                              'Filter'="DeviceId='$sysdrive'"
                              'CimSession'=$session}
            $drive = Get-CimInstance @drive_params

            $proc_params = @{'ClassName'='Win32_Processor'
                             'CimSession'=$session}
            $proc = Get-CimInstance @proc_params |
                    Select-Object -first 1

            $session | Remove-CimSession
  
            $this.OSVersion=$os.version
            $this.SPVersion=$os.servicepackmajorversion
            $this.OSBuild=$os.buildnumber
            $this.Manufacturer=$cs.manufacturer
            $this.Model=$cs.model
            $this.Procs=$cs.numberofprocessors
            $this.Cores=$cs.numberoflogicalprocessors
            $this.RAM=($cs.totalphysicalmemory / 1GB)
            $this.Arch=$proc.addresswidth
            $this.SysDriveFreeSpace=$drive.freespace

        } Catch {
            throw "Failed to connect to $this.computername on $this.protocol"
        } #try/catch
    }

} #class

Function Get-MachineInfo {
[cmdletbinding()]
Param(
[Parameter(Position = 0,ValueFromPipeline)]
[Alias("cn")]
[ValidateNotNullorEmpty()]
[string[]]$Computername = $env:COMPUTERNAME,

[ValidateSet("dcom","wsman")]
[string]$Protocol = "wsman"

)

Begin {
    Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"  
} #begin

Process {
    foreach ($computer in $computername) {
        Write-Verbose "[PROCESS] Getting machine information from $($computer.toUpper())"
        New-Object -TypeName ToolMakingMachineInfo -ArgumentList $computer,$protocol

    }

} #process

End {
    Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"
} #end

}

Function Update-MachineInfo {
[cmdletbinding()]
Param(
[Parameter(Position = 0, ValueFromPipeline)]
[ValidateNotNullorEmpty()]
[ToolmakingMachineInfo]$Info,
[switch]$Passthru
)

Begin {
    Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"  
} #begin


Process {
    Write-Verbose "[PROCESS] Refreshing: $(($Info.ComputerName).ToUpper())"
    $info.Refresh()

    if ($Passthru) {
        #write the updated object back to the pipeline
        $info
    }

} #process

End {
    Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"
} #end
}

#define command aliases
Set-Alias -Name gmi -Value Get-MachineInfo
Set-Alias -Name umi -Value Update-MachineInfo