銀河鉄道

【PowerShell】指定のフォルダをデスクトップへコピーする

サムネイル
[PowerShell]copyto desktop
functionにする

たとえば
こんなとき

  • フォルダごとデスクトップにコピーしたい
    • 毎回同じ作業を繰り返している場合

Copy-Item -LiteralPath $source -Destination $desktopRoot -Recurse -Force

# Always-clean copy to Desktop with mandatory confirmations and auto-open
# 毎回クリーン&毎回確認&コピー後に自動で開く

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# ---- Config as constants|定数としての設定 ----
$CONST_PARENT_PATH      = "(親パス)"
$CONST_CHILD_PATH       = "(子パス)"
$CONST_LAST_FOLDER_NAME = "(最終フォルダ名)"

function Copy-ToDesktop {
	[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
	param()

	# Build paths|パス構築
	$intermediate = Join-Path -Path $CONST_PARENT_PATH -ChildPath $CONST_CHILD_PATH
	$source       = Join-Path -Path $intermediate -ChildPath $CONST_LAST_FOLDER_NAME

	$desktopRoot  = [System.Environment]::GetFolderPath('Desktop')
	$destPath     = Join-Path -Path $desktopRoot -ChildPath $CONST_LAST_FOLDER_NAME

	Write-Verbose "Source: $source"
	Write-Verbose "Dest  : $destPath"

	# Validate source exists|日本語: コピー元の存在確認
	if (-not (Test-Path -LiteralPath $source -PathType Container)) {
		throw "コピー元が存在しません: $source"
	}

	# Always clean destination with confirmation|宛先を毎回削除(確認あり)
	if (Test-Path -LiteralPath $destPath -PathType Container) {
		# Mandatory confirmation dialog|強制の確認ダイアログ
		$caption = "Remove destination (Clean)|宛先クリーニング"
		$query   = "Delete existing destination and all its contents?|既存の宛先を全削除します。よろしいですか?`n$destPath"
		if ($PSCmdlet.ShouldContinue($query, $caption)) {
			if ($PSCmdlet.ShouldProcess($destPath, "Remove-Item -Recurse -Force")) {
				Remove-Item -LiteralPath $destPath -Recurse -Force
			}
		} else {
			throw "ユーザー操作でキャンセルされました(宛先削除を中止)"
		}
	}

	# Copy with confirmation|コピー実行(確認あり)
	$caption2 = "Copy folder|フォルダコピー"
	$query2   = "Copy source to Desktop?|コピーを実行しますか?`n$source`n -> `n$desktopRoot"
	if ($PSCmdlet.ShouldContinue($query2, $caption2)) {
		if ($PSCmdlet.ShouldProcess("$source -> $desktopRoot", "Copy-Item -Recurse -Force")) {
			Copy-Item -LiteralPath $source -Destination $desktopRoot -Recurse -Force
		}
	} else {
		throw "ユーザー操作でキャンセルされました(コピーを中止)"
	}

	Write-Host "[OK] Copied '$CONST_LAST_FOLDER_NAME' to Desktop." -ForegroundColor Green

	# Always open destination|毎回、宛先フォルダを開く
	if ($IsWindows) {
		Start-Process -FilePath "explorer.exe" -ArgumentList $destPath
	} elseif ($IsMacOS) {
		Start-Process -FilePath "open" -ArgumentList $destPath
	} elseif ($IsLinux) {
		Start-Process -FilePath "xdg-open" -ArgumentList $destPath
	}
}

# 実行例
Copy-ToDesktop -Verbose
# Copy-ToDesktop -Verbose -WhatIf   # WhatIf時は確認表示→実変更は実行されない

  • 宛先がすでに存在すれば毎回削除(ユーザー確認つき)
  • ShouldContinue により、必ず対話確認
  • コピー成功後はフォルダを開く
  • 例外で終了(throw)。

パスは段階的につなぐ

すでに存在すれば削除する理由

Copy-Item は既存フォルダに対して「不要ファイルの削除まではしない」

同名フォルダが既にある場合、Copy-Item だと不要ファイルは残ってしまう(差分マージ挙動)

完全同期が必要なら事前削除をする。

[Environment]::GetFolderPath('Desktop')

.NET 標準API によるデスクトップパス取得方法。

Windowsのユーザープロファイル構造や環境変数設定に依存せず、常に正しいパスを返す

応用例|Applications

以下のように統一して使うと安全:

$desktop = [Environment]::GetFolderPath('Desktop')
$documents = [Environment]::GetFolderPath('MyDocuments')
$downloads = [Environment]::GetFolderPath('Downloads')

Copy-Item "$desktop\test.txt" "$documents\backup.txt"

この方式なら、どのユーザー・PCでも正常に動作する

-WhatIf 対応

ShouldProcess を併用しているため、-WhatIf では削除・コピーは実行せず、予定表示のみをする(ShouldContinue のダイアログは表示されるが、最終的な実変更は起きない)

このスクリプトは何をするためのもの?を確認するときにWhatIfを使う

Vocabulary

always clean | 常時クリーン
mandatory confirmation | 強制確認
should continue | ShouldContinue
should process | ShouldProcess
dry run | 予行実行
idempotent | 冪等
open folder | フォルダを開く
throw | 例外送出
cross-platform | クロスプラットフォーム
configuration | 設定

confirm, clean, and then reveal.

著者

author
月うさぎ

編集後記:
この記事の内容がベストではないかもしれません。

記事一覧