第1回 VBScript PowerShellのScriptのドラッグ＆ドロップ可能なショートカット作成

#はじめに
PowerShellは、Scriptファイルをダブルクリックしても、実行できません。
Scriptファイルにドラッグ＆ドロップもできません。
それは私にとってはかなり不便です。というのも、だいたいScriptをダブルクリックするか、そこにファイルやフォルダをドラッグ＆ドロップして、Scriptを実行させることが多いからです。
そこで、調べてみると、どうやらショートカットを作成することで、Scriptをダブルクリックで実行したり、ドラッグ＆ドロップしたりできるとわかりました。
そこで、ショートカットを作成するVBScriptの作成です。
PowerShellでショートカットを作成するScriptもネットに見つけましたが、やはり実行ポリシーが面倒なので、VBScriptでいいかなと思いました。

#今回実施する内容
PowerShellのScriptのドラッグ＆ドロップ可能なショートカットを、VBScriptで作成します。
正確には、PowerShellのショートカットだとは思いますが・・・

#ソースコード(Git Hub)
[VBS_01_PSShortcut](https://github.com/Build-Mount/VBS_01_PSShortcut)

#環境
OS: Windows 10 JP (64bit)
PowerShell version: 5.1.19041.1

#参考
[PowerShellスクリプトへのショートカットを作成する](https://www.atmarkit.co.jp/fwin2k/win2ktips/1024psshrtct/psshrtct.html)
PowerShellのScriptのショートカットを作成して、ショートカットで実行する方法が記載されています。

[PowerShellを使用してショートカットを作成する方法](https://www.it-swarm.dev/ja/powershell/powershell%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/941785948/)
PowerSehllでショートカットを作成する方法が記載されています。

#用語

#PowerShellのScriptを実行するショートカット
詳しくは、[PowerShellスクリプトへのショートカットを作成する](https://www.atmarkit.co.jp/fwin2k/win2ktips/1024psshrtct/psshrtct.html)を見ていただければと思いますが、要するに、**Powershellのショートカットを作成し、その引数にScriptを持ってくるだけ**です。
コマンドプロンプト上で、実行するのと同じものをショートカットで実行するだけです。

ショートカットを手動で作成するならば、**リンク先**に以下を記載すればよいだけです。

```
powershell -NoProfile -File Scriptパス
```

ついでに、実行ポリシーも追加して、`-ExecutionPolicy Unrestricted`を追加すると以下です。

```
powershell -NoProfile -ExecutionPolicy Unrestricted -File Scriptパス
```

ざっとオプション説明を記載すると、
`-NoProfile`は、「Windows PowerShellプロファイルを読み込みません。」とヘルプに説明がありました。
要するに、プロファイルに保存した関数などは読み込まないということです。
今のところ、単体のScriptファイルだけでなんとかなっているため、これでOKです。

`-ExecutionPolicy`は、「現在のセッションの既定の実行ポリシーを設定し、 $env:PSExecutionPolicyPreference 環境変数に保存します。このパラメーターでは、レジストリに設定されている Windows PowerShell 実行ポリシーは変更されません。」とヘルプに説明がありました。
ExecutionPolicyは、デフォルトで`Restricted`となっており、PowerShellを実行できないため、起動時に変更します。
今回は`Unrestricted`にしましたが、`RemoteSinged`でもよいかもしれません。
自分で使用するだけならば、すでに`RemoteSinged`を設定しているためこの設定は不要ですが、誰かに配布することを考えて、Unrestrictedをショートカットで設定します。

#VBScriptでショートカットを生成
上記に記載した内容をショートカットに記載すればよいわけですが、ショートカットを自分で修正するのが面倒なため、VBScriptで作成すれば、もっと楽というわけです。
使い方は簡単で、**ショートカットを作成したいPowerShellのScriptファイルを今回作成するVBScriptにドラッグ＆ドロップ**すると、**PowerSehllのScriptファイルと同じフォルダに、ショートカットが作成**されます。

```VisualBasic:CreatePSShortcut.vbs
'PowerShell Scriptをドラッグ＆ドロップして起動するためのショートカット作成

Const C_LINK = ".lnk"
Const C_PS = "powershell.exe"
Const C_PS_ARGS = "-NoProfile -ExecutionPolicy Unrestricted -File "

Call Main()

'本Scriptのメイン
Public Function Main()
	Dim strFileNameWPath

	Set objWS = WScript.CreateObject("WScript.Shell")
	strFileNameWPath = GetArguments			'ドラッグ＆ドロップしたファイルのパス取得
	Call CreatePSShortcut(strFileNameWPath)	'PowerShellのショートカット生成
End Function

'ドラッグ＆ドロップしたしたパスを含むファイル名を取得する。
'ドラッグ＆ドロップしていない、もしくは２つ以上のファイルをドロップした場合にはエラーで応答する。
'
'@return string ドラッグ＆ドロップしたファイルのパス。
Private Function GetArguments()
	Dim i				'ドラッグ＆ドロップしたファイルのパスを確認するループ用カウンタ
	Dim objFSO

	Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

	If WScript.Arguments.Count = 0 Then
		MsgBox("対象のファイルをドラッグ＆ドロップしてください。")
		WScript.Quit()
	End If

	If WScript.Arguments.Count > 1 Then
		MsgBox("ドラッグ＆ドロップファイルは１つだけにしてください。")
		WScript.Quit()
	End If

	If objFSO.FolderExists(WScript.Arguments.Item(0)) Then
		MsgBox("フォルダではなくファイルをドラッグ＆ドロップしてください。")
		WScript.Quit()
	End If

	GetArguments = WScript.Arguments.Item(0)
End Function

'strFileNameWPathをもとにPowerShellのショートカットを、strFileNameWPathのあるフォルダに生成する。
'
'@strFileNameWPath string パスを含むファイル名。
Private Function CreatePSShortcut(strFileNameWPath)
	Dim objFSO, objWS
	Dim objLink
	Dim strFileLink
	Dim strLinkPath

	Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
	Set objWS = WScript.CreateObject("WScript.Shell")

	strFileLink = objFSO.GetParentFolderName(strFileNameWPath) + "\" _
				+ objFSO.GetBaseName(strFileNameWPath) _
				+ C_LINK
	Set objLink = objWS.CreateShortcut(strFileLink)
	objLink.TargetPath = C_PS
	objLink.Arguments = C_PS_ARGS + strFileNameWPath
	objLink.Save
End Function
```

コードの説明です。
##Main関数
ドラッグ＆ドロップされたファイルを確認する関数と、ショートカットを作成する関数を呼び出しているだけです。

##GetArguments関数
ドラッグ＆ドロップされたファイルを検査し、適切ならばファイルパスを応答します。
検査では、「ドラッグ＆ドロップされたか？」、「１つのファイルだけか？」、「フォルダではないか？」だけを確認します。拡張子は今のところ確認していません。

##CreatePSShortcut関数
ショートカットを生成します。
`objLink.TargetPath`に、ショートカットを設定するファイル（powershell.exe)を設定します。
`objLink.Arguments`に、オプションを設定します。今回は上記に記載したオプションを設定します。


#おわりに
今回は、PowerShellのショートカットを作成するVBScriptを作成しました。
ざっと15分程度で作成したので雑ですが、意地悪な使い方をしなければ、このくらいで十分かなと思います。
この手のScriptなどは、ネットでたくさん見つけましたが、ブラウザのお気に入りにいれることもしばしばありますが、たいてい見つからなくなってまた探す羽目になるため、Qiitaにまとめるほうが、自分的には見つかるかなとの思いで投稿しました。


#更新履歴
|日付|更新箇所|内容|
|:--|:--|:--|
|2020/08/12|はじめに|誤記・体裁修正|
|2020/08/12|参考|[PowerShellを使用してショートカットを作成する方法](https://www.it-swarm.dev/ja/powershell/powershell%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/941785948/)を追加。|
|2020/08/12|VBScriptでショートカットを生成|誤記・体裁修正|
|2020/08/12|おわりに|誤記・体裁修正|