PowerShellを使用したファイルコピーのサンプルスクリプト(備忘)
スクリプト本体
################################################################################
#処理概要
# 定義ファイルに記載されたファイルを所定のディレクトリにコピーする。
#
#スクリプト仕様
# スクリプトファイル名 : FileCopy.ps1
# スクリプト名称 : ファイルコピースクリプト
# 引数 : 1 … ファイルコピー定義ファイル名(<コビー元ファイル名>,<コピー先フォルダ/ファイル名>,<上書きフラグ(UP:上書き可/NU:上書き不可)>,<コメント>)
# 戻り値 : 0 … 正常終了
# 1 … 異常終了
# ログファイル : FileCopy.log
# 起動方法 : FileCopy.ps1 <ファイルコピー定義ファイル名>
# JP1/AJSジョブから呼び出し
# 前提 : Windows Server 2022 (PowerShell 5.1以上) で動作確認を実施
# 備考 : なし
#
#更新履歴
# Ver. 日付 コメント 担当
# -------- ---------- ------------------------------------------------------------ ----------
# V 1.00. 2024/01/01 新規作成
#
################################################################################
##### 変数 #####
$ScriptFile = Split-Path -Leaf $PSCommandPath # スクリプトファイル名
$ScriptDir = $PSScriptRoot + "\" # スクリプトファイルの格納ディレクトリ
$LogFile = ${ScriptFile}.Split(".")[0] + ".log" # スクリプトログファイル名
$LogDir = "C:\Script\Log\" # スクリプトログの格納ディレクトリ
$Log = ${LogDir} + ${LogFile} # スクリプトログファイル
$LSize = 10 # ログローテーションを行う際のログサイズ(MByte)
$LGen = 5 # ログローテーションを行う際の保存世代数(カレントログファイル以外のファイル数)
$Conf = "" # ファイルコピー定義ファイル
$NOW = "" # システム日時
$InFile = "" # カレント入力ファイル
$ReadLine = "" # 読み込み行
$Word = "" # 読み込み行($ReadLine)を区切り子で分割したオブジェクト
$CopyFileFrom = "" # コピー対象ファイル名
$CopyTo = "" # コピー先ファイル名
$UpdateFlg = "" # コピー先ファイルを上書きするかどうかのフラグ
$File1 = "" # コピー元ファイル名
$File2 = "" # コピー先ファイル名
##### メッセージ #####
$MSG01 = "【INFO】ファイルコピー処理(${ScriptFile})を開始します。"
$MSG02 = "【INFO】ファイルコピー処理(${ScriptFile})を終了します。"
$MSG03 = "【INFO】ファイルをコピーしました。"
$ERR01 = "【ERR】 ログファイルに書き込みできません。"
$ERR02 = "【ERR】 引数が設定されていません。"
$ERR03 = "【ERR】 ファイルコピー定義ファイルが存在しません。"
$ERR04 = "【ERR】 ファイルコピーに失敗しました。"
$WRN01 = "【WARN】定義ファイルの項目数が不足しています。コピー処理をスキップします。"
$WRN02 = "【WARN】コピー対象ファイルが存在しません。コピー処理をスキップします。"
$WRN03 = "【WARN】コピー先にファイルが存在します。コピー処理をスキップします。"
$WRN04 = "【WARN】複数のコピー元に対して、コピー先がフォルダではありません。コピー処理をスキップします。"
$WRN05 = "【WARN】コピー先フォルダが存在しません。コピー処理をスキップします。"
##### 関数 #####
##----- メッセージ出力関数 -----
function PrintMSG
{
param (
$Words # 出力する文言
)
##----- 変数 -----
$NOW = "" # システム日時
##----- 出力処理 -----
$NOW = (Get-DATE).ToString("yyyy/MM/dd HH:mm:ss")
Write-Host ${Words}
$NOW + " " + ${Words} >> ${Log}
}
##----- ログローテーション関数 -----
function LogRotation
{
param (
[string]$Log, # ログローテーション対象ログファイル
[int]$LSize, # ログローテーションを行う際のログサイズ(MByte)
[int]$LGen # ログローテーションを行う際の保存世代数(カレントログファイル以外のファイル数)
)
##----- 変数 -----
$TargetLogFile1 = "" # リネーム前ログファイル、もしくは、削除対象ログファイル
$TargetLogFile2 = "" # リネーム後ログファイル
##----- メッセージ -----
$MSG01 = "【INFO】ログローテーションを開始します。"
$MSG02 = "【INFO】ログローテーションを終了します。"
$MSG03 = "【INFO】保存世代より古いログファイルを削除しました。"
$MSG04 = "【INFO】ログファイルをリネームします。"
$ERR01 = "【ERR】 ログファイルの削除に失敗しました。"
$ERR02 = "【ERR】 ログファイルのリネームに失敗しました。"
##----- ファイルサイズが指定値以上の場合、ログローテーションを行う -----
if ((Get-Item ${Log}).length -ge (${LSize} * 1024 * 1024)) {
PrintMSG (${MSG01} + "[ログファイル: " + ${Log} + "]")
##----- ログローテーションの実施 -----
##----- 最も古い世代のログファイルの削除 -----
$TargetLogFile1 = ${log} + "." + ${LGen}
$TargetLogFile2 = ${log} + "." + (${LGen} - 1)
if (((Test-Path ${TargetLogFile1}) -eq $True) -and ((Test-Path ${TargetLogFile2}) -eq $True)) {
try {
Remove-Item ${TargetLogFile1}
PrintMSG (${MSG03} + "[ログファイル: " + ${TargetLogFile1} + "]")
} catch {
PrintMSG (${ERR01} + "[ログファイル: " + ${TargetLogFile1} + "]")
exit 1
}
}
##----- 途中の世代のログファイルのリネーム -----
for ($i=${LGen}; $i -gt 1; $i--) {
$TargetLogFile1 = ${log} + "." + $i
$TargetLogFile2 = ${log} + "." + ($i - 1)
##----- 若い世代のログファイルが存在する場合、リネームする -----
if ((Test-Path ${TargetLogFile2}) -eq $True) {
try {
Rename-Item -Path ${TargetLogFile2} -NewName ${TargetLogFile1}
PrintMSG (${MSG04} + "[ログファイル名 変更前: " + ${TargetLogFile2} + "][ログファイル名 変更後: " + ${TargetLogFile1} + "]")
} catch {
PrintMSG (${ERR02} + "[ログファイル名 変更前: " + ${TargetLogFile2} + "][ログファイル名 変更後: " + ${TargetLogFile1} + "]")
exit 1
}
}
}
##----- カレントログファイルのリネーム -----
$TargetLogFile1 = ${log} + ".1"
$TargetLogFile2 = ${log}
##----- 若い世代のログファイルが存在する場合、リネームする -----
if ((Test-Path ${TargetLogFile2}) -eq $True) {
try {
Rename-Item -Path ${TargetLogFile2} -NewName ${TargetLogFile1}
PrintMSG (${MSG04} + "[ログファイル名 変更前: " + ${TargetLogFile2} + "][ログファイル名 変更後: " + ${TargetLogFile1} + "]")
} catch {
PrintMSG (${ERR02} + "[ログファイル名 変更前: " + ${TargetLogFile2} + "][ログファイル名 変更後: " + ${TargetLogFile1} + "]")
exit 1
}
}
PrintMSG ${MSG02}
}
}
##### メイン処理 #####
##----- ログファイルへの区切りの書き込み -----
try {
"----------" >> ${Log}
} catch {
PrintMSG (${ERR01} + "[ログファイル: " + ${Log} + "]")
Write-Host ${MSG02}
exit 1
}
##----- ログローテーションの実施 -----
LogRotation ${Log} ${LSize} ${LGen}
##----- 処理開始メッセージ出力 -----
PrintMSG (${MSG01} + "[引数: " + ${args} + "]")
##----- 引数チェック -----
if (${args}.Length -eq 0) {
PrintMSG (${ERR02})
PrintMSG (${MSG02})
exit 1
} else {
$Conf = ${args}[0]
}
##----- 定義ファイルの存在確認 -----
if ((Test-Path ${Conf}) -ne $True) {
PrintMSG (${ERR03})
PrintMSG (${MSG02})
exit 1
}
##----- 定義ファイルの読み込み -----
$InFile = (Get-Content ${Conf}) -as [String[]]
foreach ($ReadLine in ${InFile}) {
##----- 行頭が"#"以外の文字列のみ処理する -----
if ((${ReadLine}[0] -ne "#") -and (${ReadLine}[0].count -ne 0)) {
$Word = (${ReadLine} -Split ",")
##----- 読み込んだ行の項目数チェック -----
if (${Word}.Length -lt 3) {
PrintMSG (${WRN01} + "[読み込み行: " + ${Word} + "]")
}
$CopyFileFrom = ${Word}[0].Trim('"')
$CopyTo = ${Word}[1].Trim('"')
$UpdateFlg = ${Word}[2]
##----- コピー元ファイルの一覧取得(ワイルドカード指定を想定) -----
if ((Test-Path ${CopyFileFrom}) -eq $False) {
##----- コピー元ファイルが存在しない場合はコピー処理をスキップする -----
PrintMSG (${WRN02} + "[コピー対象ファイル: " + ${CopyFileFrom} + "]")
} elseif (((Get-Item ${CopyFileFrom}).count -ge 2) -and ((Test-Path ${CopyTo}) -eq $True) -and ((Get-Item ${CopyTo}).PSIsContainer -eq $False)) {
##----- コピー元ファイルが2つ以上存在し、かつ、コピー先パスがフォルダでない場合はコピー処理をスキップする -----
PrintMSG (${WRN04} + "[コピー対象ファイル: " + ${CopyFileFrom} + "][コピー先: " + ${CopyTo} + "]")
} else {
foreach ( $File1 in (Get-Item ${CopyFileFrom}) ) {
##----- コピー先ファイルフルパスのセット -----
if (((Test-Path ${CopyTo}) -eq $True) -and ((Get-Item ${CopyTo}).PSIsContainer -eq $True)) {
##----- コピー先がフォルダの場合 -----
$File2 = Join-Path ${CopyTo} ${File1}.name
} else {
##----- コピー先がファイルの場合 -----
$File2 = ${CopyTo}
if ((Test-Path (Split-Path -Parent ${File2})) -eq $False) {
##----- コピー先ファイルを内包するフォルダが存在しない場合、処理をスキップ -----
PrintMSG (${WRN05} + "[コピー先: " + ${File2} + "]")
continue
}
}
##----- ファイル上書きフラグが指定されていない、かつ、コピー先にファイルが存在する場合はコピーを行わない -----
if ((${UpdateFlg} -ne "UP") -and ((Test-Path ${File2}) -eq $True)) {
PrintMSG (${WRN03} + "[コピー対象ファイル: " + ${File1} + "][コピー先: " + ${File2} + "]")
} else {
##----- ファイルコピー -----
try {
Copy-Item -Path ${File1} -Destination ${File2}
PrintMSG (${MSG03} + "[コピー対象ファイル: " + ${File1} + "][コピー先: " + ${File2} + "]")
} catch {
PrintMSG ($Error[0])
PrintMSG (${ERR04} + "[コピー対象ファイル: " + ${File1} + "][コピー先: " + ${File2} + "]")
}
}
}
}
}
}
##----- 処理終了メッセージ出力 -----
PrintMSG (${MSG02})
exit 0
ファイルコピー定義ファイル
#ファイルコピー定義ファイル
#<コビー元ファイル名>,<コピー先フォルダ/ファイル名>,<上書きフラグ(UP:上書き可/NU:上書き不可)>,<コメント>
#コピー元ファイル名にはワイルドカードの指定が可能
C:\Script\Test\From\File1.txt,C:\Script\Test\To\File1.txt,UP,aaaa
C:\Script\Test\From\File2.txt,C:\Script\Test\To\File2.txt,NU,aaaa
C:\Script\Test\From\File3*.txt,C:\Script\Test\To,UP,aaaa
コメント