質問者
ポートの状態監視(powershell)

質問
-
https://social.technet.microsoft.com/Forums/ja-JP/cec88c5e-eb3a-4eaa-bdca-5a4f3bcfb93a?prof=required
このような質問を事前にさせて頂きpowershellで試そうとしているところです。
調べていたらこのような情報を見つけました。
http://ooltcloud.expressweb.jp/201412/article_17235628.html
このスクリプトを作成し実行しましたがpowershellのウィンドウが一瞬立ち上がりますが何も出力されないまま落ちてしまいます。
次に下図のようにテスト実行してみました。すると結果が出力されますが同時にエラーも出力されています。
通常実行ではウィンドウが一瞬で落ちる理由、テスト実行でこのようなエラーが発生する理由について情報お持ちでしたらご教示おねがいします。
すべての返信
-
解答にならないと思いますが、PowerShellの古いバージョンを使ってらっしゃいませんか?3.0ではそうしたエラーは出ません。
私も以前、Disposeで同じエラーを見た記憶があるのですが、3.0で問題なくなりました。
(PowerShellではなく、.NET framework 4.5に上がったから、かもしれませんが)
あと、「ps1アイコンをクリックして起動する方法」を取られていますか?
私も正しい対処法を知らないのですが、ずっと以下の方法でしのいでいます。最終行や中断処理の直前に以下の1行を置くことで、とりあえずはすぐに閉じることは防げますね。
[Console]::ReadLine();
あるいは "powershell"と書いておくか・・・・
- 編集済み Fuzitaman 2015年7月1日 4:08
- 回答の候補に設定 牟田口大介Moderator 2015年7月1日 5:54
-
>どういうコードを記述しどういう操作を行ったのでしょうか
基本的には最初にキャプチャしている通りの記述をしTCPing.ps1という名前で保存。
質問時はウィンドウがすぐ閉じていたのでテスト実行で動作確認しています。
これもキャプチャに記載している通り「TCPing localhost 445」というパラメータを入力しています。
>まず、Disposeは呼び出さなくて構いません。Closeがその代わりになります
>最終行や中断処理の直前に[Console]::ReadLine(); (Fuzitamanさん)
上記のように助言頂きましたが、今のところ下記のように記入すれば緑三角ボタンのテスト実行ではエラーなく処理されます。
(キャプチャ参照)但しウィンドウは落ちます。 ([Console]::ReadLine(); を入れると「既にコマンド実行中です。お待ちください」となるのでやめました)
--------------------------------------------------------------------------------------------------------------
Function TCPing($target, $port) {
$sw = New-Object System.Diagnostics.Stopwatch
$tcp = New-Object System.Net.Sockets.TcpClient$sw.Start()
try {
$tcp.Connect($target, $port)
$sw.Stop()
Write-Output ("{0} port={1} ({2}) への接続: 時間 ={3:0.00}ms" -f $target, $port, $tcp.Client.RemoteEndPoint, ($sw.Elapsed).TotalMilliseconds)} catch {
$sw.Stop()
Write-Output ("{0} port={1} への接続: 応答が確認できません" -f $target, $port, ($sw.Elapsed).TotalMilliseconds)} finally {
$tcp.Close()}
}--------------------------------------------------------------------------------------------------------------
- 編集済み sys11 2015年7月1日 7:02
-
チャブーンです。
この件ですが、まずPowerShell ISEを使って動作を確認する必要はないと思います。ブログ作成者さんが、やり方をきちんと書かれていますので、その通りに実行したほうがいいでしょう。
Windows 7 で使っておられる前提ですが、他の方がおっしゃっておられるように、Disposeメソッドが使われていることが、直接の原因です。Disposeメソッドの実行はクローズ処理の最後に実行する「お約束」的なメソッドですが、この状況では必要ありません。そこで、コードの18行目を「コメントアウトする」必要があります。実際のコードはこのようになるでしょう。
[コードの引用元]
[PS1] Powershell で TCPing もどき | オールトの雲
http://ooltcloud.expressweb.jp/201412/article_17235628.html
Function TCPing($target, $port) { $sw = New-Object System.Diagnostics.Stopwatch $tcp = New-Object System.Net.Sockets.TcpClient $sw.Start() try { $tcp.Connect($target, $port) $sw.Stop() Write-Output ("{0} port={1} ({2}) への接続: 時間 ={3:0.00}ms" -f $target, $port, $tcp.Client.RemoteEndPoint, ($sw.Elapsed).TotalMilliseconds) } catch { $sw.Stop() Write-Output ("{0} port={1} への接続: 応答が確認できません" -f $target, $port, ($sw.Elapsed).TotalMilliseconds) } finally { $tcp.Close() # $tcp.Dispose() //ここをコメントアウトします// } }
そのあとですが、このコマンドレットはファンクション(関数)のみが記載されていますので、単純なpowershellスクリプトとしては使えません。関数としてPowerShellプロファイルに、登録する必要があります。手順はしたのようになるでしょう。
- うえのスクリプトを「Microsoft.PowerShell_profile.ps1」として保存する
- powershellで[Get-Variable|Where {$_.name -eq "PROFILE"}]を実行すると、したのような表示がでる
Name Value
---- -----
PROFILE C:\Users\<ユーザー名>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 - powershellで(2で表示された)[mkdir C:\Users\<ユーザー名>\Documents\WindowsPowerShell]を実行する(プロファイル内のドキュメントフォルダ内に「WindowsPowerShell」というサブフォルダを作ることが目的です)
- エクスプローラのアドレスバーに[C:\Users\<ユーザー名>\Documents\WindowsPowerShell]入力してフォルダを開き、Microsoft.PowerShell_profile.ps1をコピーする
- 開いていたpowershellのシェルをいったん閉じて、再度開き直す(こうするとプロファイル内に関数が読み込まれます)
あとは、[PS1] Powershell で TCPing もどき のページにある方法で、実行すれば適切に動作するはずです。
フォーラムは有償サポートとは異なる「コミュニティ」です。フォーラムでご質問頂くにあたっての注意点 をご一読のうえ、お楽しみください。
-
チャブーンです。
この件ですが、まずPowerShell ISEを使って動作を確認する必要はないと思います。ブログ作成者さんが、やり方をきちんと書かれていますので、その通りに実行したほうがいいでしょう。
Windows 7 で使っておられる前提ですが、他の方がおっしゃっておられるように、Disposeメソッドが使われていることが、直接の原因です。Disposeメソッドの実行はクローズ処理の最後に実行する「お約束」的なメソッドですが、この状況では必要ありません。そこで、コードの18行目を「コメントアウトする」必要があります。実際のコードはこのようになるでしょう。
[コードの引用元]
[PS1] Powershell で TCPing もどき | オールトの雲
http://ooltcloud.expressweb.jp/201412/article_17235628.html
Function TCPing($target, $port) { $sw = New-Object System.Diagnostics.Stopwatch $tcp = New-Object System.Net.Sockets.TcpClient $sw.Start() try { $tcp.Connect($target, $port) $sw.Stop() Write-Output ("{0} port={1} ({2}) への接続: 時間 ={3:0.00}ms" -f $target, $port, $tcp.Client.RemoteEndPoint, ($sw.Elapsed).TotalMilliseconds) } catch { $sw.Stop() Write-Output ("{0} port={1} への接続: 応答が確認できません" -f $target, $port, ($sw.Elapsed).TotalMilliseconds) } finally { $tcp.Close() # $tcp.Dispose() //ここをコメントアウトします// } }
そのあとですが、このコマンドレットはファンクション(関数)のみが記載されていますので、単純なpowershellスクリプトとしては使えません。関数としてPowerShellプロファイルに、登録する必要があります。手順はしたのようになるでしょう。
- うえのスクリプトを「Microsoft.PowerShell_profile.ps1」として保存する
- powershellで[Get-Variable|Where {$_.name -eq "PROFILE"}]を実行すると、したのような表示がでる
Name Value
---- -----
PROFILE C:\Users\<ユーザー名>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 - powershellで(2で表示された)[mkdir C:\Users\<ユーザー名>\Documents\WindowsPowerShell]を実行する(プロファイル内のドキュメントフォルダ内に「WindowsPowerShell」というサブフォルダを作ることが目的です)
- エクスプローラのアドレスバーに[C:\Users\<ユーザー名>\Documents\WindowsPowerShell]入力してフォルダを開き、Microsoft.PowerShell_profile.ps1をコピーする
- 開いていたpowershellのシェルをいったん閉じて、再度開き直す(こうするとプロファイル内に関数が読み込まれます)
あとは、[PS1] Powershell で TCPing もどき のページにある方法で、実行すれば適切に動作するはずです。
フォーラムは有償サポートとは異なる「コミュニティ」です。フォーラムでご質問頂くにあたっての注意点 をご一読のうえ、お楽しみください。
ご回答頂き有難うございました。結果としては「ウィンドウが一瞬立ち上がりますが何も出力されないまま落ちてしまう」というものになりました
-
チャブーンです。
結果としては「ウィンドウが一瞬立ち上がりますが何も出力されないまま落ちてしまう」というものになりました
ということですが、今までの環境をそのまま引きずって(以前のTCPing.ps1を削除していない等)実施をしていませんか?
こちらでは、前回の回答に書いた通りの手順で動作することは確認(Windows 7上で動作します)しています。いったんいままでの環境をすべて捨てて(このために作成した以前のps1スクリプト等は無関係のディレクトリに移動しておきます)、きれいな環境で再実施してみてはどうでしょうか。
フォーラムは有償サポートとは異なる「コミュニティ」です。フォーラムでご質問頂くにあたっての注意点 をご一読のうえ、お楽しみください。