標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

今週、書いた PowerShell スクリプト…

イクラのワールド、FTPバックアップ汎用版

  • スクリプトの第一引数にワールド名をとるようにした
  • 引数が無い場合はワールドのリストを表示する
  • 古い PowerShell だと、パイプラインにバイナリを通せないので、PowerShell 7.4 未満の場合はエラーにする

Backup-World.ps1

Param( [string] $world)

$SERVER = "(FTPサーバーのホスト名)"
$USER = "(FTPサーバーのユーザ名)"
$PASS = "(FTPサーバーのパスワード)"
$DIR = "(FTPサーバー上の置き場パス)"

If ( (Get-Host).Version -lt '7.4.0' ){
    Write-Host "Please use PowerShell 7.4 or later"
    exit 1
}
Push-Location (Join-Path $env:APPDATA ".minecraft\saves")
Try {
    if ( -not $world ){
        Get-ChildItem -Directory . | ForEach-Object {
            Write-Host $_.Name
        }
        exit 0
    }
    if ( -not (Test-Path $world)) {
        Write-Host "World: $world is not found"
        exit 0
    }

    $fname = "minecraft-" + $world + "-" + (Get-Date -Format "yyyyMMdd") + ".tar.zst"
    $fullpath = $DIR + "/" + $fname

    tar cvf - $world | zstd | curl -s -T - --user ${USER}:${PASS} ftp://$SERVER/$fullpath
    curl -s --user ${USER}:${PASS} ftp://$SERVER/$fullpath | zstd -d | verifyarc -
} Finally {
    Pop-Location
}

指定した実行ファイルで %PATH% 上の同名のファイルを更新する

scoop などのパッケージマネージャーで管理していない実行ファイルを最新版に更新する時、いちいち copy hogehoge.exe %USERPROFILE%\Share\bin64\. などと入力していたんだけど、パスを入力するのがめんどくさい。

そういった時、Update-Exe-All.ps1 hogehoge.exe だけで、%PATH% のディレクトリ上に存在する全ての hogehoge.exe を更新できるようにしてみた。 (タイプする文字の数が大して変わらないような気もするが、補完もあるので…)

Update-Exe-All.ps1

Param ([string] $source)

if ( -not $source -or -not (Test-Path $source) ){
    Write-Host "Update-Exe-All.ps1 EXECUTABLE-NAME"
    Exit 1
}

$name = (Split-Path $source -Leaf)

Get-Command $name | ForEach-Object {
    $target = $_.Source
    $dir = (Split-Path -Parent $target)
    $answer = (Read-Host "Update `"${target}`" ? [y|n]")
    if ( $answer -ieq "y" ){
        Try{
            Copy-Item $source -Destination $dir -PassThru -ErrorAction Stop
        }
        Catch{
            $backup = (Join-Path $dir ($name + "-" + (Get-Random)))
            Move-Item $target $backup -PassThru
            Copy-Item $source -Destination $dir -PassThru
        }
    }
}

コピー先がオープンされているなどの理由で上書きできない場合は、旧ファイルをリネームするなどして、コピーをなんとか実行する。なお、C:\Progmram Files 以下など管理者権限が必要な場所では使えない。そういうところでは fcopy を使おう ( 必要に応じて UAC ダイアログを表示して、管理者権限に昇格する仕組みがある )