2011年10月2日日曜日

◆Join演算子

基本的な演算子ではあるが、使い方として特に問題になるような事がなかったので特に触れたことがなかったが、幾つかサンプルをまとめておこうと思う。

ヘルプで構文を見ると

  構文
      次は、結合演算子の構文を示しています。

    -Join <String[]>
    <String[]> -Join <Delimiter>

となっていて、Delimiterをしていしなければ単項演算子、指定すれば2項演算子(と呼ぶのかな?)になります。

使用例としては、
2011-10-02 13h59_32

といった感じになるかと思います。

ちなみに、Join演算子はカンマより優先度が高く、括弧を使わないと以下のようになります。
2011-10-02 14h01_23

これは、以下のように解釈されているのでしょう。
2011-10-02 14h02_53

もう少し例をあげてみると、
例えば以下のようなケースで、
2011-10-02 14h04_35

これをCSVのようにカンマ区切りで出力(表示)したい時、もし自力でやるのであれば
(通常はCSV用のコマンドレットが用意されているので、それを使用するほうが良いかも)

2011-10-02 14h10_34

といった感じになる。

また、以下は簡便的な「かなローマ字変換」の例である。
2011-10-02 14h16_57

実際の「かなローマ字変換」は拗音とか考慮しなければいけないことが色々あるのでこんなに単純には行かないが、文字列変換パターンとしては用途がありそうなパターンだと思う。

この様にJoin演算子自体は難しいものではないが、色々と使い道はありそうだ。

2011年10月1日土曜日

◆Write-Verboseで詳細情報を書き込む(補足)

前回のBlogで牟田口さんからご指摘をいただきました。

ちょっと誤解を招く内容だったため補足致します。
ご指摘いただきましたとおり詳細情報の書き込みについてはPowershell2.0からサポートされている「高度な関数機能」を使うのがスマートな方法と思われます。
じつはこれについては以前に以下でサンプルを作成しております。
PowerShell: ◆デバッグ情報出力機能の付いた関数を作る(Write-Verbose)
PowerShell: ◆高度な関数機能を使う

今回は「Windows PowerShell: 各コマンドレットについて掘り下げる」の記事に触発されコマンドレット一覧で最後の方から眺めていたところ、上記Blogを書いたときには「Write-Verbose」自体がcmdletbinding属性を要求するものなのかと漠然と解釈していたのが実は単独でも使えるのだと判り、改めてサンプルを書いてみたものです。

加えて、つい最近スイッチパラメータをフォワードすることがあり、Bool値で指定するにはどうやるのかと調べました。(以前何度か使ったことはあるのですが失念していたため)
それで、今回のサンプルに都合が良かったので合わせて(自分のメモの意味で)使用してみました。

ですので、実は今回の内容は「詳細情報を書きこむ」のが本来の目的ではなく、あくまでも「Write-Verbose」の使い方を確認するためのものでした。

以前の記事へのリンクと、このような背景をちゃんと記述しておけば良かったのですが、ちょっと手を抜いたために誤解を与えるような内容になってしまいました。

ご指摘を頂きました牟田口さんには、いつも暖かくフォローしていただき感謝しております。

ちなみに、牟田口さんの「ポケットリファレンス」には、いつもお世話になっており、いまも机の上に常備しております。(__)

今後共ご指導のほどよろしくお願いいたします。

2011年9月29日木曜日

◆Write-Verboseで詳細情報を書き込む

Verboseパラメータは詳細情報を表示する共通パラメータとして、どのコマンドレットでも使用できる。(実際に有効なメッセージが表示されるかどうかはコマンドレットの実装次第だと思うが)

この機能を自作のコマンドレットや関数などに実装するためのコマンドレットが「Write-Verbose」(だと思う)

このコマンドレットでメッセージを書きこんでおくことにより、Verboseパラメータでの詳細情報取得が可能になる。

目的が合っているかどうかはさておき、使い方は以下のような感じ。

001
002
003
004
005
006
007
008
009

function directory($path,[switch]$verbose)
{
 
dir $path | tee -variable files
  Write-Verbose ($files | group{$_.extension} | Out-String ) -Verbose:$verbose
}
"◆◆◆normal---"
directory $pshome 
"◆◆◆verbose--"
directory $pshome -verbose

image

ちなみに、SwitchパラメータをTrue、Flseで指定するには、
「パラメータ名:$true」の様にコロンに続けて指定する。

2011年9月27日火曜日

◆Powershellで「.NET Framework 4.0」を使う

PowerShell: ◆Join-Pathの引数を配列対応にするで、ふと本家.NETの方はどうなのだろうとちょっと調べたら、Ver4.0から配列のPathを繋ぐことが出来るらしい。

2011-09-27 18h16_38

ただし、Powershellでは.NETの2.0が使われているようなのでそのままではこのオーバーロードを使うことは出来ない。

4.0を使うにはっと調べたら、単純にApp.Configを書けば良いらしい。
こんな感じのようだ。

<?xml version="1.0"?>  
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>


こいつを、




PS>notepad (Join-Path $pshome powershell.exe.config)


で、書きこんでやればOK


2011-09-27 18h26_03


まぁ、そこまでしてポータブルじゃないコードを書く必要もないと思うのでCombine自体は使わないと思うが、「.NET 4.0」を使う方法もあるということは覚えておいても良いのかもしれない。

2011年9月26日月曜日

◆Join-Pathの引数を配列対応にする

ファイル処理を行なっているとJoin-Pathをネストして使いたい時が結構ある。Pathを3つとか4つとか指定していっぺんにJoinしてくれると良いのだが、どうもそのような機能は無さそう。

ということで簡単な関数を作ってみた。

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

function Join-MPath
{
 
if(!$args.Count){return
}
 
$rtnPath = $args[0]
  foreach($p in $args[1..$args.Count]
)
  {
   
$rtnPath = Join-Path $rtnPath $p
  }
 
$rtnPath
}

"---"
Join-MPath 
"---"
Join-MPath "c:" 
"---"
Join-MPath "c:" "windows" 
"---"
Join-MPath "c:" "\windows\" "\system32"

2011-09-26 10h22_57

関数自体は何の変哲もないが、個人的には結構便利。


牟田口さんからコメントを頂きました。

いつも有益な情報をありがとうございます。
パイプで繋ぐ方法、良いですね。Powershellっぽくて。

使わせてきただきます。(__)

2011年9月20日火曜日

◆パラメータをフォワードする

Forwarding Parameters - Power Tips - Powershell.com Powershell Scripts, Tips and ResourcesにいかにもTipsというのがあったので紹介。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

function dir-name($path, $include,$erroraction) {
Get-ChildItem -Path $path -Include $include -ErrorAction $erroraction
}

function dir-name2($path, $include,$erroraction) {
Get-ChildItem @PSBoundParameters
}

function dir-name3($path, $include,$erroraction) {
Get-ChildItem @PSBoundParameters -Exclude "d*"
}

"dir-name"
dir-name ".\*" "*.accdb" 
"continue"
"dir-name2"

dir-name2 ".\*" "*.accdb" 
"continue"
"dir-name3"

dir-name3 ".\*" "*.accdb" "continue"

image

関数の引数で受け取ったパラメータを内部で実行するコマンドレットのパラメータにそのまま渡す例である。

dir-name関数はごく普通に指定した場合。

dir-name2では分配演算子を使って$PSBoundParameters自動変数をコマンドレットに引き渡している。
$PSBoundParameters自動変数は関数に渡された引数が連想配列で保持されている。

パラメーターを追加して実行する場合はdir-name3の様にすれば良い。

2011年9月13日火曜日

◆ソートのカスタマイズ

ActiveDirectoryからユーザー情報を取ってきて表示する際に独自の並び順で並べたいことがある。

例えば、役職などでは基本的に偉い順で並べたいのだが、単純に日本語で登録している場合は意図したとおりには並ばない。

幸い、Sortコマンドレットはソートプロパティに集計プロパティが指定できるのでそれを使うとこんな感じでカスタマイズが可能だ。

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

$dmAUsers = Get-QADGroupMember -Identity "Domain users" -Service "A.hoge.co.jp"
$dmBUsers = Get-QADGroupMember -Identity "Domain users" -Service "B.hoge.co.jp"

$dmAUsers + $dmBUsers   |
 
 
sort domain,department,
     @{expression=
{
     
switch ($_.
title){
       
"本部長"{1;break
}
       
"部長"{2;break
}
       
"副部長"{3;break
}
       
"主任"{4;break
}
       
"係員"{5;break
}
       
default{6;break
}
      }
    }} 
|
    select domain,department,title,name,email,samaccountname
<!--EndFragment

他ドメインの情報も必要だったのでPowerQuestの拡張コマンドを使ってユーザーを取得している。

ソートコマンドレットで並べたい順番に数字に置き換えてあげれば独自の並び順を実現できる。