最近PowerShellで遊んでいます.
前置き
Windowsを使ってると,時々突然WiFiが切れてイラっとすることがありました.
もしくは,起動したときに普段使いの無線LANに繋がっていない時がありました.
再接続するにはタスクバーからインターネットアクセスを選んで,接続したいネットワークを選んで,接続ボタンを押す必要があります
これって結構面倒じゃないですか?
コマンド入力するか,アイコンをダブルクリックするだけで勝手にWiFiに繋いでくれる,そんなことができたらいいな~って思ったのでちょっと書いてみました
完成したスクリプト
Windowsの無線LANの設定などを変更するので,.ps1ファイルで作成します
chcp 65001 $profiles $lans $i $length $result $successMessage="Connection request was completed successfully." netsh wlan disconnect $profiles=(netsh wlan show profiles) $length=$profiles.length for($i=0; $i -lt $length;$i++) { if($profiles[$i] -match ": ") { $lanName=$profiles[$i].Split(":")[1].Split(" ") echo($lanName[1]) $result=(netsh wlan connect name=($lanName[1])) echo $result if($result -eq $successMessage) { echo(" `n` `n` Connection successed !!") exit } echo(" `n``n` Connection failed...") } }
↑のコードを適当なファイルに記述して,拡張子.ps1で保存しPowerShellで実行すれば登録されている無線LANに自動で繋いでくれます
実行ポリシーの変更
...のですが,PowerShellはデフォルトではスクリプトを実行できません.セキュリティとかの問題ですね
僕が前に書いた記事とか↓に実行ポリシーを変更する方法が書いてあるので,必要に応じて変更してみてください
wgg.hatenablog.jp
qiita.com
まだアイコンダブルクリックで実行できない
PowerShellスクリプトは,アイコンをダブルクリックしてもメモ帳などのエディタが開くだけで実行してくれません.
ですが,従来のコマンドプロンプトのbatファイルはダブルクリックで実行できます
そこで作成したPoweShellスクリプトを実行するためのコマンドプロンプトのバッチファイルを作ります
@echo off powershell -Command "***.ps1"
.ps1に作成したPowerShellスクリプトのパスを渡します
拡張子を.batで保存すれば,そのbatファイルをダブルクリックするだけでPowerShellスクリプトが実行できるようになります
アイコンからじゃなくコマンドで実行したいって場合は環境変数弄るとできます
コードの説明
batファイルの方はPowerShellを起動して,引数のスクリプトを実行しているだけなので省略します
chcp 65001
文字コードの設定です
実行する環境によって文字コードが違った場合,実行したコマンドの返り値が変わったり文字化けしたりする場合があります
なので,どこでも同じように実行するために環境の統一ですね
次の6行は変数宣言です
一部無くても大丈夫ですが,一応
netsh wlan disconnect
無線LANの接続を終了します
この後で接続するので,一旦切りますね
$profiles=(netsh wlan show profiles)
(netsh wlan show profiles)の実行結果を変数$profilesに代入します
(netsh wlan show profiles)のみ実行すると,実行結果が出力されます
PowerShellScriptでは,コマンドの実行結果は返り値として扱われるので,変数に代入することで実行結果を保存することができます
↑こんな感じで,右下の隠し部分に登録済みのネットワークが表示されます
また,変数$profilesにはこの出力結果が配列として1行ずつ格納されます.
for($i=0; $i -lt $length;$i++)
↑c言語とかで書くなら
for(i=0;i<length;i++)
になるいつものfor文です
$profilesを1行ずつ操作していきます.
if($profiles[$i] -match ": ")
(netsh wlan show profiles)の実行結果から,セミコロン+空白(: )の右に無線LANの名前が書かれていることが分かったので,それを含む行に対してのみ次の処理を行います
$lanName=$profiles[$i].Split(":")[1].Split(" ")
1行毎に,セミコロンで区切った後,その後ろ側を空白で再度区切ります
かなり雑に作ってるので,もっとスマートな書き方がありそうです
しかもこの書き方だと無線LANの名前に空白が含まれていたらそこも分割してしまいます.
これを実行すると,$lanNameには
$lanName[0]=" " (空白スペース1つのみ)
$lanName[1]="***" (ネットワークの名前)
となるので,$lanName[1]を利用して,次に接続要求を行います
$echoはいわゆるprintfなので省略
$result=(netsh wlan connect name=($lanName[1]))
(netsh wlan connect name= STR)でSTRに対して接続要求を行います
$result=...としているので,その実行結果を変数$resultに格納します
これは,成功したか失敗したかを判定するのに使用します
if($result -eq $successMessage)
- eqは == です,同一かどうか判定しています.
実行結果が成功時に出力される文字列なら接続に成功したとみなして処理を終了,
失敗していたらforのカウントを進めて次のネットワークで再接続します
終わりに
こんな感じで,使うかわからないスクリプトを作成することができました.
自分の環境でしか試していないのでもしかしたら不具合起きるかもしれません.
というか自分の環境でも接続できないはずのネットワークに対して成功時のメッセージが出たりと,不具合が出ることがありました
あとは,このコードだと登録順に接続するので,あまり使いたくないネットワークに勝手に接続してしまうかもしれません
その場合は,$profilesを手書きして,優先度の高いネットワークから順に書くなどすると良いかもしれませんね
また,この方法だけだと,公共のWiFiによくあるWebページを開いて,そこで再度認証するタイプに対応できないので,必要ならそこも対応する必要がありますね