PowerShellスクリプトでWindows10を使いやすくする

## はじめに

方法の概要は以下のとおりです。
　　PowerShellスクリプトをつくる
　　→ 起動用ショートカットをPATHの通ったフォルダにおく
　　→ 「ファイル名を指定して実行」（Windows + Rキー）から実行する

<strong>方法の詳細</strong>や<strong>PATHの通し方</strong>については以下の記事をご参照ください。
[PowerShellスクリプトを「ファイル名を指定して実行」で即座に実行する](https://zenn.dev/takeaship/articles/execute_psscript_immediately)
[Windows 10 で PATH 環境変数を設定する方法](https://qiita.com/yuki12/items/9723f60907508b11504b)

当記事は、Windows10の定型操作を省力化する簡単なPowerShellスクリプトと起動用ショートカットの作成ツールを紹介させていただく内容となっております。

## 簡単なPowerShellスクリプトの例1：複数のWebページを開く

私が英語学習のために利用するWebサイトをEdge（inPrivateウィンドウ）で開くためのスクリプトを紹介させていただきます。

```Powershell eng.ps1
$urls = @()
$urls += "https://www.deepl.com/ja/translator"
$urls += "https://eow.alc.co.jp/"
$urls += "https://eikaiwa.dmm.com/app/daily-news"

foreach($url in $urls)
{
    Start-Process msedge.exe -ArgumentList $url,"-inprivate"
}
```

ブラウザのお気に入りからポチポチ開いても大した手間ではないかもしれませんが、
「ファイル名を指定して実行」（Windows + Rキー）→ "(ショートカット名)" と入力するだけの方が楽だと思いませんか？
ショートカット名を "en" 等のように短くすることで、たった1～2秒の入力で複数のWebページにアクセスできます。

ポイントは「ファイル名を指定して実行」後の入力文字を（ショートカットをリネームすることで）<strong>任意指定</strong>できることです。
ショートカット名にできるならば、短い文字列や覚えやすい日本語にすることも可能です
もし実際に使用する場合は、用途ごとにURLをカスタマイズしたスクリプトファイルを用意し、ショートカットを作成してください。

## 簡単なPowerShellスクリプトの例2：複数のファイルやフォルダを開く

私が職場の定例会議のフォルダを開くためのスクリプトを紹介させていただきます。

```Powershell 定例会議.ps1
$fps = @()
$fps += "定例会資料置き場のフォルダパス"
$fps += "課題管理表のファイルパス"

foreach($fp in $fps)
{
    Start-Process $fp
}

$fp = "重たいし毎度開く必要はないファイルパス"
Read-Host ("$fp`n上記パスを開きますか？[y/n]") | %{if($_ -eq "y"){Start-Process $fp}}
```

パス毎にショートカットをつくってポチポチ開いても大した手間ではないかもしれませんが、
（以下略）

Start-Processは、"既定のアプリ" に紐づくアプリに引数を渡して起動させる挙動なので、<strong>ファイル種別（フォルダ含め）を意識する必要がありません</strong>。
毎度開く必要のない重たいファイル等は if文 で個別に書き出すなどのカスタマイズができます。
もし実際に使用する場合は、用途ごとにパス情報をカスタマイズしたスクリプトファイルを用意し、ショートカットを作成してください。

## 起動用ショートカットをフォルダに配置するツール

PowerShellスクリプトを作る機会が増えると、作る度にショートカットを手動作成してプロパティ変更するのが手間になりますのでスクリプトをつくってみました。
<strong>複数ファイルを指定できます</strong>ので、何らかの事情でショートカットを作り直す際にも有用かと思います。
なお（少し切ないですが）当スクリプトの起動用ショートカットは手動作成となります。-NoExitオプションも付けた方がデバックしやすいです。
※参考になる記事：[Powershellを楽に実行してもらうには](https://qiita.com/tomoko523/items/df8e384d32a377381ef9#%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E4%BD%9C%E6%88%90%E7%B7%A8)

環境依存かもしれませんが、ショートカットの配置先を共有フォルダ（ローカルフォルダ外）にするとポップ（開いているファイル-セキュリティの警告）が表示されて一手間ふえるため、ショートカットの配置先はローカルフォルダにした方がよいです。
スクリプト本体は共有フォルダ（ローカルフォルダ外）に配置しておいてもポップは表示されないようです。

```Powershell pwsh用ショートカット作成.ps1
function ShowFileDialogForPwsh {
    param(
        $InitialDirectory
    )
    [Void][Reflection.assembly]::LoadWithPartialName("system.windows.forms")    
    $dialog = New-Object System.Windows.Forms.OpenFileDialog

    $dialog.Title            = "ファイルを選んでください"
    $dialog.InitialDirectory = $InitialDirectory
    $dialog.Filter           = "PowerShellスクリプト(*.ps1)|*.ps1"
    $dialog.Multiselect      = $True
    $dialog.ShowHelp         = $True

    # キャンセルを押された時は処理を止める
    if($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::NG){
        exit 1
    }
    
    Write-Output $dialog.FileNames
    Return
}

function MakeLnkForPwsh{
    param(
        $fp_source
    )

    $dn_lnk = Split-Path -Parent $fp_source
    $fn_lnk = (Split-Path -Leaf $fp_source).replace(".ps1",".lnk")
    $fp_lnk = Join-Path $dn_lnk $fn_lnk

    $WsShell = New-Object -ComObject WScript.Shell

    $Shortcut = $WsShell.CreateShortcut($fp_lnk)
    $Shortcut.TargetPath       = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
    $Shortcut.IconLocation     = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
    $Shortcut.Arguments        = "-ExecutionPolicy Bypass",$fp_source -join " " 
    $Shortcut.WorkingDirectory = $dn_lnk
    $Shortcut.Save()
    
    Write-Output $fp_lnk
    Return
}

$filepaths_source = ShowFileDialogForPwsh -InitialDirectory "PowerShellスクリプト置き場のフォルダパス" #★要置き換え★
#$filepaths_source = ShowFileDialogForPwsh -InitialDirectory $PSScriptRoot

$directory_lnk = "PATHの通ったショートカット置き場のフォルダパス、ローカルが良さげ" #★要置き換え★

Write-Output "対象スクリプト："
Write-Output $filepaths_source
Write-Output "作成先フォルダ："
Write-Output $directory_lnk
Read-Host ("`n対象スクリプトのショートカットを作成先フォルダにつくりますか？[y/n]") | %{if($_ -ne "y"){Exit}}

foreach($filepath_source in $filepaths_source)
{
    $filepath_lnk = MakeLnkForPwsh -fp_source $filepath_source

    # Move-Item $filepath_lnk $directory_lnk      # 転送先に同名ファイルあるとエラーになる
    Move-Item $filepath_lnk $directory_lnk -Force # 転送先に同名ファイルあれば上書き、エラーにならない

    Write-Output ("ショートカットを作成し転送しました`n　元ネタ：{0}`n　転送先：{1}`n　ショートカット名：{2}`n" -f $filepath_source,$directory_lnk,(Split-Path -Leaf $filepath_lnk))
}

Write-Output ("ショートカットの作成対象数は{0}件でした`n" -f $filepaths_source.count)
```

ツール作成のために参考にさせていただいたWebサイトです。
[PowerShell でファイル選択ダイアログを利用する](https://qiita.com/miyamiya/items/b0f61dc0a0bd3cb01a44)
[第14回　WshShellオブジェクトを利用する（3）](https://atmarkit.itmedia.co.jp/ait/articles/0712/27/news083_2.html)
[PowerShellを使用してショートカットを作成する方法](https://qastack.jp/programming/9701840/how-to-create-a-shortcut-using-powershell)

## そのほか

・もしPowerShellのコンソール画面からスクリプトを起動したい場合は、"(ショートカット名).lnk" と入力してください。
・表題からは脱線しますが、PowerShellスクリプト以外のショートカット（例えば、ブラウザやフォルダやファイルなど）をPATHの通ったフォルダに置いても「ファイル名を指定して実行」ができます。拡張性はありませんが手軽です。

## さいごに

Windowsユーザの方であれば、<strong>PowerShellは約1秒(!?)で起動できるとても身近なツール</strong>ですので、当記事を読んだことで「ファイル名を指定して実行」（Windows + Rキー）を好きになりPowerShellやCLI操作に興味をもっていただければ幸いです。
[【Windows10】１秒でPowerShellを起動する方法【ショートカットキー】](https://tipstour.net/windows10-powershell-shortcut)

過去記事もよろしければご覧になってください。
[PowerShellで複数のExcelファイルから複数のキーワードを検索する](https://qiita.com/miya_hira8/items/8576aee02a67f48d7240)
[PowerShellでExcelにファイル一覧を出力させる](https://qiita.com/miya_hira8/items/96e35dc3ee2a0ebf5ff7)
[PowerShellでWebブラウザのパスワード入力補助ツールをつくってみた](https://qiita.com/miya_hira8/items/2b468c6dfc7577ab1d77)

以上