'Pipe output to the clipboard using PowerShell

EDIT: 23 Oct 2020

See postanote's answer.

EDIT: 14 May 2015

After 3 years, I thought I would share my ClipboardModule (I hope I am allowed to):

Add-Type -AssemblyName System.Windows.Forms

Function Get-Clipboard {
    param([switch]$SplitLines)

    $text = [Windows.Forms.Clipboard]::GetText();
    
    if ($SplitLines) {
        $xs = $text -split [Environment]::NewLine
        if ($xs.Length -gt 1 -and -not($xs[-1])) {
            $xs[0..($xs.Length - 2)]
        } else {
            $xs
        }
    } else {
        $text
    }
}

function Set-Clipboard {
    $in = @($input)

    $out = 
        if ($in.Length -eq 1 -and $in[0] -is [string]) { $in[0] }
        else { $in | Out-String }
    
    if ($out) {
        [Windows.Forms.Clipboard]::SetText($out);
    } else {
        # input is nothing, therefore clear the clipboard
        [Windows.Forms.Clipboard]::Clear();
    }
}


function GetSet-Clipboard {
    param([switch]$SplitLines, [Parameter(ValueFromPipeLine=$true)]$ObjectSet)

    if ($input) {
        $ObjectSet = $input;
    }

    if ($ObjectSet) {
        $ObjectSet | Set-Clipboard
    } else {
        Get-Clipboard -SplitLines:$SplitLines
    }
}

Set-Alias cb GetSet-Clipboard

Export-ModuleMember -Function *-* -Alias *

I usually use the cb alias (for GetSet-Clipboard) because it is two way i.e can get or set the clipboard:

cb                # gets the contents of the clipboard
"john" | cb       # sets the clipboard to "john"
cb -s             # gets the clipboard and splits it into lines


Solution 1:[1]

If you have WMF 5.0, PowerShell contains two new cmdlets:

get-clipboard and set-clipboard

Solution 2:[2]

EDIT: Please look at question instead for solution.

Here is my solution:

Add-Type -AssemblyName 'System.Windows.Forms'

filter Set-Clipboard {
    begin {
        $cp = @()
    }
    process {
        $_ | Tee-Object -Variable 'cp0'
        $cp = $cp + @($cp0);
    }
    end {
        $str = ($cp | Out-String).ToString();

        [Windows.Forms.Clipboard]::Clear();

        if ( ($str -ne $null) -and ($str -ne '') ) {
            [Windows.Forms.Clipboard]::SetText( $str )
        }

        $cp = @()
    }
}

This collects all the objects in an array, $cp. We use Tee-Object to redirect the current element, $_, to both the next process and to store it in the array, $cp. Lastly, once the process is finished we set the clipboard's text.

I have used it in the following way:

dir -Recurse | Set-Clipboard | Select 'Name'

And it seems to work.

To use a function instead:

function Set-Clipboard-Func {
    $str = $input | Out-String

    [Windows.Forms.Clipboard]::Clear();

    if ( ($str -ne $null) -and ($str -ne '') ) {
        [Windows.Forms.Clipboard]::SetText( $str )
    }
}

Solution 3:[3]

Powershell version 6.1 removed this commandlet, so it is no longer built-in.

Instead, you need to install the ClipboardText package. In Powershell's console type:

Install-Module -Name ClipboardText

Then you can use:

 Set-ClipboardText "hello clipboard"
 Get-ClipboardText

Here is the github issue with the maintainers of Powershell redirecting you to use the ClipboardText package.

Solution 4:[4]

get-clipboard

skips newline characters when text is entered sequentially. I use

[System.Windows.Forms.Clipboard]::GetText()

as before.

Solution 5:[5]

Now that Get-clipboard and Set-Clipboard are built in PSv7 You can have this function in your profile: "C:\Users<USER_ID>\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1"

function To-Notepad {
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [object]
        $InputObject
    )
  begin   { $objs = @() }
  process { $objs += $InputObject }
  end {
        $old = Get-clipboard # store current value
        $objs | out-string -width 1000 | Set-Clipboard
        & "notepad2" /c
        sleep -mil 500
        $old | Set-Clipboard # restore the original value
  }
}

And then use in this way:

dir -Path C:\Temp | To-Notepad

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mark Minasi
Solution 2
Solution 3
Solution 4 Garric
Solution 5 Youssef Bouha