Chapters/final-exam/Prototype.ps1

function Get-TMLocalGroup {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)]
        [string[]]$ComputerName,

        [string]$LogFailedNamesToPath
    )

    BEGIN {}

    PROCESS {
        ForEach ($comp in $ComputerName) {

            Try {
                Write-Verbose "Connecting to $comp"
                $s = New-PSSession -ComputerName $comp -EA Stop
                
                Write-Verbose " Querying groups"
                $groups = Invoke-Command -Script { Get-LocalGroup | Select -Expand Name } `
                                         -Session $s

                Write-Verbose " Enumerating members..."
                ForEach ($group in $groups) {
                    Write-Verbose " $group"
                    $users = Invoke-Command -Script { Get-LocalGroupMember -Group $using:group | Select -Expand Name } `
                                            -Session $s 

                    ForEach ($user in $users) {
                        $components = $user -split '\\'
                        $props = @{'ComputerName'=$comp
                                   'GroupName'=$group
                                   'UserName'=$components[-1]}
                        New-Object -TypeName PSObject -Prop $props
                    } #foreach user
                } #foreach group

                Write-Verbose "Closing connection to $comp"
                $s | Remove-PSSession

            } Catch {
                Write-Warning "Failed connecting to $comp"

                if ($PSBoundParameters.ContainsKey('LogFailedNamesToPath')) {
                    $comp | Out-File $LogFailedNamesToPath
                }
            } #try

        } #foreach computer
    } #PROCESS

    END {}
} #function

Get-TMLocalGroup -ComputerName localhost