[!] この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
PowerShellを使いこなしてWindows操作を自動化しよう
PowerShellとは、Windowsならデフォルトで必ず入っている強力なスクリプト言語です。Windows 10からはデフォルトのシェルがコマンドプロンプトからPowerShellに変わったので、使ったことがある方もいるかと思います。
「スクリプト言語」と書いたとおり、PowerShellではインタラクティブなコマンド実行だけでなく、スクリプトを記述して実行することで一度に多くの処理が可能です。
コマンドプロンプトにおいてもバッチファイルを作成すれば同様のことはおこなえますが、PowerShellではバッチよりも強力かつ、可読性の高いコードを書くことができるようになっています。
この記事では、最近のWindows自動化においては欠かせない存在となってきているPowerShellスクリプトを習得・技術向上したい方に向けて、Tipsをご紹介します。
PowerShellでできること
-
Windowsのコマンドプロンプトでできることすべて
-
WMIオブジェクトを使うことができるので、Windowsシステム管理もPowerShellから実行することができる
- VBScriptでもWMIオブジェクトにアクセスして情報を取得することなどが可能だが、PowerShellだとより簡単にアクセス・編集できる
-
CSVやJSONといった設定ファイルでよく使われる形式のファイル読み込みをサポートしているため、複雑な設定が必要でも設定ファイルを作成して読み込ませるだけでよい
-
.NETのライブラリも使用できるため、C#で記述できる処理ならおおむねPowerShellでも書ける
- しかもコンパイルも必要ない
- ただし、PowerShellから.NETのライブラリを使用するための記法はスクリプト言語にしては少し複雑
他にも、オブジェクト指向的概念や、強力なフォーマッタなど利点は様々ですが、この辺りに留めておくことにします。
今回のテーマ
新しく導入したPCで普段使いのための設定と簡単な開発環境を整えることを想定し、以下のような設定をしたいとします。
- ホスト名を変更する
- ユーザーをドメインに参加させる
- プリンタの設定をする
- 共有ディレクトリへのショートカットを作成してデスクトップに配置する
- Gitをインストールする
完成したスクリプトから先に見たい方はこちらをご覧ください。
Tips
引数の設定
実行時に、環境やタイミングによって使用する値や挙動を変えたい場合がありますよね。
今回の例では、後述する設定ファイルを読み込むことで使用する値を柔軟に変更したいのですが、作成した設定ファイルを必ずスクリプトがある所定のディレクトリに配置して……という仕様にすると少し面倒です。そこで、設定ファイルのパスを実行時引数として渡せるようにします。
PowerShellでは、基本機能で実行時引数を名前を指定して定義することができます。
他の多くの言語では、引数指定は可能でも、順不同に引数を設定するためには引数解析器を自前で実装しなければならないものがほとんどです。
しかし、PowerShellでは以下のように書くだけです。
Param ( [parameter(Mandatory=$true)][string]$ConfigFilePath)Paramセクションの中で指定した変数が、実行時に指定できる引数(オプション)になります。引数には型を指定することができ、これによって後々の扱いが簡単になります。
また、引数の属性を指定することができます。今回指定している(Mandatory=$true)とは、「この引数は実行時に必須です」という意味です。もしこの属性の引数がスクリプト実行時に指定されなかった場合、入力を促されます。
PS C:\Current > powershell .\script.ps1ConfigFilePath:逆に必須ではない引数はどのようになるのかというと、初期化されていなければ$nullになります。初期化する場合は以下のようにします。
Param ( [string]$Path = "C:\Users")他によく使われる便利な属性としては、switchがあります。この属性を指定した引数はスイッチオプションとなり、スクリプト内ではboolean変数のように使用することができます。デフォルト値は$falseで、指定されたときだけ$trueになります。
Param ( [switch]$Debug)ライブラリの分離
複数のスクリプトから参照したい定数や関数をライブラリとして分離することができます。
今回は後述のタスクスケジューラで使用する定数を分離したいため、SetupLib.ps1というファイルを作成してそこに定数定義を書くこととします。ドメイン名のようなユーザーによって変わることのない値も定数としてここに定義しています。
$SCHTASK_NAME_MAIN = "SetupMain"$DOMAIN_NAME = "example.co.jp"作成したファイルは下記のように書くことで読み込むことができます。現在実行しているスクリプトと同じディレクトリにあるという想定で、スクリプト自身のパスをあらわす自動変数$PSScriptRoot(※1)を使用してパスを指定すると以下のようになります。
. "$PSScriptRoot\SetupLib.ps1"なお、相対パス指定をすることもできますが、スクリプトの実行ロケーションからの相対パスになるため、基本的には非推奨です。
関数
さて、まず最初にホスト名を変更し、ユーザーをドメインに参加させましょう。ここではAdd-Computerというコマンドレットを使用します。このコマンドレットはドメイン参加とホスト名変更を一度に実行できる優れものです(※2)。
このコマンドレットにはドメイン参加のためのCredentialオブジェクトを指定する必要があるため、オブジェクトをスクリプト内で作成することになります。しかし、スクリプト中に本筋と異なる処理が書かれていると読みにくくなってしまいますので、ここではユーザーIDとパスワードを渡せばCredentialオブジェクトを返してくれる関数を作成することにします。
function New-PSCredential($Id, $Pass) { $SecurePassword = ConvertTo-SecureString -String $Pass -AsPlainText -Force $Credential = New-Object System.Management.Automation.PSCredential($Id, $SecurePassword) return $Credential}このようにPowerShellでも関数が書けるのですが、PowerShellの関数を使用する上で最も注意しなければならないのは、PowerShellでは関数の戻り値が「関数内で実行したコマンドの出力すべて」になることです。
上記の関数では可読性を重視して便宜的にreturnを記述していますが、本来PowerShellでのreturnは制御を呼び出し元に返す以上の意味を持ちません。
そのため、実はreturnはなくても同じ動作になります。すなわち、「$Credential変数の中身を参照する」というコマンドの出力が戻り値になっているのです。
今回の例では上2行がコマンドの出力を変数に格納しているため出力がなく、出力を持つのは最後の一行だけであるため、この関数の戻り値を取得するとPSCredential型のオブジェクトがひとつ得られるのみです。
では以下のような例ではどうでしょうか?
function New-textFile($DirName, $FileName, $Content) { New-Item $DirName -ItemType Directory $FilePath = "$DirName\$FileName" New-Item $FilePath Set-Content -Path $FilePath -Value $Content $result = Get-Content $FilePath return $result}この関数の戻り値を取得して表示すると以下のようになります。
PS C:\Current > $newTextResult = New-textFile -DirName "hoge" -FileName "fuga.txt" -Content "piyopiyo"PS C:\Current > $newTextResult
ディレクトリ: C:\Current
Mode LastWriteTime Length Name---- ------------- ------ ----d----- 2022/09/20 13:45 hoge
ディレクトリ: C:\Current\hoge
Mode LastWriteTime Length Name---- ------------- ------ -----a---- 2022/09/20 13:45 10 fuga.txtpiyopiyoGet-Contentコマンドレットだけでなく、New-Itemコマンドレットの出力も一緒に入っていることがわかります。
試しに戻り値に対してGetType()メソッドを叩いてみると以下の結果が得られます。
PS C:\Current > $newTextResult.GetType()
IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Object[] System.Arrayこのように、関数内で複数の出力を持つ場合、戻り値はObject型の配列で取得することになります。したがって、return $resultの値のみを得たい場合は、戻り値の配列の末尾を見る必要があります。
このような仕様があるため、PowerShellで関数を作成する場合は、出力のあるコマンドレットを使用する際にパイプでOut-Nullに繋げるか、そもそも呼び出し元で戻り値を取得するような使い方をしないのがベターであると言えるでしょう。
JSONファイルの読み込み
ドメイン参加のためにユーザーIDとパスワードが必要になりますが、設定するPCによって当然アカウントは異なります。
こういった環境によって異なる値を設定するために、設定ファイルを作成します。今回はJSON形式の設定ファイルを作成して読み込んでみることにしました。
{ "hostname": "COMPUTER-ABCD", "domainuser": { "name": "alpha", "password": "fugapassword" }}JSON形式のファイルを読み込むためには、以下のようなスクリプトを記述します。
$configJson = ConvertFrom-Json -InputObject (Get-Content $ConfigFilePath -Raw)$newHostName = $configJson.hostname読み込みに使用するConvertFrom-Jsonコマンドレットは、ファイルパスではなくInputObjectにstring型のJSONテキストを指定しなければならないので、ファイルをGet-Contentで読み出したものを指定しています。
取得したオブジェクトはメンバとしてJSONファイルのキーを持ち、.でキーを指定することで値を取り出せます。
なお、ひとつ注意しなければならないのが、JSONファイルのキー名にハイフン(-)を使用してはならないという点です。これは、PowerShellではハイフンがついている文字列をコマンドレットとして認識してしまい、正常に動作しなくなるためです。
再起動後に別のスクリプトを続けて実行したい
無事にホスト名の変更とドメイン参加が終わりました。ただ、この設定を反映するにはコンピューターを再起動しなければなりません。一度スクリプトを実行してしまえばすべての設定が完了するようにしたいところですが、Restart-Computerコマンドレットの後に処理を書いていても当然実行されません。
そのため、その後の処理は別のスクリプトに分けて、再起動後にそのスクリプトを実行するように設定しましょう。
$nextScriptPath = "$PSScriptRoot\SetupMain.ps1"$adminPass = $configJson.adminpassschtasks.exe /create /tn $SCHTASK_NAME_MAIN /tr "powershell $nextScriptPath -ConfigFilePath $ConfigFilePath" /RU "Administrator" /RP "$adminPass" /sc ONSTART /delay 0:30
Restart-Computer -ForceこれはPowerShellでもコマンドプロンプトでも(おそらく)同じ方法になると思いますが、タスクスケジューラ(schtasks.exe)を使用します。
schtasksの詳細な説明は省きますが、ポイントは以下です。
/trオプションで実行するコマンドを指定しますが、PowerShellスクリプトの実行なのでpowershell.exeからスクリプトを実行するように指定します。- 管理者権限で実行させますが、パスワードを指定する必要があるため、コンフィグファイルから読み出したパスワードを
/RPオプションに指定しています(※3)。 - ユーザーが何もしなくても実行できるよう
/scオプションにONSTARTを指定して起動時に実行するようにしています。このとき、システム起動直後だと何か問題がある可能性を考慮して30秒/delayを入れていますが、無くてもいいかもしれません。 /tnオプションで指定するタスク名は、後で実行するスクリプトでタスクの削除ができるように、スクリプトで共有するライブラリファイルに記述した定数で設定するようにしています。
次のセクションからは別スクリプト(SetupMain.ps1)に再起動後の処理を書いていきます。
プリンタの設定をする
次はプリンタの設定をします。地味なのですが、実はPowerShellにはプリンタの設定をおこなうことができるコマンドレットが存在します。
Add-Printer -ConnectionName $configJson.printerSet-PrintConfiguration -PrinterName $configJson.printer -PaperSize A4 -Color false -DuplexingMode TwoSidedLongEdge使用方法はおおむね見た通りですが、今回はネットワーク上のプリンタを使用することを想定しているため、Add-Printerコマンドレットの引数に-ConnectionNameを指定していることに注意してください。ローカル接続するプリンタの場合は引数指定が異なります。
WScriptを使用する
ドメインに参加したことで、ドメインアカウントで参照できる共有ディレクトリにアクセスできるようになったかと思います。共有ディレクトリはおそらく仕事上で頻繁に使用することになりますが、サーバーへのアクセスをいちいちエクスプローラーのアドレスバーに入力するのは手間なので、ショートカットを作成しましょう。
しかし、実はショートカットの作成はPowerShellで直接実行することができません(New-Itemコマンドレットで.lnkファイルを作成すること自体はできますが、リンク先を指定することができません)。
ではどうするのかというと、WScriptの力を借ります。
$wsShell = New-Object -ComObject WScript.Shell$shortcut = $wsShell.CreateShortcut($shareFolderLnkPath)PowerShellからWScriptを使用するには、New-Objectコマンドレットを使用してWScriptのシェルオブジェクトを作成します。作成したオブジェクトにドットで使用したいメソッドを繋げることで実行することができます。
別途スクリプトを作成して呼び出すことなく、直接PowerShellスクリプト上に処理を書けるのが良いポイントですね。
作成したショートカットオブジェクトは設定を追加してSave()しないといけないのですが、WScriptについての説明はこの記事の本分から外れるため、ここでは割愛します。後に記載するスクリプト全体にはすべての処理を書いていますので、参考にしてください。
ファイル・フォルダの操作をする
最後に、必要なソフトウェアをインストールしていきます。今回はGitのインストールを例にスクリプトを書いてみます。
ここでは、Gitインストーラーと設定ファイルは共有ディレクトリ上に置かれているものとし、そこからコピーしてきてからインストーラーを実行します。
$gitInstallerPath = $configJson.sharefoler + "\" + $configJson.gitinstaller$gitConfPath = $configJson.sharefoler + "\" + $configJson.gitconf$localGitDir = "C:\Users\" + $configJson.domainuser.name + "\Downloads\GitInstaller"New-Item -ItemType Directory $localGitDirCopy-Item $gitInstallerPath $localGitDirCopy-Item $gitConfPath $localGitDirディレクトリの作成にはNew-Itemコマンドレットを使用します。ただし、このコマンドレットはデフォルトではファイルを作成するので、ディレクトリを作成する場合には-ItemType Directoryと指定する必要があります。
また、既に存在するファイル・ディレクトリを指定するとエラーになるため(※4)、以下のようにあらかじめ存在確認をしてもよいでしょう。
if (-not (Test-Path $localGitDir)) { New-Item -ItemType Directory $localGitDir}あとは作成したディレクトリにCopy-Itemでコピーするだけです。
他に、ファイルを操作するコマンドレットにはMove-Item, Remove-Item, Rename-Itemなどがあります。
exeファイルなどを実行する
インストーラーがコピーできたので、実行しましょう。
$gitInstallerPath = $localGitDir + "\" + $configJson.gitinstaller$gitConfPath = $localGitDir + "\" + $configJson.gitconf$gitArguments = "/SILENT /LOADINF=$gitConfPath"
Start-Process -FilePath $gitInstallerPath -ArgumentList $gitArguments -WaitPowerShell内で別のスクリプトやインストーラー、C言語等で作成したバイナリを実行する場合、実行したいファイルのパスをStart-Processコマンドレットに渡します。このとき、引数の文字列を-ArgumentListで渡すこともできます(※5)。
なお、別のps1スクリプトを実行したい場合はpowershell.exeを実行して引数に実行したいスクリプトのパスを書く、ということになります。
また、Start-Processコマンドレットは-Waitオプションをつけることでプロセスが終了するまで待ちます。これは、-Waitをつけなければ非同期で動作し、スクリプトはプロセスの終了を待たずに次の処理に移行してしまうということなので、スクリプトで使用する際は基本的には-Waitオプションをつけることになるでしょう。
ちなみに、スクリプトにベタ書きで以下のように記述して実行することももちろん可能です(タスクスケジューラはこの方法で実行していました)。
C:\Users\alpha\Downloads\Git-X.Y.Z-64-bit.exe /SILENT /LOADINF=C:\Users\alpha\Documents\gitconfig.infただ、実行ファイルのパスが変数に格納されている場合、以下のように実行することはできません。
# 間違った例$gitPath = "C:\Users\alpha\Downloads\Git-X.Y.Z-64-bit.exe"$gitPathこれは、$gitPath変数があくまで文字列として認識されているためで、このスクリプトを実行するとexeのパス文字列がただ表示されて終わりになります。このような場合にはStart-Processコマンドレットを使用するとよいでしょう。
.NETを使用する
これで構築は一通り完了ですが、通知が何もないとユーザーからは使いはじめていいのかどうかわからないので、メッセージボックスを表示しましょう。
Add-Type -AssemblyName "System.Windows.Forms"[System.Windows.Forms.MessageBox]::Show("セットアップが完了しました! OKを押すと再起動します。", "Complete", "OK")PowerShellはシェルであるため、基本的にGUIには対応していませんが、.NETのクラスを使用すればウィンドウを出すことができます。
Add-Typeコマンドレットを使用することで、.NETのクラスをインポートすることができます。
インポートしたクラスは[]で囲った上で、該当クラスのメソッドを::で繋げて使用します。
実際にはAdd-TypeでC#のソースコードをそのまま読み込んだり、クラスをオブジェクトとして変数に格納したりもできるのですが、PowerShellのコードとしての可読性が悪くなりがちなので、私はあまりオススメしません(※6)。
できることが広がるのは確かなので、状況に応じて使用を検討してください。
以上で処理は完了ですが、PowerShellスクリプトを書くにあたって補足しておきたい内容が少しありますので、以下に記します。
エイリアスについて
PowerShellではディレクトリ下のファイルを表示するのにGet-ChildItemコマンドレットを使用しますが、dirやlsと入力しても同様の結果が得られます。
これはPowerShellがデフォルトでdirをGet-ChildItemのエイリアスとして設定しているためで、実際に実行されているのはGet-ChildItemコマンドレットであるというわけです。
しかし、この記事のスクリプト内ではこういった便利なエイリアスを意図的に使用していません(例えば、Copy-Itemはcopyで実行できますが、元のコマンドレットを使用しています)。
これは、実行環境によってはユーザーがエイリアスをカスタマイズしている可能性があるためです。極端な話をすれば全然別のコマンドレットがアサインされている可能性もありますし、そうでなくてもオプションをつけて実行できるようにカスタマイズされていれば実行結果が異なってきます。
このため、どのような環境で実行されるかが不明なスクリプトでは基本的にエイリアスを使用しないことが推奨されます。
「コマンドプロンプトで使用していたあのコマンドをPowerShellで使いたいけど、何という名前のコマンドレットかわからない」という場合には、Get-Aliasコマンドレットを使用してください。指定した文字列にアサインされているコマンドレットが表示されます(※7)。
演算子とnull比較
スクリプトを書く際に、オブジェクトや変数のnullチェックをしたくなることがあると思います。
その際、PowerShellでは比較演算子の右辺に$nullを置いてはいけないとされています。
# 駄目な例if ($var -eq $null) { Write-Output "var is null." }これはなぜかというと、PowerShellでは-eqと-ne演算子は左辺に配列が与えられた場合にフィルタとして働くためです。
例えば、以下の式はtrueやfalseではなく、2を返します。
@(1,2,3) -eq 2すなわち、変数そのものが$nullでなくても、変数が配列で、その中に$nullを含んでいた場合には右辺に$nullを書いてチェックしてしまうと結果は$nullになってしまいます(ちなみにPowerShellでは$nullはfalsyな値です)。
$array = @(1, 3 ,5, $null, 9)$array -eq $null # この式は$nullを返す当然、スクリプトは想定と異なる動作をすることになるため、PowerShellでnullチェックをおこなう場合は左辺に$nullを書くようにしましょう。
# 良い例if ($null -eq $var) { Write-Output "var is null." }スクリプト全容
初期状態ではps1スクリプトの実行が許可されていないことが多いため、Set-ExecutionPolicyを手動で実行してからスクリプトを実行するか、以下のようなバッチファイルを作成して実行する必要があります。
AutoSetupWindows.bat
@echo off
rem 管理者権限で実行されているかチェックするため、openfilesを使用する。rem (openfilesは管理者権限がない場合ERRORLEVELを0以外にセットする)openfiles > NUL 2>&1if not %ERRORLEVEL% == 0 ( echo 一般権限で実行されたため管理者権限で再実行します。 powershell Start-Process \"%~f0\" -Verb runas goto exit)
rem スクリプトをRemoteSigned権限で実行powershell -ExecutionPolicy RemoteSigned -File .\scripts\SetupStart.ps1 -ConfigFilePath .\ConfigFile.json以降、セットアップを実行するPowerShellスクリプト本体です。
全部で100行程度あるので折りたたんでいます。クリックするとスクリプトを表示します
SetupStart.ps1
Param ( [parameter(Mandatory=$true)][string]$ConfigFilePath)
. "$PSScriptRoot\SetupLib.ps1"
function New-PSCredential($Id, $Pass) { $SecurePassword = ConvertTo-SecureString -String $Pass -AsPlainText -Force $Credential = New-Object System.Management.Automation.PSCredential($ID, $SecurePassword) return $Credential}
$configJson = ConvertFrom-Json -InputObject (Get-Content $ConfigFilePath -Raw)$newHostName = $configJson.hostname
$newUser = $configJson.domainuser$credential = New-PSCredential -Id $newUser.name -Pass $newUser.password
# 名前がわかりにくいが、これがドメイン参加のコマンドレット# -NewNameオプションを指定することで、ホスト名の変更も同時におこなうことができるAdd-Computer -DomainName $DOMAIN_NAME -Credential $credential -NewName $newHostName -Force
# 再起動後にスクリプトを実行するためのタスク作成$nextScriptPath = "$PSScriptRoot\SetupMain.ps1"$adminPass = $configJson.adminpassschtasks.exe /create /tn $SCHTASK_NAME_MAIN /tr "powershell $nextScriptPath -ConfigFilePath $ConfigFilePath" /RU "Administrator" /RP "$adminPass" /sc ONSTART /delay 0:30
# 念のため再起動前にウェイトを入れるStart-Sleep 5
Restart-Computer -ForceSetupMain.ps1
Param ( [parameter(Mandatory=$true)][string]$ConfigFilePath)
# このスクリプトを実行するために登録したタスクを削除しておくschtasks.exe /delete /tn $SCHTASK_NAME_MAIN /f
$configJson = ConvertFrom-Json -InputObject (Get-Content $ConfigFilePath -Raw)
# プリンタの設定をするAdd-Printer -ConnectionName $configJson.printerSet-PrintConfiguration -PrinterName $configJson.printer -PaperSize A4 -Color false -DuplexingMode TwoSidedLongEdge
# 共有ディレクトリへのショートカットを作成してデスクトップに配置する$shareFolderLnkPath = "C:\Users\" + $configJson.domainuser.name + "\Desktop\sharefolder.lnk"$wsShell = New-Object -ComObject WScript.Shell$shortcut = $wsShell.CreateShortcut($shareFolderLnkPath)$shortcut.TargetPath = $configJson.sharefoler$shortcut.IconLocation = $configJson.sharefoler$shortcut.Save()
# Gitをインストールする(共有ディレクトリからインストーラをコピーする)$gitInstallerPath = $configJson.sharefoler + "\" + $configJson.gitinstaller$gitConfPath = $configJson.sharefoler + "\" + $configJson.gitconf$localGitDir = "C:\Users\" + $configJson.domainuser.name + "\Downloads\GitInstaller"New-Item -ItemType Directory $localGitDirCopy-Item $gitInstallerPath $localGitDirCopy-Item $gitConfPath $localGitDir$gitInstallerPath = $localGitDir + "\" + $configJson.gitinstaller$gitConfPath = $localGitDir + "\" + $configJson.gitconf$gitArguments = "/SILENT /LOADINF=$gitConfPath"Start-Process -FilePath $gitInstallerPath -ArgumentList $gitArguments -Wait
# その他エディタなどのインストールもGitと同様なコードなので、省略
# 完了した旨のウィンドウを表示するAdd-Type -AssemblyName "System.Windows.Forms"[System.Windows.Forms.MessageBox]::Show("セットアップが完了しました! OKを押すと再起動します。", "Complete", "OK")
Restart-Computer -ForceSetupLib.ps1
$SCHTASK_NAME_MAIN = "SetupMain"$DOMAIN_NAME = "example.co.jp"ConfigFile.json
{ "adminpass": "hogepassword", "hostname": "COMPUTER-ABCD", "domainuser": { "name": "alpha", "password": "fugapassword" }, "printer": "\\\\server\\printer", "sharefolder": "\\\\piyonet\\share"}おわりに
PowerShellの魅力が伝わりましたでしょうか?
環境構築だけでなく、Windowsでおこなう定常作業などもPowerShellで自動化できるので、使い方を覚えて業務を効率化していきましょう。
また、今回PC導入時の環境構築というテーマで記事を執筆しましたが、「複数の社内PC・運用しているPCの環境を常に一定に保ちたい」というような課題がございましたら、ぜひ当社の環境復元システム「V-Recover」 ⧉(20台程度の小規模向けに安価でご提供) 、またはPC管理運用システム「V-Boot」 ⧉(大規模な運用向けに、より高度な管理システム)をご検討ください!
脚注
- ※1
$PSScirptRootを使用するにはPowerShell v3以降が必要です。v2以前では別の方法で取得する必要がありますが、相当古い環境でない限りv3よりは新しいので、ここでは割愛します。 - ※2 ホスト名の変更だけをおこなえる
Rename-Computerというコマンドレットもあります。 - ※3 実際の運用ではパスワードを暗号化することが多いと思います。暗号化されたパスワードを復号するスクリプトはこちら ⧉が参考になるかと思います。
- ※4
-Forceオプションを指定した場合はこの限りではありません。今回は新規コンピューターの構築を想定しているので強制作成でも良いと思いますが、場合によっては既存の環境を壊してしまうので-Forceの使用には十分注意しましょう。 - ※5 厳密には
-ArgumentListに渡すのはstring型の配列なのですが、わざわざ配列として定義しなくても動作します。 - ※6 逆に、C#で書いたコードをわざわざコンパイラを通さずに簡単に実行したい、という場合には良いアプローチかもしれません。
- ※7 文字列を指定しない場合、エイリアス設定の一覧が表示されます。一覧を見ると、しばしば使用される
%や?も実はエイリアスであることがわかります。