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"

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




如果是要從 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


2025-02-04 PowerShell 修改檔案日期與時間 (3)

PowerShell 修改檔案日期與時間 (3)

tags: 部落格文章


關於檔案的 修改時間 和 存取時間有什麼差別可以看這篇站內文


字串格式和日期格式怎麼互轉可以參考這一邊



修改檔案日期

代碼開源在這裡: hunandy14/FileDateEditor


快速使用

irm bit.ly/4gkzM5D|iex; Set-FileDate -File "test\file.txt" "2025-2-4"


詳細功能

# 載入函式
irm bit.ly/4gkzM5D|iex;

# 建立日期
Get-Item "test\file.txt" | Set-FileDate "2025-2-4" -Creation

# 修改日期
Get-Item "test\file.txt" | Set-FileDate "2025-2-4" -Write

# 存取日期
Get-Item "test\file.txt" | Set-FileDate "2025-2-4" -Access

# 日期字串
Get-Item "test\file.txt" | Set-FileDate "2025-02-04" -Format "yyyy-MM-dd"


生成測試檔案

irm bit.ly/4gkzM5D|iex; 1..10 | ForEach-Object{
  $idx=$_.ToString('00')
  New-Item -ItemType File -Path "file_2025-02-$idx.txt" |
  Set-FileDate "2025-02-$idx"
}




2025年1月10日 星期五

git 無更動檔案 合併當前到主分支

git 無更動檔案 合併當前到主分支

最大的分支雖然都是由PR合併的,但是開發的次要主線規模不大太大還是有可能會讓開發者自己管理的

在這種情況下每當做好功能之後會合併回去還得退回,檔案會經過一次大洗牌,這邊提供一個可以不更動檔案的方式合併到分支

為什麼會洗牌是因為git並不提交 merage to 他只有 merage from,就注定你只能切過去不然不要合

解法是還是得造一個工作區,但是不是當前的目錄,而次第二個工作樹,在次要的工作樹合併這件事情就解決了

大概需要底下幾個流程

# 進入主工作樹目錄
cd "Z:/my-project"

# 新增臨時工作樹,檢查出目標分支
git worktree add "Z:/my-project-dev" dev

# 在臨時工作樹中進行合併
cd "Z:/my-project-dev"
git merge fix

# 合併完成後,回到主工作樹刪除臨時工作樹
cd "Z:/my-project"
git worktree remove "Z:/my-project-dev"

對就是單純的在檢出一個工作樹就行了,不過做完記得要刪除因為那個工作樹是會佔用分支的,會導致你的主目錄切不過去。