2011年1月18日火曜日

◆SQL Server PowerShellの環境を作る

SQL Server PowerShellとはPowershellからSQL Serverを管理するためのツールセット(実体は、いくつかのコマンドレットとプロバイダー、環境変数、型定義等)である。

SQL Server2008をインストールすると一緒にインストールされる。(R2の場合はインストール時の機能選択で管理ツールを選ぶとインストールされるようだ)
Expressでもwith Advanced Services 版をインストールすれば使える。

一番簡単な使い方はコマンドラインから「sqlps」と打ち込む。20110118140923

するとSQL Server用の機能が組み込まれたPowershellが起動する。
SQLプロバイダーがルートになっているのでdirコマンドを打つと以下のような内容が表示される。

20110118141648

ルートのsqlを潜っていくとDatabasesが現れる。
image

この中身をまた潜っていくとTableやColumnが現れる。

というように、SQLプロバイダーのおかげでSQL Serverも通常のファイルツリーの様にアクセスが可能になっている。

あとはこれらのオブジェクトを使って様々な情報を引き出せば良い。

以下を参考にサンプルを作ってみた。
SQL Server PowerShell を使用した管理手法 第 2 回 実践編

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023

$server = get-item SQLSERVER:\sql\localhost\sqlexpress\databases

$dbinfos = @()
$fmt = "#,##0.0"
 
#データベースの数だけ繰り返し
foreach ( $db in $server.
Collection )
{
 
$dbinfo = New-Object PsObject |
 
     
select データベース名,DB,空き, データ,インデクス
  #データベース名
  $dbinfo.データベース名 = $db.
Name
 
#DBの容量
  $dbinfo.DB = $db.Size.ToString($fmt) + "MB"
  #DBの空き容量
  $dbinfo.空き = ($db.SpaceAvailable / 1024).ToString($fmt) + "MB"
  #データの容量
  $dbinfo.データ = ($db.DataSpaceUsage / 1024).ToString($fmt) + "MB"
  #インデックスの容量
  $dbinfo.インデクス = ($db.IndexSpaceUsage / 1024).ToString($fmt) + "MB"
  $dbinfos += $dbinfo
}
$dbinfos | ft
-Auto

結果
20110118152238

ちなみに、スクリプトファイルを実行するときは、
sqlps -noexit -command "d:\desktop\db.ps1"
の様に起動してあげれば良い。

2011年1月17日月曜日

◆文字列からWMIオブジェクトを作る

通常WMIオブジェクトは Get-WmiObject コマンドレットで作ることが出来る。<

001
002
003

#デフォルトプリンターを設定する
$printer = gwmi win32_printer | ?{$_.name -eq "FX mini Driver for XPS"}
$printer.SetDefaultPrinter()

別な方法として、文字列をWMIクラスにキャストなんてことも出来るようだ。

</
001
002
003
004
005

#デフォルトプリンターを設定する
([wmi]'win32_printer="FX mini Driver for XPS"').SetDefaultPrinter()

#Cドライブの容量を表示する
"Cドライブの容量" + ([int](([wmi]'Win32_LogicalDisk="C:"').size/1gb)) + "GB"

([wmi]'Win32_Service.Name="Spooler"').StartMode

2011年1月14日金曜日

◆環境変数を更新する

環境変数を参照するには、 dir  env:

個々の変数は、 $env:temp とかやると参照可能。

$env:temp = “c:\temp” とかやれば値の設定も可能なのだが、その値は設定したPowershellセッションでしか有効にならない。
Profileに設定しておけばすべてのPowershellセッションで有効になるが、Powershell以外では無効。

永続的に更新するには以下のようにすると良さそうだ。

[Environment]::SetEnvironmentVariable(“temp”, “D:\temp”, “User”)

2011年1月12日水曜日

◆パラメータ属性

Powershellのパラメータには様々な属性が用意されている。
例えば、あるパラメータを必須にしたければParameter属性のMandatory引数を指定すれば良い。指定の仕方はこんな感じだ。

001
002
003
004
005
006

Param(
[parameter(Mandatory=$true)]
[string]$name
)

Write-Host $name

nameパラメータを指定せずに実行すると以下のようなプロンプトが表示される。
20110112162751

合わせてHelpMessage引数を指定すると簡易ヘルプを表示させることもできる。

001
002
003
004
005
006
007

Param(
[parameter(Mandatory=$true,
HelpMessage="あなたの名前を入力してください")]
[string]$name
)

Write-Host $name

20110112163617 <!--EndFr

 

必須パラメータの引数にNullを許可するようにするにはAllowNull属性を使う。

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

Param(
 
[parameter(Mandatory=$true)]
  [object]
  [AllowNull()]
  $obj
)

if($obj
){
 
Write-Host $obj.
GetType()
}
else
{
 
Write-Host "obj = null"
}

AllowNull属性を指定せずにパラメータにNullを指定した場合は以下のようなエラーとなる。
20110113115356

似たようなものに、Stringの必須引数に空の文字列を許可するAllowEmptyString属性などがある。

その他にはValidation系の属性がいくつか揃っている。
たとえば、ValidateLength属性は文字列の長さを限定できる。

001
002
003
004
005
006
007
008
009

Param(
 
[parameter(Mandatory=$true)]
  [string]
  [ValidateLength(1,10)]
  $name
)

{
以下のパラメータが指定されました}
Write-Host $name
<
!-20110113144619 -End

ValidatePattern 属性は引数の検証パターンを正規表現で指定する。

001
002
003
004
005
006
007
008
009

Param(
 
[parameter(Mandatory=$true)]
  [string]
  [ValidatePattern("\d{3}-\d{3}-\d{4}")]
  $phone
)

{
以下のパラメータが指定されました}
Write-Host $phone
End

20110113145620

他にも色々と属性はあるので詳細はabout_Functions_Advanced_Parametersを参照すると良い。

2011年1月11日火曜日

◆SendKeyを使う

アプリケーションを制御する方法としてSendKeyでキーストロークをアプリケーションに送る方法がある。
タイミングなども関係してくるのであくまでも簡便的な方法ではあるが、それなりに使える局面はあるとおもう。

という事でSendKeyのサンプルを作ってみた。
電卓を起動し、計算をさせて結果をメモ帳にコピーペーストしている。

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

add-type -AssemblyName System.Windows.Forms

$calc = Start-Process Calc -PassThru
start-sleep -Milliseconds 300

[System.Windows.Forms.SendKeys]::SendWait("2{*}3=")
[System.Windows.Forms.SendKeys]::SendWait("^(C)")

notepad
start-sleep
 -Milliseconds 300
[System.Windows.Forms.SendKeys]::SendWait("^V")
$calc.Kill()

キーストロークの詳細は以下を参照。
SendKeys メソッド

2011年1月5日水曜日

◆パイプライン入力(ByPropertyName)

コマンドレットのパラメータでパイプライン入力を許可するものの中にByValueとByPropertyNameの2種類がある。
ちなみに、以下はSet-VariableコマンドレットのValueパラメータのヘルプ表示である。20110105162227

ByValueというのは通常のパターン。
”test” | Set-Variable  var
とやると$varという変数に”test”という値が設定される。

ByPropertyNameというのはパイプライン入力オブジェクトのプロパティ名とSet-Variableのパラメータを名前でマッピングしてくれるものだ。
例えば、Set-VariabaleコマンドレットのNameとValueというパラメータはパイプライン入力オブジェクトにNameとValueというプロパティがあるとそれらが使用される。
以下のような感じだ。

001
002
003
004
005
006

$obj = New-Object PsObject | select Name,Value
$obj.Name = "住所"
$obj.Value = "神奈川県川崎市"
$obj | Set-Variable
$住所


20110112114640

ん~、結果を見るとちょっと期待と違っている。
NameはOKなのだが、Valueのほうは$objがそのまま設定されている。
これはByValueの動きだ。
もしかして、ValueパラメータのパイプラインにByPropertyNameとあるのはヘルプの誤り?
(もしくは私の理解が若干違うのかもしれない)

2011年1月4日火曜日

◆カスタムオブジェクト(PsObject)を使う(New-Object)2

PowerShell: ◆カスタムオブジェクト(PsObject)を使う(New-Object)ではNew-ObjectコマンドレットでPsobjectを作った。

プロパティの追加にはAdd-Memberコマンドレットを使ったり、集計プロパティを使ったり、ハッシュテーブルでアサインしたりと色々な方法があるが、以下のような方法もある。
(個人的にはこれが一番覚えやすく簡単に思える)

001
002
003

$obj = New-Object PsObject | select name,value
$obj.name,$obj.value = "Address","盛岡市大通4-7"
$obj | ft * -AutoSize

結果はこんな感じ。
20110104165150