作者:陳計節
個人部落格:https://blog.jijiechen.com/post/powershell-remoting/
在 Linux/Unix 世界裡 SSH 是個好東西,SSH 是 Secure Shell 的縮寫,用它可以很容易連接配接到指定的伺服器,并執行特定指令行。除了支援遠端終端,作為一種安全的通信協定,還為很多其他工具的提供安全通信功能(比如 Git)。
在本文裡,SSH 主要指代的是基于 SSH 通信協定建構的安全終端連接配接。SSH 遠端連接配接用起來非常簡單,下面就是一個 ssh 的示例:

指定伺服器位址,即可開啟連接配接——簡單到難以置信!然後,接下來的指令就是在目标機器上運作了。工作完成了,要斷開連接配接?照常一個 exit 指令即可終止會話,就像關閉一個終端一樣容易!
由于 SSH 本身是基于指令行環境的,是以如果要在一批遠端伺服器上執行任務也很容易,寫一個 for 語句,很輕松就能完成:
于是,很多人發現,批量管理 Linux 伺服器很輕松,即使沒有那些功能大而全的工具,隻要有管理(使用)單台伺服器的經驗,再加上 ssh 就可以輕松管理一個叢集了。如果希望伺服器能夠通過遠端管理,就需要在伺服器上安裝配置 openssh-server 了。這在 Linux 上基本也隻是幾個指令也就輕松搞定了。一切都是如此美好!
Windows 世界的遠端管理
當類似的工作回到 Windows 上,人們首先想到的遠端管理的方式是遠端桌面連接配接,就是這個視窗:
遠端桌面連接配接(RDP)也是一個神器,隻要知道網絡位址(機器名稱),以及使用者名和密碼,就可以連接配接到任何一台 Windows 電腦上。連接配接建立之後,幾乎就像在操作本地電腦一樣地使用遠端電腦。 在實踐中我們發現,RDP 的表現相當不錯。即使在網絡不好的情況下,也能有良好的性能;遠端操作的不光是桌面,還有剪貼闆和音視訊等豐富的資源。另外,RDP 的用戶端也是很豐富,不但可以跨平台(包括 macOS、Linux 和手機平闆電腦等),還有很多能同時連接配接多個電腦的工具。下面是在 Mac 上連接配接 Windows 伺服器的效果:
基于 WinRM 的 PowerShell Remoting
既然 Windows 上的圖形界面無法提供批量的遠端管理能力,那麼指令行界面呢? 等一等,Windows 的指令行界面?Windows 有指令行界面嗎? 大概不少人會有這樣的疑問。答案不言自明,Windows 不光内置有指令行系統,而且很強大。隻是大部分人不怎麼用它而已。在早期,Windows 有指令提示符(cmd),後來 Windows 又添加了基于 .NET 的 PowerShell,大大強化了腳本化程式設計能力。
幸運的是,包括 PowerShell 的 Windows 的指令行體系提供了完善的遠端連接配接和批量執行的能力。與 SSH 類似,PowerShell Remoting 也隻需要知道伺服器位址,就可以輕松連接配接;而要結束會話,也是一樣的 exit 指令:
另外,PowerShell 中不少指令還專門為遠端執行提供了優化,比如 Invoke-Command 等。下面的代碼查詢兩台遠端計算機的界面語言(代碼引自文檔):
Invoke-Command -ComputerName Server01, Server02 -ScriptBlock { Get-UICulture }
輸出結果為:
LCID Name DisplayName PSComputerName
---- ---- ----------- --------------
1033 en-US English (United States) server01.corp.fabrikam.com
1033 en-US English (United States) server02.corp.fabrikam.com
PowerShell Remoting 是基于 Windows 内置的遠端管理技術 WinRM 提供的。如果希望 Windows 伺服器能夠通過遠端管理,需要在伺服器啟用 WinRM,并配置防火牆規則:
Enable-PSRemoting -SkipNetworkProfileCheck -Force
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -RemoteAddress Any
完成上述配置之後,用戶端使用 PowerShell 就可以使用 Enter-PSSession 等指令連接配接到伺服器上了。
配置無密碼 的 PowerShell Remoting 體驗
密碼是一種簡單直覺,卻不夠安全的身份鑒别方法。說它不夠安全,主要原因是對于叢集中的大量伺服器而言,如果要分别使用不同的密碼,那麼維護密碼表就成為一項麻煩事了。但如果都用相同的密碼,一旦密碼洩漏,整個叢集都陷入風險。是以不少人隻好選一個折衷,為叢集中的計算機使用統一密碼的同時,又定時(比如每兩個月)集中改一次密碼。進而在便利和安全之間取得平衡。但始終,密碼登入的方式是不夠安全的。 在登入伺服器時,SSH 支援使用密碼,還支援使用證書公鑰(public key)。證書公鑰登入的原理是,管理者生成一對密鑰,将公鑰複制到伺服器上,自己持有私鑰并保護好私鑰的内容。在需要連接配接伺服器時,将在用戶端用私鑰與伺服器進行一系列的登入驗證後,開啟安全的通信。由于公鑰的公開并不會導緻私鑰(private key)的安全風險,是以這種登入方式并不會有洩漏風險。
PowerShell Remoting 的服務端 WinRM 支援兩種無密碼登入的方式。一種是使用用戶端證書登入,身份驗證過程與 SSH 很類似。另外它還支援借助 Active Directory 環境進行集中式登入。 要為 WinRM 開啟用戶端證書登入(Client Certificate),主要步驟有: 在服務端為 WinRM 啟用 Client Certificate 登入功能 在服務端為 WinRM 啟用 HTTPS 支援,設定防火牆規則 在用戶端生成證書,并将證書的公鑰(public key)導入到伺服器上,并映射到指定的伺服器上的使用者 在用戶端将證書導入本地計算機 使用證書連接配接到伺服器 這些步驟并不複雜,卻也沒有像配置 SSH 服務端那麼簡單。是以我把這些腳本都寫好了,請轉到 GitHub 檢視和下載下傳。這裡有一篇文章詳細介紹了各步驟中要使用的指令。
除了基于 WinRM 的用戶端證書登入,新版本的跨平台 PowerShell 6 還支援基于 OpenSSH 直接提供與 Linux 伺服器上的 SSH 完全一緻的體驗。請轉到官方文檔了解具體配置方法,更多關于 PowerShell Remoting 的資料,還可以參考這本電子書。
在伺服器上啟用了 WinRM 之後,不光可以支援 PowerShell Remoting 功能,還能為 Windows 伺服器提供其他衆多遠端管理功能。比如,著名的自動化配置軟體 Ansible 就可以使用 PowerShell Remoting 一樣的方式來為 Windows 伺服器提供自動化配置能力,同時也很好地支援了上面介紹的用戶端證書登入。 事實證明,經過上述簡單的配置,也可以很輕松地對 Windows 伺服器進行批量的自動化管理了。
如果您覺得本文對你有用,不妨幫忙點個贊,或者在評論裡給我一句贊美。我們正在使用.NET Core / Azure / Xamarin等技術開發基于網際網路和移動應用平台上的各種新産品和商業服務。我們的目标是通過舉辦各種分享活動,交流開發心得和經驗來推動.NET技術棧在西安乃至西北地區的發展。我們是一個開發和自由的社群,歡迎您加入西安.NET社群,微信賬号:dotNetXA
歡迎您持續關注我的部落格
文章出處:.NET西安社群
版權所有,歡迎保留原文連結進行轉載:)