如何在 powershell 远程会话(powershell)中编辑文件
Posted
技术标签:
【中文标题】如何在 powershell 远程会话(powershell)中编辑文件【英文标题】:how to edit a file in powershell remoting session (powershell) 【发布时间】:2011-03-26 20:32:15 【问题描述】:我正在使用 powershell 远程连接到另一台计算机,非常好。可以做很多事情,但是如何编辑文件?
PS C:\Users\guutlee> Enter-PSSession -ComputerName appprod
[appprod]: PS C:\Users\guutlee\Documents> cd \myapp
[appprod]: PS C:\myapp>
如何在远程机器上的文件上打开文件编辑器?
[appprod]: PS C:\myapp> 编辑 app.config
所以编辑“文件名”似乎挂起,来自 powershell.exe 或来自 powershell_ise.exe
我唯一能想到的就是退出 pssession 并“启动 \webprod\c$\inetpub\myapp\web.config”,这将打开 Visual Studio。
[appprod]: PS C:\myapp> 退出
PS C:\Users\guutlee> 开始\agobuild\c$\myapp\app.config
PS C:\Users\guutlee> Enter-PSSession -ComputerName appprod
[appprod]: PS C:\Users\guutlee\Documents> cd \myapp
[appprod]: PS C:\myapp> myapp.exe
当然,我必须重新找到该文件,希望 c$ 共享可用且可访问,并在我想继续时重新连接我的 pssession 并重新找到我的工作目录。看起来不是很优雅。
也许我可以把它包装成一个函数,但是我很难把它包装起来..
那么如何使用远程 pssession 方便地编辑文件?
编辑
kbrimington 的帖子让我想到了 ssh 的 -X 选项。对于 powershell 会话来说,能够将窗口应用程序转发回原始窗口环境可能是一件很棒的事情......
但我仍然很乐意编辑文件。
编辑
使用 vi、emacs、cmd 和编辑进行测试
PS C:\Users\Meredith> Enter-PSSession -ComputerName appprod
[appprod]: PS C:\Users\guutlee\Documents> C:\vim\vim72\vim filename.txt
[appprod]: PS C:\Users\guutlee\Documents> C:\emacs-23.2\bin\emacs.exe -nw filename.txt
emacs.exe : emacs: 标准输入不是 tty
+ CategoryInfo \: NotSpecified: (emacs: standard input is not a tty:String) [], RemoteException + FullyQualifiedErrorId \: NativeCommandError
[appprod]: PS C:\Users\guutlee\Documents> cmd
Microsoft Windows [版本 6.1.7600]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\guutlee\Documents>
[appprod]: PS C:\Users\guutlee\Documents> 编辑文件名.txt
vi 和编辑挂起(Control-C 得到提示)
cmd 运行,产生一个提示,但立即退出到 powershell 提示
emacs 产生错误(标准输入不是 tty)
编辑
Jered 建议将文件拉回本地进行编辑。我用 pssessions 而不是 UNCs 修饰了他对复制的回答(也许这就是他的意图)
PS C:\Users\Meredith> Invoke-Command -Session $ps -ScriptBlock get-content c:/inetpub/myapp/web.config > web.config
编辑网页配置
PS C:\Users\Meredith> 获取内容 web.config |调用命令 -Session $ps -ScriptBlock set-content c:/inetpub/myapp/web.config
可能我们可以在任一方向运行调用命令,本地到远程或远程返回本地。
【问题讨论】:
这并没有回答如何方便地编辑文件,而是对挂起行为的解释,所以我将作为评论发布。您的会话似乎挂起,因为远程会话不会为您虚拟化窗口应用程序;也就是说,如果您通过终端服务连接,您的编辑会话将在远程桌面中对您可见。 它在交互式控制台应用程序中也不能很好地工作。 【参考方案1】:如果您使用的是 Powershell 5,则可以使用名为 PSEdit 的命令。它仅适用于 ISE。
-
首先,打开 PowerShell ISE
然后使用 Enter-PSSession 打开与远程计算机的远程会话
然后使用 PsEdit 'filename' 编辑文件
远程文件将在您(本地)ISE 窗口的新选项卡中打开。
其实我是从this SO question 的 cmets 部分找到的这个答案,但我认为如果我将它作为答案发布在这里对其他人会有所帮助。
【讨论】:
【参考方案2】:你不能在本地拉文件,编辑它并发布它吗?我知道这很乏味而且不优雅,但编辑们目前似乎遇到了远程会话问题。
例如,
Get-Content REMOTE\Filename.txt > LOCAL\Filename.txt
在本地进行更改,然后
Set-Content -path REMOTE\Filename.txt -value (get-content LOCAL\Filename.txt)
编辑
此外,如果您只替换某些实例,您可以很容易地做到这一点。
例如,
Get-Content REMOTE\Filename.txt | foreach-object $_ -replace "OLD", "NEW" | Set-Content REMOTE\Filename.txt
【讨论】:
一个很好的替代我最初在远程共享上打开本地编辑器的想法。但它通过使用复制到本地共享,然后再次使用本地编辑器和复制回原始位置来反转依赖关系。我真的很想失去对文件共享的依赖,这样我就可以只公开 winrm 而不能公开任何其他服务。 你在做什么编辑?它遵循一个模式吗? 我猜主要是临时的;可能会在 html 文件中添加一段文本;可能会更新网络应用程序中的连接字符串;可能会更改 powershell 脚本以添加一些功能。 只有当您在 Get-Content 周围加上括号以确保文件在写入时不会被它打开时,编辑才会起作用。查看帮助(示例 3)Technet Set-Content【参考方案3】:经过大量挖掘,我在 powershell 帮助文档中发现了一些似乎相关的内容。在 powershell 提示符下,键入:
帮助关于_remote_troubleshooting
在显示的帮助文件的最后,有一个标题为“故障排除无响应行为”的部分,其中指出:
对反应迟钝的行为进行故障排除
本节讨论阻止命令执行的远程处理问题 完成并阻止或延迟 Windows PowerShell 的返回 提示。
如何中断命令
一些本地 Windows 程序,例如带有用户界面的程序, 提示输入的控制台应用程序和控制台 使用 Win32 控制台 API 的应用程序无法运行 在 Windows PowerShell 远程主机中正确。
当您使用这些程序时,您可能会看到意外的行为,例如 作为无输出、部分输出或不输出的远程命令 完全的。要结束无响应的程序,请键入 CTRL + C。要查看任何 可能已报告的错误,请在 本地主机和远程会话。
因此,不幸的是,即使是非 GUI 控制台应用程序(如 VIM)也无法运行。任何人 小心阐明为什么会出现这种情况和/或是否可以工作 大约?如果我可以使用 vim 而不是 powershell 远程处理,我会非常喜欢它。
【讨论】:
我可以解释为什么:Windows 上的控制台 IO 更接近于在设备上执行 ioctls(带外信号),而不是流控制代码。在msdn.microsoft.com/en-us/library/windows/desktop/… 中查看 API 的结构。将此与诸如 VT100 仿真之类的工作方式(带内嵌入转义序列)进行对比。 PowerShell 在 I/O 的流式基础上运行,而不是在控制台上运行。【参考方案4】:PowerShell_ISE.exe \\REMOTE\...\File.txt
将直接加载和编辑文件,然后一步将其保存回远程计算机,并且由于它的命令行,使用它可以轻松构建功能。无法解决共享问题,但我找到了最简单的方法。
【讨论】:
【参考方案5】:首先,在本地计算机上创建一个临时文件夹 (LOCALTEMPFOLDER)。然后,使用以下函数:
function vimrem param([parameter(position=0,mandatory=$true)][string]$Session, [parameter(position=1,mandatory=$true)][string]$Path)
$TempFile = split-path -path $Path -leaf
copy-item -fromsession $Session -path $Path -destination LOCALTEMPFOLDER\$TempFile
vim $LOCALTEMPFOLDER\$TempFile
copy-item -tosession $Session -path LOCALTEMPFOLDER\$TempFile -destination $Path
remove-item -path LOCALTEMPFOLDER\$TempFile
这应该可以,但在使用此功能之前,您必须先离开一个交互式会话。
【讨论】:
您无需在回答前陈述示例问题。只是答案和任何随附的解释。【参考方案6】:尝试使用基于控制台的编辑器,例如 VI 或 Emacs。在我的评论中,我认为问题在于编辑命令绑定到一个窗口应用程序,而该窗口应用程序又没有跨远程会话进行虚拟化。
【讨论】:
我相信edit.com 是控制台编辑器,而不是窗口应用程序。我确实安装了 emacs,(好吧,我已经安装了 emacs,试图用 powershell 摆脱我的 UNIX 根目录 :))。这是输出 > [appprod]: PS C:\emacs-23.2> .\bin\emacs.exe -nw .\README.W32 > emacs.exe : emacs: 标准输入不是 tty > + CategoryInfo : NotSpecified: (emacs: 标准输入不是 tty:String) [ > ], RemoteException > + FullyQualifiedErrorId : NativeCommandError 无赖。 VI 能带你到任何地方吗?我可以从远程会话运行cmd
,所以我可能过于乐观地认为其他控制台应用程序也能正常工作。
我从远程会话运行 cmd,它运行了,但立即退出到 powershell。这是您看到的不同行为吗?我试过vi,它就像编辑一样挂起。我的测试总结在上面。
我很确定,但我应该回办公室检查一下。我似乎记得在控制我的 SharePoint 服务器时在远程会话中使用 cmd。
顺便说一句,您可能希望 c$ 共享可以访问,因为它只对管理员可用,并且您必须是管理员才能使用远程处理。这并不能解决通过远程会话进行编辑的问题,但可能会增加您可以依赖本地会话中的编辑器的信心。【参考方案7】:
我尝试了上述所有建议,甚至其他与微软相关的解决方案,但没有一个能像你和我想要的那样工作——“完全交互式和响应式外壳”——。如果你真的想拥有 unix 用户从一开始就拥有的 ssh 体验,我建议你安装一个 ssh 服务器。我个人使用 freesshd,你可以在这里找到它 http://www.freesshd.com 和如何配置它的说明在这里 http://www.windowsnetworking.com/articles_tutorials/install-SSH-Server-Windows-Server-2008.html。在完成说明中所说的所有内容后,您只需使用任何 ssh 客户端应用程序连接到您的计算机并使用 powershell 完全交互。 Vim、edit、emacs 或用于编辑文件的任何工具都可以正常工作。
我鼓励你不要把时间浪费在 psremoting、telnet、winrs、psexec 上,试图实现真正的交互式 shell 提供的功能(我已经失去了它,T_T)。自己试试那个 ssh 服务器。
【讨论】:
Powershell 会话被设计为无状态的,它们从来都不是“完全交互式和响应式的 shell”。 *nix shell 和 powershell 有优点,而这恰好是缺点之一。也就是说,有一些很好的建议来解决它。【参考方案8】:受@chenz 提供的答案的启发,这也可以在 Powershell Integrated Shell 中使用 Visual Studio Code 完成。我在 SSH 远程处理上使用 Powershell 7 进行了尝试,但也应该与 WinRM 远程处理一起使用。
Enter-Session ...
[RemoteSystem] PS> psedit service.log
文件名将遵循以下模式:
C:\users\dev\appdata\local\temp\2\pses-15960\remotefiles\1702137071\winboxname\service.log
【讨论】:
【参考方案9】:我让 nano 通过 SSH 到 PowerShell 轻松工作。它在 Chocolatey 中可用,所以你可以这样做......
choco install nano -y
那你就可以了……
nano filename
【讨论】:
【参考方案10】:考虑到 PSRemoting 的局限性以及可能的变通方法或解决方案,我一直在非常彻底地研究这个问题。
控制台编辑器不起作用,因为它们是本机 (exe) 命令并且是基于字符的。 (我想知道 cmd over ssh 是否可以与这些一起使用)它需要是一个 cmdlet 才能通过 psremote 会话与控制台主机正确交互。
PSRemote 会话是基于行的。您在本地编辑该行 push enter 然后将其发送到远程端,执行命令并返回结果。所以它确实支持行交互,但不支持字符交互。
鉴于所有这些限制,GNU 的 ed 似乎是一个完美的选择。我很惊讶没有人考虑将它作为一个 cmdlet 来实现。
我决定对此进行进一步调查,我检查了 powershell cmdlet read-host
是否有效,然后 C# 等效项 PSHostUserInterface.ReadLine()
在 PSRemote 会话中工作,它们确实如此,这是制作工作行编辑器所需的全部内容。
这就是我到目前为止所做的。我可能会在更奇特的正则表达式代码上使用一些帮助。
https://github.com/silicontrip/ps-ed
我使用它通过 psremote 会话编辑文件。 (我不会用它来编辑大型源文件,但对于奇怪的小配置文件或 ps1 脚本来说,它是完美的。)
在使用此 cmdlet 之前,请确保您熟悉 GNU ED。这就像第一次尝试使用 VI,否则。
【讨论】:
以上是关于如何在 powershell 远程会话(powershell)中编辑文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在powershell的任务调度程序中设置触发器“连接到用户会话”?