2010年12月9日木曜日

◆Pingでサーバーの死活確認(Test-Connection)

Test-Connectionコマンドレットを使うとPingコマンドを直接使うよりも簡単に結果を確認することが出来る(文字列解析が不要)

Quietスイッチを指定すると単純にPingが成功したか失敗したかの結果だけを返してくれる。
以下の例では直接Server名を指定するパターンと、Server名の入ったテキストファイルを用意するパターンに対応してみた。

結果はそのままテキストで表示してもよいが、ここではHTML形式にして表示させている。
(HTML化が本題ではないのでごく簡単な表示で済ませている)
また、場合によってはこのHTMLテキストをPowerShell: ◆メールを送る(Send-MailMessage)を使って管理者にメールするなんてのも良いだろう。

PowerShell: ◆コメントベースのヘルプを記述するで書いたコメントも先頭に付けてみた。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035

<#
.SYNOPSIS
サーバーの死活確認を行う
.DESCRIPTION
Serversに指定したServerまたはinputpathで指定したテキストファイル中のServerに
対してPingを送信しその死活を確認する。
結果は指定されたパスにHTML形式で出力する。
.NOTES
inputpath、serversともに指定しないとエラーとなる。
.LINK
http://www.powershell.com
.EXAMPLE
Ping.ps1 -inputpath w:\pcname.txt
.EXAMPLE
Ping.ps1 -servers vista3,goemon
#>

param
(
 
[string]$inputpath,
  [string[]]$Servers,
  [string]$outputpath="W:\servers.htm"
)
if($inputpath
){
 
$pcname = Get-Content $inputpath
}elseif($Servers
){
 
$pcname = $servers
}else
{
 
Write-Warning "Please Specify Params"
  exit
}
$isalive = @(Test-Connection -ComputerName $pcname -Quiet)
$result = 0..($pcname.Count - 1) | %{$pcname[$_] + "," + $isalive[$_]}
$head = (Get-Date).ToString() + " サーバー死活確認"
$html =  $result | ConvertFrom-Csv -Header "PC名","IsAlive" |
 
 
ConvertTo-Html -Head $head -Title "Servers" 
$html | 
Out-File $outputpath

結果はこんな感じになる。
20101209194217

◆PowerGUIにスニペットを追加する。

前回コメントベースのヘルプの記述方法を説明したが、毎回手で追加するのは面倒。
PowerGUIにはスニペットを挿入する機能があるので、スニペットとして追加してみた。
スニペットはインストールしたフォルダー配下のsnippetsフォルダーにある。
通常は”C:\Program Files\PowerGUI\snippets” 。

既存のスニペットをコピーして適当に変更してやれば良い。
コメントベースのヘルプを挿入するために作ったのが以下である。

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>comment</Title>
      <Shortcut>comment</Shortcut>
      <Description>Comment For Help</Description>
      <Author>minminnana</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
        <SnippetType>SurroundsWith</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
       <Literal>
          <ID>gaiyou</ID>
        </Literal>
        <Literal>
          <ID>setsumei</ID>
        </Literal>
        <Literal>
          <ID>link</ID>
        </Literal>
        <Literal>
          <ID>memo</ID>
        </Literal>
        <Literal>
          <ID>sample</ID>
        </Literal>
      </Declarations>
      <Code Language="powershell">
        <![CDATA[<#
.SYNOPSIS
    $gaiyou$
.DESCRIPTION
    $setsumei$
.LINK
    $link$
.NOTES
    $memo$
.EXAMPLE
    $sample$
#>
]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

赤で記述した箇所が変更(追加)した部分。
<ID>で入力を促す項目を定義しておき、<Code>の中で$hoge$の形式で参照してやると良いようだ。

定型的なコーディングを色々と登録しておけば効率UPする事だろう。

ちなみに私が試した限りでは日本語は通らない(スニペットの一覧に表示されなくなる)ようだ。

◆コメントベースのヘルプを記述する

以前PowerShell: ◆スクリプトファイルを作るで独自のコメントを使ったヘルプを記述したが、Ver2になってPowershellの機能としてコメントベースのヘルプがサポートされた。(about_Comment_Based_Help)
VisualStudioで言うところのコードコメントと同じイメージかな。
以下のようにスクリプトや関数の先頭にコメントを書いておく。
<#
.SYNOPSIS
    概要のテスト
.DESCRIPTION
    説明のテスト
.LINK
    http://mtgpowershell.blogspot.com/
.NOTES
    メモのテスト
.EXAMPLE
    Write-Comment ”コメント"
#>
Get-Help W:\Write-Comment.ps1 –full
っとやると以下のように通常のコマンドレットと同じ書式でヘルプが表示される。
20101209115524

2010年12月7日火曜日

◆多次元配列と多段階配列(ジャグ配列)

PowerShell: ◆配列関連でも書いたが、いろいろなサイトを見ているとあまり区別していないケースが多いので少し補足。(多段階配列を指して多次元配列と呼んでいるケースが多いようだ)

多段階配列も多次元配列の一種なのかもしれないが、アクセスする文法が違うのでやはり区別したほうが良いものと思う。

PS>#多段階(ジャグ)配列
PS>$arrJag = @((New-Object string[] 2) , (New-Object int[] 3), (New-Object int[] 2))
PS>$arrJag[0][0] = "aaa"
PS>$arrJag[0][1] = "bbb"
PS>$arrJag[1][0] = 1
PS>$arrJag[1][1] = 2
PS>$arrJag[1][2] = 3
PS>$arrJag[2][0] = 4
PS>$arrJag[2][1] = 5
PS>Write-Host $arrJag
aaa bbb 1 2 3 4 5
PS>
PS>$arrJag = (("c","d"),(6,7,8),(9,0))
PS>Write-Host $arrJag
c d 6 7 8 9 0
PS>
PS>#多次元配列
PS>$arrMulti = New-Object "int[,]" 2,3
PS>$arrMulti.Count
6
PS>
PS>$arrMulti[0,0] = 1
PS>$arrMulti[0,1] = 2
PS>$arrMulti[0,2] = 3
PS>$arrMulti[1,0] = 4
PS>$arrMulti[1,1] = 5
PS>$arrMulti[1,2] = 6
PS>Write-Host $arrMulti
1 2 3 4 5 6
PS>$arrMulti[(1,0),(0,1)]
4
2

多段階配列とは、配列の個々の要素が配列になっている物。
上記の例の様にそれぞれで違うデータ型を取ることが出来る。
全体の要素数は個々の配列の要素数を足した値となる。

多次元配列とはスプレッドシートの様に次元を掛けあわせた形の配列。
要素のデータ型は一律。
全体の要素数は個々の配列の要素数を掛けた値となる。

といった違いがあるので表の様なデータを扱うには多次元配列。
そうでなければ多段階配列を使うと良いのだと思う。
多段階配列の方が必要な分しか領域が確保されないのでメモリー的には優位と思われる。

2010年12月3日金曜日

◆フォントの一覧を取得する

HTMLなどを書いているとフォントを文字列で指定したいことがあるが、正式な名前が判らないことがある。

MSゴシックなども、半角なのか全角なのか、間にスペースは入るのか、そのスペースは半角か全角か・・・。

そんな時はPowershellで文字列表示してコピーすると確実だ。

PS>add-type -AssemblyName system.drawing
PS>(New-Object System.Drawing.Text.InstalledFontCollection).Families

◆DOSコマンドをPowershellから使う

ヒア文字列で定義してパイプで渡してあげると簡単に実行できる。
以下では2つのテキストファイルをまとめて一つのテキストファイルにしている。
大きいファイルではPowershellでやるよりこちらのほうが効率的かもしれない。

001
002
003
004
005
006
007
008
009
010
011
012
013

Set-Location d:\Desktop
"---- test1.txt ----------"
Get-Content test1.txt
"---- test2.txt ----------"
Get-Content test2.txt
$cmd = 
@"
  if exist test3.txt (del test3.txt)
  copy /b test1.txt + test2.txt test3.txt
"@

$cmd | 
cmd
Write-Host

"---- test3.txt ----------"
Get-Content test3.txt

結果
20101203222959

2010年12月1日水曜日

◆長いパスの指定を簡単にする(New-PsDrive)

スクリプトを書いていてデスクトップのパスを使いたいことがよくある。
そのたびに、「C:\Users\minminnana\Desktop」とか「C:\Documents and Settings\minminnana\デスクトップ」とか打ち込むのは非常に面倒だ。
そこでデスクトップのパスをPsDriveにしてあげると非常に簡単にアクセスできる。<!-

001
002
003
004
005
006
007
008
009

#デスクトップにWドライブを割り当てる。
$parm =
 @{ 
  name 
= "w"
 
  psprovider 
= "FileSystem"
 
  root 
= "d:\Desktop"
 
} 


New-PSDrive @parm | Out-Null 
Remove-Variable parm
<!-

これをProfileに追加しておけば次からは「w:」でデスクトップにアクセス可能になる。
ドライブ名は必ずしも1文字でなくてもよい。deskとかにすれば、desk: でアクセスできる。

注意点として、Powereshellの世界はこれでOKなのだが他の世界ではこのドライブは通用しない。
例えば.NETのクラスにパスを引数で渡す場合などには使用できない。
正式なパスを指定するか、Convert-Pathコマンドレットで変換して渡す必要がある。

001
002
003
004
005

# encoding設定
$encoding = [Text.Encoding]::
default
  

# テキスト読み込み
$sr = new-Object IO.StreamReader((Convert-Path w:pcname_SJIS.txt),$encoding)