PowerShellには式モード、コマンドモードがある。それにより構文解釈が異なる。$、@、'、"、(
で始まった場合は式モード。アルファベットで始まった場合はコマンドモード。引数の解釈が違うのかな?
-
式モード
文字列として解釈させるには’, “などの引用符が必要となる。
echo 'test'、echo "test"
←それぞれtestとだけ解釈され引用符('、"
)は含まれない。 -
コマンドモード
演算子などを含めても、それぞれがスペース区切りの引数として解釈される。
echo 1+1←"1+1"
という一つの引数で解釈
echo 1 + 1
←“1”、"+"、“1"という3つの引数で解釈。それぞれ2と解釈されない。これの違いが分かってないと、MS-DOSのコマンドをそのまま貼り付けた時に、思った通りの挙動をしてくれないこととなる。
コマンドモードの中で、式モードとして解釈させたい場合は括弧()で括る必要がある。
echo (1 + 1)
←2という結果。
echo (Get-Location)
←Pathが出力される。 -
ネットワークドライブと接続
$net = new-object -ComObject WScript.Network $net.MapNetworkDrive([ドライブローカル名], [UNC名], [マッピング情報をプロファイルに格納するか、しないか], [ユーザー名], [パスワード]) $net.MapNetworkDrive("Z:", "\\192.168.x.x\arimasou16", $false, "username", "password")
-
標準出力を文字エンコーディングをしてファイル出力
| Out-File $cfmfile -encoding UTF8
-
外部プログラムを実行
-
制御を移さないまま(結果を待たないで)実行
& "E:\Downloads\software\sakura\sakura.exe" "test.txt"
-
制御を移して(結果が待って)実行
Start-Process -FilePath "E:\Downloads\software\sakura\sakura.exe" -ArgumentList "test.txt" -Wait
-
-
メッセージボックスの表示 Windowsフォームのロードすることで、ウィンドウ処理が行えるようになる。
[Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms"); [Windows.Forms.MessageBox]::Show([内容],[タイトル]); # YesNoのメッセージボックス(注意) $ret = [System.Windows.Forms.MessageBox]::Show([内容],[タイトル], [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
-
処理終了
exit
以上を踏まえて、MS-DOSで書いていた以下のrobocopy\MyMusic.batファイルを
MyMusic.bat
@echo off
if exist z:\. net use z: /delete /yes
if not exist z:\. net use z: \\UBUNTU\arimasou16
set cfmfile=log\ConfirmationMusic.log
set logfile=log\MusicBackupLog_%date:~-10,4%%date:~-5,2%%date:~-2,2%.log
robocopy "E:\My Music" Z:\Public_Music\ * /S /COPY:DAT /DCOPY:DAT /PURGE /FFT /XO /XA:S /XF *.flac *.wave *.mp4 /XD Incoming iTunes /R:0 /L /FP /NS /NDL /UNICODE /UNILOG:%cfmfile%
echo msgbox
"バックアップ(音楽)の予想が出来ました。確認して下さい。",vbExclamation,"メッセージ" > %TEMP%/msgboxtest.vbs
%TEMP%/msgboxtest.vbs
start E:\Downloads\software\sakura\sakura.exe %cfmfile%
PAUSE
del %cfmfile%
robocopy "E:\My Music" Z:\Public_Music\ * /S /COPY:DAT /DCOPY:DAT /PURGE /FFT /XO /XA:S /XF *.flac *.wave *.mp4 /XD Incoming iTunes /R:0 /FP /NS /NDL /NP /UNICODE /UNILOG+:%logfile%
echo msgbox
"Musicのバックアップが完了しました。",vbInformation,"メッセージ" > %TEMP%/msgboxtest.vbs
%TEMP%/msgboxtest.vbs
robocopy\Muisc.PS1に変えた。
Muisc.PS1
[String]$netdrive = Get-PSDrive | Where-Object {$_.Name -eq 'Z'}
if($netdrive -eq $null){
Write-Output ("Zと繋がってません。")
(new-object -ComObject WScript.Network).MapNetworkDrive("Z:", "\\192.168.x.xx\arimasou16", $false, "user", "password")
}
$cfmfile = (Split-Path $MyInvocation.MyCommand.Path -parent) + "\log\ConfirmationMusic.log"
$logfile = (Split-Path $MyInvocation.MyCommand.Path -parent) + "\log\MusicBackupLog_" + (Get-Date -Format "yyyyMMdd") + ".log"
robocopy "E:\My Music" Z:\Public_Music\ * /S /COPY:DAT /DCOPY:DAT /PURGE /FFT /XO /XA:S /XF *.flac *.wave *.mp4 /XD Incoming iTunes /R:0 /L /FP /NS /NDL /UNICODE /UNILOG:$cfmfile > $null
[Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
Start-Process -FilePath "E:\Downloads\software\sakura\sakura.exe" -ArgumentList $cfmfile -Wait
[String]$ret = [System.Windows.Forms.MessageBox]::Show('バックアップ(音楽)の予想が出来ました。処理を継続しますか?', '確認メッセージ', [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
Remove-Item $cfmfile
if ($ret -eq 'No') {
exit
}
robocopy "E:\My Music" Z:\Public_Music\ * /S /COPY:DAT /DCOPY:DAT /PURGE /FFT /XO /XA:S /XF *.flac *.wave *.mp4 /XD Incoming iTunes /R:0 /FP /NS /NDL /NP /UNICODE /UNILOG+:$logfile > $null
[System.Windows.Forms.MessageBox]::Show('Musicのバックアップが完了しました。', '終了メッセージ')
PowerShellはダブルクリック起動とかはショートカットとかでやるしかないらしいので、リンク先を
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe E:\MyDocument\robocopy\robocopy.PS
として作った。