Quantcast
Channel: PowerShell –俺的備忘録 〜なんかいろいろ〜
Viewing all 20 articles
Browse latest View live

Windows版iTunesをPowerShellで操作 その②

$
0
0

前回、WindowsのiTunesでタイトル名の一括置換を行うスクリプトを作成したが、今回はトラック番号の一括採番スクリプトを作成。

■iTunes_項目別一括変換.ps1

$iTunes = New-Object -comObject iTunes.Application
 
$NumTracks = $iTunes.SelectedTracks.count
$Tracks = 1
 
$iTunes.SelectedTracks `
| foreach {
    $_.Name; $_.TrackNumber = $Tracks
    $_.Name; $_.TrackCount = $NumTracks
    $Tracks++
    }

使い方としては、採番する曲(ビデオ)を選択した状態で実行するだけ。使い方は前回の内容に記述しているため省略。

 


WindowsにSSH接続できるPowerShell SSH Serverの構築

$
0
0

最近知ったのだが、WindowsにSSH接続を行える『PowerShell SSH Server』なるものがあるらしい。

ツールボックス: IT プロフェッショナル向けの新製品: – TechNet

http://technet.microsoft.com/ja-jp/magazine/ff808410.aspx

有償製品のようだが、無償提供版もあるらしい。
通常、Windowsへの接続といえばRDP接続で、コマンドラインでの接続はあまりメジャーではない。
(PSexecでの接続も可能だけど、これは通常の手法ではないような気もするし…)

MacやLinuxのsshコマンドから接続出来るようにもなるので、構築してみよう。

1.ダウンロード

まずはソフトのダウンロードから。
以下のリンク先へ飛んで、『DOWNLOAD』からダウンロードする。

PowerShell Server | Secure Remote Access to PowerShell

http://www.powershellserver.com/

2.インストール

次に、実際にインストールを開始する。
先ほどダウンロードした「setup.exe」を実行する。

20140520_000000

『PowerShell Server V6 Setup』が開くので、「Next」をクリックする。

20140520_000001

『License Agreement』画面が開くので、「I Agree」をクリックする。

20140520_000002

『Choose Install Location』画面が開くので、デフォルトのままで「Next」をクリックする。

20140520_000003

『Choose Components』画面が開くので、デフォルトのまま「Next」をクリックする。

20140520_000004

『Choose Start Menu Folder』画面が開くので、デフォルトのまま「Next」をクリックする。

20140520_000005

『Installation Options』画面が開くので、デフォルトのまま「Next」をクリックする。

20140520_000006

『Ready to Install』画面が開くので、「Install」をクリックしインストールを開始。

20140520_000007

インストール完了後、『Installation completed successfully』画面が開く。
これでインストールは完了した。

20140520_000008

3.初期設定

インストール完了後、『PowerShell SSH Server』の管理ウィンドウが表示される。
「Start」をクリックし、PowerShell SSH Serverを起動させる。

20140520_000010

「Service」タブで、「Run as a Windows Services」にチェックを入れる。

20140520_000011

「Connection」タブに移動し、画面にある3つのチェックボックスにチェックをして「Save Changes」をクリック。

20140520_000013

これで、SSH接続(+α)が出来るようになった。

4.接続

さて、それでは早速SSH接続してみよう。
Teratermから接続。

 

20140520_000003

20140520_000004

無事接続できた。試しに、「get-help」コマンドを実行してみる。

20140520_000005

…あれ?
なんか文字化けしている…

もし文字化けした場合は、「Other」タブから使用したいエンコードを選択する。
今回は「UTF-8」を選択した。

20140520_000014

再度接続して「get-help」コマンドを実行。

20140520_000006

無事日本語で表示された。
リモートデスクトップの出来ない環境であれば、このプログラムをインストールするとWindowsの管理が捗るね。

 

シェルスクリプトやバッチの引数で外部ファイルを絶対パスで扱う

$
0
0

シェルスクリプトやバッチを作成する際、外部ファイルを引数として指定して使用する事が多々ある。
その際、相対パスで外部ファイルを引数した後にcdコマンドを使用するとうまく動かないため、相対パスで引数とした外部ファイルをソース内で絶対パス(フルパス)に変換させる。

シェルスクリプトの場合

シェルスクリプトの場合は、以下のように記述をする事で相対パスを絶対パスに変換する事が出来る。

$(cd $(dirname "対象ファイルのパス") && pwd)/$(basename "対象ファイルのパス")

cdコマンドが入っているが、実際にかれんとディレクトリが変更される訳ではないので安心してもらいたい。
実際に使用する場合の例を以下に示す。

#!/bin/sh
FILE_PATH=$(cd $(dirname "$1") && pwd)/$(basename "$1")
echo $FILE_PATH

なお、この内容はこちらの記事を参考に記述させていただいた。
感謝!

バッチファイルの場合

バッチファイルの場合は、以下のように記述する事で絶対パスを取得する事ができる。

rem 引数1の場合
set 変数名=%~f1

rem 引数2の場合
set 変数名=%~f2

意外にも、シェルスクリプトよりバッチファイルの方が簡単に記述できるようだ。

PowerShellの場合

PowerShellの場合は、以下のように記述する。

Convert-Path 対象ファイルのパス

 

Windowsで容量の大きいファイル&ディレクトリを調べる

$
0
0

以前、Linuxで容量の大きいファイル、ディレクトリを調べる方法について記述したので、今回はWindows版。PowerShell、コマンドプロンプトでの調べ方を紹介する。

1.容量の大きいファイルを調べる

Windowsのコマンドプロンプトで容量の大きいファイルを調べる場合、forfilesコマンドを用いると良いだろう。
とは言え、容量の大きいファイルを上から順に何個、というのはコマンドプロンプト上から一行で出力は難しい。そのため、何バイト以上のファイルのみ出力させる方法で確認をする。
以下の例では、1GB以上のファイルのみ出力するように指定している。

forfiles -s -p "確認するディレクトリのパス" -c "cmd /c if @fsize gtr 1073741824 echo @FDATE @FSIZE @PATH"

20150106_000002

 

PowerShellで確認する場合は、以下のコマンドで指定したディレクトリのサブディレクトリを含めた、容量の大きいファイルから順に出力可能だ。

(Get-ChildItem "確認するディレクトリのパス" -recurse -force |  Select-Object Fullname,Length  | Sort-Object Length -descending )[0..10]

20150106_000003

2.容量の大きいディレクトリを調べる

Windowsで容量の大きいディレクトリを調べる場合、カレントディレクトリ配下のもののみであれば、以下のコマンドで確認出来る。

cd 確認するディレクトリのパス
for /D %a in (*) do @for /F "tokens=3" %s in ('dir "%a" ^| find "個のファイル"') do @echo %a : %s : %~ta

20150106_000004

もしくは、こちらの方が作成されたコマンドを利用することで、一行で利用容量が上位のディレクトリを確認出来る。

 

PowerShellの場合だと、Microsoftの公式なHowto情報より、以下のようにコマンドを実行することで確認可能だ。

function dusage{ 
  param([String]$tgtDir = (pwd).Path) 
  
  filter dusage_filter{ 
    $sum = (dir -literalpath $_.FullName -recurse -force -erroraction silentlycontinue | 
      measure-object Length -sum).Sum 
    $result = New-Object Object |  
      Add-Member NoteProperty Folder $_.FullName -PassThru |  
      Add-Member NoteProperty Size $sum -PassThru 
    return $result 
  } 
  
  dir $tgtDir -force -erroraction silentlycontinue | 
    ? {$_.PSIsContainer} | dusage_filter 
} 
  
dusage -tgtDir "c:\work" | sort -des size

…さすがに、Linux/UNIXほど思っていたように、しかも簡単には出力出来ないようだ。
もうちょっと、簡単にコマンド操作が出来るといいんだけど…

Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ) Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ)

PowerShellでhead,tail相当の処理を行う

$
0
0

LinuxやUNIXを利用している方であれば特に説明する必要も無いが、UNIX系OSにはhead、tailという「最初(最後)から数えて◯行分を出力する」というコマンドが存在する。
特にtailは、fオプションと組み合わせてログの監視を行う際に非常に重宝する。

これと同じことをPowerShellで行う場合は、以下のようにする。

1.headコマンドの場合

headコマンドに相当する操作をPowerShell2.0で行う場合は、以下のようにする。

(出力させるコマンド)[0..出力させたい行数-1]

実際に実行した際の例が以下。頭から数えて5行出力させている。

PS C:\Users\Work> Get-Content C:\Users\Work\test.txt
2 xxxxxxxx
1 xxxxxxxx
3 xxxxxxxx
7 xxxxxxxx
8 xxxxxxxx
4 xxxxxxxx
5 xxxxxxxx
6 xxxxxxxx
13 xxxxxxxx
14 xxxxxxxx
9 xxxxxxxx
10 xxxxxxxx
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
PS C:\Users\Work> (Get-Content C:\Users\Work\test.txt)[0..4]
2 xxxxxxxx
1 xxxxxxxx
3 xxxxxxxx
7 xxxxxxxx
8 xxxxxxxx

20150106_000005

 

なお、Select-Objectコマンドであれば、firstオプションを用いる事で同様の対応を行う事が出来る。

PowerShell3.0以降の場合、Get-Contentコマンドのオプションにheadが追加されている。

Get-Content 出力させたいファイル -head 出力させたい行数

20150106_000007

 

2.tailコマンドの場合

tailコマンドに相当する操作をPowerShell2.0で行う場合は、以下のようにする。

(出力させるコマンド)[-出力させたい行数..-1]

実際に実行した際の例が以下。後ろから数えて5行出力させている。

20150106_000008

 

PowerShell2.0で「tail -f」を再現するには上記とwhileを組み合わせると良いだろう。
…といっても、完璧に「tail -f」を再現する訳ではなく、ただただコマンドを何度も実行させているだけなんだけど。

while ($true -eq $true){(実行させたいコマンド)[-出力させたい行数..-1] ; sleep 間隔(秒)}

実際に実行した例がこちら。

PS C:\Users\Work> while ($true -eq $true) {(Get-Content C:\Users\Work\test.txt)[-5..-1] ; sleep 1}
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
…

20150106_000009

 

見難いようであれば、sleepの前に区切り(“——–“とか)をechoで呼び出す、もしくはコマンド実行前にdateを出力してあげるといいかも知れない。

PS C:\Users\Work> while ($true -eq $true) { Get-Date ; (Get-Content C:\Users\Work\test.txt)[-5..-1] ; echo "----------" ; sleep 1}
2015年1月6日 20:13:00
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
----------
2015年1月6日 20:13:01
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
----------
2015年1月6日 20:13:02
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
----------
2015年1月6日 20:13:03
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
----------
2015年1月6日 20:13:04
16 xxxxxxxx
11 xxxxxxxx
12 xxxxxxxx
15 xxxxxxxx
aaga
----------
…

20150106_000010

 

更に上記コマンドの最後にclearを組み合わせて上げれば、実行結果も全て削除される。
なお、Get-Contentコマンドにはファイルに変動があった場合、再度読込みを行うwaitオプションが存在している。

PowerShell3.0以降の場合、Get-Contentコマンドのオプションにtailが追加されている。

Get-Content 出力させたいファイル -head 出力させたい行数

20150106_000012

 

Windows PowerShell超入門 [4.0対応] Windows PowerShell超入門 [4.0対応]

PowerShellでwatch相当の処理を行う

$
0
0

Linuxではおなじみのwatchコマンド。
これと同等の事をPowerShellで実行する場合、Whileコマンドをうまく組み合わせる事で実現可能だ。

while ($true -eq $true) { 実行させたいコマンド ; sleep 1 ; clear}

実際に実行させた例が以下。
1秒ごとにディレクトリ配下のファイル一覧を取得させている。

while ($true -eq $true) { Get-ChildItem |  Format-Table -auto ;  sleep 1 ; clear}

20150106_000013

 

なお、コマンドプロンプトで同様の事を実現する場合、以下のようなバッチファイルを作成すると良いだろう。

@ECHO OFF
:loop
  実行するコマンド
  timeout /t 1
goto loop

 

Windows PowerShellクックブック Windows PowerShellクックブック

WindowsのPowerShellでファイルのフルパスを取得する

$
0
0

以前、Windowsのコマンドプロンプトからファイルのフルパスを取得した事があったのだが、今回はそれをPowerShellで行ってみる。

PowerShellで指定したフォルダ配下のファイルのフルパスを出力する場合、以下のように記述すると良いだろう。

Get-ChildItem -Recurse 指定したフォルダ | ?{ $_.Length -ne $null } | Select-Object Fullname

上記コマンドについて一応解説しておくと、

  • 「Get-ChildItem -Recurse 指定したフォルダ」で指定したフォルダ配下の一覧を取得
  • 「?{ $_.Length -ne $null }」でファイルのみを抽出
  • 「Select-Object Fullname」で、一覧の列からファイルのフルパスのみ出力

という感じだ。

20150212-000000

 

なお、配下にあるフォルダ を出力する場合は以下のようにする。

Get-ChildItem -Recurse 指定したフォルダ | ?{ $_.Length -eq $null } | Select-Object Fullname

20150212-000001

Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ) Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ)

PowerShellのStart-TranscriptでDOSコマンドの実行結果が保存されない時の対処法

$
0
0

LinuxやUNIXにあるscriptコマンドと同様に、PowerShellにも操作ログを記録するコマンドが存在する。それが『Start-Transcript(Stop-Transcript)』だ。
さて、このコマンドでログを記録する際、ちょっと困った挙動がある。コマンドプロンプト(cmd.exe)のコマンドを実行すると、ログに記録されないのだ…。

実際に、以下のようなコマンドを実行したとしよう。

Start-Transcript
Get-ChildItem
ipconfig
Stop-Transcript

20150227-000001

 

しかし、出力されるログは以下のようになってしまう。

**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20150227002537
ユーザー名  : Work-PC\Work 
コンピューター	  : WORK-PC (Microsoft Windows NT 6.1.7601 Service Pack 1) 
**********************
トランスクリプトが開始されました。出力ファイル: C:\Users\Work\Documents\PowerShell_transcript.20150227002537.txt
PS C:\> Get-ChildItem


    ディレクトリ: C:\


Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
d----        2014/01/25     22:48            cygwin                                                                    
d----        2014/01/25     18:04            cygwin64                                                                  
d----        2014/07/27     21:23            DeploymentShare                                                           
d----        2014/01/19     20:24            ipmitool                                                                  
d----        2014/08/09      7:40            Offiline                                                                  
d----        2009/07/14     12:20            PerfLogs                                                                  
d-r--        2015/01/18     17:06            Program Files                                                             
d-r--        2015/02/11     17:07            Program Files (x86)                                                       
d----        2015/02/26     22:49            PSTools                                                                   
d----        2014/12/21     16:31            Public                                                                    
d----        2014/03/03     23:49            teraterm                                                                  
d----        2014/03/03     22:45            teraterm_log                                                              
d-r--        2013/12/21      7:05            Users                                                                     
d----        2013/12/24      3:29            Windows                                                                   


PS C:\> ipconfig
PS C:\> 
PS C:\> Stop-Transcript
**********************
Windows PowerShell トランスクリプト終了
終了時刻: 20150227002552
**********************

見てわかるように、ipconfigの出力値だけが記録されていない。
これを出力させるには、以下のようにコマンドを実行させると良いだろう。

Start-Transcript
Get-ChildItem
ipconfig | Out-Default
Stop-Transcript

20150227-000002

 

今度は、きちんとログに出力させることが出来た。

**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20150227003014
ユーザー名  : Work-PC\Work 
コンピューター	  : WORK-PC (Microsoft Windows NT 6.1.7601 Service Pack 1) 
**********************
トランスクリプトが開始されました。出力ファイル: C:\Users\Work\Documents\PowerShell_transcript.20150227003014.txt
PS C:\> Get-ChildItem


    ディレクトリ: C:\


Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
d----        2014/01/25     22:48            cygwin                                                                    
d----        2014/01/25     18:04            cygwin64                                                                  
d----        2014/07/27     21:23            DeploymentShare                                                           
d----        2014/01/19     20:24            ipmitool                                                                  
d----        2014/08/09      7:40            Offiline                                                                  
d----        2009/07/14     12:20            PerfLogs                                                                  
d-r--        2015/01/18     17:06            Program Files                                                             
d-r--        2015/02/11     17:07            Program Files (x86)                                                       
d----        2015/02/26     22:49            PSTools                                                                   
d----        2014/12/21     16:31            Public                                                                    
d----        2014/03/03     23:49            teraterm                                                                  
d----        2014/03/03     22:45            teraterm_log                                                              
d-r--        2013/12/21      7:05            Users                                                                     
d----        2013/12/24      3:29            Windows                                                                   


PS C:\> 
PS C:\> ipconfig | Out-Default

Windows IP 構成


イーサネット アダプター ローカル エリア接続:

   接続固有の DNS サフィックス . . . : 
   IPv6 アドレス . . . . . . . . . . . : 240f:7:63e5:1:80f7:eca9:781f:987d
   一時 IPv6 アドレス. . . . . . . . . : 240f:7:63e5:1:8df6:cc92:d66f:6725
   リンクローカル IPv6 アドレス. . . . : fe80::80f7:eca9:781f:987d%10
   IPv4 アドレス . . . . . . . . . . : 192.168.0.183
   サブネット マスク . . . . . . . . : 255.255.255.0
   デフォルト ゲートウェイ . . . . . : fe80::1eb1:7fff:fe44:2d3c%10
                                       192.168.0.1

Tunnel adapter isatap.{59563340-7AE0-4F33-AD42-27CD5865DD5A}:

   メディアの状態. . . . . . . . . . : メディアは接続されていません
   接続固有の DNS サフィックス . . . : 

Tunnel adapter ローカル エリア接続*:

   接続固有の DNS サフィックス . . . : 
   IPv6 アドレス . . . . . . . . . . . : 2001:0:5ef5:79fb:147c:1472:8967:8e3c
   リンクローカル IPv6 アドレス. . . . : fe80::147c:1472:8967:8e3c%12
   デフォルト ゲートウェイ . . . . . : 
PS C:\> 
PS C:\> Stop-Transcript
**********************
Windows PowerShell トランスクリプト終了
終了時刻: 20150227003043
**********************

…う~ん、もうちょっと、Linuxとかの使い勝手に近づいて貰えないものだろうか。
bashからkshになっても、scriptコマンドは問題なく動作してくれるんだけど…

 

Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ) Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ)

PowerShellで『PSTerminalServices』を使ってリモートデスクトップの接続クライアントのIPアドレスを調べる

$
0
0

Windowsにリモートデスクトップで繋げる際、セッション数などの問題から、現在サーバに接続しているユーザーとその接続元IPアドレス、ホスト名などを知りたい時がある。
UNIXの場合だと、whoコマンド、lastコマンドで接続元IPアドレスとそのユーザーが取得できるのだが、WindowsのDOSコマンドで使える「query session」だと、接続しているユーザーまではわかるが、接続元IPアドレスまでは取得することが出来ない。いちいち接続しているユーザーを元にイベントログから推測して調べるのも効率的ではない。

そんなときは、今回紹介する『PSTerminalServices』モジュールをインストールすると良いだろう。
このモジュールに用意されている「Get-TSSession」コマンドを利用することで、接続しているユーザ名と接続元IPアドレスを取得できる。

今回は、Windows 7 Professionalにこのモジュールをインストール、検証することにする。

1.インストール

まずは、『PSTerminalServices』モジュールのインストールを行う。
こちらからmsiファイルをダウンロードし、インストーラーを起動させる。

20150425-000001

20150425-000002

20150425-000003

20150425-000004

20150425-000005

 

無事インストールかどうかを確認するため、PowerShellで以下のコマンドを実行する。

Get-Module -Name PSTerminalServices -ListAvailable
Import-Module PSTerminalServices
Get-Command -Module PSTerminalServices

実行した結果がこちら。

PS C:\Users\Work> Get-Module -Name PSTerminalServices -ListAvailable

ModuleType Name                      ExportedCommands                                                           
---------- ----                      ----------------                                                           
Manifest   PSTerminalServices        {}                                                                         

PS C:\Users\Work> Import-Module PSTerminalServices
PS C:\Users\Work> Get-Command -Module PSTerminalServices

CommandType     Name                   Definition
-----------     ----                   ----------
Function        Disconnect-TSSession   ...
Function        Get-TSCurrentSession   ...
Function        Get-TSProcess          ...
Function        Get-TSServers          ...
Function        Get-TSSession          ...
Function        Send-TSMessage         ...
Function        Stop-TSProcess         ...
Function        Stop-TSSession         ...

無事、インストールできたことが確認出来た。

2.「Get-TSSession」コマンドの実行

さて、それでは実際に「Get-TSSession」コマンドを実行してみよう。

Get-TSSession

実際にコマンドを実行した結果がこちら。

20150425-000006

PS C:\Users\Work> Get-TSSession

Server          SessionID State           IPAddress       ClientName      WindowStationName UserName            
------          --------- -----           ---------       ----------      ----------------- --------            
localhost       0         Disconnected                                    Services                              
localhost       1         Connected                                       Console                               
localhost       2         Active          192.168.X.XXX   XXXXXXXXXXX     RDP-Tcp#0         Work-PC\Work        
localhost       65536     Listening                                       RDP-Tcp

無事、接続元IPアドレスが取得できた。
PowerShellならPSexecから接続して利用できるので、これならば良いだろう。

(本当は、whoコマンド相当のものを入れてくれればいいんだけど…まぁいいか…)

動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応 動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応

Windowsでファイル名・フォルダ名の一括置換を行う

$
0
0

UNIX、Linuxと同様に、Windowsでもファイル名やフォルダ名を一括で置換したいときがある。
そんな時はどうすればよいのか?

1.コマンドプロンプトから置換を行う

非常に限定的な用途(拡張子をtxtからbatに変換する等)であれば、コマンドプロンプトからrenコマンドを使うと良いだろう。

ren リネーム前 リネーム後

20150704-000000

 

ただ、このコマンドでちゃんとした置換(たとえば、「TEST」というキーワードを「A」と変える)は難しい。
というのも、普通にコマンドを実行すると、以下の画像のようになってしまうからだ。

20150704_000001

 

手軽ではあるのだが、ちゃんとした置換であれば別の手段を取りたい所だ。

2.PowerShellから置換を行う

やはりrenコマンドを用いるよりは、PowerShellを用いる方が応用が効く。
以下のようにコマンドを実行することで、一括でファイル名を置換することができる。

Get-ChildItem <対象PATH> | Rename-Item -NewName { $_.Name -replace '置換したい単語','置換後の単語' }

20150704-000002

 

Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ) Windows PowerShell 実践システム管理ガイド2版 (TechNet ITプロシリーズ)

PowerShellで対象URLのステータス(200,404etc…)を取得する

$
0
0

仕事で、PowerShellから対象URLのステータス状態(200とか404とか)を取得する必要があったので、その備忘。
PowerShellでその辺りの情報を取得する場合は、以下のように記述する。

$url = "対象URL"
[System.Net.HttpWebRequest]$REQUEST = [System.Net.WebRequest]::Create($url)
$RESPONSE = $REQUEST.GetResponse()
$RESPONSE.Close()
[int]$RESPONSE.StatusCode

対象URLの所は、適当に引数等を指定してスクリプト化すると良いだろう。

動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応 動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応

Windows(PowerShell)でプログラムをnohupのようにバックグラウンド実行させる

$
0
0

だいぶ前に、Windows上でnohupのようにプログラムをバックグラウンド実行させられないか調べた事があった。
Windowsでnohup相当の処理を行わせるには、『-AsJob』パラメーターを利用するか、PowerShellに用意されている『Start-Job』コマンドを利用する。
コマンドによっては「-AsJob」はサポートしていないので、基本的に『Start-Job』で対応する事が多そうだ。

Start-Jobコマンドは、基本的に以下のように実行する。

Start-Job -ScriptBlock { 実行コマンド }

もしくは

Start-Job { & 実行コマンド }

 

Windows PowerShell実践システム管理ガイド 第2版 Windows PowerShell実践システム管理ガイド 第2版

PowerShellでリストボックスを使ったリモートデスクトップ(RDP)自動接続スクリプト

$
0
0

今までに、SSHでの選択型の自動ログインについてはTeratermマクロPythonのスクリプトを作ってみたりしたが、そういえばRDPの接続ではやってないなぁ…
と思ったので、簡素なものではあるがPowerShellで作ってみた。

まぁ、転職するので今後Windowsサーバを仕事で使うことがあるのやら不明だけど。
次のクライアントMacだし。

作りは、ホストのIPアドレスやらユーザ、パスワードを記述した「host.list」とスクリプト本体である「RDP_CONNECT.ps1」の2つ。
同じディレクトリ配下においておく。

1.host.list

「host.list」については、今まで書いたTeratermマクロなどと同じく、以下のようにカンマ区切りで作成している。
Azureなどへの接続でポート番号を指定する必要がある場合は、IPアドレスの後ろに普通に記述する。

●host.list

# HOST_NAME, HOST_IP, HOST_USER, HOST_PASS
テスト1,172.28.0.1,test,test
テスト2,172.28.0.2,test,test
テスト3,172.28.0.3,test,test
テスト4,172.28.0.4:4444,test,test
テスト5,172.28.0.5,test,test
テスト6,172.28.0.6:6666,test,test
テスト7,172.28.0.7,test,test

2.RDP_CONNECT.ps1

スクリプト本体。
リストボックスの作成部分についてはこちらを参考に、RDPの接続部分についてはこれをまんま使った。

●RDP_CONNECT.ps1

################
# - Function - #
################
function ListBox($FOREACH_HOST_LIST)
{
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

    $objForm = New-Object System.Windows.Forms.Form
    $objForm.Text = "RDP自動接続"
    $objForm.Size = New-Object System.Drawing.Size(300,200)
    $objForm.StartPosition = "CenterScreen"

    $objForm.KeyPreview = $True
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
        {$x=$objListBox.SelectedIndex;$objForm.Close()}})
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
        {$objForm.Close()}})

    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(75,120)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({$x=$objListBox.SelectedIndex;$objForm.Close()})
    $objForm.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(150,120)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$objForm.Close()})
    $objForm.Controls.Add($CancelButton)

    $objLabel = New-Object System.Windows.Forms.Label
    $objLabel.Location = New-Object System.Drawing.Size(10,20)
    $objLabel.Size = New-Object System.Drawing.Size(280,20)
    $objLabel.Text = "接続先のコンピュータを選択してください:"
    $objForm.Controls.Add($objLabel) 

    $objListBox = New-Object System.Windows.Forms.ListBox
    $objListBox.Location = New-Object System.Drawing.Size(10,40)
    $objListBox.Size = New-Object System.Drawing.Size(260,20)
    $objListBox.Height = 80

    Foreach($i in $FOREACH_HOST_LIST) {
        [void] $objListBox.Items.Add($i)
        }

    $objForm.Controls.Add($objListBox)
    $objForm.Topmost = $True
    $objForm.Add_Shown({$objForm.Activate()})
    [void] $objForm.ShowDialog()

    $x
    }

function RDPConnect($CONNECT_IP, $CONNECT_USER, $CONNECT_PASS)
{
    # Cmdkey用に、接続先情報にポート番号が指定されている場合は除外する
    $CMDKEY_CONNECT_IP = $CONNECT_IP | %{ $_.Split(":")[0]}

    Cmdkey.exe /generic:TERMSRV/"$CMDKEY_CONNECT_IP" /user:"$CONNECT_USER" /pass:"$CONNECT_PASS"
    Start mstsc /v:$CONNECT_IP
    Timeout 5
    Cmdkey.exe /delete:TERMSRV/$CMDKEY_CONNECT_IP
}

############
# - Main - #
############

# 『host.list』PATH取得
$SCRIPT_PATH = Split-Path $myInvocation.MyCommand.path
$LIST_FILE = Join-Path $SCRIPT_PATH "host.list"

# 空配列の作成
$HOST_NAME_LIST = @()
$HOST_IP_LIST   = @()
$HOST_USER_LIST = @()
$HOST_PASS_LIST = @()

# 『host.list』読込み
Foreach ($i in Get-Content $LIST_FILE) {
    # 空行・コメント行を無視する
    If (($i -eq "") -Or ($i.substring(0,1) -eq "#")) {
        Continue
        }

    # 変数へ代入
    $HOST_NAME      = $i | %{ $_.Split(",")[0]}
    $HOST_IP        = $i | %{ $_.Split(",")[1]}
    $HOST_USER      = $i | %{ $_.Split(",")[2]}
    $HOST_PASS      = $i | %{ $_.Split(",")[3]}

    # 配列へ代入
    $HOST_NAME_LIST = $HOST_NAME_LIST + $HOST_NAME
    $HOST_IP_LIST   = $HOST_IP_LIST + $HOST_IP
    $HOST_USER_LIST = $HOST_USER_LIST + $HOST_USER
    $HOST_PASS_LIST = $HOST_PASS_LIST + $HOST_PASS
    }

# リストボックスを呼び出し、SeletedIndexを取得する
$SELECT_INDEX_NO = ListBox($HOST_NAME_LIST)

# 何も選択しなかった場合は処理を終了する
If ($SELECT_INDEX_NO -eq $null) {
    exit
    }

# RDP接続を行う
RDPConnect $HOST_IP_LIST[$SELECT_INDEX_NO] `
           $HOST_USER_LIST[$SELECT_INDEX_NO] `
           $HOST_PASS_LIST[$SELECT_INDEX_NO]

 

念のため、ファイルはここにあげておいた。

動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応 動くサンプルで学べる Windows PowerShell コマンド&スクリプティングガイド PowerShell 4.0対応

WindowsでLinux/UNIXのtouchコマンド相当(0Byteのファイル作成)の処理

$
0
0

Windowsでサンプルファイル(0Byteのファイルを20個くらい)を作成する事になったので、Linuxでいうtouchコマンドに当たるコマンドについて調べてみた。
といっても、別にタイムスタンプ変える事は考えず、単に空ファイル作成するだけなのだが。

コマンドプロンプトとPowerShell、それぞれで0Byteのファイルを作るコマンドは以下のようだ。

コマンドプロンプトで作成する

コマンドプロンプトで0Byteのファイルを作成する場合は、以下のようにnul(Linuxでいう/dev/null)をコピーして作成する方法がある。

copy nul 作成するファイル名(PATH)

20160116_000001

PowerShellで作成する

PowerShellで0Byteのファイルを作成する場合は、以下のように「New-Item」コマンドレットを用いる方法がある。

New-Item -ItemType file 作成するファイル名(PATH)

20160116_000002

 

後は、これらをfor文で回すだけだ。

 

PowerShellからDatadogにイベントを通知する

$
0
0

LinuxのコンソールなどからコマンドでDatadogのDashboardとかを編集したり、イベントの通知をする場合はDatadogpyなどを用いれば良いのだが、Windows Server上からコマンドで実行させたい事があった。
で、結論としてはDatadogではRestAPIが用意されているので、PowerShellでそれ経由で処理させれば良い。

●datadog-sample.ps1

# ----------------------
# Datadog Powershellイベント通知スクリプト(Sample)
# ----------------------

$url_base = "https://app.datadoghq.com/"
$api_key = 'APIキー'
$app_key = 'APPキー'

$http_method = "POST"
$url_signature = "api/v1/events"
$currenttime = (Get-Date -date ((get-date).ToUniversalTime()) -UFormat %s) -Replace("[,\.]\d*", "")
$parameters = "{
    `"title`":`"PowerShell テスト`",
    `"text`":`"PowerShellでのDatadog通知テスト`",
    `"priority`": `"normal`",
    `"alert_type`": `"warning`"
    }"

$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key"
$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open($http_method, $url, $false)
$http_request.setRequestHeader("Content-type", "application/json")
$http_request.setRequestHeader("Connection", "close")
$http_request.send($parameters)
$http_request.status
$http_request.responseText

 

イベント以外もRestAPIから操作可能なので、bashなどのサンプルを参考にPowerShellに書き直していけば良い。

Windows PowerShell逆引きハンドブック Windows PowerShell逆引きハンドブック

PowerShellでAzure Blob StorageのSnapshotを取得する

$
0
0

仕事でAzure Blob Storageをいじってるのだけど、ポータル画面からだとスナップショットの取得ができなそうなので、PowerShellから取ってみる事にした。

残念ながら、コンテナ単位でSnapshotを取得する事は出来ないようで、オブジェクト単位での取得をする必要があるようだ。

# Blob Storageに関する情報
# StorageAccountName: Blobアカウント名
# StorageAccountKey : Blobアクセスキー
# ContainerName : Blobコンテナ名
# BlobName : Blob名
$StorageAccountName = "Blobアカウント名"
$StorageAccountKey = "Blobアクセスキー=="
$ContainerName = "コンテナ名"
$Ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey

# コンテナ情報を取得する
$BlobsContainer = Get-AzureStorageBlob -Context $Ctx -Container $ContainerName

# foreachでコンテナ内の必要なBlob(今回はvhd)に対しスナップショットを取得する
foreach($Blob in $BlobsContainer) {
    if((!$Blob.ICloudBlob.IsSnapshot) -and ($Blob.Name.EndsWith("vhd"))){
        # スナップショットの取得を行う
        $snap = $blob.ICloudBlob.CreateSnapshot()
        # 指定したBlobのスナップショットを確認する
        Get-AzureStorageBlob –Context $Ctx -Prefix $Blob.Name -Container $ContainerName  | Where-Object  { $_.ICloudBlob.IsSnapshot -and $_.Name -eq $Blob.Name }
    }
}

 

スナップショットの取得条件は環境に合わせて書き換えてもらえれば良いだろう。

 

Windows PowerShellクックブック Windows PowerShellクックブック

WindowsのBatch(cmd)/PowerShellで0バイトのファイル(空ファイル)や空のディレクトリを一括削除する

$
0
0

WindowsでBatchやPowerShellを用いて、Linuxと同じように空ファイルや空ディレクトリを抽出、それらを一括削除する方法があるかを調べてみた。

1.空ファイルの削除

カレントディレクトリ配下の空ファイルを一括削除する場合、以下のようにする。
(PowerShellの方は再帰的に削除させている)

●Batch(cmd)の場合

for %F in (*) do if %~zF equ 0 del "%F"

 

●PowerShellの場合

get-childItem -recurse | where {$_.length -eq 0} | remove-Item

2.空ディレクトリの削除

カレントディレクトリ配下の空ディレクトリを一括削除する場合、以下のようにする。

●Batch(cmd)の場合

for /f "usebackq delims=" %d in (`"dir /ad/b/s | sort /R"`) do rd "%d"

 

●PowerShellの場合

Get-ChildItem -recurse | Where-Object {$_.PSIsContainer -eq $true -and (Get-ChildItem -Path $_.FullName) -eq $null} | Remove-Item

 

Windowsで更新日が○日前のファイルを削除する方法

$
0
0

先日、Twitterで『Windowsで更新日が◯日前のファイルを削除する方法』について見かけたので、そういえばどのくらいあるんだろう?と思って調べてみた。
もともとPowerShellではできるであろうとは認識してたので、他にもお手軽な方法があるのかなと。

1.PowerShellの場合

まぁ、PowerShellでやる方法についてはMicroSoftでも公式で例を出してるので…。
PowerShellの2と3で、以下のようなやり方があるようだ。

●PowerShell2

Get-ChildItem パス名 –Recurse | Where-Object{$_.CreationTime –lt (Get-Date).AddDays(-日数)} | Remove-Item

 

●PowerShell3

Get-ChildItem パス名 –Recurse | Where-Object CreationTime –lt (Get-Date).AddDays(-日数) | Remove-Item

 

まぁ、PowerShell2の書き方であれば大体の環境で動作するので、そちらを使うと良いだろう。

 

2.cmd(コマンドプロンプト)の場合

cmd(コマンドプロンプト)で古いファイルを削除する場合、以下のようにする。
1行目のコマンドで対象のファイルを抽出、2行目で削除している。

forfiles -p パス名 -s -m *.* -d -日数 -c "cmd /c echo @path"
forfiles -p パス名 -s -m *.* -d -日数 -c "cmd /c del @path"

 

3.Explorerからファイルを検索して削除する場合

最後に、PowerShellもコマンドプロンプトもちょっと…全部GUIからやりたいという人の場合は、Explorerから対象のファイルを検索して削除すればいいだろう。
Explorerで削除を行う対象のパスに移動して、右上の検索バーに以下のように入力してやれば良い。

< 日付
もしくは
datemodified < 日付

 

これで、その日付よりも前のファイルだけを抽出できるので、あとはすべて選択して削除すればよい。

20161001_145026000000_

 

まぁ、普通に定期的に実行するならPowerShellかbatchでスクリプト作ってタスクマネージャで定期実行させるのをおすすめするけど…
世の中、誰もがスクリプト書けたりするわけでも無いので、お好みで。

Windowsネットワーク上級リファレンス Windows 10/8.1/7完全対応 Windowsネットワーク上級リファレンス Windows 10/8.1/7完全対応

PowerShellでファイルの作成や編集、削除の検知・モニタリングを行う

$
0
0

Windowsで、Linuxのようにinotify-toolsを使ってファイルの作成や編集、削除について検知とかをするにはどうすればいいのかなと思って調べてみた。どうやら、PowerShellでもやろうと思えばできるようだ。Windowsでinotifyのようにファイルのイベントを検知する場合は「System.IO.FileSystemWatcher」を用いることで同様のことが行える。

参考元に記述されているようなPowerShellスクリプトを記述することで、指定されたログに監視PATHで発生したイベントをログに記録させることができるようだ。ちょっとだけ記述を変えて試してみたので、一応変えたソースも置いておく。実際に利用するのであれば、PowerShellでバックグラウンドプロセスとして動作させる必要があるので、『Start-Job』コマンドを用いてキックする必要があると思う。下記の例だと、スクリプトの引数1を監視し、その結果を引数2で指定したログファイルに出力するような感じ。とりあえず、手元のWindows 10では確かにイベント発生と同時にログが出力された。

●fwatch.ps1

$watchDirPath = $Args[0]
$logPath = $Args[1]

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "$watchDirPath"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true

$action = { $path = $Event.SourceEventArgs.FullPath
            $changeType = $Event.SourceEventArgs.ChangeType
            $logline = "$(Get-Date), $changeType, $path"
            Add-content $logPath -value $logline
          }


Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Deleted" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 1}

 

【参考】

 

Windows PowerShell逆引きハンドブック Windows PowerShell逆引きハンドブック

PowerShellでMacのsayコマンドのように合成音声にテキストを読み上げさせてみる

$
0
0

ふと、PowerShellでMac OS Xのsayコマンドのようにテキストを合成音声で読み上げさせることができないかと思い調べてみたところ、Add-Typeで.NetのSpeechSynthesizerを追加したらできそうだったので、試しにやってみることにした。
なお、OSはWindows 10を用いている。

Add-Type -AssemblyName System.speech
$s = New-Object System.Speech.Synthesis.SpeechSynthesizer
$s.Speak("えっさほいさ")

 

残念ながら単体のコマンドではないのだが、一応似たような事はできるということで。
本当に必要ならPowerShellスクリプト組んでおけばいいし。

Windows PowerShell逆引きハンドブック Windows PowerShell逆引きハンドブック
Viewing all 20 articles
Browse latest View live