顯示具有 ssh 標籤的文章。 顯示所有文章
顯示具有 ssh 標籤的文章。 顯示所有文章

2025年6月26日 星期四

在 pwsh 中使用 Remoting 連入 linux

在 pwsh 中使用 Remoting 連入 linux

用習慣 pwsh 有時候沒要幹嘛只是做一點點事情,直接用 pwsh 會比較快,真的要做比較複雜的事情還是切 bash 好,因為網上的教學是以 bash 為主的。



linux 端的設定1:: 安裝 pwsh

安裝 pwsh 可以參考微軟的網站有教學
Installing PowerShell on Ubuntu - PowerShell | Microsoft Learn


範例用從 github 下載的方式 (因為我是安裝在 pi5 上)

載點記得選 gihub 上自己合適的系統與版本,我的是 arm64 如果一般選 x64 即可

# 下載
wget https://github.com/PowerShell/PowerShell/releases/download/v7.5.2/powershell-7.5.2-linux-arm64.tar.gz

# 刪除舊內容
sudo rm -rf /opt/powershell/7/*

# 解壓縮
sudo tar -xzf ~/powershell-7.5.2-linux-arm64.tar.gz -C /opt/powershell/7

# 建立連結
sudo ln -sf /opt/powershell/7/pwsh /usr/local/bin/pwsh

# 賦予執行權
sudo chmod +x /opt/powershell/7/pwsh

# 執行
pwsh

到這邊就可以正常執行

手動安裝差在沒辦法透過 apt-get 自動升級版本,好處是可以裝到最新板的。



linux 端的設定1:: 設定 ssh 的子系統

在 linux 端打開 Subsystem 即可 (不用像 Win 需要啟動 WinRM)

先到SSH設定中

sudo nano /etc/ssh/sshd_config

拉到最下面找到 # override default of no subsystems 這個註解
下面可能有 sftp 範例但是不管手動加上這行就行

Subsystem powershell    /usr/local/bin/pwsh -sshs -NoLogo

存檔後就設定好了



pwsh 連接方法

在連接之前先確保 ssh 金鑰已經配置完畢,可以無密碼登入,然後使用下面的指令連接

Enter-PSSession -HostName 192.168.3.88 -UserName chg

連入之後會長這個樣子




2025年2月4日 星期二

PowerShell 使用 ssh 驗證本地與遠端檔案的 SHA256 是否一致

PowerShell 使用 ssh 驗證本地與遠端檔案的 SHA256 是否一致

要驗證傳輸到底有沒有傳對用的函式

# 獲取遠端檔案的雜湊值
function Get-RemoteFileHash {
    [CmdletBinding()]
    param ( 
        # 遠端檔案路徑
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$Path,
        # 遠端登入資訊
        [Parameter(Mandatory)]
        [string]$RemoteLoginInfo,
        # 遠端私鑰
        [Parameter(Mandatory)]
        [string]$IdentityFile,
        # 遠端作業系統
        [Parameter(Mandatory)]
        [ValidateSet('Windows', 'Linux')]
        [string]$RemoteOS
    ) begin {
        # 檢查私鑰是否存在
        if (-not (Test-Path $IdentityFile)) {
            Write-Error "Cannot find path '$IdentityFile' because it does not exist."
        }
        # 定義不同作業系統的雜湊命令
        $hashCommands = @{
            'Windows' = "powershell `"(Get-FileHash -Path ([WildcardPattern]::Escape('$Path')) -Algorithm SHA256 -EA 1).Hash`""
            'Linux'   = "sha256sum '$Path' 2>&1 >/dev/null && sha256sum '$Path' | cut -d' ' -f1 | tr '[:lower:]' '[:upper:]'"
        }
        # SSH 連線參數設定
        $sshParams = @(
            '-oBatchMode=yes'
            "-oIdentityFile=$IdentityFile"
            $RemoteLoginInfo
        )
    } process {
        # 執行遠端雜湊命令
        $hash = & ssh @sshParams $hashCommands[$RemoteOS] 2>&1
        # 檢查 ssh 命令是否成功
        if ($LASTEXITCODE -ne 0) {
            Write-Error "ssh command failed: $hash" 
            return $null
        }
        # 檢查雜湊值格式是否正確 (SHA-256 應為 64 個十六進制字符)
        if (-not ($hash -match '^[A-F0-9]{64}$')) {
            Write-Error "The hash value '$hash' returned from command '$hashCommand' is not a valid SHA-256 format"
            return $null
        }
        return $hash
    }
}


使用範例

Get-RemoteFileHash "/home/chg/work/Tester.bats" `
    -RemoteLoginInfo "chg@192.168.3.53" `
    -IdentityFile "${env:USERPROFILE}\.ssh\id_ed25519" `
    -RemoteOS "Linux"

執行完會自動返回遠端檔案的哈希值,再來比較本地端即可知道是否一致了。


更進階的可以讓這個函式再跟自動判斷組合
CHG: 如何僅利用 sftp 判斷對方是 unix 還是 win




如果是要從 sftp 指令腳本中,獲取傳輸的路徑可以參考這個

# 解析 SFTP 命令
function ParseSftpCommandPath {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [string]$CommandText
    )
    process {
        # 跳過空行和註解
        if (-not ($CommandText -match '\S') -or $CommandText -match '^\s*#') { return }
        # 解析命令行
        $tokens = [regex]::Matches(
            $CommandText.Trim(), '"[^"]+"|[^\s"]+'
        ).Value.Trim('"')
        # 獲取遠端檔案路徑
        if ($tokens[0] -in 'get','put') {
            $paths = $tokens[1..($tokens.Count-1)].Where({ $_ -notmatch '^-' })
            $idx = @{
                'get' = @{local=-1; remote=0}
                'put' = @{local=0; remote=-1}
            }[$tokens[0]]
            [PSCustomObject]@{
                Command = $tokens[0]
                LocalPath = $paths[$idx.local]
                RemotePath = $paths[$idx.remote]
            }
        }
    }
} # "get /home/chg/work/Tester.bats Tester.bats" | ParseSftpCommandPath