【オフィスワーカー必見】定型タスクはPowerShellで半自動化しよう~文字列置換メール作成スクリプト~
定型タスクはつまらない
僕は仕事を減らしたい。削除、コピペの連続みたいな定型タスクはつまらない。できるだけ暇になるか、もっと面白い作業に取り組みたい。だから定型メールの一部はPowerShellにさせている。自動化しているのだ。
今所属しているプロジェクトでは、運用チームに連携内容などを引き継いでいる最中だ。運用チームのタスクの中に毎月末お客さんに連絡するという作業がある。ただ、これがかなり大変で、何十社もある会社に対して名前の入れ替えを手動ですると膨大な時間がかかる。今日はその連携用メールを書かなくてはならなかった。毎月やるのがめんどくさいのでPowerShellで半分自動化してみた。 どうも、エンジニア兼大学生のタイガ(pf.tiger)です。ちなみに、これはエンジニアじゃなくても少し頑張ればできることだ。
はやくスクリプトを読みたくて仕方がない人は、目次にある「実際のスクリプト」の項目をクリック。
目次
- 定型タスクはつまらない
- PowerShellとは
- PowerShellスクリプトとは
- なぜオフィスワーカーとエンジニアにPowerShellスクリプトなのか
- テンプレ半自動化PowerShellスクリプトの設計
- 実際のスクリプト
- 今度取り組んでみたいこと
- 追記:
- 参考文献:
PowerShellとは
PowerShell(パワーシェル)とは、Windowsのコマンドラインツールで、CMDよりもよりパワフルかつLinuxライクな仕様になっている。自動化や、システム管理によく使用されている。GUIのバックグラウンドが青色であることも特徴の一つだ。より複雑なコマンドを実行することができ、処理の負担はCMDよりも大きいが、自由度が高いものになっている。もちろんCMDでできることはたくさんあるが、一部コマンド名が同じことからPowerShellのほうがLinuxと親和性が高いように感じる。LinuxとWindowsを両方使うのであればCMDよりもPowerShellのほうが板につきやすいといえるだろう。
PowerShellスクリプトとは
PowerShellスクリプトとはPowerShellで使用できるコマンドをまとめて、一連の作業にしたもの。1行のみのスクリプトはワンライナー(One-Liner)と呼ばれる。テキストベースのファイルにしたものはスクリプトファイルという。ファイル拡張子は.ps1。コマンドラインに不慣れな人であっても、ps1ファイルを右クリック→PowerShellで実行をクリックで実行できる。決まった作業であればコマンドを打ったり、マウスやショートカットで細かく操作するよりすごく簡単だし、大きな時短になる。また、自動化されるので人間とは違い、指令にミスがなければ処理にミスもない。作業内容の修正も必要がなくなるかもしれないのだ。
なぜオフィスワーカーとエンジニアにPowerShellスクリプトなのか
PowerShellは筋トレ。プログラミングは野球。PowerShellはエンジニアだけでなく、オフィスワーカーにもおすすめだ。Windowsであればほかに何もインストールしないで使えるから。依存関係がほぼない(使用自体が禁止されていれば別)ことを理由にPowerShellを使うことにした。
ほかのソリューションもあるが、追加で用意しないといけないものがある。Pythonで書くとPythonをインストールしていない人は使えないし、ほかの言語だとコンパイルしないといけない。コンパイルができたとしても.Debや.exeなど実行すらできない場合もある。コンプライアンスやセキュリティポリシーが原因で、簡単なプログラミング言語、Non-Techフレンドリーと称されるPythonさえも使わせてもらえないかもしれないのだ。
だが、PowerShellはWindowsにデフォルトで入っている。Macユーザの人はすぐに使えないが、大半の業務用PCはクリエイティブ業界をのぞいてWindowsなので非常に汎用的だ。一応Macで使う方法もあるが、自己責任で。
トラブルシューティングの必要性もあるので、権限が必要なコマンド以外は使えるはずだ。セキュリティの制限はそこまで関係ない。プログラミング言語は野球みたいなもので、PowerShellは筋トレのようなものだ。野球は道具(環境)がないとできない(やりづらい)が、筋トレは道具(環境)なしでもすることができる。バットが凶器とみられることがあっても、体は凶器とみなされない。(しつこい)
テンプレ半自動化PowerShellスクリプトの設計
Automation Vectors by Vecteezy
くどい比喩は置いといて、ここではメインのスクリプトについて紹介する。概要と設計、要件について簡単に説明。
スクリプトの概要
指定したテキストファイルの特定の文字列を、変数で割り当てた文字列に置換する。いいかえると、テンプレートで変更が必要な部分を一括で変換してくれるスクリプト。置換する箇所が多ければおおいほど時間短縮が効果的になるスクリプトだ。
テンプレ半自動化の要件
- スクリプトに対応したテンプレがすでに存在していること。(一番重要)
- テンプレのなかで変換したい文字列が適切に使用されていること。
- 置換の対象の文字列がユニークで、誤変換のリスクが低いこと。
ダメな置換の具体例:
- 置換対象:AD
- 置換後の文字列:Android
- 元テキスト: ADVENTURE WORLD HAS PRODUCED AN AD
- 置換後のテキスト:AndroidVENTURE WORLD HAS PRODUCED AN Android
最後のADの部分を置換したかったにも関わらず、主語にAD(置換対象)が含まれているのでADVENTUREの部分がAndroidVENTUREに変換されてしまった。置換対象の文字列は意図しない置換を避けるため、ユニークかつ偶然発生することのない文字列にしよう。
スクリプトのタスクフロー
このスクリプトのタスク(処理)のフロー。
今回紹介するスクリプトでは反復処理などを含んでいないので、順序表示にしている。
- テキストのテンプレートを用意する
- 変数を用意する
- テンプレートのテキストデータをゲット
- 3のテキストデータに存在する指定した文字列を変数の値に変換する
- 加工されたテキストデータを別ファイルとして出力する
実際のスクリプト
実務でつかったファイルは出せないので同じ仕組みのスクリプトを掲載。もちろんコピペOK!試す場合、使用する場合は自身で変数の値を変更してください。先ほど説明したように要件としてスクリプトに対応したテンプレートじゃないとうまく置換できないので注意。
(今回は編集モードの都合上スクリプトを埋め込むことができませんでした。次から気を付けます。引用形式で貼っておきます。)
<実際のスクリプトを挿入>
- 変数の定義
- 実行対象ファイルの絶対パス
- 置換後の値
- テキストデータの参照
- テキストデータをメモリに保存し置換を実行
- 置換後のテキストファイルを書き出し(上書き禁止状態)
$template_path = "template_path"
$company_name = "KIDTiger, LLC"
$company_abrv = "KIDT"
$sender_name = "Tiger"
$day = "13th"
$month = "June"
$year = "2022"
#actual replacing process
Get-Content -Encoding UTF8 ./template.txt `
| ForEach-Object {$_ -replace "YYYY", $year} `
| ForEach-Object {$_ -replace "MM", $month} `
| ForEach-Object {$_ -replace "DD", $day} `
| ForEach-Object {$_ -replace "company_name", $company_name} `
| ForEach-Object {$_ -replace "sender_name", $sender_name} `
| ForEach-Object {$_ -replace "company_abrv", $company_abrv} `
| Out-File -Encoding UTF8 $company_abrv$month$year.txt -NoClobber
実行前(Template.txt)
実行後(KIDJune2022.txt)
To KIDTiger, LLC,
I am Tiger from TigerSecurity, LLC.
This is a reminder of the monthly meeting for June, 2022.
The meeting will be hosted on 13th, June, 2022.
Thank you for your cooperation.
Best regards,
デスクトップで実行すると、ちゃんとTXTファイルが生成されている。また、ファイル名も会社名の略称+月+年になっている。
カギとなる置換のスクリプト:
置換のカギとなるコマンドは以下のようになっている。
非常にシンプルだ。
<置換のスクリプト>
これで対象テキストに存在するすべてのcustom_textを$replacement_str に変換する。せっかくかいたものの、僕が働いている会社ではセキュリティ上の都合からPs1ファイルは実行できなかった。なので、コマンド部分をコピー&ペーストという手法で使用している。実際、十分に機能していて、15分かかっていた作業が4分くらいに短縮された。
もし可能であればClipコマンドなどを合わせ、クリップボードにコピーしてもいいかも。文字コードの問題や、クリップボードにある内容が失われる場合もあるので要注意。自動化することは楽しいと感じたし、役立つが、メール送信などセンシティブな部分があるので自動化に関してルールを設けたほうがいいと感じた。
今度取り組んでみたいこと
制作時間:2時間
もっとPowerShellコマンドを学び、いわゆる「つまらないこと」を自動化し たい。今の処理のレベルはまだシンプルなので、より複雑なタスクも自動化してミスを減らしたいと思う。PowerShellを使いこなして暇になるか、その時間分なにか面白いことをしたい。朝の出勤報告も自動化しようなんて考えたこともあったが、さすがにそれはイレギュラー対応が難しいのでやめておく。
もちろん自分のアイデアがベースになっているものの、ほぼ参考文献のパクリになってしまっている。もう少し自分で考えられるようになりたい。QiitaやStackOverflowに頼りすぎなエンジニアになりたくはない。今回は引き継ぎという短い時間のなかだったため、スピーディに完成させられたのでよかった。慣れの問題だと思うので、必要に応じて学び、できることを増やす。Oreillyのウェブサイトにあるタスク自動化に関する本を片っ端から読んでいく。もっとテクいOne-Linerを書いていきたい。
追記:
この記事を書いている最中の数日間でスクリプトをステップアップさせ、CSVファイルの読み込みとCSVファイルのデータを変数に代入、一回の実行で各社分繰り返すなど、自分なりにいろいろできるようになった(結局セキュリティの都合上スクリプトは見せられませんが、記事にします)。これからもいろいろ学んだことを書いていく。「タイガのたわごと、ガチすぎてたわごとじゃねえ!」なんてツイッターで言われるくらい意味のある内容を掲載予定。
ちなみに、この記事ではエンジニア兼大学生の僕が仕事と勉強で大切だと思ったことを書いています。実生活でかなり使えるので読んでください。
tigerpicsnfilms.hatenablog.com
PowerShellスクリプトに関するこの記事を読んで「ほぉーん…」と頭の中でつぶやいた人はインスタをフォローしてください。そしてなにより、この記事をシェアして情報を発信する側になりましょう。
参考文献:
Qiitaのスレッド
PowerShellのdocumentation - microsoft