FileMakerからPowerShellスクリプト実行

FileMakerのスクリプト内でPowerShellを動かしたくなったのですが、概ねうまく行ったのでノウハウを忘れないうちにブログにしておきます。もちろん、Windows版です。PowerShellで動かしたいのは画面ショットです。こちらのサイト「Windowsのコマンドラインからスクリーンショットを撮る(PowerShell)」にそのまま使えるスクリプトがあったので使わせてもらいました。ありがとうございます。また、FileMakerのスクリプトからシェルスクリプトを稼働する方法は、「Claris Community | Powershell script not working」に記載があります。

これで終わるかといえば、それだけならブックマークに忘れないように覚えさせておくだけで終わってしまいます。まず、通常は、Windowsでは、いきなりシェルスクリプトはセキュリティ的な理由で動かせないようになっています。そこで、以下のようなコマンドを、PowerShell等で入れておく必要があります。これで実行権限が与えられます。そのユーザでログインしている間は再起動してもシェルスクリプトは動きます。「Bypass」はなんでも動かすためのものなので、オンラインからの素材は検疫(デジタル署名の確認を)する「RemoteSigned」という設定の方が少しはマシかもしれません。

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser

これが実行されていないと全くスクリプトは動きません。

続いて、前述のClaris Communityのやり取りにもあるのですが、Quote関数を使うことが重要です。スクリプトを実行するためには、「イベントを送信」スクリプトステップを利用し、「送信イベント」は「ファイル/アプリケーションを開く」を選択しておきます。この選択肢は、FileMakerをWindows版で動かさないと出てきません。そして、「計算」を選択して、コマンドを送り込みます。ここで、あるシェルスクリプトにファイル名の引数を付与してPowerShellで実行する場合はこのような式になるかと思います。変数に期待する値などの状況も含めて書きます。

仮定
$scriptPath ← "C:/Users/msyk/myscript.ps1" // シェスルクリプトへの絶対パス
$targetPath ← "C:/Users/msyk/data.bmp" // スクリプトの引数に渡すファイルパス

「イベントを送信」スクリプトステップの「計算」の式:
"powershell.exe -command " & 
Quote(Quote($scriptPath) & " " &Quote($targetPath))

-commandパラメータの引数は、単一の文字列で「コマンドライン」を指定します。ですが、コマンド中に”があると、そこでパラメータが終わっているとシェルは思ってしまうので、全体をQuoteで囲みます。Quoteは全体をQuoteで囲むだけでなく、文字列内部の”は、\”のようにエスケープします。ただ、元のコマンド自体もパスであり、スペースが入る可能性を考えると、やっぱりQuoteします。コマンドラインとしてうまく値を引き渡すには、このQuoteのQuoteで大体うまくいくことがわかりました。

まず、ここで、Get関数を使えやと思うところかと思いますが、FileMakerのGet (ドキュメント)等は、「/C:/Users/msyk/Documents/」のように、頭に/がついてしまいますが、それだとPowerShellは正しくパスとして認識しません。C:/Users/…のように記述されていないといけないようです。ということで、Get関数の結果を文字列処理するか、いっそのこと、絶対パスを文字列で書くか、まあ、その辺りはソリューションに応じて頑張ってください。

もう1つ、ファイル名に使ってはいけない文字列があることを忘れないでください(例えば、こちらのサイトで一覧されています)。|や/はファイル名としては使えません。これらは、Substitute関数で置き換えてから、PowerShell実行スクリプトの引数に与えます。また、ファイル名として使えない名前(COM1など)もあるので、何かで取得した名前をファイル名として利用する場合にはデータを俯瞰して対策は必要になります。