2015年4月21日火曜日

◆Splatting(分配演算子)

以前ちょっとだけ以下で書いたことのある機能。
PowerShell: ◆分配演算子

もう少しわかり易い例が載っていたのでメモしておく。
Using Splatting - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

この記事に対する質問で「どんな時に使うんだい?」ってのあったが、そこが大事。

使いでがあるのは、関数などで受け取ったパラメータをそのままフォワードしたりする時。

image

(私は、引数が長くなって見づらくなる時によく使っている)

ちなみに「Splat」は「ぶつけて平らに延ばす」的な意味。
PowerShellの何かのエラーメッセージで「分配演算子」と訳していたので私はその名前を使っている。

Help的には3.0から「about_splatting」として載っているようだ。
相変わらず日本語訳はされていないので正式になんという日本語名かは不明。

PowerShellに限らず、日本語訳は機械翻訳程度しかやらないのがMSの主流になってきているようなので、これからは一段と英語力が要求されそうだ。

2015年4月16日木曜日

◆Gourp-Object からのHashTable

ちょっと躓いたのでメモ。

001
002
003
004
005
006
007

$HashService = Get-WmiObject Win32_Service | 
 
Group-Object State -AsHashTable
$HashService.Stopped 
"◆◆◆◆"
$HashService2 = Get-Service |
 
 
Group-Object Status -AsHashTable 
$HashService2.Stopped

$HashService.Stoppedは参照できるが、$HashService2.Stoppedの方は参照できない。
AsStringをつければうまくいくことは判っているが、なぜ違いが出るのだろう・・・。

あとで調査。

2015年4月10日金曜日

◆カスタムオブジェクトに表示用の型を指定する

Faking Object Type - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

「PSCustomObject」を作るときに既存の型を表示用に指定することができるそうな。

image

「PSTypeName」として型を指定しておくと表示するときに、その型のフォーマットで表示してくれる。
メンバーを表示してみると「CodeProperty」というちょっと変わったプロパティで保持されているのが判る。

image

既存の一覧に独自のオブジェクトを追加して一緒に表示するなんて使い方ができたりするのかな。

image

image

ただし、この機能はVer.3.0以降が要求される。

2015年4月7日火曜日

◆Wordのテンプレートを指定する

Wordの独自テンプレートを置いていたサーバーがリプレースされてパスが変わってしまったため、Word文書のテンプレートパスを一括で変更するスクリプトを作った。

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

$iPath = "\\hogeServer\public\*"
$ext = "docx"

$targetDocs = Get-ChildItem -Path $iPath -Include "*.$ext" -r 
$word = new-object -comObject "Word.Application" 
$word.Visible = $true

foreach($doc in $targetDocs
){ 
   
$word.Documents.Open($doc.fullname) | Out-Null
 
   
#Template設定
        $word.ActiveDocument.AttachedTemplate =
 
           
"\\hogehogeServer\pub\テンプレート.dotx"

    #保存して終了
    [void]$word.Application.ActiveDocument.
Save()
   
[void]$word.Application.ActiveDocument.
Close()
}


$word.Quit()
<!--EndFrag

ちなみに、ファイルサーバーの名前が変わってしまうと、Hostsファイルやlmhostsファイルでアドレスを置き換えてあげてもうまくいかない。(場合による?)

サーバー側のレジストリーでエイリアス名を設定すると良さそうではあるが・・・。

2015年4月2日木曜日

◆High Impact のコマンドレットを探す

Discovering High Impact Cmdlets - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

上記の記事で、High Impactのコマンドレットを探すスクリプトが紹介されている。
(High Impact  とは、確認ダイアログが表示されるコマンド?)
image

改行とかを若干調整して以下にメモしておく。

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

Get-Command -CommandType Cmdlet | % { 
   
$type = $_.
ImplementingType
   
if ($type
)
    {
       
$type.GetCustomAttributes($true) | ? { $_.VerbName } |
        Select
 @{
            Name
='Name'
            Expression={'{0}-{1}' -f $_.VerbName, $_.
NounName}
        }
,ConfirmImpact
    }
} 
| 
Sort ConfirmImpact -Descending

結果はこんな感じ。
image

ただし、Set-ExecutionPolicyなどはHighにならないので、単純に確認ダイアログが出るかどうかでもないのか・・・。

2015年2月4日水曜日

◆文字の出現回数を調べる

とりあえず文字コードはユニコードが前提。

特殊文字、たとえばタブなどを検索する場合は、
$findChar = “`t”
として指定する。

001
002
003
004
005
006

$findChar = "探"
$inputFile = "d:\Desktop\uniTest.txt"

$findCharCD = [int][char]
$findChar
$text
=[System.IO.File]::ReadAllText($inputFile
)
@(
[int[]][char[]]$text -eq $findCharCD).Count

--- 20150209 追記 ---

この記事が結構見られているようなので別の方法を補足。

ネットを見てみると、検索文字列を空文字に置き換えて、減った長さから文字数をカウントするという方法が多く使われているようだ。

なので、一応その方法も記載しておく。
この方法だと単語での検索もできるのでベターかも。(速さ的にもこちらが速そう)

001
002
003
004
005
006

$findChar = "探す"
$inputFile = "d:\Desktop\uniTest.txt"

$text=[System.IO.File]::ReadAllText($inputFile
)
(
$text.Length -
 
 
$text.Replace($findChar,"").Length)/$findChar.Length

SJISファイルの場合は、ReadAllTextに文字コードを指定する。
ReadAllText($inputFile,[System.Text.Encoding]::GetEncoding("shift_jis"))
といった感じだろうか。

--- 20150323 追記 ---

ついでに、正規表現を使う場合はRegexクラスを使うか、PowerShellのReplace演算子を使う。

ここではReplace演算子に書き換えてみる。

001
002
003
004
005
006

$findChar = "\w探す"
$inputFile = "d:\Desktop\uniTest.txt"

$text=[System.IO.File]::ReadAllText($inputFile
)
(
$text.Length -
 
  (
$text -replace $findChar,"").Length)/3

findCharの長さは汎用的には求められないと思うのでここでは固定値で指定した。
検索する文字列長が可変の場合は今回の方式では辛くなるので、地道に先頭からなめて行くしか無いのかな・・・。

2015年1月7日水曜日

◆明示的に追加されたPermissionを表示する

明示的に追加された(継承されたものでは無いって事かな)Permissionを表示するサンプル。
この例では「C:\Windows」配下のフォルダを再帰してGridViewに表示している。
Creating NTFS Security Report - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

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

$Path = 'C:\windows'
Get-ChildItem -Path $Path -Recurse  -ErrorAction SilentlyContinue |
?{$_.PSIsContainer} |
ForEach-Object
 {
   
$result = $_ |
 
   
Select -Property FullName, ExplicitePermissions, Count, Preview
    $result.ExplicitePermissions =
 
        (
Get-Acl -Path $_.FullName -ErrorAction SilentlyContinue).Access |
 
       
Where-Object { $_.isInherited -eq $false
 }
   
$result.Count = $result.ExplicitePermissions.
Count
   
$result.Preview =
 
   
$result.ExplicitePermissions.IdentityReference -join ','
    if ($result.ExplicitePermissions.Count -gt 0
)
    {
       
$result | Select fullname,count,preview
    }
} 
| Out-GridView