当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 星期五乐趣:捕获命令

作者:精品下载站 日期:2024-12-14 07:47:01 浏览:14 分类:玩电脑

PowerShell 星期五乐趣:捕获命令


这周的周五欢乐实际上是有目的的,至少对我来说是这样。但我始终希望您能学到一两个可以在自己的 PowerShell 工作中使用的技巧。

因为我写了很多有关 PowerShell 的文章,所以我经常在 PowerShell 会话和 Microsoft Word 之间进行复制粘贴。尽管当我为我的函数编写帮助示例时也是如此。我可以用这个技巧将命令输出保存到剪贴板:


Get-service | Group Status | clip

但我永远不知道命令是否成功,直到我粘贴然后我需要再次复制命令。多年来,我想出了许多工具来使这个过程变得更容易,但现在我想我终于拥有了它。

我的新命令称为 Out-Copy。它旨在接受任何 PowerShell 命令。该函数本质上会将结果传递回管道,因此在这方面它类似于 Tee-Object。它还将输出的副本发送到剪贴板。但等等还有更多!剪贴板输出将包括提示和您运行的命令。

在 PowerShell 提示符下,我可以运行如下命令:

[玩转系统] PowerShell 星期五乐趣:捕获命令

然后我可以粘贴到另一个应用程序中

[玩转系统] PowerShell 星期五乐趣:捕获命令

我还添加了一个参数,仅将命令复制到剪贴板。该命令按预期运行:

[玩转系统] PowerShell 星期五乐趣:捕获命令

得到这个结果:

[玩转系统] PowerShell 星期五乐趣:捕获命令

我的函数的这个版本只会复制发送到成功管道的内容。它不会捕获来自其他流的任何内容,例如详细、警告或错误。通常我都会做屏幕截图。但这可能是我稍后会研究的事情。

这是包含别名的完整函数。


#requires -version 4.0

Function Out-Copy {

<#
.Synopsis
Send command output to the pipeline and Windows clipboard.
.Description
This command is intended for writers and those who need to document with PowerShell. You can pipe any command to this function and you will get the regular output in your PowerShell session. But a copy of the output will be copied to the Windows clipboard. Additionally, the copy will include your prompt and the command that you executed, without the Out-Copy portion.

NOTE: You can only capture what is written to the Success pipeline. This command will not copy any other streams such as Verbose or Error.
.Parameter CommandOnly
Only copy the executed command, without references to Out-Copy, to the Windows clipboard.
.Parameter Width
Specifies the number of characters in each line of output. Any additional characters are truncated, not wrapped.
.Example
PS C:\> Get-Process | Sort WS -Descending | Select -first 5 | out-copy

This will execute your expression and write the output to the pipeline. In addition this text will be copied to the Windows clipboard:

PS C:\> Get-Process | Sort WS -Descending | Select -first 5

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1242 133 1047776 1002596 1987 4,499.78 1416 waterfox
1182 101 438800 409020 1285 854.53 6528 powershell_ise
321 22 245568 202236 362 730.05 2484 ZeroConfigService
1314 177 229772 187324 792 ...70.95 6500 SugarSync
651 37 199160 162216 343 597.16 1052 svchost

.Example
PS C:\scripts> dir *.ps1 | out-file c:\work\ps.txt

Even if your command doesn't write anything to the pipeline, Out-Copy will still capture your prompt and PowerShell expression.
.Example
PS C:\> gcim win32_logicaldisk -filter "drivetype = 3" | out-copy -commandonly

This will run the Get-CimInstance command and write results to the pipeline. But the only text that will be copied to the clipboard is:

gcim win32_logicaldisk -filter "drivetype = 3"

.Notes
Last Updated: 30 October 2015
Version : 1.0

Learn more about PowerShell:
Essential PowerShell Learning Resources

****************************************************************
* DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
* THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF *
* YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
* DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. *
****************************************************************
.Link
Out-String
.Inputs
[object]
.Outputs
[object]

#>

[cmdletbinding()]
Param(
[Parameter(Mandatory,ValueFromPipeline)]
[object]$InputObject,
[ValidateNotNullorEmpty()]
[int]$Width = 80,
[switch]$CommandOnly
)

Begin {
Write-Verbose "Starting: $($MyInvocation.Mycommand)"
Write-Verbose "Adding necessary .NET assembly"
Add-Type -AssemblyName system.windows.forms

#initialize an array to hold all incoming data
$Data = @()
} #begin

Process {
#add each input to the array
$data += $InputObject

} #process

End {
Write-Verbose "In the End block"

#write data to the pipeline
Write-Verbose "Here is the PowerShell output"
$data

Write-Verbose "Getting the currently running command"
$Invoked = $MyInvocation.Line
#parse out the Out-Copy command
$cmd = $Invoked.substring(0,$invoked.LastIndexOf("|"))
if ($CommandOnly) {
Write-Verbose "Copying command expression"
$Text = $cmd
}
else {
#convert data to text
Write-Verbose "Getting current prompt"
$text = "$((Prompt | Out-String).Trim()) "
$text += $cmd
#insert a blank line
$text += "`n"
Write-Verbose "Converting data to text"
#using a regular expression to try and clean up the output
$text += ($data | Out-String -Width $Width) -replace "(?<=\S*)\s+`r`n$","`r`n"
}

Write-Verbose "Copy text to the clipboard"
[System.Windows.Forms.Clipboard]::SetText( $text,[System.Windows.Forms.TextDataFormat]::Text)
Write-Verbose "Ending: $($MyInvocation.Mycommand)"
} #end

}

#define an alias
Set-Alias -Name oc -Value Out-Copy

唯一的其他参数是宽度。我为其指定了默认值 80,该值在粘贴到 Word 或文本文档时效果最佳。您可以对此进行调整,通常最多可达 PowerShell 主机的宽度。超出的任何内容都会被截断。

我花了几个小时来完善它,但从现在开始它会节省我的时间和挫败感,也许你需要使用它。另外,当我使用它时,它会让我脸上露出笑容,因为我感觉自己在表演魔术。

享受!

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯