【手動設定とおさらば】バッチファイルとnetsh:簡単にIPとDNSを変える

この記事の概要を簡単まとめ!

  • やりたいことが見つかってバッチファイル作成第5回
  • IPアドレス(IPv4)やDNSサーバーは設定と編集が可能
  • しかし編集するまでの画面を開く手順、編集方法は面倒である
  • cmdから編集するにはSystem32にあるnetsh.exeを使う
  • netshのオプションを利用することでcmdからでも可能になる
  • バッチファイルにすれば簡単に変更が可能になる
  • これでフリーのDNSサーバーも簡単に変えられる

ネタにするにあたり、事前準備が必要なものがある。プログラミングはその1つであろう。あらかじめ作成したソースコードとその結果を用意し、その上で文章を構成していかなければならないからである。ただ、文章そのものの構成は問題なく、不備無く完全に動くソースコードの開発がむしろ難しいものである。もっとも私は技術者ではないので、完璧なものを作れる保証はない。

さて、バッチファイルも一種のプログラミングと定義することができると思われるが、使いこなせばGUIでは面倒だったことがcmd(CUI)でさくっと完結できるものになる。第5回となる今回はPCを使う上で重要なことでもある「ネットワーク」に関係したものである。その中の最も初歩的かつ重要な事項として、IPアドレスとそれに付随する設定、そしてDNSサーバーについて取り上げる。特にDNSサーバーは公開DNSサーバーを利用する時に変更することが多いであろう。キャリア一般のDNSサーバーより高速でセキュリティの設定やログ保存をしないなどのポリシーの観点から、手動で設定することが多くなっている。

ただ、IPアドレスやDNSサーバーを設定する際のGUIはどうにも使いにくく、そしてそこまで辿り着くのが面倒になっている。Windows 10になって以降は尚更、コントロールパネルではなく設定を呼び出そうとする面倒な改悪が入っているため、面倒が増している。そんな面倒は、netsh.exeを使うことで解決することができるのである。これを使用したバッチファイル作成を書いていく。

ブンブンハローnetsh.exe、どうもKIBEKINです。

PCとインターネット

前提:これまでのおさらい

Kibekin BLOG. では、私がKIBEKINになる前からバッチファイルについて取り上げていた。また、少し前に久々にバッチファイルについて書いた。それが以下の通りである。

これらがこれまでのバッチファイルについて書いた記事である。このうち第1回~第3回までは初心者が基礎から学べるように構成したもので、第3回でpowercfg.exeを使った電源プラン変更のバッチファイルを呼んでも分からないことがないようにしている。第4回についてはバッチファイル実行時の引数の扱いについて解説したものであり、これはバッチファイルの基本的な部分を知っている前提で構成している。これから解説するバッチファイルのコマンドについても、過去記事で解説済みのものについては過去記事を参照するようにして、本記事での解説は原則として行わないものとする。



PCとインターネットは切り離せない存在

今日に至るまで、インターネットに接続しないPCは果たしてどれくらい存在するであろうか。ある機械を動かすためにPCを利用する、或いはそもそもインターネットに接続することができない旧世代型のPCなどを考えても、インターネットに接続しているPCと比較しても圧倒的に少ないはずだ。それほどまでに、PCとインターネットは切り離せない存在である。

インターネットに接続するには、かつては電話回線を利用したダイアルアップ接続で、その後にADSLができ、後に有線(LANケーブル型)、そして無線LANというように進化していった。今では殆どの電子機器が無線LANに対応しているため、もはやインターネットに接続することは当たり前の時代である。ネット回線が無ければ人権はない、そう言いきってもいい程だ。

そのインターネットに接続する際、多くはルーターを介して接続する。このとき、自分で設定しているのでなければ、ルーターからIPアドレスが接続している全ての機器に割り当てられる。所謂DHCPであるが、基本的にはルーターへのアクセスができればインターネットに接続できると思って大丈夫だ。もちろん、IPアドレス(とサブネットマスク、デフォルトゲートウェイ、DNSサーバー)は後述するが手動設定が可能である。しかし設定を間違えればインターネットに接続できなくなるのでネットワークの仕組みについてあまり分かっていない人はDHCPに任せるべきである。

IPアドレスやDNSサーバはから編集と設定が可能

IPアドレスやDNSサーバは通常、インターネットに接続するだけであれば何も考える必要はない。DHCPサーバがIPアドレスを自動的に割り当て、DNSサーバーのアドレスを自動的に設定してくれるためである。したがって、ユーザーはこれらのことについて何も考える必要はないのである。楽な時代になったものである。

だが全部が自動だけで対応しているというわけでもなく、手動設定ももちろん可能である。手動設定はPCは当然ながら、スマートフォン、ゲーム機でも手動設定が可能である。ここではPCの話をしているので、PCについて解説する。なお当然のことながら、cmdを扱うのでOSはWindowsである。PCの場合は通常、この画面でIPアドレスやDNSサーバーを設定することができるようになっている。

IPアドレスとDNSサーバー設定画面
Winodwsにおける、IPアドレス及びDNSサーバーの設定画面。一番右の画面が設定画面になる。

Windowsにおいてはこの画像の一番右にある画面で、一般的なIPアドレスの書式である”[a].[b].[c].[d]”の形で、それぞれが0~255の範囲で値を入力する。また、サブネットマスク、デフォルトゲートウェイの設定項目もあり、これも同じ形式で入力する。そして下にはDNSサーバーの設定があり、IPアドレスを手動設定する場合、これも同時に設定しなければならない。DNSサーバーだけ自動というわけにはいかないようだ。

編集するまでの画面を開く手順、編集方法は面倒

だが、このIPアドレスは編集するにあたって、編集するまでの画面を開く手順、そして編集方法は面倒であるという欠点が存在する。編集するまでの画面を開く手順についてはWinodowsの標準のOSがWindows 10になったことによる弊害で、編集方法についてはWindows 10になる以前からの問題である。これらについてそれぞれどういうことかを解説する。

まず編集するまでの画面を開く手順についてである。Windows 10よりスタートメニューに「設定」という項目が追加されたが、これが面倒である。これが存在しなかったWindows 7の頃は、右下のLANケーブルマークまたは無線LANマークを右クリックして”ネットワークとインターネットの設定を開く”で簡単にその画面を呼び出すことができた。しかし現在はクソ使えない設定の”設定/ネットワークとインターネット”を開いてしまい、しかも画面が全く違うので(そもそもコントロールパネルですらない)、いちいちコントロールパネルのホームからそこまで行く必要がある。余計なことをしてくれた。

また、これは昔からであるが、IPアドレスをはじめとした10進数の入力は、実は面倒である。数値入力はドットで区切られていて、4つの区間に0~255を入れるわけだが、一度入力した値を消すにも1区間ずつしか消せず、数値が3桁ではない場合自動で右に入力カーソルが移動しない、タブキー操作で下に行ってしまう、エンターキーで変更反映になる、「自動」にチェックを入れた時点で入力が全て消えてしまうなど、面倒なことが多々存在する。あまり触らない人からすれば面倒ではないのであろう、しかしDNSサーバーが不調な時に変更することの多い私としては、実は面倒に感じるものである。もっとスマートにできないものか、そう考えていた。




cmdとnetsh.exe:netshのコマンド解説

GUIではわざわざそこまで行って、面倒な操作をして変えなければならないのでうんざりしていたわけである。だが、Windowsは幸いにして、疑似的だがCUI環境が未だに使える状態であり、一部の高度な機能についてはCUIからしか変更できないようになっている。これはWindowsにおいてはコマンドプロンプト、正式にはcmd.exe、単にcmdと呼ばれるものである。

いまでこそGUIが存在するため、何をするにもクリック1つで何とでもなるわけだが、その昔は黒い画面にコマンドを入力してあらゆる命令を行っていたことは想像に難くない。また、まだ不十分とはいえインターネットが利用できていたのなら、ネットワーク設定もコマンド入力でできたはずである。MS-DOSの頃はどうだったか不明であるが、System32にある”netsh.exe“でcmdからネットワーク設定を行えるのである。

ここからはバッチファイル記事ではお馴染みの、本体ソースコード掲載の前に今回使用するnetsh.exe(以下netsh)のコマンドについて解説を行う。なお、解説するにあたり過去4回の記事を閲覧済みで、バッチファイルに関する基礎的なものはわかっているものとして扱う。

前提:netshとは?

netsh は、現在実行中のコンピューターのネットワーク構成を表示したり変更したりするためのコマンド ライン スクリプト ユーティリティです。 netsh コマンドは、netsh プロンプトでコマンドを入力することで実行し、バッチ ファイルまたはスクリプトで使用できます。 リモート コンピューターとローカル コンピューターは、netsh コマンドを使用して構成できます。

また、指定したコンピューターに対して一連のコマンドをバッチ モードで実行できるスクリプト機能も備えています。 netsh では、構成スクリプトをテキスト ファイルに保存して、アーカイブとして保管したり、他のコンピューターの構成に利用したりできます。

Netsh コマンドの構文、コンテキスト、形式 | Microsoft Docs

netshは簡単に言えば、使用中のPCのネットワークを色々弄れるコマンドラインのスクリプトユーティリティの1つである。netshはcmdで単にnetshと入力して実行すると、netsh>となり入力受付状態となる。cmdから直接操作する場合はこれでOKであるが、コマンドをいちいち入力するのはネットワーク管理者でもない限りは酷な話である。当然ながらこれもバッチファイルでの使用が可能であり、多くの場合はバッチファイルを介して利用するものとなる。

次項から、今回使用するnetshのオプション(コンテキスト)を解説する。なお、netshのヘルプ情報はこのテキストファイルから見れる。

netsh interfaceとコマンド

netsh interfaceは今回のバッチファイルで絶対に使用するコンテキストである。このコンテキストのコマンドについてはこのテキストファイルを参照してもらうとして、実はこれ単体では何もできない。さらに半角スペースの後にコマンドを入力する必要がある。ただし、その中で使用するコマンド(コンテキスト)はipのみである。これを詳しく見ていく。

netsh interface ip

netsh interface ipはコンテキストであり、IPアドレスの設定を行う。これもコマンド一覧はこのテキストファイルに掲載している。やはりこれも単体では機能せず、コマンド及びコンテキストの使用が前提となる。この中から使用するコマンド及びコンテキストは多数存在するため、順を追って解説する。

netsh interface ip show addresses

netsh interface ip show addressesは、IPアドレスの構成を表示するものである。このテキストファイルに解説が載っている。書式はshow addresses "[インタフェース名]"になる。インタフェース名についてはなくても問題なく、その場合は全てのインタフェースを対象にIPアドレスの構成を出力する。このとき、インターネット接続とは無関係のインタフェースについても出力される。VPNやBluetoothの構成を出力されてどうしろというのだろうか。

インタフェース名を指定した場合、指定したインタフェースの構成のみを表示する。例えば多くのPCにおいて、内蔵の無線LANカードの名前は”ワイヤレス ネットワーク接続 2″という名前になっていることであろう。スペースも含めてこの名前を指定すると、”ワイヤレス ネットワーク接続 2″の構成のみを表示して、他は表示しなくなる。したがって、ある名前の構成だけを取り出したい場合、これを利用する。なお、インタフェース名は将来的にも変わることがあり得ない名前であるので、バッチファイルで扱うにも困らないはずだ。

netsh インタフェース名でのshow
インタフェース名を指定してnetsh interface ip show addressesを実行した結果例。特定のインタフェースの構成だけを得たいときはこれを使用する。

netsh interface ip set

netsh interface ip setは、これ単体では何もできない。後に続くコマンドを指定する必要がある。ここで使用するのはaddressとdnsservers(=dns)である。それ以外のコマンドについてはこのテキストファイルを参照すること。



netsh interface ip set address

netsh interface ip set addressは、IPアドレスを設定するコマンドである。解説はこのテキストファイルから読める。書式はset address "[インタフェース名]" [ソース] [IPv4アドレス] [サブネットマスク] [デフォルトゲートウェイ] [ゲートウェイメトリック]が基本である。例を挙げるのであれば、以下のように入力する。

まずは対象となるインタフェース名を指定する。殆どのインタフェース名にスペースが入ることが多いため、ダブルクォーテーションを使用すると安全である。手動設定の場合、ソースをstatic(静的)と明示する。これにより手動設定が可能になる。その後にIPv4、サブネットマスク、デフォルトゲートウェイ、ゲートウェイメトリックを入力する。ゲートウェイメトリックについては、一般家庭であればルーターは1つしか存在しないことが多いので、1と指定しておけば問題ない。実は詳しいことは調べてもあまり出てこなかった。

また、手動設定が可能ならDHCPも可能である。DHCPに設定したい場合、ソースをdhcpにして、それ以降の値の入力は不要である。こうすることでDHCPが有効になる。

どちらの設定も可能であるので、これが使えることを知っていると設定も楽になる。

netsh interface ip set dns

IPアドレスがset addressなら、DNSサーバーはset dnsserversで可能になる。解説はこのテキストファイルから読める。ただ、dnsserversと書くのは長くて面倒であるため、set dnsとしても認識するようにエイリアスが設定されている。したがって、多くの場合は省略形であるset dnsと記述した方が楽である。DNSサーバーの場合の書式はset dns "[インタフェース名]" [ソース] [IPv4アドレス] [登録] [検証実施]である。例として、任意の公開DNSサーバー及びDHCPに設定するコマンドを両方記述する。

コマンドはこの通りである。それほど難しいものではない。しかしこれには1つだけ問題が存在し、この方法ではプライマリDNSしか登録できないのである。多くの場合、公開DNSサーバーはプライマリとセカンダリが両方存在し、それを両方設定しなければ機能しないことが殆どだ。したがってこれとは別のコマンドを利用してセカンダリを登録する必要がある。これについては後述する。

ちなみに、DNSサーバーをDHCPにする場合、IPアドレスについてもDHCPを適用しておかなければ正常にインターネットに接続することはできない。したがって、DNSサーバーに対してDHCPを適用する場合、同時にIPアドレスもDHCPになるようにコマンドを実行する、またはバッチファイルで同時に処理できるようにしておく必要がある。逆に、IPアドレスがDHCPでDNSサーバーが手動設定である場合は問題ない。設定時はこの点には注意である。

netsh interface ip add dns

先のset dnsではプライマリしか設定できなかった。セカンダリも設定する場合は、別のコマンドで設定しなければならない。それを実現するコマンドがadd dnsである。setとの違いは構成情報の追加であり、既存のものにプラスする形である。書式はadd dns "[インタフェース名]" [IPv4アドレス] [インデックス] [検証実施]である。setとは書式が異なるものとなっている。

このコマンドのヘルプの注釈には、『新しいDNSサーバーの IP アドレスを静的に構成された一覧に追加します。既定では、DNSサーバーが一覧の最後に追加されます。』と書かれている。つまり、普通にこのコマンドを実行すれば、既に存在するDNSサーバーの後ろに登録されることを意味する。この時にDNSサーバーが何も設定されていなかった場合、プライマリとして登録される。これは実際にコマンドを実行して確認した。

コマンドの意味で考えるのであれば、setは書き換え、addは書き換えず追加であると認識すればわかりやすい。何にせよ、これと先のset dnsと同時に利用することでDNSサーバーの変更が可能ということである。

netshの解説は以上である。




実践バッチファイル:netshでIPアドレスとDNSサーバーを変更する

解説事項が終了したため、いよいよそのバッチファイルのお披露目である。今回作成したバッチファイルは、これまでのバッチファイルの記述量及びファイルサイズを圧倒的に超えた、rem文(解説行)を含めて189行/10.4KBである。さて、重要な機能についてであるが、このバッチファイルだけでIPv4とDNSサーバーを変更できるように設計している。まずはソースコードを示し、そして実行結果の例を示す。

実行結果例
実行結果例。上はIPアドレス、DNSサーバーのDHCP設定。下はDNSサーバーの手動設定。手動と言っても一覧から選択する形式である。わかりやすいようにGUI画面も掲載している。

まず注意事項であるが、このバッチファイルは権限の関係から、cmdを管理者権限で実行する必要がある。或いはこのバッチファイル自体を管理者権限で直接実行してもいい。このバッチファイルの場合、バッチファイルから直接実行しても弊害はないためである。とはいえ、cmdから実行した方がいいのは言うまでもない。



このバッチファイルの流れを分かりやすくリスト化すると、以下のようになる。

  • バッチファイルを実行すると、IPアドレスまたはDNSサーバーの設定を行うか、バッチファイルを終了するかを選択する。バッチファイル終了を選択した場合、何もせずに終了する。
  • IPアドレスを選択した場合、ホスト部([a].[b].[c].[d]で[d]にあたる部分)を1~254の範囲で入力する。将来的にはサブネットマスクの違いで自動的に範囲が指定できるようにする。
  • DNSサーバーを選択した場合、DHCPにするか手動設定するかを選択する。
    • DHCPにした場合、IPアドレス、DNSサーバー共にDHCPに設定してバッチファイルを終了する。
    • 手動設定の場合、公開DNSサーバー一覧が表示される。この中から任意のサーバーを、表示されている選択文字列を入力して選択する。正しく選択されていれば、これを反映してバッチファイルを終了する。

簡単にまとめれば、このような処理を行っているということになる。ちなみに、エラー処理については省略しているが、想定されるエラー(入力ミス、無入力エンター)については既に検証済みであるため、解説する必要はないと判断したためである。ソースコードを確認すれば、どのような処理が行われているかはわかるはずである。

解説:バッチファイルの一部コマンドについて

バッチファイル内の一部コマンドについては、過去4回の記事で解説していないことがあるためこれを別途解説する。なお、サブルーチン処理、for /fの使い方は第3回記事、変数展開における特別な展開方法は第4回記事を参照すること。

バッチファイルを開始する際に冒頭及び終了時に記述するものとして、@echo offsetlocal, endlocalがある。これはバッチファイルを実行する際の処理としては必ず入れるほどにお馴染みのものであるが、このうちsetlocalには、変数に関する特殊な取り扱いを可能にする宣言を行うことができる。ソースコードでは5行目にsetlocalをしているが、その後ろにenabledelayedexpansionとある。これは遅延環境変数を有効にする宣言である。今回のバッチファイルではこれが必要である。

「遅延環境変数」とは一体何なのか

これはバッチファイル(MS-DOS)の特性であるが、コマンドの実行はインタプリタである。つまり、1行単位で実行することになる。このときに変数展開の命令があれば展開し、全ての変数を一気に展開する。そしてバッチファイルでは()を使用すると、()内を1行として認識する。これが変数を展開する際には曲者で、1行ずつ認識・一気に変数展開される関係から、ifやforを利用して()内で変数を扱おうとした際、echoで表示してほしい内容が想定していたのと違ったり、ifのネスト処理がうまくいかずエラーになることが多発する。要するに、自分がしたいこととコンピュータの処理が異なるのである。例えば以下のような計算を行うと想定する。

これを実行すると、300と表示されると予想するが実際は100が表示される。この理由は簡単で、ifの行に到達した時点で変数をあらかじめ展開するからである。つまり、もう100として表示されることが決まってしまっているのである。これでは、計算はおろかifの後でforやさらにifをして処理をしたいときに面倒が起きるのである。

遅延環境変数はこの問題を解決する。遅延環境変数はあらかじめsetlocalのタイミングで宣言しなければ使用できないが、この宣言後は通常変数を%で囲って展開するところ、!で変数を囲うことで変数が遅延展開される。これにより、通常は一気に変数展開されるのをあえて遅らせて、実行時に変数が展開されるようになる。上の場合はecho %a%echo !a!とすることで、その直上の計算が行われた後で変数が展開されるので、表示は300となる。これが遅延環境変数でありその展開である1)参照:遅延環境変数とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

ソースコードでは66, 88, 91行目にこれを使用している。これらはいずれもifやforの中にある変数であり、88行目はifとforの二重ネストである。この状態で通常の変数展開を行っても正常に展開できないが、遅延環境変数の展開を行えばほぼ想定通りの処理が可能になる。多数の変数を利用してif文のネストを構成する場合には非常に使える宣言であるので、覚えておいて損はない。




余談:1つのバッチファイル完結か、別途テキストファイル用意か

実はこのバッチファイルを作成するにあたり、公開DNSサーバーの扱いをどうするか考えていた。というのも、公開DNSサーバーの一覧をバッチファイル内に記述して直接実行するか、テキストファイルを用意して、for /fのトークン取り出しを利用して設定する、という2つの案があった。元々は後者の案を採用する予定であったが、テキストファイルを読み込んでその内容を表示するコマンドcatうまく機能しなかった(=テキストファイルが存在するにも関わらず解明不能な謎のエラーで読み込まなかった)ため、1つのバッチファイル内で完結するように変更したのである。それが今回のこれである。

バッチファイルを作成する上で考えるのは、そのバッチファイルだけで完結させるか、或いは別のバッチファイルかテキストファイルを用意して処理をするかである。それぞれのメリットとデメリットを考えると、以下のようになる。

  • バッチファイル完結のメリット:そのバッチファイルだけで終わらせているため、他に必要な物がない
  • バッチファイル完結のデメリット:記述量が多くなる。処理が増えすぎると整備するのが難しくなる
  • 別のファイルを用意するメリット:単純な情報などを扱う場合、追加と削除が簡単に行える
  • 別のファイルを用意するデメリット:パス指定の場合、バッチファイルやファイルを移動したらそれを修正しなければならない。コマンドの謎のエラーで読み込めない可能性もある

客観的評価を行うとすれば、このようなことが考えられる。このうち実際に発生したのがcatの読み込みエラーである。このエラーについては私の環境がそうなっているだけの可能性もあるが、しかしエラーはエラーであり、実際に発生したのであればこれへの対処を行い、バッチファイルの実行に支障がないようにしておく方が先決である。これを商売に使うわけではないのだから、それで問題ない。

しかし本音としては、管理が簡単なテキストファイル経由が良かったものである。これについては解決策を模索中であるが、おそらく解決は難しいと思われる。

解説は以上である。

これでフリーのDNSサーバーも簡単に変えられる

GUIでの設定は面倒で、CUIでの設定は簡単なものは何かあるかと探していた時、IPアドレスと(手動の)公開DNSサーバー設定はGUIでは面倒であることを思い出した。GUIでの設定は面倒さを感じる物であったし、設定画面を呼び出すまでもが面倒であった。これは、そこにいくまでに必要となる、何回かしなければならないマウス操作が煩わしいということである。

GUIのできる以前は、全てをコマンドで指定し、様々な処理を行っていたことは想像に難くない。確かにGUIでは直感的操作が可能である反面、平面的な移動距離と目的までの画面遷移の時間を要する。CUIは直感的操作は不可能だが、GUIのような画面的なタイムロスは殆どなしに命令を伝達し実行させることができる。GUIもCUIも、どちらも一長一短があるので、極端にどちらかが良いというわけではない。

しかしそれでも、cmd(バッチファイル)から数回のキー操作だけでさくっと変えられるのは非常に楽だ。もうあの面倒な画面遷移を行わず、cmdの黒い画面1つで完結できてしまう。そう思えば、わざわざバッチファイルを作って簡略化する意味はあるというものだ。そして、バッチファイルを作成することは、必然とPC(Windows)の勉強をすることにもなるので、この点でもやる意味はある。そして私はまだまだバッチファイルを作り続けることであろう。また新しくバッチファイルを作ることになったら、その時は書きたいと思う。

 

以上、バッチファイルとnetsh:簡単にIPとDNSを変える、であった。それでは、次回の記事で会おう。ン、バァーイ!

 

KIBEKIN at 11:11 May 15th, 2021


スポンサーリンク




KIBEKIN
会社員という働き方が合わないのに会社員になってしまってから、半ば自分からリタイア後ブログクリエイターとなり活動してきた社会不適合者。今後の活躍の約束とHIKAKINリスペクトの意味を込め、リンクス岐部からKIBEKINに改名した。

コメントを残す

メールアドレスが公開されることはありません。
名前は必須項目となります。記入をお願いいたします。

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)