0

I am trying to repeat *nix watch functionality as provided by johnrizzo1 here.

function Watch {
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='High')]
    param (
        [Parameter(Mandatory=$False,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)]
        [int]$n = 10,

        [Parameter(Mandatory=$True,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)]
        [string]$command
    )
    process {
        $cmd = [scriptblock]::Create($command);
        While($True) {
            Clear-Host;
            Write-Host "Command: " $command;
            $cmd.Invoke();
            sleep $n;
        }
    }
}

Export-ModuleMember -function Watch

watch -n 1 '$PSVersionTable.PSVersion'

The problem is that only 1st run displays headers. After that is looks ugly as headers are being stripped from output:

Command:  $PSVersionTable.PSVersion                                     
5      0      10586  117

By the way all other PS solutions to watch in the link above suffer from the same problem.

Community
  • 1
  • 1
Anton Krouglov
  • 3,077
  • 2
  • 29
  • 50

2 Answers2

1

This will work now, but your output is forced to be piped to Format-Table so it will always be in Table format.

function Watch {
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='High')]
    param (
        [Parameter(Mandatory=$False,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)]
        [int]$n = 10,

        [Parameter(Mandatory=$True,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)]
        [string]$command
    )
    process {
        $cmd = [scriptblock]::Create($command)
        While($True) {
            Clear-Host
            Write-Host "Command: " $command
            $cmd.Invoke() | Format-Table -HideTableHeaders:$false
            sleep $n
        }
    }
}

watch -n 1 '$PSVersionTable.PSVersion'
Shawn Esterman
  • 2,292
  • 1
  • 10
  • 15
1

Most likely this has other issues but simply changing

$cmd.invoke();

to

$cmd.invoke() | ft;

works for me

Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
  • So there should be `ft` either inside ScriptBlock (as Shawn Esterman suggested) or in the `watch` code. This solution is acceptable but does not look nice for me. – Anton Krouglov Aug 16 '16 at 15:51
  • 1
    Shawn changed his answer to the same as this one. He should re-add his original solution to his answer. – Lieven Keersmaekers Aug 16 '16 at 17:47