2014年10月30日木曜日

◆WPF(XAML)を使う

PowerShellからXAMLで作ったウインドウを扱ってみる。

XAML自体は直接作るのは面倒なのでVisualStudioからコピーする。
image

Windowのx:Classの指定はエラーになるようなので削除する(行削除)

後はXAMLの記述をヒア文字列で定義してWindows.Markup.XamlReaderクラスのParseメソッドで変換してあげるだけのようだ。

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

$xaml = @"
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Button"
            HorizontalAlignment="Left" VerticalAlignment="Top"
   Width="75" Margin="230,138,0,0" Name="button1"/>
        <Label Content="Label" HorizontalAlignment="Left" Height="34"
   Margin="198,202,0,0" VerticalAlignment="Top"
   Width="171" Name="label1"/>

    </Grid>
</Window>
"@


Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase
$window = [Windows.Markup.XamlReader]::Parse($xaml)
$button = $window.FindName("button1")
$label = $window.FindName("label1")
$button.add_Click({$label.Content = "Hello World"})

$window.ShowDialog() | Out-Null

実行すると以下のウインドウが表示されて、

image

ボタンをクリックすると「Hello World」が表示される。

image

Windowsフォームより使いやすいかも。

2014年10月29日水曜日

◆「Format-List *」をプロパティ順に表示する

以下のプロパティをPS3.0で表示する。

image

image

できればプロパティの名前順に表示したい。

Format-Listは基本的にパイプラインの最後なので簡単にソートすることは出来ない。

とりあえず以下のような感じだろうか。

>(Get-NetAdapter イーサーネット1 | tee -var net) | fl -Prop ($net | gm | sort name).name

2014年10月10日金曜日

◆CRをCRLFに変換する

以下のTipsの内容をメモしておく。

Normalizing Line Endings - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

 

たまに、どこかから取ってきたファイルなどで改行コードがCRだけの場合があり、メモ帳で開くと残念な結果になる。

少し高機能なエディターとかであればCRだけでも旨く表示してくれるし、CRLFに変換して保存したりも出来る。

上記Tipsによると、PowerShellでも簡単に変換が可能だ。
特に、Replaceとか使わずとも「Get-Content」で読んでそのまま「Set-Content」で出力するだけで良いのだそうだ。

---

以下の説明が詳しい
http://www.atmarkit.co.jp/ait/articles/1605/16/news023.html

2014年10月8日水曜日

◆パラメータ名の一部省略の不思議

コマンドレットのパラメータは他のパラメータと区別可能ならば途中までの文字で指定が可能だ。

image

dir –p と入力してタブを押すと「Path」しか出てこないので「p」だけでも良さそうだが、なぜか以下のようなエラーとなる。

PS>dir -p c:\
Get-ChildItem : パラメーター名 'p' があいまいなため、パラメーターを処理できません。一致する名前の候補は次のとおりです:
-Path -LiteralPath。
発生場所 行:1 文字:4
+ dir <<<<  -p c:\
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem]、ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.GetChildItemCommand

なぜ「LiteralPath」も対象になるのだろう。

2014年10月6日月曜日

◆IF文での判定条件の書き方

今更ながら基本の基本を確認しておく。

IF文での判定条件は普通に考えると、

if($a –eq 1){hogehoge}

てな感じに書くのが一般的な気がする。
ただし、これは一般的な他の言語と同様な書き方で一見何の問題も無いように見えるが、PowerShellの場合はちょっと事情が異なる。

例えば以前PowerShell: ◆配列をフィルターするで書いたように、配列などではイコール演算子が感覚とはちょっと違った動作をする。

この間、PowerShell: ◆閾値以下の空き容量のHDドライブがあったら警告するで使った抽出判定も、

if(Get-PSDrive | ?{$_.USED –ne “”}){hogehoge}

ってな感じでは旨くいかない。(余計なものが幾つか残ってしまう)
image

では、どうすればよいのか。
昔からなんとなく使っている以下の書き方が実は正しい書き方なのではと最近思っている。

if($a){hogehoge}

こう書いた場合、どう判定されるかというと(経験的に)、その変数のデータ型の初期値であればFalse、初期値以外がTrueになる。

数値であれば、0がFalse、文字列であれば””がFalse、オブジェクトであればNullがFalseといった具合。
配列がちょっと厄介だが、要素が複数の場合はTrue、ひとつの場合はその変数の属性に応じて上記と同様に判定される。

この機能はおそらく、PowerShellが$aをbool型に自動変換しているのだろう。
即ち、

if([bool]$a){hogehoge}

と書くのと同じではないかと思う。

image

 

先に書いた、

if(Get-PSDrive | ?{$_.USED –ne “”}){hogehoge}

のパターンでは、USEDプロパティがスクリプトプロパティなので、ドライブによってUSEDのデータ型が違ってきている。

なので、演算子を直接使って判定しようとすると

image

てな感じになってしまう。

これはやはり普段から

if($a){hogehoge}

の書き方を使うのが良いのだろうと思う。

ちなみに、「-ne」の場合は「!」を使って(!$a)とする。

 

あくまでも、経験則で考えたものですが・・・・。

2014年10月1日水曜日

◆閾値以下の空き容量のHDドライブがあったら警告する

>if(Get-PSDrive | ?{$_.used} | %{$_.Free / ($_.used + $_.free)} | ?{$_ -lt 0.6}){"HD容量不足発生";Read-Host}

image

ここでは閾値として0.6(60%)を指定している。

後はこれをスタートアップで実行しても良いし、サーバーなどを巡回しても良いしって感じだろうか。

---

質問があったので補足

各ドライブの空き容量を表示するにはとりあえずこんな感じで

>Get-PSDrive | ?{$_.used} | select name , @{name="残容量(%)";expression={[int](($_.Free / ($_.used + $_.free))*100)}}

image