有馬総一郎のブログ

(彼氏の事情)

2013年03月20日 23:14:00 JST - 4 minute read - PowerShell

PowerShellを使ってみる その2

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

有馬総一郎のブログ

として作った。

Tags: PowerShell

PowerShellを使ってみる その1 robocopyでのUNICODE出力の謎