如何建立 PowerShell 工具來設定 SFTP
當您使用多台運行 Windows 的電腦時,可能需要透過不同的通訊協定來存取共用資源。在 Windows 電腦上建立檔案分享時,通常會使用 SMB 通訊協定。然而,在非 Windows 電腦上,則可透過 NFS、FTP、SFTP、FTPS、SCP 及其他通訊協定來共用檔案。 舉例來說,若您僅在未安裝圖形介面的 Windows Server 上使用 PowerShell,首次連線至 SFTP 共用資料夾可能會顯得有些困難。這篇部落格文章將說明如何在 Windows 中透過 PowerShell 使用 SFTP。
什麼是 SFTP?
SFTP 代表 SSH 檔案傳輸協定(Secure File Transfer Protocol)。SFTP 是傳統檔案傳輸協定(FTP)的安全替代方案,具備類似的功能性。SFTP 運作於 OSI 模型的應用層(第 7 層),使用 SSH 連線,並在 Linux 系統上特別普及,因為這些系統通常內建了命令列 SFTP 客戶端。 若您使用 Windows,請安裝免費的 SSH 客戶端(例如 WinSCP),該軟體具備圖形化介面且支援 SFTP 以外的功能;若需使用命令列,則可設定 PowerShell 工具。由於 Windows 和 PowerShell 本身不支援 SFTP,因此需要安裝額外的元件。
使用 SSH 連線時,網路上的資料傳輸會經過加密,連線也更為安全,這與傳統未加密的 FTP 協定不同,後者中的資料可能被攻擊者攔截。SSH 用於身份驗證,如果您擁有 Linux 使用者憑證,即可透過命令列 SFTP 客戶端或圖形化介面客戶端通過驗證後,存取目標 Linux 機器上的檔案。 它還允許您將檔案從遠端 Linux 機器複製到本地 Linux 或 Windows 機器,或反之亦然。在 Linux 上配置 SFTP 伺服器並不困難——您只需安裝 SSH 伺服器、建立使用者,並為使用者及檔案/目錄授予必要的權限。
請勿將 SFTP 與 FTPS 混淆。這兩種協定用於類似的目的。 然而,SFTP 僅使用一個連接埠號進行連線,而 FTPS 則需使用多個連接埠號分別處理控制通道與資料通道(從安全性角度考量,包括防火牆設定在內,這可能更難配置)。FTPS 即是採用 SSL(安全通訊端層)的 FTP。本文不會深入探討如何設定 SFTP 伺服器。關於在 Hyper-V 上安裝與設定 Linux(包含 SSH 伺服器)的相關內容,請參閱 這裡.
安裝 Posh-SSH 模組
若要在 PowerShell 中透過 SFTP 和 SCP 對遠端電腦的檔案執行操作(例如複製或刪除檔案),您必須在 PowerShell 中安裝 Posh-SSH 模組。安裝此模組後,您還可透過 SSH 連線在遠端電腦上執行遠端指令。 安裝和使用 Posh-SSH 需要 PowerShell 3.0 及 .NET Framework 4.0。因此,您可以在 Windows 8 或更新版本的 Windows 系統上安裝此模組。您也可以在 Windows 7 SP1 上手動更新 PowerShell 和 .NET Framework。執行以下指令以安裝 PowerShell SFTP 模組 (Posh-SSH):
install-module posh-ssh
此外,您也可以使用以下指令安裝 PowerShell 的 Posh-SSH 模組:
iex (New-Object Net.WebClient).DownloadString("https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev")
若要使用上述指令安裝 Posh-SSH,必須具備網際網路連線。就我而言,我已在 PowerShell 中安裝了 Posh-SSH 模組,現在可以進行接下來的設定步驟。
在 PowerShell 中連線至遠端主機
在這篇部落格文章中,我使用的是由一台本地 Windows 電腦和一台遠端 Linux 電腦組成的環境,這兩台電腦連接到同一個網路:
- 192.168.101.210 是一台安裝了 Windows 10 版本 20H2 的本地 Windows 電腦
- 192.168.101.209 是一台正在執行 SSH(SFTP)伺服器的遠端 Linux 機器
- user1 是 Linux 用戶的名稱
這些 IP 位址僅用於我的範例中。請在相應的指令與設定檔中輸入您的 IP 位址及憑證。
讓我們透過 WinSCP(一款免費的 Windows SFTP 客戶端)以 SFTP 方式連線至 Linux 伺服器,來檢查我們的 SFTP 共用資料夾。連線至 SFTP 伺服器的步驟非常簡單。 輸入目標主機的 IP 位址、連接埠號碼(TCP 22 為預設連接埠,但您可以將 SSH 伺服器設定為使用自訂連接埠)、使用者名稱及密碼即可建立連線。請記得選取 SFTP 協定。
在我的情況下,SFTP 連線運作正常。我們已將兩個檔案複製到共用資料夾中(檔案的位置是 /home/user1/shared/ (在遠端 Linux 機器上)。讓我們來看看如何從 Windows 連線到共用資料夾,以及如何在 PowerShell 中使用 Posh-SSH 搭配 SFTP。
若要透過 SFTP 處理檔案,您應先建立連線。請在 PowerShell 中執行以下指令:
New-SFTPSession -Computername 192.168.101.209
執行指令後,系統將顯示驗證視窗。請輸入使用者名稱和密碼,以透過 SFTP 存取您所需的檔案所在的遠端 Linux 電腦。若您輸入的憑證正確,您應會看到 PowerShell 輸出訊息,其中包含 SFTP 連線編號、遠端主機的 IP 位址以及連線狀態。連線建立後,系統會為該連線指派一個索引編號。
您可以隨時輸入 help 指令並搭配適當的參數,以顯示有關 PowerShell 指令使用語法的簡要說明:
help New-SFTPSession
列出所有可用的 posh PowerShell 指令:
Get-Command -Module Posh-SSH
或
Get-command -Name * -module *posh-ssh
以下是建立 SSH 連線的方法,讓您能在遠端主機上執行指令,例如列出目錄中的檔案:
Import-Module Posh-SSH
$SSHSession = New-SSHSession -ComputerName 192.168.101.209 -Credential $(Get-Credential) -Verbose
$SSH = $SSHSession | New-SSHShellStream
Invoke-SSHCommand -Index 0 -Command "ls -l /home/user1/shared"
建立 PowerShell 腳本
讓我們建立一個測試腳本,用以探索在 PowerShell 中處理 SFTP 資源時可執行的基本操作。這並非一個 SFTP 腳本,而是一個用於處理 SFTP 的 PowerShell 腳本。此測試腳本將把 .NET Framework 安裝程式檔案從遠端 Linux 機器複製到本機 Windows 機器。
建立一個 test-PS.ps1 內容如下所示的腳本檔案。
#Creating a folder to store files downloaded from the SFTP share
New-item -itemtype directory -force -path c:tempps
#Setting credentials for the user account
$password = ConvertTo-SecureString "My_Password000" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("user1", $password)
#Establishing an SFTP session
$Session = New-SFTPSession -Computername 192.168.101.209 -credential $creds
#Downloading the .NET installer file by using the established SFTP session
Get-SFTPFile -SessionId $session.SessionID -RemoteFile /home/user1/shared/NetFrameworkNDP462.exe -LocalPath c:tempps
在 Windows 電腦上開啟 PowerShell,前往存放此測試腳本的資料夾,然後執行該腳本
.test-PS.ps1
該 NetFrameworkNDP462.exe 檔案應從 /home/user1/shared/ (在遠端 Linux 機器上)至 C:tempps (在本地 Windows 電腦上)。如下方截圖所示,在我的情況下,檔案已成功複製。
若要在 SFTP 資源中列出目錄中的檔案,您可以建立一個內容如下所示的 PowerShell 腳本:
$passwordTest = "Your_Password000"
$securePasswordTest = ConvertTo-SecureString $passwordTest -AsPlainText -Force
$credentialsTest = New-Object System.Management.Automation.PSCredential ("user1", $securePasswordTest)
$sessionTest = New-SFTPSession -ComputerName 192.168.101.209 -Credential $credentialsTest -AcceptKey
$sourceTest = "/home/user1/shared/"
$destinationTest= "c:tempps"
Get-SFTPChildItem -Recursive $sessionTest -Path $sourceTest | ForEach-Object{
if ($_.Fullname -like '*.csv')
{
Get-SFTPFile $sessionTest -RemoteFile $_.FullName -LocalPath $destinationTest -Overwrite
}
write-output $_.FullName
}
Remove-SFTPSession $sessionTest -Verbose
地點:
您的密碼000 是透過 SSH 連線至 SFTP 共用資料夾時所使用之使用者帳戶的密碼;
user1 是使用者的名稱;
192.168.101.209 這是我們透過 SFTP 連線以存取檔案的遠端主機 IP 位址。
將腳本儲存為 list-files.ps1 並在您的本機電腦上,從存放此腳本檔案的資料夾中,透過 PowerShell 執行此腳本。
.list-files.ps1
請注意 -Recursive 在測試腳本中定義的參數。在下方的螢幕截圖中,您可以看到使用該 -Recursive 包含此參數與不包含此參數的情況。
執行如上例所示的腳本時,其中一個缺點在於憑證會以明文形式儲存在腳本中,這並不安全。任何能夠開啟腳本的使用者(即使僅具唯讀權限),都能看到密碼並利用該密碼進行未經授權的存取。
有一種方法可以提升安全性,將密碼以加密形式儲存於檔案中。透過 Windows 資料保護 API 對密碼進行加密,此加密密碼檔案僅能由建立該檔案時所使用的使用者帳戶及電腦存取。
(get-credential).password | ConvertFrom-SecureString | set-content "C:temppassword.txt"
然後,密碼會以加密形式儲存於該文字檔案中。即使有人查看此檔案的內容,密碼也不會以明文形式顯示。
當您需要輸入密碼時,請指定儲存了加密密碼的檔案(C:temppassword.txt (就我們的情況而言)。
$password = Get-Content "C:temppassword.txt" | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential("user1",$password)
這種定義密碼的方式更為安全。您可以修改定義密碼的腳本。除了在文字編輯器中開啟腳本之外,您也可以右鍵點擊該 ps1 檔案,並在快顯選單中點選 Edit.
Windows PowerShell ISE 已開啟。這是一款原生 Windows 工具,會為語法進行色彩標示以提升使用便利性,並在右側窗格中顯示可用的 PowerShell 指令。
測試腳本中的指令現已如下:
New-item -itemtype directory -force -path c:tempps
$password = Get-Content "C:temppassword.txt" | ConvertTo-SecureString
$creds = $credential = New-Object System.Management.Automation.PsCredential("user1",$password)
$Session = New-SFTPSession -Computername 192.168.101.209 -credential $creds
Get-SFTPFile -SessionId $session.SessionID -RemoteFile /home/user1/shared/NetFrameworkNDP462.exe -LocalPath c:tempps
您可以再次修改腳本,並設定其在 Windows 電腦上執行已下載的安裝程式檔案。以下是在靜默模式下安裝 .NET Framework 的指令(從安裝程式檔案的位置執行):
.NetFrameworkNDP462.exe /q /norestart
如果安裝檔名稱不同,請輸入您的安裝檔名稱。
在腳本結尾處加入以下行:
Start-process "C:temppsNetFrameworkNDP462.exe" -argumentlist /q /norestart
若您希望在安裝完成後刪除安裝檔案,請考慮在腳本結尾處加入以下這行:
remove-item -path "C:temppsNetFrameworkNDP462.exe" -recurse -force
透過 PowerShell 和 Posh-SSH,您可以利用 SFTP 協定在 PowerShell 中自動化操作,以便在網路中的主機之間複製檔案。當您需要在大量電腦上進行軟體批量安裝時,可以建立一個腳本來下載檔案並執行,從而儲存時間。
結論
現在,只要在 Linux 機器上設定了 SSH 伺服器,您就可以透過 SFTP 在 Linux 機器之間複製檔案。Posh-SSH 是一個 PowerShell 模組,若您希望從 Windows 機器存取遠端 SFTP 伺服器並執行 SFTP 自動化任務,則必須安裝此模組。PowerShell 和 SFTP 可供組織內的託管服務供應商及系統管理員使用。
PowerShell 常被用於管理 Hyper-V 虛擬機器和 VMware 虛擬機器(在 PowerCLI)。請記得備份 Hyper-V 虛擬機器。正如 PowerShell 可用於自動化執行指令, NAKIVO Backup & Replication 可自動化虛擬機器備份,並提供眾多額外資料保護特點。此外,本產品支援多租戶模式安裝,對於託管服務供應商而言尤為實用。下載免費版本 NAKIVO Backup & Replication 立即開始保護您的虛擬機器和實體機器。










