如何建立 PowerShell 工具來設定 SFTP
當您使用多台執行 Windows 的電腦時,可能需要透過不同的通訊協定來存取共用資源。在 Windows 電腦上建立檔案分享時,通常會使用 SMB 通訊協定。然而,在非 Windows 電腦上,則可透過 NFS、FTP、SFTP、FTPS、SCP 及其他通訊協定來共用檔案。 舉例來說,若您僅在沒有圖形介面的 Windows Server 上使用 PowerShell,首次連線至 SFTP 共用資料夾可能會顯得有些困難。這篇部落格文章將說明如何在 Windows 中透過 PowerShell 使用 SFTP。
什麼是 SFTP?
SFTP 代表 SSH 檔案傳輸協定(SSH File Transfer Protocol)或安全檔案傳輸協定(Secure File Transfer Protocol)。SFTP 是傳統檔案傳輸協定(FTP)的安全替代方案,功能性與之相似。SFTP 運作於 OSI 模型的應用層(第 7 層),使用 SSH 連線,並在 Linux 系統上特別普及,因為這些系統通常內建了命令列 SFTP 客戶端。 若您使用 Windows,請安裝免費的 SSH 客戶端(例如 WinSCP),該軟體具備圖形使用者介面 (GUI),且不僅支援 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 機器或從 Linux 機器複製檔案。Posh-SSH 是一個 PowerShell 模組,若您希望從 Windows 機器存取遠端 SFTP 伺服器並執行 SFTP 自動化任務,則必須安裝此模組。PowerShell 和 SFTP 可供組織中的託管服務供應商及系統管理員使用。
PowerShell 常被用於管理 Hyper-V 虛擬機器和 VMware 虛擬機器(在 PowerCLI). 請記得備份 Hyper-V 虛擬機器。正如 PowerShell 可用於自動化執行指令一樣, NAKIVO Backup & Replication 可自動化虛擬機器備份,並提供許多額外的数据保護特點。此外,該產品支援以多租戶模式進行安裝,這對託管服務供應商而言尤其實用。下載免費版本 NAKIVO Backup & Replication 並從今天起開始保護您的虛擬機器和實體機器。










