everydayPS_Instructional.psm1

FUNCTION Get-PipeByPart {
    <#
        .SYNOPSIS
        The intention of this script is merely to show the breakdown
        of a piped command as PowerShell processes it.
 
        .DESCRIPTION
        A piped command can be passed to the function, as a string,
        parsed into separate commands, and each segment then showing
        its results before being passed on to the next command.
 
        .EXAMPLE
        $WMISplat = @{
            ComputerName = "127.0.0.1", "192.168.2.60"
            Class = "Win32_BIOS"
            Property = "SMBIOSBIOSVersion", "Manufacturer", "Version"
            WarningAction = "SilentlyContinue"
            ErrorAction = "SilentlyContinue"
        }
        Get-PipeByPart -PipedCommand "Get-WMIObject @WMISplat |
            SELECT-Object SMBIOSBIOSVersion, Manufacturer |
            SORT SMBIOSBIOSVersion -Descending"
 
        The above command will first gather BIOS info from two computers.
        Next, it will SELECT-Objectonly 2 attributes or properties, the
        SN and Manufacturer.
        Finally, it will sort the results by SN.
 
        Notice, the piped commands need to be within overall quotes in
        order to be passed to Get-PipeByPart as a single parameter.
 
        .EXAMPLE
        Get-PipeByPart -PipedCommand "Get-Disk -Number '1' | FL"
 
        If you need to use quotes within the piped commands you're
        passing, you can use single quotes to include them inside
        your overall quotes.
 
        .EXAMPLE
        Get-PipeByPart -PipedCommand "Get-Disk -Number `"1`" | FL"
 
        If you need to use quotes within the piped commands you're
        passing, you can use tickmark double quotes (`") to include
        them inside your overall quotes.
 
        .EXAMPLE
        $myResult =
            Get-PipeByPart -PipedCommand "Get-Disk -Number `"1`" |
            FL" -returnResults
 
        Finally, if you need to save the individual results of the
        piping process, you can have them returned as show above,
        using the -returnResults switch.
 
        .PARAMETER PipedCommand
        PipedCommand is looking for the... piped command... you're
        looking to examine. Use the examples to see how to deal
        with quotes you want to include in your commands as
        outer-double-quotes will need to wrap this parameter.
 
        .PARAMETER returnResults
        returnResults will, instead of presenting the breakdown on
        the screen, return an array with columns for each command
        ($myResult.Command) and then the result ($myResult.Result).
 
        .LINK
        http://blog.everydaypowershell.com/2019/03/get-pipebypart.html
 
        .NOTES
        Mark Smith
        blog.everydayPowerShell.com
        Twitter: @edPowerShell
    #>


    #region Param + Checks
        [cmdletbinding(SupportsShouldProcess=$True)]
        param(
            [String]$PipedCommand,
            [Switch]$returnResults
        )
        $failure=$currentState=$null
        IF(!($PipedCommand)){
            $failure = -JOIN(
                "No piped command was provided. Please use ",
                "`"Get-Help Get-PipeByPart -Examples`" for ",
                "examples of how to use this function."
            )
            Write-Warning -Message $failure
            return
        }
        ELSEIF($PipedCommand -notlike "*`|*"){
            $failure = -JOIN(
                "You've included no actual piped (`"`|`") ",
                "commands. Please use `"Get-Help ",
                "Get-PipeByPart -Examples`" for examples of ",
                "how to use this function."
            )
            Write-Warning -Message $failure
            return
        }
    #endregion

    #region Parse And Prep
        [Array]$PipedCommand = ($PipedCommand).Split("|")
        $PipedCommand = $PipedCommand.Trim()
        $commandCount = $PipedCommand.Count
        $pipedCommandResults = @()
        Clear-Host
        Start-Sleep -Seconds 1
        $nowCount = 0
    #endregion

    #region Present Commands
        ForEach($currentCommand in $PipedCommand){
            $nowCount++
            $newRow = "" | SELECT-Object Command,Result
            $newRow.Command = [string]$currentCommand
            $newRow.Result = $null
            IF($nowCount -eq 1){
                $currentState =
                    [PSObject](
                        Invoke-Command -ScriptBlock (
                            [scriptblock]::Create($currentCommand)
                        )
                    )
                $newRow.Result = $currentState
            }
            ELSEIF($nowCount -eq $commandCount){
                $currentState =
                    $currentState |
                    Invoke-Command -ScriptBlock (
                        [scriptblock]::Create($currentCommand)
                    )
                $newRow.Result = $currentState
            }
            ELSE{
                $currentState =
                    $currentState |
                    Invoke-Command -ScriptBlock (
                        [scriptblock]::Create($currentCommand)
                    )
                $newRow.Result = $currentState
            }
            $pipedCommandResults += $newRow
        }
    #endregion
    IF($returnResults){
        return $pipedCommandResults
    }
    ELSE{
        $PipedCommandResults | ForEach-Object {
            Write-Verbose $_.Command -Verbose
            Write-Output $_.Result
        }
    }
}
Export-ModuleMember -Function Get-PipeByPart