JSXファイルの先頭の連番を振り直し、元ファイルを残して新しい名前のコピーを作ります。
旧版の移動・削除や直接リネームのコードを、変更予定の確認と重複時の停止ができる方式へ更新しました。
入力と出力の例
ZIPは空の練習フォルダーへ展開し、下の手順で指定するサブフォルダーを開いて使います。
01_Alpha.jsx、20_日本語 ! & [x].jsx、Zeta.jsxから、001_Alpha.jsx、002_日本語 ! & [x].jsx、003_Zeta.jsxを作ります。
出力ルートのmapping.csvには元の絶対パス、出力名、SHA256が記録されます。
対象はinputの直下にある.jsxだけで、名前順に001から付けます。
数字とアンダースコアで始まる部分だけを除き、連番のない名前を切り落としません。
上限は999件で、SendToの選択順に番号を付けるコードではありません。
変更予定を確認してコピーする
- ZIPのnumberフォルダーで、inputに練習用ファイルを用意する
- 下のPS1をnumber.ps1として保存するか、ZIPの同名ファイルを開く
- BATを実行し、SourceとRelativeOutputの予定だけを確認する
- 問題なければコマンドプロンプトで次の-Apply付きコマンドを実行する
- output/dataの内容とmapping.csvを確認し、inputが残っていることを確かめる
Windows PowerShell 5.1用のPS1はUTF-8(BOM付き)で保存します。
BATのRemoteSigned指定は起動したプロセスだけに適用し、ユーザーやPC全体の実行ポリシーは変更しません。
ダウンロードしたPS1が署名エラーになる場合は内容と出所を確認し、対象ファイルのプロパティからブロックを解除します。
組織のポリシーで実行できない場合は管理者へ確認し、ポリシーを回避して実行しないでください。
@echo off
setlocal DisableDelayedExpansion
powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "%~dp0number.ps1"
exit /b %errorlevel%
BATはnumber.batとしてPS1と同じ場所へ保存し、プレビュー用の起動に使います。
powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "number.ps1" -Apply
上の実行コマンドはnumber.ps1のあるフォルダーで使います。
param([string]$Source,
[string]$Output,
[switch]$Apply)
if (-not $Source) { $Source = Join-Path $PSScriptRoot 'input' }
if (-not $Output) { $Output = Join-Path $PSScriptRoot 'output' }
$ErrorActionPreference = 'Stop'
$rootItem = Get-Item -LiteralPath $Source
if (-not $rootItem.PSIsContainer) { throw 'Source must be a folder' }
$root = $rootItem.FullName.TrimEnd('\')
$out = [IO.Path]::GetFullPath($Output).TrimEnd('\')
if ($out -eq $root -or $out.StartsWith($root + '\', [StringComparison]::OrdinalIgnoreCase)) {
throw 'Output must be outside Source'
}
if (Test-Path -LiteralPath $out) { throw 'Output already exists; choose a new name' }
$entries = @(Get-ChildItem -LiteralPath $root -Recurse -Force)
if (($rootItem.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
@($entries | Where-Object { $_.Attributes -band [IO.FileAttributes]::ReparsePoint }).Count) {
throw 'Links/junctions are not supported'
}
$files = @($entries | Where-Object { -not $_.PSIsContainer })
$files = @($files | Where-Object { $_.DirectoryName -eq $root -and $_.Extension -ieq '.jsx' } | Sort-Object Name)
if (-not $files.Count) { throw 'No matching files' }
if ($files.Count -gt 999) { throw 'At most 999 files' }
$i = 0
$plan = @(foreach ($file in $files) {
$i++
$name = ('{0:D3}_' -f $i) + ($file.Name -replace '^\d+_', '')
if ([string]::IsNullOrWhiteSpace($name) -or $name.IndexOfAny([IO.Path]::GetInvalidFileNameChars()) -ge 0 -or
$name -match '[. ]$|^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)') { throw 'Invalid output name' }
$relative = $name
[pscustomobject]@{
Source = $file.FullName
RelativeOutput = $relative
Destination = [IO.Path]::Combine($out, 'data', $relative)
SHA256 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash
}
})
if (@($plan | Group-Object Destination | Where-Object Count -gt 1).Count) {
throw 'Duplicate destination names; nothing copied'
}
$plan | Format-List Source, RelativeOutput
if (-not $Apply) { Write-Host 'Preview only'; return }
[IO.Directory]::CreateDirectory($out) | Out-Null
$plan | Export-Csv -LiteralPath ([IO.Path]::Combine($out, 'mapping.csv')) -NoTypeInformation -Encoding UTF8
foreach ($row in $plan) {
[IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($row.Destination)) | Out-Null
[IO.File]::Copy($row.Source, $row.Destination, $false)
if ((Get-FileHash -LiteralPath $row.Destination -Algorithm SHA256).Hash -ne $row.SHA256) {
throw 'Hash mismatch; keep originals and inspect output'
}
}
Write-Host ('Copied: ' + $plan.Count)
末尾へ文字を付ける場合
対象を同じ直下の.jsxとしたまま末尾へ文字を追加する場合は、上の$nameを代入する1行だけを次に置き換えます。
$name = $file.BaseName + '_サンプル' + $file.Extension
例:20_日本語 ! & [x].jsxは20_日本語 ! & [x]_サンプル.jsxになります。
失敗したときの確認と戻し方
Duplicate destination namesが出たら、同じ出力名になるファイルを一覧で確認し、入力のコピー側で名前を分けてからやり直します。
Output already existsが出たら既存の出力を上書きせず、-Outputで新しい絶対パスを指定します。
Sourceの内側を出力先にした場合、入力が空の場合、リンクやジャンクションがある場合は停止します。
コピー中の権限エラーや容量不足、ハッシュ不一致では出力が一部だけ残るため、元データを使い続け、出力は未完成として確認します。
戻すときは変更していないinputを利用し、途中のoutputを制作データへ置き換えないでください。
この方法は通常ファイルの内容をコピーし、ACLや代替データストリームなどを含む完全なバックアップを作るものではありません。
2026年10月2日に実際のWindows PowerShell 5.1で、日本語・空白・!・&・角括弧を含む名前、プレビュー、コピー結果と元データの保持を確認しました。
Explorerのクリック操作とネットワーク共有上の処理は今回の検証に含みません。
コマンド仕様:Microsoft公式の実行ポリシー、File.Copyの上書き指定(2026年10月2日確認)。
従来の操作画面
以下は旧版の画面で、リスト入力や元の操作例の参考として残しています。
現在の手順は上のコードと入力・出力例を使い、CSVの拡張子変更や元ファイルの直接リネームは行いません。


業務効率化に役立つほかのツールは、以下のまとめ記事で紹介しています。

Windowsバッチファイルに関するほかの解説記事は、こちらをご覧ください。




まとめ
名前順と対象拡張子を固定し、連番を付けたコピーを出力して確認します。
